Index: _dev/fckreleaser.xml
===================================================================
--- _dev/fckreleaser.xml	(revision 1591)
+++ _dev/fckreleaser.xml	(working copy)
@@ -28,13 +28,14 @@
 	<IgnoreDir path="_testcases" />
 
 	<!--
-		The following directory should not existing in the development version,
+		The following files should not existing in the development version,
 		but we leave it here just in case the packager has been run by mistake.
 	-->
-	<IgnoreDir path="editor/js" />
+	<IgnoreFile path="editor/js/fckeditorcode_ie.js" />
+	<IgnoreFile path="editor/js/fckeditorcode_gecko.js" />
 
 	<!--
-	<IgnoreFile path="anyfile.xxx" />
+	<IgnoreDir path="dir/path" />
 	-->
 
 </Release>
Index: _samples/adobeair/application.xml
===================================================================
--- _samples/adobeair/application.xml	(revision 0)
+++ _samples/adobeair/application.xml	(revision 0)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<application xmlns="http://ns.adobe.com/air/application/1.0.M6">
+	<!-- AIR Application Descriptor File. See http://www.adobe.com/go/air_1.0_application_descriptor. -->
+	<id>net.fckeditor.air.samples.sample01</id>
+	<name>FCKeditor Sample Application 1.0</name>
+	<version>1.0</version>
+	<filename>FCKeditor AIR Sample</filename>
+	<description>This is a sample AIR application including FCKeditor.</description>
+	<copyright>Copyright (C) 2003-2008 Frederico Caldeira Knabben</copyright>
+	<initialWindow>
+		<content>_samples/adobeair/sample01.html</content>
+		<title>FCKeditor AIR Sample</title>
+		<systemChrome>standard</systemChrome>
+		<transparent>false</transparent>
+		<visible>true</visible>
+		<minimizable>true</minimizable>
+		<maximizable>true</maximizable>
+		<resizable>true</resizable>
+		<x>100</x>
+		<y>80</y>
+		<width>800</width>
+		<height>600</height>
+		<minSize>600 400</minSize>
+	</initialWindow>
+	<installFolder>FCKeditor/AIR Samples/Sample01</installFolder>
+	<programMenuFolder>FCKeditor/AIR Samples</programMenuFolder>
+	<customUpdateUI>false</customUpdateUI>
+	<allowBrowserInvocation>false</allowBrowserInvocation>
+</application>
Index: _samples/adobeair/run.bat
===================================================================
--- _samples/adobeair/run.bat	(revision 0)
+++ _samples/adobeair/run.bat	(revision 0)
@@ -0,0 +1,26 @@
+@ECHO OFF
+
+::
+:: FCKeditor - The text editor for Internet - http://www.fckeditor.net
+:: Copyright (C) 2003-2008 Frederico Caldeira Knabben
+::
+:: == BEGIN LICENSE ==
+::
+:: Licensed under the terms of any of the following licenses at your
+:: choice:
+::
+::  - GNU General Public License Version 2 or later (the "GPL")
+::    http://www.gnu.org/licenses/gpl.html
+::
+::  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+::    http://www.gnu.org/licenses/lgpl.html
+::
+::  - Mozilla Public License Version 1.1 or later (the "MPL")
+::    http://www.mozilla.org/MPL/MPL-1.1.html
+::
+:: == END LICENSE ==
+::
+
+:: adl [-runtime runtime-directory] [-pubId publisher-id] [-nodebug] application.xml [rootdirectory] [-- arguments]
+
+"C:\Adobe AIR SDK\bin\adl" application.xml ../../
Index: _samples/adobeair/sample01.html
===================================================================
--- _samples/adobeair/sample01.html	(revision 0)
+++ _samples/adobeair/sample01.html	(revision 0)
@@ -0,0 +1,58 @@
+﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Sample Adobe AIR application.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>FCKeditor - Adobe AIR Sample</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<meta name="robots" content="noindex, nofollow" />
+	<link href="../sample.css" rel="stylesheet" type="text/css" />
+	<script type="text/javascript" src="../../fckeditor.js"></script>
+	<style type="text/css">
+		body { margin: 10px ; }
+	</style>
+</head>
+<body>
+	<h1>
+		FCKeditor - Adobe AIR Sample
+	</h1>
+	<div>
+		This sample loads FCKeditor with full features enabled.
+	</div>
+	<hr />
+	<script type="text/javascript">
+
+// Automatically calculates the editor base path based on the _samples directory.
+// This is usefull only for these samples. A real application should use something like this:
+// oFCKeditor.BasePath = '/fckeditor/' ;	// '/fckeditor/' is the default value.
+var sBasePath = document.location.href.substring(0,document.location.href.lastIndexOf('_samples')) ;
+
+var oFCKeditor = new FCKeditor( 'FCKeditor1' ) ;
+oFCKeditor.BasePath	= sBasePath ;
+oFCKeditor.Height	= 400 ;
+oFCKeditor.Value	= '<p>FCKeditor is in the <strong>AIR</strong>!<\/p>' ;
+oFCKeditor.Create() ;
+
+	</script>
+</body>
+</html>
Index: _whatsnew.html
===================================================================
--- _whatsnew.html	(revision 1591)
+++ _whatsnew.html	(working copy)
@@ -37,6 +37,8 @@
 	<p>
 		New Features and Improvements:</p>
 	<ul>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/1886">#1886</a>] <strong>
