X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fcore%2Fdom%2Frange.js;h=8f10980e472a859f093ce39bc09249c49e4af736;hb=614511639979907ceb0da3614122a4d8eb963ad4;hp=a8b102d933599d5a5f332b7df784b4633457b9e1;hpb=7cd80714081a8ffdf4a1a8d2c72f120ed5ef3d6d;p=ckeditor.git diff --git a/_source/core/dom/range.js b/_source/core/dom/range.js index a8b102d..8f10980 100644 --- a/_source/core/dom/range.js +++ b/_source/core/dom/range.js @@ -1,8 +1,11 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ +/** + * @class + */ CKEDITOR.dom.range = function( document ) { this.startContainer = null; @@ -133,7 +136,7 @@ CKEDITOR.dom.range = function( document ) currentNode = levelStartNode.getNext(); - while( currentNode ) + while ( currentNode ) { // Stop processing when the current node matches a node in the // endParents tree or if it is the endNode. @@ -180,7 +183,7 @@ CKEDITOR.dom.range = function( document ) { currentNode = levelStartNode.getPrevious(); - while( currentNode ) + while ( currentNode ) { // Stop processing when the current node matches a node in the // startParents tree or if it is the startNode. @@ -252,10 +255,10 @@ CKEDITOR.dom.range = function( document ) } // Cleanup any marked node. - if( removeStartNode ) + if ( removeStartNode ) startNode.remove(); - if( removeEndNode && endNode.$.parentNode ) + if ( removeEndNode && endNode.$.parentNode ) endNode.remove(); }; @@ -278,7 +281,7 @@ CKEDITOR.dom.range = function( document ) if ( CKEDITOR.tools.trim( node.getText() ).length ) return false; } - else if( node.type == CKEDITOR.NODE_ELEMENT ) + else if ( node.type == CKEDITOR.NODE_ELEMENT ) { // If there are non-empty inline elements (e.g. ), then we're not // at the start. @@ -305,7 +308,7 @@ CKEDITOR.dom.range = function( document ) return node.type != CKEDITOR.NODE_TEXT && node.getName() in CKEDITOR.dtd.$removeEmpty || !CKEDITOR.tools.trim( node.getText() ) - || node.getParent().hasAttribute( '_fck_bookmark' ); + || node.getParent().hasAttribute( '_cke_bookmark' ); } var whitespaceEval = new CKEDITOR.dom.walker.whitespaces(), @@ -348,7 +351,10 @@ CKEDITOR.dom.range = function( document ) this.collapsed = true; }, - // The selection may be lost when cloning (due to the splitText() call). + /** + * The content nodes of the range are cloned and added to a document fragment, which is returned. + * Note: Text selection may lost after invoking this method. (caused by text node splitting). + */ cloneContents : function() { var docFrag = new CKEDITOR.dom.documentFragment( this.document ); @@ -359,6 +365,9 @@ CKEDITOR.dom.range = function( document ) return docFrag; }, + /** + * Deletes the content nodes of the range permanently from the DOM tree. + */ deleteContents : function() { if ( this.collapsed ) @@ -367,6 +376,10 @@ CKEDITOR.dom.range = function( document ) execContentsAction( this, 0 ); }, + /** + * The content nodes of the range are cloned and added to a document fragment, + * meanwhile they're removed permanently from the DOM tree. + */ extractContents : function() { var docFrag = new CKEDITOR.dom.documentFragment( this.document ); @@ -397,9 +410,10 @@ CKEDITOR.dom.range = function( document ) var startNode, endNode; var baseId; var clone; + var collapsed = this.collapsed; startNode = this.document.createElement( 'span' ); - startNode.setAttribute( '_fck_bookmark', 1 ); + startNode.setAttribute( '_cke_bookmark', 1 ); startNode.setStyle( 'display', 'none' ); // For IE, it must have something inside, otherwise it may be @@ -413,7 +427,7 @@ CKEDITOR.dom.range = function( document ) } // If collapsed, the endNode will not be created. - if ( !this.collapsed ) + if ( !collapsed ) { endNode = startNode.clone(); endNode.setHtml( ' ' ); @@ -442,7 +456,8 @@ CKEDITOR.dom.range = function( document ) return { startNode : serializable ? baseId + 'S' : startNode, endNode : serializable ? baseId + 'E' : endNode, - serializable : serializable + serializable : serializable, + collapsed : collapsed }; }, @@ -465,6 +480,8 @@ CKEDITOR.dom.range = function( document ) var startOffset = this.startOffset, endOffset = this.endOffset; + var collapsed = this.collapsed; + var child, previous; // If there is no range then get out of here. @@ -501,7 +518,7 @@ CKEDITOR.dom.range = function( document ) } // Process the end only if not normalized. - if ( !this.isCollapsed ) + if ( !collapsed ) { // Find out if the start is pointing to a text node that // will be normalized. @@ -532,10 +549,11 @@ CKEDITOR.dom.range = function( document ) return { start : startContainer.getAddress( normalized ), - end : this.isCollapsed ? null : endContainer.getAddress( normalized ), + end : collapsed ? null : endContainer.getAddress( normalized ), startOffset : startOffset, endOffset : endOffset, normalized : normalized, + collapsed : collapsed, is2 : true // It's a createBookmark2 bookmark. }; }, @@ -697,7 +715,7 @@ CKEDITOR.dom.range = function( document ) }, /** - * Move the range out of bookmark nodes if they're been the container. + * Move the range out of bookmark nodes if they'd been the container. */ optimizeBookmark: function() { @@ -705,10 +723,10 @@ CKEDITOR.dom.range = function( document ) endNode = this.endContainer; if ( startNode.is && startNode.is( 'span' ) - && startNode.hasAttribute( '_fck_bookmark' ) ) + && startNode.hasAttribute( '_cke_bookmark' ) ) this.setStartAt( startNode, CKEDITOR.POSITION_BEFORE_START ); if ( endNode && endNode.is && endNode.is( 'span' ) - && endNode.hasAttribute( '_fck_bookmark' ) ) + && endNode.hasAttribute( '_cke_bookmark' ) ) this.setEndAt( endNode, CKEDITOR.POSITION_AFTER_END ); }, @@ -742,15 +760,21 @@ CKEDITOR.dom.range = function( document ) startOffset = startContainer.getIndex() + 1; startContainer = startContainer.getParent(); - // Check if it is necessary to update the end boundary. - if ( !collapsed && this.startContainer.equals( this.endContainer ) ) + + // Check all necessity of updating the end boundary. + if ( this.startContainer.equals( this.endContainer ) ) this.setEnd( nextText, this.endOffset - this.startOffset ); + else if ( startContainer.equals( this.endContainer ) ) + this.endOffset += 1; } this.setStart( startContainer, startOffset ); if ( collapsed ) + { this.collapse( true ); + return; + } } var endContainer = this.endContainer; @@ -908,7 +932,7 @@ CKEDITOR.dom.range = function( document ) // If this is a visible element. // We need to check for the bookmark attribute because IE insists on // rendering the display:none nodes we use for bookmarks. (#3363) - if ( sibling.$.offsetWidth > 0 && !sibling.getAttribute( '_fck_bookmark' ) ) + if ( sibling.$.offsetWidth > 0 && !sibling.getAttribute( '_cke_bookmark' ) ) { // We'll accept it only if we need // whitespace, and this is an inline @@ -919,7 +943,7 @@ CKEDITOR.dom.range = function( document ) siblingText = sibling.getText(); - if ( !(/[^\s\ufeff]/).test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF) + if ( (/[^\s\ufeff]/).test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF) sibling = null; else { @@ -1067,7 +1091,7 @@ CKEDITOR.dom.range = function( document ) // If this is a visible element. // We need to check for the bookmark attribute because IE insists on // rendering the display:none nodes we use for bookmarks. (#3363) - if ( sibling.$.offsetWidth > 0 && !sibling.getAttribute( '_fck_bookmark' ) ) + if ( sibling.$.offsetWidth > 0 && !sibling.getAttribute( '_cke_bookmark' ) ) { // We'll accept it only if we need // whitespace, and this is an inline @@ -1078,7 +1102,7 @@ CKEDITOR.dom.range = function( document ) siblingText = sibling.getText(); - if ( !(/[^\s\ufeff]/).test( siblingText ) ) + if ( (/[^\s\ufeff]/).test( siblingText ) ) sibling = null; else { @@ -1160,13 +1184,13 @@ CKEDITOR.dom.range = function( document ) var walker = new CKEDITOR.dom.walker( walkerRange ), blockBoundary, // The node on which the enlarging should stop. - tailBr, // - defaultGuard = CKEDITOR.dom.walker.blockBoundary( + tailBr, // In case BR as block boundary. + notBlockBoundary = CKEDITOR.dom.walker.blockBoundary( ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br : 1 } : null ), // Record the encountered 'blockBoundary' for later use. boundaryGuard = function( node ) { - var retval = defaultGuard( node ); + var retval = notBlockBoundary( node ); if ( !retval ) blockBoundary = node; return retval; @@ -1187,8 +1211,9 @@ CKEDITOR.dom.range = function( document ) // It's the body which stop the enlarging if no block boundary found. blockBoundary = blockBoundary || body; - // Start the range at different position by comparing - // the document position of it with 'enlargeable' node. + // Start the range either after the end of found block (
...
[text) + // or at the start of block ([text...), by comparing the document position + // with 'enlargeable' node. this.setStartAt( blockBoundary, !blockBoundary.is( 'br' ) && @@ -1214,8 +1239,8 @@ CKEDITOR.dom.range = function( document ) // It's the body which stop the enlarging if no block boundary found. blockBoundary = blockBoundary || body; - // Start the range at different position by comparing - // the document position of it with 'enlargeable' node. + // Close the range either before the found block start (text]
...
) or at the block end (...text]) + // by comparing the document position with 'enlargeable' node. this.setEndAt( blockBoundary, ( !enlargeable && this.checkEndOfBlock() @@ -1230,6 +1255,111 @@ CKEDITOR.dom.range = function( document ) }, /** + * Descrease the range to make sure that boundaries + * always anchor beside text nodes or innermost element. + * @param {Number} mode ( CKEDITOR.SHRINK_ELEMENT | CKEDITOR.SHRINK_TEXT ) The shrinking mode. + *