X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=_source%2Fcore%2Fdom%2Frange.js;h=a47173f383ab123516813946ea825291e0ca8adb;hb=9afde8772159bd3436f1f5b7862960307710ae5a;hp=a8b102d933599d5a5f332b7df784b4633457b9e1;hpb=7cd80714081a8ffdf4a1a8d2c72f120ed5ef3d6d;p=ckeditor.git
diff --git a/_source/core/dom/range.js b/_source/core/dom/range.js
index a8b102d..a47173f 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();
};
@@ -277,8 +280,8 @@ CKEDITOR.dom.range = function( document )
// If there's any visible text, then we're not at the start.
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().data( '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.data( '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.data( 'cke-bookmark' ) )
this.setStartAt( startNode, CKEDITOR.POSITION_BEFORE_START );
if ( endNode && endNode.is && endNode.is( 'span' )
- && endNode.hasAttribute( '_fck_bookmark' ) )
+ && endNode.data( '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.data( '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.data( '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. + *