diff --git a/CHANGES.html b/CHANGES.html
index 6d571eb127..d079b1b1d1 100644
--- a/CHANGES.html
+++ b/CHANGES.html
@@ -69,6 +69,7 @@
#7490 : [IE] Block format leaks to the next unselected line when enterMode
is set to BR
.
#8087 : Indenting list items may add redundant text direction attributes.
#6200 : Styling for certain dialog element type that miss focus outline like checkbox.
+ #7894 : Fault tolerance when parsing malformed link.
Updated the following language files:
- #8128 : Italian;
- #8126, #8256 : Norwegian (Bokmål and Nynorsk);
diff --git a/_source/core/htmlparser/fragment.js b/_source/core/htmlparser/fragment.js
index 2b6c411845..b7157aff63 100644
--- a/_source/core/htmlparser/fragment.js
+++ b/_source/core/htmlparser/fragment.js
@@ -46,6 +46,11 @@ CKEDITOR.htmlParser.fragment = function() {
// Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan - .
var rootDtd = CKEDITOR.tools.extend( {}, { html:1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style:1,script:1 } );
+ function isRemoveEmpty( node ) {
+ // Empty link is to be removed when empty but not anchor. (#7894)
+ return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
+ }
+
/**
* Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string.
* @param {String} fragmentHtml The HTML to be parsed, filling the fragment.
@@ -94,6 +99,11 @@ CKEDITOR.htmlParser.fragment = function() {
// to properly process the next entry).
pendingInline.splice( i, 1 );
i--;
+ } else {
+ // Some element of the same type cannot be nested, flat them,
+ // e.g. foobar. (#7894)
+ if ( pendingName == currentNode.name )
+ addElement( currentNode, currentNode.parent, 1 ), i--;
}
}
}
@@ -179,7 +189,7 @@ CKEDITOR.htmlParser.fragment = function() {
element.isOptionalClose = tagName in optionalCloseTags || optionalClose;
// This is a tag to be removed if empty, so do not add it immediately.
- if ( CKEDITOR.dtd.$removeEmpty[ tagName ] ) {
+ if ( isRemoveEmpty( element ) ) {
pendingInline.push( element );
return;
} else if ( tagName == 'pre' )