Index: _source/core/htmlparser/element.js =================================================================== --- _source/core/htmlparser/element.js (revision 6557) +++ _source/core/htmlparser/element.js (revision ) @@ -50,6 +50,8 @@ isEmpty = !!dtd.$empty[ name ]; this.isEmpty = isEmpty; + // Indicate there's no explicit close tag on this element. + this.isOptionalClose = false; this.isUnknown = !dtd[ name ]; /** @private */ Index: _source/core/htmlparser/fragment.js =================================================================== --- _source/core/htmlparser/fragment.js (revision 6629) +++ _source/core/htmlparser/fragment.js (revision ) @@ -184,7 +184,7 @@ currentNode = moveCurrent ? target : savedCurrent; } - parser.onTagOpen = function( tagName, attributes, selfClosing ) + parser.onTagOpen = function( tagName, attributes, selfClosing, optionalClose ) { var element = new CKEDITOR.htmlParser.element( tagName, attributes ); @@ -193,6 +193,8 @@ if ( element.isUnknown && selfClosing ) element.isEmpty = true; + element.isOptionalClose = optionalClose; + // This is a tag to be removed if empty, so do not add it immediately. if ( CKEDITOR.dtd.$removeEmpty[ tagName ] ) { @@ -224,22 +226,27 @@ // If the element cannot be child of the current element. if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) { + // Current node doesn't have a close tag, time for a close + // as this element isn't fit in. (#7497) + if ( currentNode.isOptionalClose ) + parser.onTagClose( currentName ); // Fixing malformed nested lists by moving it into a previous list item. (#3828) - if ( tagName in listBlocks + else if ( tagName in listBlocks - && currentName in listBlocks ) + && currentName in listBlocks ) { var children = currentNode.children, - lastChild = children[ children.length - 1 ]; + lastChild = children[ children.length - 1 ]; // Establish the list item if it's not existed. if ( !( lastChild && lastChild.name == 'li' ) ) addElement( ( lastChild = new CKEDITOR.htmlParser.element( 'li' ) ), currentNode ); + !element.returnPoint && ( element.returnPoint = currentNode ); currentNode = lastChild; } // Establish new list root for orphan list items. else if ( tagName in CKEDITOR.dtd.$listItem && currentName != tagName ) - parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {} ); + parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {}, 0, 1 ); // We're inside a structural block like table and list, AND the incoming element // is not of the same type (e.g.