+			Adobe AIR</strong> compatibility.</li>
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/123">#123</a>] Full support
 			for <strong>document.domain</strong> with automatic domain detection.</li>
 		<li>New language file for <strong>Canadian French</strong>.</li>
Index: editor/_source/classes/fckeditingarea.js
===================================================================
--- editor/_source/classes/fckeditingarea.js	(revision 1591)
+++ editor/_source/classes/fckeditingarea.js	(working copy)
@@ -133,6 +133,9 @@
 			oDoc.close() ;
 		}
 
+		if ( FCKBrowserInfo.IsAIR )
+			FCKAdobeAIR.EditingArea_Start( oDoc, html ) ;
+
 		// Firefox 1.0.x is buggy... ohh yes... so let's do it two times and it
 		// will magically work.
 		if ( FCKBrowserInfo.IsGecko10 && !secondCall )
Index: editor/_source/classes/fckpanel.js
===================================================================
--- editor/_source/classes/fckpanel.js	(revision 1591)
+++ editor/_source/classes/fckpanel.js	(working copy)
@@ -80,6 +80,9 @@
 		oDocument.write( '<html><head>' + sBase + '<\/head><body style="margin:0px;padding:0px;"><\/body><\/html>' ) ;
 		oDocument.close() ;
 
+		if( FCKBrowserInfo.IsAIR )
+			FCKAdobeAIR.Panel_Contructor( oDocument, window.document.location ) ;
+
 		FCKTools.AddEventListenerEx( oIFrameWindow, 'focus', FCKPanel_Window_OnFocus, this ) ;
 		FCKTools.AddEventListenerEx( oIFrameWindow, 'blur', FCKPanel_Window_OnBlur, this ) ;
 	}
Index: editor/_source/fckeditorapi.js
===================================================================
--- editor/_source/fckeditorapi.js	(revision 1591)
+++ editor/_source/fckeditorapi.js	(working copy)
@@ -39,7 +39,7 @@
 		// code (like JSON) can extend the Object prototype and we get then extra oEditor
 		// objects that aren't really FCKeditor instances.
 		var sScript =
-			'var FCKeditorAPI = {' +
+			'window.FCKeditorAPI = {' +
 				'Version : "[Development]",' +
 				'VersionBuild : "[DEV]",' +
 				'__Instances : new Object(),' +
@@ -111,6 +111,10 @@
 				// following seams to work well.
 				eval.call( oParentWindow, sScript ) ;
 			}
