CKEDITOR.POSITION_AFTER_START :\r
CKEDITOR.POSITION_AFTER_END );\r
\r
+ // Avoid enlarging the range further when end boundary spans right after the BR. (#7490)\r
+ if ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS )\r
+ {\r
+ var theRange = this.clone();\r
+ walker = new CKEDITOR.dom.walker( theRange );\r
+\r
+ var whitespaces = CKEDITOR.dom.walker.whitespaces(),\r
+ bookmark = CKEDITOR.dom.walker.bookmark();\r
+\r
+ walker.evaluator = function( node ) { return !whitespaces( node ) && !bookmark( node ); };\r
+ var previous = walker.previous();\r
+ if ( previous && previous.type == CKEDITOR.NODE_ELEMENT && previous.is( 'br' ) )\r
+ return;\r
+ }\r
+\r
+\r
// Enlarging the end boundary.\r
walkerRange = this.clone();\r
walkerRange.collapse();\r
*/\r
moveToElementEditablePosition : function( el, isMoveToEnd )\r
{\r
- var isEditable;\r
-\r
- // Empty elements are rejected.\r
- if ( CKEDITOR.dtd.$empty[ el.getName() ] )\r
- return false;\r
-\r
- while ( el && el.type == CKEDITOR.NODE_ELEMENT )\r
+ function nextDFS( node, childOnly )\r
{\r
- isEditable = el.isEditable();\r
+ var next;\r
\r
- // If an editable element is found, move inside it.\r
- if ( isEditable )\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
+ if ( node.type == CKEDITOR.NODE_ELEMENT\r
+ && node.isEditable( false )\r
+ && !CKEDITOR.dtd.$nonEditable[ node.getName() ] )\r
{\r
- this.moveToPosition( el, isMoveToEnd ?\r
- CKEDITOR.POSITION_AFTER_END :\r
- CKEDITOR.POSITION_BEFORE_START );\r
- return true;\r
+ next = node[ isMoveToEnd ? 'getLast' : 'getFirst' ]( nonWhitespaceOrBookmarkEval );\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[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( nonWhitespaceOrBookmarkEval );\r
- else\r
- el = el[ isMoveToEnd ? 'getLast' : 'getFirst' ]( nonWhitespaceOrBookmarkEval );\r
+ if ( !childOnly && !next )\r
+ next = node[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( nonWhitespaceOrBookmarkEval );\r
+\r
+ return next;\r
+ }\r
+\r
+ var found = 0;\r
\r
+ while ( el )\r
+ {\r
// Stop immediately if we've found a text node.\r
- if ( el && el.type == CKEDITOR.NODE_TEXT )\r
+ if ( el.type == CKEDITOR.NODE_TEXT )\r
{\r
this.moveToPosition( el, isMoveToEnd ?\r
CKEDITOR.POSITION_AFTER_END :\r
CKEDITOR.POSITION_BEFORE_START );\r
- return true;\r
+ found = 1;\r
+ break;\r
}\r
+\r
+ // If an editable element is found, move inside it, but not stop the searching.\r
+ if ( el.type == CKEDITOR.NODE_ELEMENT )\r
+ {\r
+ if ( el.isEditable() )\r
+ {\r
+ this.moveToPosition( el, isMoveToEnd ?\r
+ CKEDITOR.POSITION_BEFORE_END :\r
+ CKEDITOR.POSITION_AFTER_START );\r
+ found = 1;\r
+ }\r
+ }\r
+\r
+ el = nextDFS( el, found );\r
}\r
\r
- return isEditable;\r
+ return !!found;\r
},\r
\r
/**\r