JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.2
[ckeditor.git] / _source / plugins / wysiwygarea / plugin.js
index d3b9e62..c256646 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -10,18 +10,18 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
 (function()\r
 {\r
-       /**\r
-        * List of elements in which has no way to move editing focus outside.\r
-        */\r
+       // List of elements in which has no way to move editing focus outside.\r
        var nonExitableElementNames = { table:1,pre:1 };\r
+\r
        // Matching an empty paragraph at the end of document.\r
-       var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\1>)?\s*$/gi;\r
+       var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\1>)?\s*(?=$|<\/body>)/gi;\r
 \r
        function onInsertHtml( evt )\r
        {\r
                if ( this.mode == 'wysiwyg' )\r
                {\r
                        this.focus();\r
+                       this.fire( 'saveSnapshot' );\r
 \r
                        var selection = this.getSelection(),\r
                                data = evt.data;\r
@@ -46,6 +46,11 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        }\r
                        else\r
                                this.document.$.execCommand( 'inserthtml', false, data );\r
+\r
+                       CKEDITOR.tools.setTimeout( function()\r
+                               {\r
+                                       this.fire( 'saveSnapshot' );\r
+                               }, 0, this );\r
                }\r
        }\r
 \r
@@ -84,7 +89,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                var current, dtd;\r
                                if ( isBlock )\r
                                {\r
-                                       while( ( current = range.getCommonAncestor( false, true ) )\r
+                                       while ( ( current = range.getCommonAncestor( false, true ) )\r
                                                        && ( dtd = CKEDITOR.dtd[ current.getName() ] )\r
                                                        && !( dtd && dtd [ elementName ] ) )\r
                                        {\r
@@ -138,7 +143,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
        // DOM modification here should not bother dirty flag.(#4385)\r
        function restoreDirty( editor )\r
        {\r
-               if( !editor.checkDirty() )\r
+               if ( !editor.checkDirty() )\r
                        setTimeout( function(){ editor.resetDirty(); } );\r
        }\r
 \r
@@ -190,7 +195,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        // If the fixed block is blank and already followed by a exitable\r
                        // block, we should revert the fix. (#3684)\r
-                       if( fixedBlock.getOuterHtml().match( emptyParagraphRegexp ) )\r
+                       if ( fixedBlock.getOuterHtml().match( emptyParagraphRegexp ) )\r
                        {\r
                                var previousElement = fixedBlock.getPrevious( isNotWhitespace ),\r
                                        nextElement = fixedBlock.getNext( isNotWhitespace );\r
@@ -209,7 +214,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                        range.select();\r
                        // Notify non-IE that selection has changed.\r
-                       if( !CKEDITOR.env.ie )\r
+                       if ( !CKEDITOR.env.ie )\r
                                editor.selectionChange();\r
                }\r
 \r
@@ -220,7 +225,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                if ( lastNode && lastNode.getName && ( lastNode.getName() in nonExitableElementNames ) )\r
                {\r
                        restoreDirty( editor );\r
-                       if( !CKEDITOR.env.ie )\r
+                       if ( !CKEDITOR.env.ie )\r
                                body.appendBogus();\r
                        else\r
                                body.append( editor.document.createText( '\xa0' ) );\r
@@ -236,112 +241,79 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                        var fixForBody = ( editor.config.enterMode != CKEDITOR.ENTER_BR )\r
                                ? editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false;\r
 \r
+                       var frameLabel = editor.lang.editorTitle.replace( '%1', editor.name );\r
+\r
                        editor.on( 'editingBlockReady', function()\r
                                {\r
                                        var mainElement,\r
-                                               fieldset,\r
                                                iframe,\r
                                                isLoadingData,\r
                                                isPendingFocus,\r
                                                frameLoaded,\r
                                                fireMode;\r
 \r
+\r
                                        // Support for custom document.domain in IE.\r
                                        var isCustomDomain = CKEDITOR.env.isCustomDomain();\r
 \r
                                        // Creates the iframe that holds the editable document.\r
-                                       var createIFrame = function()\r
+                                       var createIFrame = function( data )\r
                                        {\r
                                                if ( iframe )\r
                                                        iframe.remove();\r
-                                               if ( fieldset )\r
-                                                       fieldset.remove();\r
 \r
                                                frameLoaded = 0;\r
-                                               // The document domain must be set within the src\r
-                                               // attribute;\r
-                                               // Defer the script execution until iframe\r
-                                               // has been added to main window, this is needed for some\r
-                                               // browsers which will begin to load the frame content\r
-                                               // prior to it's presentation in DOM.(#3894)\r
-                                               var src = 'void( '\r
-                                                               + ( CKEDITOR.env.gecko ? 'setTimeout' : '' ) + '( function(){' +\r
-                                                               'document.open();' +\r
-                                                               ( CKEDITOR.env.ie && isCustomDomain ? 'document.domain="' + document.domain + '";' : '' ) +\r
-                                                               'document.write( window.parent[ "_cke_htmlToLoad_' + editor.name + '" ] );' +\r
-                                                               'document.close();' +\r
-                                                               'window.parent[ "_cke_htmlToLoad_' + editor.name + '" ] = null;' +\r
-                                                               '}'\r
-                                                               + ( CKEDITOR.env.gecko ? ', 0 )' : ')()' )\r
-                                                               + ' )';\r
-\r
-                                               // Loading via src attribute does not work in Opera.\r
-                                               if ( CKEDITOR.env.opera )\r
-                                                       src = 'void(0);';\r
 \r
-                                               iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +\r
-                                                               ' style="width:100%;height:100%"' +\r
-                                                               ' frameBorder="0"' +\r
-                                                               ' tabIndex="-1"' +\r
-                                                               ' allowTransparency="true"' +\r
-                                                               ' src="javascript:' + encodeURIComponent( src ) + '"' +\r
-                                                               '></iframe>' );\r
+                                               var setDataFn = !CKEDITOR.env.gecko && CKEDITOR.tools.addFunction( function( doc )\r
+                                                       {\r
+                                                               CKEDITOR.tools.removeFunction( setDataFn );\r
+                                                               doc.write( data );\r
+                                                       });\r
 \r
-                                               var accTitle = editor.lang.editorTitle.replace( '%1', editor.name );\r
+                                               var srcScript =\r
+                                                       'document.open();' +\r
 \r
-                                               if ( CKEDITOR.env.gecko )\r
-                                               {\r
-                                                       // Double checking the iframe will be loaded properly(#4058).\r
-                                                       iframe.on( 'load', function( ev )\r
+                                                       // The document domain must be set any time we\r
+                                                       // call document.open().\r
+                                                       ( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) +\r
+\r
+                                                       // With FF, it's better to load the data on\r
+                                                       // iframe.load. (#3894,#4058)\r
+                                                       // But in FF, we still need the open()-close() call\r
+                                                       // to avoid HTTPS warnings.\r
+                                                       ( CKEDITOR.env.gecko ? '' : ( 'parent.CKEDITOR.tools.callFunction(' + setDataFn + ',document);' ) ) +\r
+\r
+                                                       'document.close();';\r
+\r
+                                               iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +\r
+                                                       ' style="width:100%;height:100%"' +\r
+                                                       ' frameBorder="0"' +\r
+                                                       ' src="javascript:void(function(){' + encodeURIComponent( srcScript ) + '}())"' +\r
+                                                       ' tabIndex="' + editor.tabIndex + '"' +\r
+                                                       ' allowTransparency="true"' +\r
+                                                       '></iframe>' );\r
+\r
+                                               // With FF, it's better to load the data on iframe.load. (#3894,#4058)\r
+                                               CKEDITOR.env.gecko && iframe.on( 'load', function( ev )\r
                                                        {\r
                                                                ev.removeListener();\r
-                                                               contentDomReady( iframe.$.contentWindow );\r
-                                                       } );\r
 \r
-                                                       // Accessibility attributes for Firefox.\r
-                                                       mainElement.setAttributes(\r
-                                                               {\r
-                                                                       role : 'region',\r
-                                                                       title : accTitle\r
-                                                               } );\r
-                                                       iframe.setAttributes(\r
-                                                               {\r
-                                                                       role : 'region',\r
-                                                                       title : ' '\r
-                                                               } );\r
-                                               }\r
-                                               else if ( CKEDITOR.env.webkit )\r
-                                               {\r
-                                                       iframe.setAttribute( 'title', accTitle );       // Safari 4\r
-                                                       iframe.setAttribute( 'name', accTitle );        // Safari 3\r
-                                               }\r
-                                               else if ( CKEDITOR.env.ie )\r
-                                               {\r
-                                                       // Accessibility label for IE.\r
-                                                       fieldset = CKEDITOR.dom.element.createFromHtml(\r
-                                                               '<fieldset style="height:100%' +\r
-                                                               ( CKEDITOR.env.ie && CKEDITOR.env.quirks ? ';position:relative' : '' ) +\r
-                                                               '">' +\r
-                                                                       '<legend style="display:block;width:0;height:0;overflow:hidden;' +\r
-                                                                       ( CKEDITOR.env.ie && CKEDITOR.env.quirks ? 'position:absolute' : '' ) +\r
-                                                                       '">' +\r
-                                                                               CKEDITOR.tools.htmlEncode( accTitle ) +\r
-                                                                       '</legend>' +\r
-                                                               '</fieldset>'\r
-                                                               , CKEDITOR.document );\r
-                                                       iframe.appendTo( fieldset );\r
-                                                       fieldset.appendTo( mainElement );\r
-                                               }\r
+                                                               var doc = iframe.getFrameDocument().$;\r
+\r
+                                                               doc.open();\r
+                                                               doc.write( data );\r
+                                                               doc.close();\r
+                                                       });\r
 \r
-                                               if ( !CKEDITOR.env.ie )\r
-                                                       mainElement.append( iframe );\r
+                                               mainElement.append( iframe );\r
                                        };\r
 \r
                                        // The script that launches the bootstrap logic on 'domReady', so the document\r
                                        // is fully editable even before the editing iframe is fully loaded (#4455).\r
                                        var activationScript =\r
-                                               '<script id="cke_actscrpt" type="text/javascript">' +\r
-                                                       'window.parent.CKEDITOR._["contentDomReady' + editor.name + '"]( window );' +\r
+                                               '<script id="cke_actscrpt" type="text/javascript" cke_temp="1">' +\r
+                                                       ( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) +\r
+                                                       'parent.CKEDITOR._["contentDomReady' + editor.name + '"]( window );' +\r
                                                '</script>';\r
 \r
                                        // Editing area bootstrap code.\r
@@ -349,9 +321,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                        {\r
                                                if ( frameLoaded )\r
                                                        return;\r
-\r
                                                frameLoaded = 1;\r
 \r
+                                               editor.fire( 'ariaWidget', iframe );\r
+\r
                                                var domDocument = domWindow.document,\r
                                                        body = domDocument.body;\r
 \r
@@ -416,7 +389,7 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                                                // IE standard compliant in editing frame doesn't focus the editor when\r
                                                // clicking outside actual content, manually apply the focus. (#1659)\r
-                                               if( CKEDITOR.env.ie\r
+                                               if ( CKEDITOR.env.ie\r
                                                        && domDocument.$.compatMode == 'CSS1Compat' )\r
                                                {\r
                                                        var htmlElement = domDocument.getDocumentElement();\r
@@ -445,10 +418,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                                if ( CKEDITOR.env.gecko )\r
                                                                {\r
                                                                        var first = body;\r
-                                                                       while( first.firstChild )\r
+                                                                       while ( first.firstChild )\r
                                                                                first = first.firstChild;\r
 \r
-                                                                       if( !first.nextSibling\r
+                                                                       if ( !first.nextSibling\r
                                                                                && ( 'BR' == first.tagName )\r
                                                                                && first.hasAttribute( '_moz_editor_bogus_node' ) )\r
                                                                        {\r
@@ -475,31 +448,45 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
 \r
                                                if ( CKEDITOR.env.ie )\r
                                                {\r
-                                                       // Cancel default action for backspace in IE on control types. (#4047)\r
+                                                       // Override keystrokes which should have deletion behavior\r
+                                                       //  on control types in IE . (#4047)\r
                                                        domDocument.on( 'keydown', function( evt )\r
                                                        {\r
-                                                               // Backspace.\r
-                                                               var control = evt.data.getKeystroke() == 8\r
-                                                                                         && editor.getSelection().getSelectedElement();\r
-                                                               if ( control )\r
+                                                               var keyCode = evt.data.getKeystroke();\r
+\r
+                                                               // Backspace OR Delete.\r
+                                                               if ( keyCode in { 8 : 1, 46 : 1 } )\r
                                                                {\r
-                                                                       // Make undo snapshot.\r
-                                                                       editor.fire( 'saveSnapshot' );\r
-                                                                       // Remove manually.\r
-                                                                       control.remove();\r
-                                                                       editor.fire( 'saveSnapshot' );\r
-                                                                       evt.cancel();\r
+                                                                       var sel = editor.getSelection(),\r
+                                                                               control = sel.getSelectedElement();\r
+\r
+                                                                       if ( control )\r
+                                                                       {\r
+                                                                               // Make undo snapshot.\r
+                                                                               editor.fire( 'saveSnapshot' );\r
+\r
+                                                                               // Delete any element that 'hasLayout' (e.g. hr,table) in IE8 will\r
+                                                                               // break up the selection, safely manage it here. (#4795)\r
+                                                                               var bookmark = sel.getRanges()[ 0 ].createBookmark();\r
+                                                                               // Remove the control manually.\r
+                                                                               control.remove();\r
+                                                                               sel.selectBookmarks( [ bookmark ] );\r
+\r
+                                                                               editor.fire( 'saveSnapshot' );\r
+\r
+                                                                               evt.data.preventDefault();\r
+                                                                       }\r
                                                                }\r
                                                        } );\r
 \r
                                                        // PageUp/PageDown scrolling is broken in document\r
                                                        // with standard doctype, manually fix it. (#4736)\r
-                                                       if( domDocument.$.compatMode == 'CSS1Compat' )\r
+                                                       if ( domDocument.$.compatMode == 'CSS1Compat' )\r
                                                        {\r
                                                                var pageUpDownKeys = { 33 : 1, 34 : 1 };\r
                                                                domDocument.on( 'keydown', function( evt )\r
                                                                {\r
-                                                                       if( evt.data.getKeystroke() in pageUpDownKeys )\r
+                                                                       if ( evt.data.getKeystroke() in pageUpDownKeys )\r
                                                                        {\r
                                                                                setTimeout( function ()\r
                                                                                {\r
@@ -586,54 +573,108 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                                        {\r
                                                                isLoadingData = true;\r
 \r
-                                                               // Get the HTML version of the data.\r
-                                                               if ( editor.dataProcessor )\r
+                                                               var config = editor.config,\r
+                                                                       fullPage = config.fullPage,\r
+                                                                       docType = config.docType;\r
+\r
+                                                               // Build the additional stuff to be included into <head>.\r
+                                                               var headExtra =\r
+                                                                       '<style type="text/css" cke_temp="1">' +\r
+                                                                               editor._.styles.join( '\n' ) +\r
+                                                                       '</style>';\r
+\r
+                                                               !fullPage && ( headExtra =\r
+                                                                       CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss ) +\r
+                                                                       headExtra );\r
+\r
+                                                               var baseTag = config.baseHref ? '<base href="' + config.baseHref + '" cke_temp="1" />' : '';\r
+\r
+                                                               if ( fullPage )\r
                                                                {\r
-                                                                       data = editor.dataProcessor.toHtml( data, fixForBody );\r
+                                                                       // Search and sweep out the doctype declaration.\r
+                                                                       data = data.replace( /<!DOCTYPE[^>]*>/i, function( match )\r
+                                                                               {\r
+                                                                                       editor.docType = docType = match;\r
+                                                                                       return '';\r
+                                                                               });\r
                                                                }\r
 \r
-                                                               data =\r
-                                                                       editor.config.docType +\r
-                                                                       '<html dir="' + editor.config.contentsLangDirection + '">' +\r
-                                                                       '<head>' +\r
-                                                                               '<link type="text/css" rel="stylesheet" href="' +\r
-                                                                               [].concat( editor.config.contentsCss ).join( '"><link type="text/css" rel="stylesheet" href="' ) +\r
-                                                                               '">' +\r
-                                                                               '<style type="text/css" _fcktemp="true">' +\r
-                                                                                       editor._.styles.join( '\n' ) +\r
-                                                                               '</style>'+\r
-                                                                       '</head>' +\r
-                                                                       '<body>' +\r
-                                                                               data +\r
-                                                                       '</body>' +\r
-                                                                       '</html>' +\r
-                                                                       activationScript;\r
-\r
-                                                               window[ '_cke_htmlToLoad_' + editor.name ] = data;\r
-                                                               CKEDITOR._[ 'contentDomReady' + editor.name ] = contentDomReady;\r
-                                                               createIFrame();\r
+                                                               // Get the HTML version of the data.\r
+                                                               if ( editor.dataProcessor )\r
+                                                                       data = editor.dataProcessor.toHtml( data, fixForBody );\r
 \r
-                                                               // Opera must use the old method for loading contents.\r
-                                                               if ( CKEDITOR.env.opera )\r
+                                                               if ( fullPage )\r
                                                                {\r
-                                                                       var doc = iframe.$.contentWindow.document;\r
-                                                                       doc.open();\r
-                                                                       doc.write( data );\r
-                                                                       doc.close();\r
+                                                                       // Check if the <body> tag is available.\r
+                                                                       if ( !(/<body[\s|>]/).test( data ) )\r
+                                                                               data = '<body>' + data;\r
+\r
+                                                                       // Check if the <html> tag is available.\r
+                                                                       if ( !(/<html[\s|>]/).test( data ) )\r
+                                                                               data = '<html>' + data + '</html>';\r
+\r
+                                                                       // Check if the <head> tag is available.\r
+                                                                       if ( !(/<head[\s|>]/).test( data ) )\r
+                                                                               data = data.replace( /<html[^>]*>/, '$&<head><title></title></head>' ) ;\r
+\r
+                                                                       // The base must be the first tag in the HEAD, e.g. to get relative\r
+                                                                       // links on styles.\r
+                                                                       baseTag && ( data = data.replace( /<head>/, '$&' + baseTag ) );\r
+\r
+                                                                       // Inject the extra stuff into <head>.\r
+                                                                       // Attention: do not change it before testing it well. (V2)\r
+                                                                       // This is tricky... if the head ends with <meta ... content type>,\r
+                                                                       // Firefox will break. But, it works if we place our extra stuff as\r
+                                                                       // the last elements in the HEAD.\r
+                                                                       data = data.replace( /<\/head\s*>/, headExtra + '$&' );\r
+\r
+                                                                       // Add the DOCTYPE back to it.\r
+                                                                       data = docType + data;\r
                                                                }\r
+                                                               else\r
+                                                               {\r
+                                                                       data =\r
+                                                                               config.docType +\r
+                                                                               '<html dir="' + config.contentsLangDirection + '">' +\r
+                                                                               '<title>' + frameLabel + '</title>' +\r
+                                                                               '<head>' +\r
+                                                                                       baseTag +\r
+                                                                                       headExtra +\r
+                                                                               '</head>' +\r
+                                                                               '<body' + ( config.bodyId ? ' id="' + config.bodyId + '"' : '' ) +\r
+                                                                                                 ( config.bodyClass ? ' class="' + config.bodyClass + '"' : '' ) +\r
+                                                                                                 '>' +\r
+                                                                                       data +\r
+                                                                               '</html>';\r
+                                                               }\r
+\r
+                                                               data += activationScript;\r
+\r
+                                                               CKEDITOR._[ 'contentDomReady' + editor.name ] = contentDomReady;\r
+                                                               createIFrame( data );\r
                                                        },\r
 \r
                                                        getData : function()\r
                                                        {\r
-                                                               var data = iframe.getFrameDocument().getBody().getHtml();\r
+                                                               var config = editor.config,\r
+                                                                       fullPage = config.fullPage,\r
+                                                                       docType = fullPage && editor.docType,\r
+                                                                       doc = iframe.getFrameDocument();\r
+\r
+                                                               var data = fullPage\r
+                                                                       ? doc.getDocumentElement().getOuterHtml()\r
+                                                                       : doc.getBody().getHtml();\r
 \r
                                                                if ( editor.dataProcessor )\r
                                                                        data = editor.dataProcessor.toDataFormat( data, fixForBody );\r
 \r
                                                                // Strip the last blank paragraph within document.\r
-                                                               if ( editor.config.ignoreEmptyParagraph )\r
+                                                               if ( config.ignoreEmptyParagraph )\r
                                                                        data = data.replace( emptyParagraphRegexp, '' );\r
 \r
+                                                               if ( docType )\r
+                                                                       data = docType + '\n' + data;\r
+\r
                                                                return data;\r
                                                        },\r
 \r
@@ -691,14 +732,26 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
                                        editor.on( 'selectionChange', onSelectionChangeFixBody, null, null, 1 );\r
                                });\r
 \r
+                       var titleBackup;\r
+                       // Setting voice label as window title, backup the original one\r
+                       // and restore it before running into use.\r
+                       editor.on( 'contentDom', function ()\r
+                               {\r
+                                       var title = editor.document.getElementsByTag( 'title' ).getItem( 0 );\r
+                                       title.setAttribute( '_cke_title', editor.document.$.title );\r
+                                       editor.document.$.title = frameLabel;\r
+                               });\r
+\r
+\r
                        // Create an invisible element to grab focus.\r
-                       if( CKEDITOR.env.ie )\r
+                       if ( CKEDITOR.env.ie )\r
                        {\r
                                var ieFocusGrabber;\r
                                editor.on( 'uiReady', function()\r
                                {\r
                                        ieFocusGrabber = editor.container.append( CKEDITOR.dom.element.createFromHtml(\r
-                                       '<input tabindex="-1" style="position:absolute; left:-10000">' ) );\r
+                                               // Use 'span' instead of anything else to fly under the screen-reader radar. (#5049)\r
+                                               '<span tabindex="-1" style="position:absolute; left:-10000" role="presentation"></span>' ) );\r
 \r
                                        ieFocusGrabber.on( 'focus', function()\r
                                                {\r
@@ -710,30 +763,28 @@ For licensing, see LICENSE.html or http://ckeditor.com/license
        });\r
 \r
        // Fixing Firefox 'Back-Forward Cache' break design mode. (#4514)\r
-       if( CKEDITOR.env.gecko )\r
+       if ( CKEDITOR.env.gecko )\r
        {\r
-               var topWin = window.top;\r
-\r
                ( function ()\r
                {\r
-                       var topBody = topWin.document.body;\r
+                       var body = document.body;\r
 \r
-                       if( !topBody )\r
-                               topWin.addEventListener( 'load', arguments.callee, false );\r
+                       if ( !body )\r
+                               window.addEventListener( 'load', arguments.callee, false );\r
                        else\r
                        {\r
-                               topBody.setAttribute( 'onpageshow', topBody.getAttribute( 'onpageshow' )\r
+                               body.setAttribute( 'onpageshow', body.getAttribute( 'onpageshow' )\r
                                                + ';event.persisted && CKEDITOR.tools.callFunction(' +\r
                                                CKEDITOR.tools.addFunction( function()\r
                                                {\r
                                                        var allInstances = CKEDITOR.instances,\r
                                                                editor,\r
                                                                doc;\r
-                                                       for( var i in allInstances )\r
+                                                       for ( var i in allInstances )\r
                                                        {\r
                                                                editor = allInstances[ i ];\r
                                                                doc = editor.document;\r
-                                                               if( doc )\r
+                                                               if ( doc )\r
                                                                {\r
                                                                        doc.$.designMode = 'off';\r
                                                                        doc.$.designMode = 'on';\r
@@ -792,3 +843,9 @@ CKEDITOR.config.disableNativeSpellChecker = true;
  * config.ignoreEmptyParagraph = false;\r
  */\r
 CKEDITOR.config.ignoreEmptyParagraph = true;\r
+\r
+/**\r
+ * Fired when data is loaded and ready for retrieval in an editor instance.\r
+ * @name CKEDITOR.editor#dataReady\r
+ * @event\r
+ */\r