+			else if( FCKBrowserInfo.IsAIR )
+			{
+				FCKAdobeAIR.FCKeditorAPI_Evaluate( oParentWindow, sScript ) ;
+			}
 			else if ( FCKBrowserInfo.IsSafari || FCKBrowserInfo.IsGecko19 )
 			{
 				// oParentWindow.eval in Safari and Gran Paradiso executes in the calling window
Index: editor/_source/internals/fckbrowserinfo.js
===================================================================
--- editor/_source/internals/fckbrowserinfo.js	(revision 1591)
+++ editor/_source/internals/fckbrowserinfo.js	(working copy)
@@ -31,6 +31,7 @@
 	IsGecko		: s.Contains('gecko/'),
 	IsSafari	: s.Contains(' applewebkit/'),		// Read "IsWebKit"
 	IsOpera		: !!window.opera,
+	IsAIR		: s.Contains(' adobeair/'),
 	IsMac		: s.Contains('macintosh')
 } ;
 
Index: editor/_source/internals/fcktoolbarset.js
===================================================================
--- editor/_source/internals/fcktoolbarset.js	(revision 1591)
+++ editor/_source/internals/fcktoolbarset.js	(working copy)
@@ -50,7 +50,10 @@
 			var oOutMatch = sLocation.match( /^Out:(.+)\((\w+)\)$/ ) ;
 			if ( oOutMatch )
 			{
-				eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ;
+				if ( FCKBrowserInfo.IsAIR )
+					FCKAdobeAIR.ToolbarSet_GetOutElement( window, oOutMatch ) ;
+				else
+					eToolbarTarget = eval( 'parent.' + oOutMatch[1] ).document.getElementById( oOutMatch[2] ) ;
 			}
 			else
 			{
@@ -111,6 +114,9 @@
 					+ '</script></head><body style="overflow: hidden">' + document.getElementById( 'xToolbarSpace' ).innerHTML + '</body></html>' ) ;
 			eTargetDocument.close() ;
 
+			if( FCKBrowserInfo.IsAIR )
+				FCKAdobeAIR.ToolbarSet_InitOutFrame( eTargetDocument ) ;
+
 			FCKTools.AddEventListener( eTargetDocument, 'contextmenu', FCKTools.CancelEvent ) ;
 
 			// Load external resources (must be done here, otherwise Firefox will not
Index: editor/fckeditor.html
===================================================================
--- editor/fckeditor.html	(revision 1591)
+++ editor/fckeditor.html	(working copy)
@@ -198,6 +198,10 @@
 	</script>
 	<script type="text/javascript">
 
