JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.6.4
[ckeditor.git] / _source / core / dom / range.js
index 30a78c4..c8312b7 100644 (file)
@@ -349,7 +349,10 @@ CKEDITOR.dom.range = function( document )
        // check(Start|End)OfBlock.\r
        function getCheckStartEndBlockEvalFunction( isStart )\r
        {\r
-               var hadBr = false, bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true );\r
+               var skipBogus = false,\r
+                       bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true ),\r
+                       nbspRegExp = /^[\t\r\n ]*(?: |\xa0)$/;\r
+\r
                return function( node )\r
                {\r
                        // First ignore bookmark nodes.\r
@@ -358,8 +361,16 @@ CKEDITOR.dom.range = function( document )
 \r
                        if ( node.type == CKEDITOR.NODE_TEXT )\r
                        {\r
+                               // Skip the block filler NBSP.\r
+                               if ( CKEDITOR.env.ie &&\r
+                                        nbspRegExp.test( node.getText() ) &&\r
+                                        !skipBogus &&\r
+                                        !( isStart && node.getNext() ) )\r
+                               {\r
+                                       skipBogus = true;\r
+                               }\r
                                // If there's any visible text, then we're not at the start.\r
-                               if ( node.hasAscendant( 'pre' ) || CKEDITOR.tools.trim( node.getText() ).length )\r
+                               else if ( node.hasAscendant( 'pre' ) || CKEDITOR.tools.trim( node.getText() ).length )\r
                                        return false;\r
                        }\r
                        else if ( node.type == CKEDITOR.NODE_ELEMENT )\r
@@ -368,10 +379,14 @@ CKEDITOR.dom.range = function( document )
                                // at the start.\r
                                if ( !inlineChildReqElements[ node.getName() ] )\r
                                {\r
-                                       // If we're working at the end-of-block, forgive the first <br /> in non-IE\r
-                                       // browsers.\r
-                                       if ( !isStart && !CKEDITOR.env.ie && node.getName() == 'br' && !hadBr )\r
-                                               hadBr = true;\r
+                                       // Skip the padding block br.\r
+                                       if ( !CKEDITOR.env.ie &&\r
+                                                node.is( 'br' ) &&\r
+                                                !skipBogus &&\r
+                                                !( isStart && node.getNext() ) )\r
+                                       {\r
+                                               skipBogus = true;\r
+                                       }\r
                                        else\r
                                                return false;\r
                                }\r
@@ -513,7 +528,7 @@ CKEDITOR.dom.range = function( document )
                        if ( serializable )\r
                        {\r
                                baseId = 'cke_bm_' + CKEDITOR.tools.getNextNumber();\r
-                               startNode.setAttribute( 'id', baseId + 'S' );\r
+                               startNode.setAttribute( 'id', baseId + ( collapsed ? 'C' : 'S' ) );\r
                        }\r
 \r
                        // If collapsed, the endNode will not be created.\r
@@ -544,7 +559,7 @@ CKEDITOR.dom.range = function( document )
                                this.moveToPosition( startNode, CKEDITOR.POSITION_AFTER_END );\r
 \r
                        return {\r
-                               startNode : serializable ? baseId + 'S' : startNode,\r
+                               startNode : serializable ? baseId + ( collapsed ? 'C' : 'S' ) : startNode,\r
                                endNode : serializable ? baseId + 'E' : endNode,\r
                                serializable : serializable,\r
                                collapsed : collapsed\r
@@ -1828,11 +1843,6 @@ CKEDITOR.dom.range = function( document )
                                        return false;\r
                        }\r
 \r
-                       // Antecipate the trim() call here, so the walker will not make\r
-                       // changes to the DOM, which would not get reflected into this\r
-                       // range otherwise.\r
-                       this.trim();\r
-\r
                        // We need to grab the block element holding the start boundary, so\r
                        // let's use an element path for it.\r
                        var path = new CKEDITOR.dom.elementPath( this.startContainer );\r
@@ -1862,11 +1872,6 @@ CKEDITOR.dom.range = function( document )
                                        return false;\r
                        }\r
 \r
-                       // Antecipate the trim() call here, so the walker will not make\r
-                       // changes to the DOM, which would not get reflected into this\r
-                       // range otherwise.\r
-                       this.trim();\r
-\r
                        // We need to grab the block element holding the start boundary, so\r
                        // let's use an element path for it.\r
                        var path = new CKEDITOR.dom.elementPath( this.endContainer );\r
@@ -1934,16 +1939,14 @@ CKEDITOR.dom.range = function( document )
                 */\r
                moveToElementEditablePosition : function( el, isMoveToEnd )\r
                {\r
+                       var nbspRegExp = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/;\r
+\r
                        function nextDFS( node, childOnly )\r
                        {\r
                                var next;\r
 \r
-                               if ( node.type == CKEDITOR.NODE_ELEMENT\r
-                                               && node.isEditable( false )\r
-                                               && !CKEDITOR.dtd.$nonEditable[ node.getName() ] )\r
-                               {\r
+                               if ( node.type == CKEDITOR.NODE_ELEMENT && node.isEditable( false ) )\r
                                        next = node[ isMoveToEnd ? 'getLast' : 'getFirst' ]( nonWhitespaceOrBookmarkEval );\r
-                               }\r
 \r
                                if ( !childOnly && !next )\r
                                        next = node[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( nonWhitespaceOrBookmarkEval );\r
@@ -1951,6 +1954,15 @@ CKEDITOR.dom.range = function( document )
                                return next;\r
                        }\r
 \r
+                       // Handle non-editable element e.g. HR.\r
+                       if ( el.type == CKEDITOR.NODE_ELEMENT && !el.isEditable( false ) )\r
+                       {\r
+                               this.moveToPosition( el, isMoveToEnd ?\r
+                                                                                CKEDITOR.POSITION_AFTER_END :\r
+                                                                                CKEDITOR.POSITION_BEFORE_START );\r
+                               return true;\r
+                       }\r
+\r
                        var found = 0;\r
 \r
                        while ( el )\r
@@ -1958,7 +1970,11 @@ CKEDITOR.dom.range = function( document )
                                // Stop immediately if we've found a text node.\r
                                if ( el.type == CKEDITOR.NODE_TEXT )\r
                                {\r
-                                       this.moveToPosition( el, isMoveToEnd ?\r
+                                       // Put cursor before block filler.\r
+                                       if ( isMoveToEnd && this.checkEndOfBlock() && nbspRegExp.test( el.getText() ) )\r
+                                               this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );\r
+                                       else\r
+                                               this.moveToPosition( el, isMoveToEnd ?\r
                                                                 CKEDITOR.POSITION_AFTER_END :\r
                                                                 CKEDITOR.POSITION_BEFORE_START );\r
                                        found = 1;\r
@@ -1975,6 +1991,9 @@ CKEDITOR.dom.range = function( document )
                                                                                                 CKEDITOR.POSITION_AFTER_START );\r
                                                found = 1;\r
                                        }\r
+                                       // Put cursor before padding block br.\r
+                                       else if ( isMoveToEnd && el.is( 'br' ) && this.checkEndOfBlock() )\r
+                                               this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );\r
                                }\r
 \r
                                el = nextDFS( el, found );\r