X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=_source%2Fplugins%2Fwysiwygarea%2Fplugin.js;h=a6b06390d8d4c08df0d898b5fcfdacb4be029a44;hb=8665a7c6c60586526e32e8941fe2896739b6ebfb;hp=11fd76eb32f24108b9fcfd03ab6f95e94fb58a04;hpb=c6e377a02b54abc07129d72b632763c727476a15;p=ckeditor.git diff --git a/_source/plugins/wysiwygarea/plugin.js b/_source/plugins/wysiwygarea/plugin.js index 11fd76e..a6b0639 100644 --- a/_source/plugins/wysiwygarea/plugin.js +++ b/_source/plugins/wysiwygarea/plugin.js @@ -161,6 +161,22 @@ For licensing, see LICENSE.html or http://ckeditor.com/license && CKEDITOR.tools.trim( node.getText() ).match( /^(?: |\xa0)$/ ); } + function restoreSelection( selection ) + { + if ( selection.isLocked ) + { + selection.unlock(); + setTimeout( function() { selection.lock(); }, 0 ); + } + } + + function isBlankParagraph( block ) + { + return block.getOuterHtml().match( emptyParagraphRegexp ); + } + + isNotWhitespace = CKEDITOR.dom.walker.whitespaces( true ); + /** * Auto-fixing block-less content by wrapping paragraph (#3190), prevent * non-exitable-block by padding extra br.(#3189) @@ -182,7 +198,10 @@ For licensing, see LICENSE.html or http://ckeditor.com/license && blockLimit.getName() == 'body' && !path.block ) { + editor.fire( 'updateSnapshot' ); restoreDirty( editor ); + CKEDITOR.env.ie && restoreSelection( selection ); + var fixedBlock = range.fixBlock( true, editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' ); @@ -193,20 +212,21 @@ For licensing, see LICENSE.html or http://ckeditor.com/license first && isNbsp( first ) && first.remove(); } - // If the fixed block is blank and already followed by a exitable - // block, we should revert the fix. (#3684) - if ( fixedBlock.getOuterHtml().match( emptyParagraphRegexp ) ) + // If the fixed block is actually blank and is already followed by an exitable blank + // block, we should revert the fix and move into the existed one. (#3684) + if ( isBlankParagraph( fixedBlock ) ) { var previousElement = fixedBlock.getPrevious( isNotWhitespace ), nextElement = fixedBlock.getNext( isNotWhitespace ); - if ( previousElement && previousElement.getName && !( previousElement.getName() in nonExitableElementNames ) + && isBlankParagraph( previousElement ) && range.moveToElementEditStart( previousElement ) || nextElement && nextElement.getName - && !( nextElement.getName() in nonExitableElementNames ) - && range.moveToElementEditStart( nextElement ) ) + && !( nextElement.getName() in nonExitableElementNames ) + && isBlankParagraph( nextElement ) + && range.moveToElementEditStart( nextElement ) ) { fixedBlock.remove(); } @@ -221,14 +241,32 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // All browsers are incapable to moving cursor out of certain non-exitable // blocks (e.g. table, list, pre) at the end of document, make this happen by // place a bogus node there, which would be later removed by dataprocessor. - var lastNode = body.getLast( CKEDITOR.dom.walker.whitespaces( true ) ); - if ( lastNode && lastNode.getName && ( lastNode.getName() in nonExitableElementNames ) ) + var walkerRange = new CKEDITOR.dom.range( editor.document ), + walker = new CKEDITOR.dom.walker( walkerRange ); + walkerRange.selectNodeContents( body ); + walker.evaluator = function( node ) { + return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in nonExitableElementNames ); + }; + walker.guard = function( node, isMoveout ) + { + return !( ( node.type == CKEDITOR.NODE_TEXT && isNotWhitespace( node ) ) || isMoveout ); + }; + + if ( walker.previous() ) + { + editor.fire( 'updateSnapshot' ); restoreDirty( editor ); - if ( !CKEDITOR.env.ie ) - body.appendBogus(); + CKEDITOR.env.ie && restoreSelection( selection ); + + var paddingBlock; + if ( enterMode != CKEDITOR.ENTER_BR ) + paddingBlock = body.append( new CKEDITOR.dom.element( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ); else - body.append( editor.document.createText( '\xa0' ) ); + paddingBlock = body; + + if ( !CKEDITOR.env.ie ) + paddingBlock.appendBogus(); } } @@ -241,16 +279,19 @@ For licensing, see LICENSE.html or http://ckeditor.com/license var fixForBody = ( editor.config.enterMode != CKEDITOR.ENTER_BR ) ? editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false; + var frameLabel = editor.lang.editorTitle.replace( '%1', editor.name ); + + var contentDomReadyHandler; editor.on( 'editingBlockReady', function() { var mainElement, - fieldset, iframe, isLoadingData, isPendingFocus, frameLoaded, fireMode; + // Support for custom document.domain in IE. var isCustomDomain = CKEDITOR.env.isCustomDomain(); @@ -259,99 +300,63 @@ For licensing, see LICENSE.html or http://ckeditor.com/license { if ( iframe ) iframe.remove(); - if ( fieldset ) - fieldset.remove(); - frameLoaded = 0; + + var srcScript = + 'document.open();' + + + // The document domain must be set any time we + // call document.open(). + ( isCustomDomain ? ( 'document.domain="' + document.domain + '";' ) : '' ) + + + 'document.close();'; iframe = CKEDITOR.dom.element.createFromHtml( '' ); - // Register onLoad event for iframe element, which - // will fill it with content and set custom domain. - iframe.on( 'load', function( e ) - { - e.removeListener(); - var doc = iframe.getFrameDocument().$; - - // Custom domain handling is needed after each document.open(). - doc.open(); - if ( isCustomDomain ) - doc.domain = document.domain; - doc.write( data ); - doc.close(); - - } ); + // With FF, it's better to load the data on iframe.load. (#3894,#4058) + iframe.on( 'load', function( ev ) + { + frameLoaded = 1; + ev.removeListener(); - var accTitle = editor.lang.editorTitle.replace( '%1', editor.name ); + var doc = iframe.getFrameDocument().$; - if ( CKEDITOR.env.gecko ) - { - // Accessibility attributes for Firefox. - mainElement.setAttributes( - { - role : 'region', - title : accTitle - } ); - iframe.setAttributes( - { - role : 'region', - title : ' ' - } ); - } - else if ( CKEDITOR.env.webkit ) - { - iframe.setAttribute( 'title', accTitle ); // Safari 4 - iframe.setAttribute( 'name', accTitle ); // Safari 3 - } - else if ( CKEDITOR.env.ie ) - { - // Accessibility label for IE. - fieldset = CKEDITOR.dom.element.createFromHtml( - '
' - , CKEDITOR.document ); - iframe.appendTo( fieldset ); - fieldset.appendTo( mainElement ); - } + // Don't leave any history log in IE. (#5657) + doc.open( "text/html","replace" ); + doc.write( data ); + doc.close(); + }); - if ( !CKEDITOR.env.ie ) - mainElement.append( iframe ); + mainElement.append( iframe ); }; // The script that launches the bootstrap logic on 'domReady', so the document // is fully editable even before the editing iframe is fully loaded (#4455). + contentDomReadyHandler = CKEDITOR.tools.addFunction( contentDomReady ); var activationScript = ''; // Editing area bootstrap code. - var contentDomReady = function( domWindow ) + function contentDomReady( domWindow ) { - if ( frameLoaded ) + if ( !frameLoaded ) return; + frameLoaded = 0; - frameLoaded = 1; + editor.fire( 'ariaWidget', iframe ); var domDocument = domWindow.document, body = domDocument.body; @@ -360,8 +365,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license var script = domDocument.getElementById( "cke_actscrpt" ); script.parentNode.removeChild( script ); - delete CKEDITOR._[ 'contentDomReady' + editor.name ]; - body.spellcheck = !editor.config.disableNativeSpellChecker; if ( CKEDITOR.env.ie ) @@ -376,7 +379,32 @@ For licensing, see LICENSE.html or http://ckeditor.com/license body.removeAttribute( 'disabled' ); } else + { + // Gecko need a key event to 'wake up' the editing + // ability when document is empty.(#3864) + if ( CKEDITOR.env.gecko && !body.childNodes.length ) + { + setTimeout( function() + { + restoreDirty( editor ); + + // Simulating keyboard character input by dispatching a keydown of white-space text. + var keyEventSimulate = domDocument.$.createEvent( "KeyEvents" ); + keyEventSimulate.initKeyEvent( 'keypress', true, true, domWindow.$, false, + false, false, false, 0, 32 ); + domDocument.$.dispatchEvent( keyEventSimulate ); + + // Restore the original document status by placing the cursor before a bogus br created (#5021). + domDocument.createElement( 'br', { attributes: { '_moz_editor_bogus_node' : 'TRUE', '_moz_dirty' : "" } } ) + .replace( domDocument.getBody().getFirst() ); + var nativeRange = new CKEDITOR.dom.range( domDocument ); + nativeRange.setStartAt( new CKEDITOR.dom.element( body ) , CKEDITOR.POSITION_AFTER_START ); + nativeRange.select(); + }, 0 ); + } + domDocument.designMode = 'on'; + } // IE, Opera and Safari may not support it and throw // errors. @@ -441,32 +469,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license focusTarget.on( 'focus', function() { - // Gecko need a key event to 'wake up' the editing - // ability when document is empty.(#3864) - if ( CKEDITOR.env.gecko ) - { - var first = body; - while ( first.firstChild ) - first = first.firstChild; - - if ( !first.nextSibling - && ( 'BR' == first.tagName ) - && first.hasAttribute( '_moz_editor_bogus_node' ) ) - { - var keyEventSimulate = domDocument.$.createEvent( "KeyEvents" ); - keyEventSimulate.initKeyEvent( 'keypress', true, true, domWindow.$, false, - false, false, false, 0, 32 ); - domDocument.$.dispatchEvent( keyEventSimulate ); - var bogusText = domDocument.getBody().getFirst() ; - // Compensate the line maintaining