+// Adobe AIR compatibility file.
+if ( FCKBrowserInfo.IsAIR )
+	LoadScript( 'js/fckadobeair.js' ) ;
+
 if ( FCKBrowserInfo.IsIE )
 {
 	// Remove IE mouse flickering.
Index: editor/js/fckadobeair.js
===================================================================
--- editor/js/fckadobeair.js	(revision 0)
+++ editor/js/fckadobeair.js	(revision 0)
@@ -0,0 +1,166 @@
+﻿/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2008 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * Compatibility code for Adobe AIR.
+ */
+
+if ( FCKBrowserInfo.IsAIR )
+{
+	var FCKAdobeAIR = (function()
+	{
+		/*
+		 * ### Private functions.
+		 */
+
+		function _GetDocumentHead( doc )
+		{
+			var head ;
+			var heads = doc.getElementsByTagName( 'head' ) ;
+
+			if( heads && heads[0] )
+				head = heads[0] ;
+			else
+			{
+				head = doc.createElement( 'head' ) ;
+				doc.documentElement.insertBefore( head, doc.documentElement.firstChild ) ;
+			}
+
+			return head ;
+		} ;
+
+		/*
+		 * ### Public interface.
+		 */
+		return {
+			FCKeditorAPI_Evaluate : function( parentWindow, script )
+			{
+				// TODO : This one doesn't work always. The parent window will
+				// point to an anonymous function in this window. If this
+				// window is destroyied the parent window will be pointing to
+				// an invalid reference.
+
+				// Evaluate the script in this window.
+				eval( script ) ;
+
+				// Point the FCKeditorAPI property of the parent window to the
+				// local reference.
+				parentWindow.FCKeditorAPI = window.FCKeditorAPI ;
+			},
+
+			EditingArea_Start : function( doc, html )
+			{
+				// Get the HTML for the <head>.
+				var headInnerHtml = html.match( /<head>([\s\S]*)<\/head>/i )[1] ;
+
+				if ( headInnerHtml && headInnerHtml.length > 0 )
+				{
+					// Inject the <head> HTML inside a <div>.
+					// Do that before _GetDocumentHead because WebKit moves
+					// <link css> elements to the <head> at this point.
+					var div = doc.createElement( 'div' ) ;
+					div.innerHTML = headInnerHtml ;
+
+					// Move the <div> nodes to <head>.
+					FCKDomTools.MoveChildren( div, _GetDocumentHead( doc ) ) ;
+				}
+
+				doc.body.innerHTML = html.match( /<body>([\s\S]*)<\/body>/i )[1] ;
+
+				//prevent clicking on hyperlinks and navigating away
+				doc.addEventListener('click', function( ev )
+					{
+						ev.preventDefault() ;
+						ev.stopPropagation() ;
+					}, true ) ;
+			},
+
+			Panel_Contructor : function( doc, baseLocation )
+			{
+				var head = _GetDocumentHead( doc ) ;
+
+				// Set the <base> href.
+				head.appendChild( doc.createElement('base') ).href = baseLocation ;
+
+				doc.body.style.margin	= '0px' ;
+				doc.body.style.padding	= '0px' ;
+			},
+
+			ToolbarSet_GetOutElement : function( win, outMatch )
+			{
+				var toolbarTarget = win.parent ;
+
+				var targetWindowParts = outMatch[1].split( '.' ) ;
+				while ( targetWindowParts.length > 0 )
+				{
+					var part = targetWindowParts.shift() ;
+					if ( part.length > 0 )
+						toolbarTarget = toolbarTarget[ part ] ;
+				}
+
+				toolbarTarget = toolbarTarget.document.getElementById( outMatch[2] ) ;
+			},
+
+			ToolbarSet_InitOutFrame : function( doc )
+			{
+				var head = _GetDocumentHead( doc ) ;
+
+				head.appendChild( doc.createElement('base') ).href = window.document.location ;
+
+				var targetWindow = doc.defaultView;
+
+				targetWindow.adjust = function()
+				{
+					targetWindow.frameElement.height = doc.body.scrollHeight;
+				} ;
+
+				targetWindow.onresize = targetWindow.adjust ;
+				targetWindow.setTimeout( targetWindow.adjust, 0 ) ;
+
+				doc.body.style.overflow = 'hidden';
+				doc.body.innerHTML = document.getElementById( 'xToolbarSpace' ).innerHTML ;
+			}
+		} ;
+	})();
+
+	/*
+	 * ### Overrides
+	 */
+	( function()
+	{
+		// Save references for override reuse.
+		var _Original_FCKPanel_Window_OnFocus	= FCKPanel_Window_OnFocus ;
+		var _Original_FCKPanel_Window_OnBlur	= FCKPanel_Window_OnBlur ;
+
+		FCKPanel_Window_OnFocus = function( e, panel )
+		{
+			// Call the original implementation.
+			_Original_FCKPanel_Window_OnFocus.call( this, e, panel ) ;
+
+			if ( panel._focusTimer )
+				clearTimeout( panel._focusTimer ) ;
+		}
+
+		FCKPanel_Window_OnBlur = function( e, panel )
+		{
+			// Delay the execution of the original function.
+			panel._focusTimer = FCKTools.SetTimeout( _Original_FCKPanel_Window_OnBlur, 100, this, [ e, panel ] ) ;
+		}
+	})();
+}
Index: fckeditor.js
===================================================================
--- fckeditor.js	(revision 1591)
+++ fckeditor.js	(working copy)
@@ -287,8 +287,14 @@
 
 	// Opera 9.50+
 	if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
-			return true ;
+		return true ;
 
+	// Adobe AIR
+	// Checked before Safari because AIR have the WebKit rich text editor
+	// features from Safari 3.0.4, but the version reported is 420.
+	if ( sAgent.indexOf( ' adobeair/' ) != -1 )
+		return ( sAgent.match( / adobeair\/(\d+)/ )[1] >= 1 ) ;	// Build must be at least v1
+
 	// Safari 3+
 	if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
 		return ( sAgent.match( / applewebkit\/(\d+)/ )[1] >= 522 ) ;	// Build must be at least 522 (v3)
