/*\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
\r
currentNode = levelStartNode.getNext();\r
\r
- while( currentNode )\r
+ while ( currentNode )\r
{\r
// Stop processing when the current node matches a node in the\r
// endParents tree or if it is the endNode.\r
{\r
currentNode = levelStartNode.getPrevious();\r
\r
- while( currentNode )\r
+ while ( currentNode )\r
{\r
// Stop processing when the current node matches a node in the\r
// startParents tree or if it is the startNode.\r
}\r
\r
// Cleanup any marked node.\r
- if( removeStartNode )\r
+ if ( removeStartNode )\r
startNode.remove();\r
\r
- if( removeEndNode && endNode.$.parentNode )\r
+ if ( removeEndNode && endNode.$.parentNode )\r
endNode.remove();\r
};\r
\r
if ( CKEDITOR.tools.trim( node.getText() ).length )\r
return false;\r
}\r
- else if( node.type == CKEDITOR.NODE_ELEMENT )\r
+ else if ( node.type == CKEDITOR.NODE_ELEMENT )\r
{\r
// If there are non-empty inline elements (e.g. <img />), then we're not\r
// at the start.\r
\r
startOffset = startContainer.getIndex() + 1;\r
startContainer = startContainer.getParent();\r
- // Check if it is necessary to update the end boundary.\r
- if ( !collapsed && this.startContainer.equals( this.endContainer ) )\r
+\r
+ // Check all necessity of updating the end boundary.\r
+ if ( this.startContainer.equals( this.endContainer ) )\r
this.setEnd( nextText, this.endOffset - this.startOffset );\r
+ else if ( startContainer.equals( this.endContainer ) )\r
+ this.endOffset += 1;\r
}\r
\r
this.setStart( startContainer, startOffset );\r
\r
if ( collapsed )\r
+ {\r
this.collapse( true );\r
+ return;\r
+ }\r
}\r
\r
var endContainer = this.endContainer;\r
else\r
{\r
endBlock = this.splitElement( startBlock );\r
+\r
// In Gecko, the last child node must be a bogus <br>.\r
// Note: bogus <br> added under <ul> or <ol> would cause\r
// lists to be incorrectly rendered.\r
},\r
\r
/**\r
- * Moves the range boundaries to the first editing point inside an\r
+ * Moves the range boundaries to the first/end editing point inside an\r
* element. For example, in an element tree like\r
* "<p><b><i></i></b> Text</p>", the start editing point is\r
* "<p><b><i>^</i></b> Text</p>" (inside <i>).\r
* @param {CKEDITOR.dom.element} el The element into which look for the\r
* editing spot.\r
+ * @param {Boolean} isMoveToEnd Whether move to the end editable position.\r
*/\r
- moveToElementEditStart : function( el )\r
+ moveToElementEditablePosition : function( el, isMoveToEnd )\r
{\r
var isEditable;\r
\r
\r
// If an editable element is found, move inside it.\r
if ( isEditable )\r
- this.moveToPosition( el, CKEDITOR.POSITION_AFTER_START );\r
+ this.moveToPosition( el, isMoveToEnd ?\r
+ CKEDITOR.POSITION_BEFORE_END :\r
+ CKEDITOR.POSITION_AFTER_START );\r
// Stop immediately if we've found a non editable inline element (e.g <img>).\r
else if ( CKEDITOR.dtd.$inline[ el.getName() ] )\r
{\r
- this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );\r
+ this.moveToPosition( el, isMoveToEnd ?\r
+ CKEDITOR.POSITION_AFTER_END :\r
+ CKEDITOR.POSITION_BEFORE_START );\r
return true;\r
}\r
\r
// Non-editable non-inline elements are to be bypassed, getting the next one.\r
if ( CKEDITOR.dtd.$empty[ el.getName() ] )\r
- el = el.getNext( nonWhitespaceOrBookmarkEval );\r
+ el = el[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( nonWhitespaceOrBookmarkEval );\r
else\r
- el = el.getFirst( nonWhitespaceOrBookmarkEval );\r
+ el = el[ isMoveToEnd ? 'getLast' : 'getFirst' ]( nonWhitespaceOrBookmarkEval );\r
\r
// Stop immediately if we've found a text node.\r
if ( el && el.type == CKEDITOR.NODE_TEXT )\r
{\r
- this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );\r
+ this.moveToPosition( el, isMoveToEnd ?\r
+ CKEDITOR.POSITION_AFTER_END :\r
+ CKEDITOR.POSITION_BEFORE_START );\r
return true;\r
}\r
}\r
},\r
\r
/**\r
+ *@see {CKEDITOR.dom.range.moveToElementEditablePosition}\r
+ */\r
+ moveToElementEditStart : function( target )\r
+ {\r
+ return this.moveToElementEditablePosition( target );\r
+ },\r
+\r
+ /**\r
+ *@see {CKEDITOR.dom.range.moveToElementEditablePosition}\r
+ */\r
+ moveToElementEditEnd : function( target )\r
+ {\r
+ return this.moveToElementEditablePosition( target, true );\r
+ },\r
+\r
+ /**\r
* Get the single node enclosed within the range if there's one.\r
*/\r
getEnclosedNode : function()\r