Index: /CKEditor/branches/features/adobeair/_source/core/dom/document.js
===================================================================
--- /CKEditor/branches/features/adobeair/_source/core/dom/document.js	(revision 4405)
+++ /CKEditor/branches/features/adobeair/_source/core/dom/document.js	(revision 4406)
@@ -26,242 +26,253 @@
 CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
 
-CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype,
+CKEDITOR.tools.extend(CKEDITOR.dom.document.prototype,
 	/** @lends CKEDITOR.dom.document.prototype */
-	{
-		/**
-		 * Appends a CSS file to the document.
-		 * @param {String} cssFileUrl The CSS file URL.
-		 * @example
-		 * <b>CKEDITOR.document.appendStyleSheet( '/mystyles.css' )</b>;
-		 */
-		appendStyleSheet : function( cssFileUrl )
-		{
-			if ( this.$.createStyleSheet )
-				this.$.createStyleSheet( cssFileUrl );
-			else
-			{
-				var link = new CKEDITOR.dom.element( 'link' );
-				link.setAttributes(
-					{
-						rel		:'stylesheet',
-						type	: 'text/css',
-						href	: cssFileUrl
-					});
-
-				this.getHead().append( link );
-			}
-		},
-
-		createElement : function( name, attribsAndStyles )
-		{
-			var element = new CKEDITOR.dom.element( name, this );
-
-			if ( attribsAndStyles )
-			{
-				if ( attribsAndStyles.attributes )
-					element.setAttributes( attribsAndStyles.attributes );
-
-				if ( attribsAndStyles.styles )
-					element.setStyles( attribsAndStyles.styles );
-			}
-
-			return element;
-		},
-
-		createText : function( text )
-		{
-			return new CKEDITOR.dom.text( text, this );
-		},
-
-		focus : function()
-		{
-			this.getWindow().focus();
-		},
-
-		/**
-		 * Gets and element based on its id.
-		 * @param {String} elementId The element id.
-		 * @returns {CKEDITOR.dom.element} The element instance, or null if not found.
-		 * @example
-		 * var element = <b>CKEDITOR.document.getById( 'myElement' )</b>;
-		 * alert( element.getId() );  // "myElement"
-		 */
-		getById : function( elementId )
-		{
-			var $ = this.$.getElementById( elementId );
-			return $ ? new CKEDITOR.dom.element( $ ) : null;
-		},
-
-		getByAddress : function( address, normalized )
-		{
-			var $ = this.$.documentElement;
-
-			for ( var i = 0 ; $ && i < address.length ; i++ )
-			{
-				var target = address[ i ];
-
-				if ( !normalized )
-				{
-					$ = $.childNodes[ target ];
+{
+	/**
+	 * Appends a CSS file to the document.
+	 * @param {String} cssFileUrl The CSS file URL.
+	 * @example
+	 * <b>CKEDITOR.document.appendStyleSheet( '/mystyles.css' )</b>;
+	 */
+	appendStyleSheet : function( cssFileUrl )
+	{
+		if ( this.$.createStyleSheet )
+			this.$.createStyleSheet(cssFileUrl);
+		else
+		{
+			var link = new CKEDITOR.dom.element('link');
+			link.setAttributes(
+			{
+				rel		:'stylesheet',
+				type	: 'text/css',
+				href	: cssFileUrl
+			});
+
+			this.getHead().append(link);
+		}
+	},
+
+	createElement : function( name, attribsAndStyles )
+	{
+		var element = new CKEDITOR.dom.element(name, this);
+
+		if ( attribsAndStyles )
+		{
+			if ( attribsAndStyles.attributes )
+				element.setAttributes(attribsAndStyles.attributes);
+
+			if ( attribsAndStyles.styles )
+				element.setStyles(attribsAndStyles.styles);
+		}
+
+		return element;
+	},
+
+	createText : function( text )
+	{
+		return new CKEDITOR.dom.text(text, this);
+	},
+
+	focus : function()
+	{
+		this.getWindow().focus();
+	},
+
+	/**
+	 * Gets and element based on its id.
+	 * @param {String} elementId The element id.
+	 * @returns {CKEDITOR.dom.element} The element instance, or null if not found.
+	 * @example
+	 * var element = <b>CKEDITOR.document.getById( 'myElement' )</b>;
+	 * alert( element.getId() );  // "myElement"
+	 */
+	getById : function( elementId )
+	{
+		var $ = this.$.getElementById(elementId);
+		return $ ? new CKEDITOR.dom.element($) : null;
+	},
+
+	getByAddress : function( address, normalized )
+	{
+		var $ = this.$.documentElement;
+
+		for ( var i = 0; $ && i < address.length; i++ )
+		{
+			var target = address[ i ];
+
+			if ( !normalized )
+			{
+				$ = $.childNodes[ target ];
+				continue;
+			}
+
+			var currentIndex = -1;
+
+			for ( var j = 0; j < $.childNodes.length; j++ )
+			{
+				var candidate = $.childNodes[ j ];
+
+				if ( normalized === true &&
+					 candidate.nodeType == 3 &&
+					 candidate.previousSibling &&
+					 candidate.previousSibling.nodeType == 3 )
+				{
 					continue;
 				}
 
-				var currentIndex = -1;
-
-				for (var j = 0 ; j < $.childNodes.length ; j++ )
-				{
-					var candidate = $.childNodes[ j ];
-
-					if ( normalized === true &&
-							candidate.nodeType == 3 &&
-							candidate.previousSibling &&
-							candidate.previousSibling.nodeType == 3 )
-					{
-						continue;
-					}
-
-					currentIndex++;
-
-					if ( currentIndex == target )
-					{
-						$ = candidate;
-						break;
-					}
+				currentIndex++;
+
+				if ( currentIndex == target )
+				{
+					$ = candidate;
+					break;
 				}
 			}
-
-			return $ ? new CKEDITOR.dom.node( $ ) : null;
-		},
-
-		getElementsByTag : function( tagName, namespace )
-		{
-			if ( !CKEDITOR.env.ie && namespace )
-				tagName = namespace + ':' + tagName;
-			return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
-		},
-
-		/**
-		 * Gets the &lt;head&gt; element for this document.
-		 * @returns {CKEDITOR.dom.element} The &lt;head&gt; element.
-		 * @example
-		 * var element = <b>CKEDITOR.document.getHead()</b>;
-		 * alert( element.getName() );  // "head"
-		 */
-		getHead : function()
-		{
-			var head = this.$.getElementsByTagName( 'head' )[0];
-			head = new CKEDITOR.dom.element( head );
-
-			return (
-			/** @ignore */
-			this.getHead = function()
+		}
+
+		return $ ? new CKEDITOR.dom.node($) : null;
+	},
+
+	getElementsByTag : function( tagName, namespace )
+	{
+		if ( !CKEDITOR.env.ie && namespace )
+			tagName = namespace + ':' + tagName;
+		return new CKEDITOR.dom.nodeList(this.$.getElementsByTagName(tagName));
+	},
+
+	/**
+	 * Gets the &lt;head&gt; element for this document.
+	 * @returns {CKEDITOR.dom.element} The &lt;head&gt; element.
+	 * @example
+	 * var element = <b>CKEDITOR.document.getHead()</b>;
+	 * alert( element.getName() );  // "head"
+	 */
+	getHead : function()
+	{
+		var head = this.$.getElementsByTagName( 'head' )[ 0 ];
+		head = new CKEDITOR.dom.element( head );
+
+		return (
+			/** @ignore */
+				this.getHead = function()
 				{
 					return head;
 				})();
-		},
-
-		/**
-		 * Gets the &lt;body&gt; element for this document.
-		 * @returns {CKEDITOR.dom.element} The &lt;body&gt; element.
-		 * @example
-		 * var element = <b>CKEDITOR.document.getBody()</b>;
-		 * alert( element.getName() );  // "body"
-		 */
-		getBody : function()
-		{
-			var body = new CKEDITOR.dom.element( this.$.body );
-
-			return (
-			/** @ignore */
-			this.getBody = function()
+	},
+
+	/**
+	 * Gets the &lt;body&gt; element for this document.
+	 * @returns {CKEDITOR.dom.element} The &lt;body&gt; element.
+	 * @example
+	 * var element = <b>CKEDITOR.document.getBody()</b>;
+	 * alert( element.getName() );  // "body"
+	 */
+	getBody : function()
+	{
+		var body = new CKEDITOR.dom.element(this.$.body);
+
+		return (
+			/** @ignore */
+				this.getBody = function()
 				{
 					return body;
 				})();
-		},
-
-		getDocumentElement : function()
-		{
-			var documentElement = new CKEDITOR.dom.element( this.$.documentElement );
-
-			return (
-			/** @ignore */
-			this.getDocumentElement = function()
+	},
+
+	getDocumentElement : function()
+	{
+		var documentElement = new CKEDITOR.dom.element(this.$.documentElement);
+
+		return (
+			/** @ignore */
+				this.getDocumentElement = function()
 				{
 					return documentElement;
 				})();
-		},
-
-		/**
-		 * Gets the window object that holds this document.
-		 * @returns {CKEDITOR.dom.window} The window object.
-		 * @example
-		 */
-		getWindow : function()
-		{
-			var win = new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
-
-			return (
-			/** @ignore */
-			this.getWindow = function()
+	},
+
+	/**
+	 * Gets the window object that holds this document.
+	 * @returns {CKEDITOR.dom.window} The window object.
+	 * @example
+	 */
+	getWindow : function()
+	{
+		var win = new CKEDITOR.dom.window(this.$.parentWindow || this.$.defaultView);
+
+		return (
+			/** @ignore */
+				this.getWindow = function()
 				{
 					return win;
 				})();
-		},
-
-		write : function( html )
-		{
-			if( !CKEDITOR.env.air )
-			{
-				this.$.open();
-				this.$.write( html );
-				this.$.close();
-			}
-			else
-			{
-				var doc = this;
-				// Grab all the <link> and <style> tags.
-				var stylesHtml = '';
-				html.replace( /<style[^>]*>[\s\S]*<\/style>|<link[^>]*?>/gi, function( match )
-				{
-					stylesHtml += match;
-				} );
-
-				if ( stylesHtml )
-				{
-					// 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 = new CKEDITOR.dom.element( 'div', doc );
-					div.setHtml( stylesHtml );
-					var getDocumentHead = function( 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 ;
-					} ;
-
-					// Move the <div> nodes to <head>.
-					div.moveChildren( new CKEDITOR.dom.element( getDocumentHead( doc.$ ) ) ) ;
+	},
+
+	write : function( html )
+	{
+		// document.write() or document.writeln() fail silently after
+		// the page load event has been handled in Adobe AIR.
+		// DOM manipulation could be used instead.
+		if ( CKEDITOR.env.air && this.getBody() )
+		{
+			var doc = this;
+
+			// Grab all the <link>s and <style>s.
+			var styleSheetLinks = [],
+					styleTexts = [];
+			html.replace( /<style[^>]*>([\s\S]*?)<\/style>/gi, function ( match, styleText )
+			{
+				styleTexts.push( styleText );
+			} );
+
+			html.replace( /<link[^>]*?>/gi, function( linkHtml )
+			{
+				styleSheetLinks.push( linkHtml );
+			} );
+
+			if ( styleSheetLinks.length )
+			{
+				// 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 = new CKEDITOR.dom.element( 'div', doc );
+				div.setHtml( styleSheetLinks.join( '' ) );
+				// Move the <div> nodes to <head>.
+				div.moveChildren( this.getHead( doc ) );
+			}
+
+			// Create style nodes for inline css.
+			// ( <style> content doesn't applied when setting via innerHTML )
+			var nums = styleTexts.length;
+			if ( nums )
+			{
+				var head = this.getHead( doc );
+				for ( var i = 0; i < nums; i++ )
+				{
+					var node = head.append( 'style' );
+					node.setAttribute( "type", "text/css" );
+					node.append( doc.createText( styleTexts[ i ] ) );
 				}
-
-				var bodyMatch = html.match( /<body[^>]*>([\s\S]*)<\/body>/i ),
-					bodyContent = bodyMatch && bodyMatch[ 1 ],
-					body = bodyMatch && CKEDITOR.htmlParser.fragment.fromHtml( bodyMatch[ 0 ] ).children[ 0 ],
+			}
+
+			var bodyHtml = html.match( /<body[^>]*>([\s\S]*)<\/body>/i ),
+					bodyContent = bodyHtml && bodyHtml[ 1 ],
+					body = bodyHtml && CKEDITOR.htmlParser.fragment.fromHtml( bodyHtml[ 0 ] ).children[ 0 ],
 					bodyAttrs = body.attributes,
 					docBody = doc.getBody();
 
+			if( bodyContent )
+			{
 				docBody.setHtml( bodyContent );
-				if( bodyAttrs )
-					docBody.setAttributes( bodyAttrs );
-			}
-		}
-	});
+				bodyAttrs && docBody.setAttributes( bodyAttrs );
+			}
+		}
+		else
+		{
+			this.$.open();
+			this.$.write(html);
+			this.$.close();
+		}
+	}
+});
+
Index: /CKEditor/branches/features/adobeair/_source/plugins/adobeair/plugin.js
===================================================================
--- /CKEditor/branches/features/adobeair/_source/plugins/adobeair/plugin.js	(revision 4405)
+++ /CKEditor/branches/features/adobeair/_source/plugins/adobeair/plugin.js	(revision 4406)
@@ -8,127 +8,139 @@
 	init : function( editor )
 	{
-		function convertInlineHandlers( container, eventNameList )
-		{
-			for ( var i = 0; i < eventNameList.length; i++ )
-			{
-				( function( eventName ){
 
-					var targetList =
-						 container.eachChildWithAttribute( 'on'+ eventName, function( item )
-					{
-						item.on( eventName, function( evt )
-						{
-							var inlineEventHandler = item.getAttribute( 'on' + eventName ),
-								callFunc = /callFunction\(([^)]+)\)/.exec( inlineEventHandler ),
-								callFuncArgs = callFunc &&  callFunc[ 1 ].split( ',' ),
-								preventDefault = /return false;/.test( inlineEventHandler );
+		// Body doesn't get default margin on AIR. 
+		editor.addCss( 'body { padding: 8px }' );
 
 
-							if ( callFuncArgs )
+		// document.querySelectAll() is not presented in AIR.
+		function eachChildWithAttribute( element, name, processor )
+		{
+		};
+
+
+		var eventNameList = [ 'click', 'keydown', 'mousedown', 'keypress' ];
+
+		// any inline event callbacks assigned via innerHTML/outerHTML such as
+		// onclick/onmouseover, are ignored in AIR.
+		// Use DOM2 event listeners to substitue inline handlers instead.
+		function convertInlineHandlers( container )
+		{
+			// TODO: document.querySelectorAll is not supported in AIR.
+			var children = container.getElementsByTag( '*' ),
+				count = children.count(),
+				child;
+			for ( var i = 0; i < count; i++ )
+			{
+				child = children.getItem( i );
+
+				( function( node )
+				{
+					for ( var j = 0; j < eventNameList.length; j++ )
+					{
+						( function( eventName )
+						{
+
+							if( node.hasAttribute( 'on' + eventName ) )
 							{
-								var nums = callFuncArgs.length,
-									argName;
-								for ( var i = 0; i < nums; i++ )
+								node.on( eventName, function( evt )
 								{
-									callFuncArgs[ i ] = argName
-										= CKEDITOR.tools.trim( callFuncArgs[ i ] );
+									var inlineEventHandler = node.getAttribute( 'on' + eventName ),
+										callFunc = /callFunction\(([^)]+)\)/.exec( inlineEventHandler ),
+										callFuncArgs = callFunc &&  callFunc[ 1 ].split( ',' ),
+										preventDefault = /return false;/.test( inlineEventHandler );
 
-									// String form param.
-									var strPattern = argName.match( /^(["'])([^"']*?)\1$/ );
-									if ( strPattern )
+									if ( callFuncArgs )
 									{
-										callFuncArgs[ i ] = strPattern[ 2 ];
-										continue;
+										var nums = callFuncArgs.length,
+											argName;
+
+										for ( var i = 0; i < nums; i++ )
+										{
+											// Trim spaces around param.
+											callFuncArgs[ i ] = argName = CKEDITOR.tools.trim( callFuncArgs[ i ] );
+
+											// String form param.
+											var strPattern = argName.match( /^(["'])([^"']*?)\1$/ );
+											if ( strPattern )
+											{
+												callFuncArgs[ i ] = strPattern[ 2 ];
+												continue;
+											}
+
+											// Integer form param.
+											if ( argName.match( /\d+/ ) )
+											{
+												callFuncArgs[ i ] = parseInt( argName );
+												continue;
+											}
+
+											// Speical variables.
+											switch( argName )
+											{
+												case 'this' :
+													callFuncArgs[ i ] = node.$;
+													break;
+												case 'event' :
+													callFuncArgs[ i ] = evt.data.$;
+													break;
+												case 'null' :
+													callFuncArgs [ i ] = null;
+													break;
+											}
+										}
+
+										CKEDITOR.tools.callFunction.apply( window, callFuncArgs );
 									}
 
-									// Integer form param.
-									if ( argName.match( /\d+/ ) )
-									{
-										callFuncArgs[ i ] = parseInt( argName );
-										continue;
-									}
-
-									switch( argName )
-									{
-										case 'this' :
-											callFuncArgs[ i ] = item.$;
-											break;
-										case 'event' :
-											callFuncArgs[ i ] = evt.data.$;
-											break;
-										case 'null' :
-											callFuncArgs [ i ] = null;
-											break;
-									}
-								}
-								console.log( callFuncArgs );
-								CKEDITOR.tools.callFunction.apply( window, callFuncArgs );
+									if( preventDefault )
+										evt.data.preventDefault();
+								} );
 							}
-
-							if( preventDefault )
-								evt.data.preventDefault();
-
-						} );
-					} );
-
-				} )( eventNameList[ i ] );
+						} )( eventNameList[ j ] );
+					}
+					
+				} )( child );
 			}
 		}
 
-		if( CKEDITOR.env.air )
+		editor.on( 'uiReady', function()
 		{
-			editor.on( 'uiReady', function()
-			{
-				convertInlineHandlers( editor.container, [ 'click', 'keydown', 'mousedown', 'keypress' ] );
-			} );
+			convertInlineHandlers( editor.container );
+		} );
 
-			var richCombo = CKEDITOR.ui.richCombo,
-				panelButton = CKEDITOR.ui.panelButton,
-				menu = CKEDITOR.menu,
-				dialog = CKEDITOR.dialog;
+		var richCombo = CKEDITOR.ui.richCombo,
+			panelButton = CKEDITOR.ui.panelButton,
+			menu = CKEDITOR.menu,
+			dialog = CKEDITOR.dialog;
 
-			function onPanelUIReady( evt )
-			{
-				var floatPanel = evt.data._.panel,
-					panel = floatPanel._.panel,
-					holder;
+		function onPanelUIReady( evt )
+		{
+			var floatPanel = evt.data._.panel,
+				panel = floatPanel._.panel,
+				holder;
 
-				( function(){
+			( function(){
 
-					// Off-line dom event is not supported in AIR, waiting for
-					// panel iframe loaded.
-					if ( !panel.isLoaded )
-					{
-						setTimeout( arguments.callee, 30 );
-						return;
-					}
-					holder = panel._.holder;
-					convertInlineHandlers( holder, [ 'click', 'keydown', 'mousedown', 'keypress' ] );
-				})();
-
-			}
-
-			richCombo && richCombo.on( 'uiReady', onPanelUIReady );
-			panelButton && panelButton.on( 'uiReady', onPanelUIReady );
-			menu && menu.on( 'uiReady', onPanelUIReady );
-			dialog && dialog.on( 'uiReady', function ( evt )
-			{
-				convertInlineHandlers( evt.data._.element, [ 'click', 'keydown', 'mousedown', 'keypress' ] );
-			} );
+				// Adding dom event listeners off-line are not supported in AIR,
+				// waiting for panel iframe loaded.
+				if ( !panel.isLoaded )
+				{
+					setTimeout( arguments.callee, 30 );
+					return;
+				}
+				holder = panel._.holder;
+				convertInlineHandlers( holder );
+			})();
 
 		}
+
+		richCombo && richCombo.on( 'uiReady', onPanelUIReady );
+		panelButton && panelButton.on( 'uiReady', onPanelUIReady );
+		menu && menu.on( 'uiReady', onPanelUIReady );
+		dialog && dialog.on( 'uiReady', function ( evt )
+		{
+			convertInlineHandlers( evt.data._.element );
+		} );
 	}
-});
+} );
 
-CKEDITOR.dom.element.prototype.eachChildWithAttribute = function( name, processor )
-{
-	var children = this.getElementsByTag( '*' ),
-		count = children.count(),
-		child;
-	for ( var i = 0; i < count; i++ )
-	{
-		child = children.getItem( i );
-		if( child.hasAttribute( name ) )
-			processor( child );
-	}
-};
Index: /CKEditor/branches/features/adobeair/_source/plugins/panel/plugin.js
===================================================================
--- /CKEditor/branches/features/adobeair/_source/plugins/panel/plugin.js	(revision 4405)
+++ /CKEditor/branches/features/adobeair/_source/plugins/panel/plugin.js	(revision 4406)
@@ -101,5 +101,5 @@
 			// The iframe must source from a 'application sandbox' file,
 			// otherwise the dynamically linked stylesheets and scripts
-			// won't work.
+			// won't work in AIR.
 			if( CKEDITOR.env.air )
 			{
Index: /CKEditor/branches/features/adobeair/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/branches/features/adobeair/_source/plugins/wysiwygarea/plugin.js	(revision 4405)
+++ /CKEditor/branches/features/adobeair/_source/plugins/wysiwygarea/plugin.js	(revision 4406)
@@ -269,5 +269,5 @@
 								// The iframe must source from a 'application sandbox' file,
 								// otherwise the dynamically linked stylesheets and scripts
-								// won't work.
+								// won't work in AIR.
 								' src="' +
 								 ( CKEDITOR.env.air ? ( CKEDITOR.basePath + 'air_sandbox_frame.html' )
Index: /CKEditor/branches/features/adobeair/air_sandbox_frame.html
===================================================================
--- /CKEditor/branches/features/adobeair/air_sandbox_frame.html	(revision 4405)
+++ /CKEditor/branches/features/adobeair/air_sandbox_frame.html	(revision 4406)
@@ -7,9 +7,4 @@
 <head>
 	<title></title>
-	<script> window.onload = function()
-	{
-		var onload = parent.air_sandbox_frame_load;
-		if( onload) onload();	
-	}</script>
 </head>
 <body ></body>
