JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
vanilla ckeditor-3.5.1
[ckeditor.git] / _source / core / htmlparser / fragment.js
index 6c7686c..f94f4e9 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
-Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.\r
+Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.\r
 For licensing, see LICENSE.html or http://ckeditor.com/license\r
 */\r
 \r
@@ -64,6 +64,7 @@ CKEDITOR.htmlParser.fragment = function()
                        html = [],\r
                        fragment = new CKEDITOR.htmlParser.fragment(),\r
                        pendingInline = [],\r
+                       pendingBRs = [],\r
                        currentNode = fragment,\r
                    // Indicate we're inside a <pre> element, spaces should be touched differently.\r
                        inPre = false,\r
@@ -71,6 +72,8 @@ CKEDITOR.htmlParser.fragment = function()
 \r
                function checkPending( newTagName )\r
                {\r
+                       var pendingBRsSent;\r
+\r
                        if ( pendingInline.length > 0 )\r
                        {\r
                                for ( var i = 0 ; i < pendingInline.length ; i++ )\r
@@ -82,6 +85,12 @@ CKEDITOR.htmlParser.fragment = function()
 \r
                                        if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) )\r
                                        {\r
+                                               if ( !pendingBRsSent )\r
+                                               {\r
+                                                       sendPendingBRs();\r
+                                                       pendingBRsSent = 1;\r
+                                               }\r
+\r
                                                // Get a clone for the pending element.\r
                                                pendingElement = pendingElement.clone();\r
 \r
@@ -99,24 +108,29 @@ CKEDITOR.htmlParser.fragment = function()
                        }\r
                }\r
 \r
+               function sendPendingBRs( brsToIgnore )\r
+               {\r
+                       while ( pendingBRs.length - ( brsToIgnore || 0 ) > 0 )\r
+                               currentNode.add( pendingBRs.shift() );\r
+               }\r
+\r
                function addElement( element, target, enforceCurrent )\r
                {\r
                        target = target || currentNode || fragment;\r
 \r
-                       // If the target is the fragment and this element can't go inside\r
+                       // If the target is the fragment and this inline element can't go inside\r
                        // body (if fixForBody).\r
                        if ( fixForBody && !target.type )\r
                        {\r
                                var elementName, realElementName;\r
                                if ( element.attributes\r
                                         && ( realElementName =\r
-                                                 element.attributes[ '_cke_real_element_type' ] ) )\r
+                                                 element.attributes[ 'data-cke-real-element-type' ] ) )\r
                                        elementName = realElementName;\r
                                else\r
                                        elementName =  element.name;\r
-                               if ( elementName\r
-                                               && !( elementName in CKEDITOR.dtd.$body )\r
-                                               && !( elementName in CKEDITOR.dtd.$nonBodyContent )  )\r
+\r
+                               if ( elementName && elementName in CKEDITOR.dtd.$inline )\r
                                {\r
                                        var savedCurrent = currentNode;\r
 \r
@@ -181,6 +195,12 @@ CKEDITOR.htmlParser.fragment = function()
                                return;\r
                        }\r
 \r
+                       if ( tagName == 'br' )\r
+                       {\r
+                               pendingBRs.push( element );\r
+                               return;\r
+                       }\r
+\r
                        var currentName = currentNode.name;\r
 \r
                        var currentDtd = currentName\r
@@ -196,7 +216,7 @@ CKEDITOR.htmlParser.fragment = function()
                                        addPoint;   // New position to start adding nodes.\r
 \r
                                // Fixing malformed nested lists by moving it into a previous list item. (#3828)\r
-                               if( tagName in listBlocks\r
+                               if ( tagName in listBlocks\r
                                        && currentName in listBlocks )\r
                                {\r
                                        var children = currentNode.children,\r
@@ -216,6 +236,12 @@ CKEDITOR.htmlParser.fragment = function()
                                {\r
                                        addElement( currentNode, currentNode.parent );\r
                                }\r
+                               else if ( tagName in CKEDITOR.dtd.$listItem )\r
+                               {\r
+                                       parser.onTagOpen( 'ul', {} );\r
+                                       addPoint = currentNode;\r
+                                       reApply = true;\r
+                               }\r
                                else\r
                                {\r
                                        if ( nonBreakingBlocks[ currentName ] )\r
@@ -239,7 +265,7 @@ CKEDITOR.htmlParser.fragment = function()
                                        reApply = true;\r
                                }\r
 \r
-                               if( addPoint )\r
+                               if ( addPoint )\r
                                        currentNode = addPoint;\r
                                // Try adding it to the return point, or the parent element.\r
                                else\r
@@ -253,6 +279,7 @@ CKEDITOR.htmlParser.fragment = function()
                        }\r
 \r
                        checkPending( tagName );\r
+                       sendPendingBRs();\r
 \r
                        element.parent = currentNode;\r
                        element.returnPoint = returnPoint;\r
@@ -308,9 +335,12 @@ CKEDITOR.htmlParser.fragment = function()
 \r
                                currentNode = candidate;\r
 \r
-                               if( currentNode.name == 'pre' )\r
+                               if ( currentNode.name == 'pre' )\r
                                        inPre = false;\r
 \r
+                               if ( candidate._.isBlockLike )\r
+                                       sendPendingBRs();\r
+\r
                                addElement( candidate, candidate.parent );\r
 \r
                                // The parent should start receiving new nodes now, except if\r
@@ -321,7 +351,7 @@ CKEDITOR.htmlParser.fragment = function()
                                pendingInline = pendingInline.concat( newPendingInline );\r
                        }\r
 \r
-                       if( tagName == 'body' )\r
+                       if ( tagName == 'body' )\r
                                fixForBody = false;\r
                };\r
 \r
@@ -336,6 +366,7 @@ CKEDITOR.htmlParser.fragment = function()
                                        return;\r
                        }\r
 \r
+                       sendPendingBRs();\r
                        checkPending();\r
 \r
                        if ( fixForBody\r
@@ -360,12 +391,17 @@ CKEDITOR.htmlParser.fragment = function()
 \r
                parser.onComment = function( comment )\r
                {\r
+                       sendPendingBRs();\r
+                       checkPending();\r
                        currentNode.add( new CKEDITOR.htmlParser.comment( comment ) );\r
                };\r
 \r
                // Parse it.\r
                parser.parse( fragmentHtml );\r
 \r
+               // Send all pending BRs except one, which we consider a unwanted bogus. (#5293)\r
+               sendPendingBRs( !CKEDITOR.env.ie && 1 );\r
+\r
                // Close all pending nodes.\r
                while ( currentNode.type )\r
                {\r