diff --git a/packages/happy-dom/src/xml-parser/XMLParser.ts b/packages/happy-dom/src/xml-parser/XMLParser.ts index fc704af04..b2334a417 100755 --- a/packages/happy-dom/src/xml-parser/XMLParser.ts +++ b/packages/happy-dom/src/xml-parser/XMLParser.ts @@ -13,6 +13,9 @@ import HTMLLinkElement from '../nodes/html-link-element/HTMLLinkElement'; import IDocumentFragment from '../nodes/document-fragment/IDocumentFragment'; import PlainTextElements from '../config/PlainTextElements'; +const CONDITION_COMMENT_REGEXP = + //gi; +const CONDITION_COMMENT_END_REGEXP = //gi; const MARKUP_REGEXP = /<(\/?)([a-z][-.0-9_a-z]*)\s*([^<>]*?)(\/?)>/gi; const COMMENT_REGEXP = /|<([!?])([^>]*)>/gi; const DOCUMENT_TYPE_ATTRIBUTE_REGEXP = /"([^"]+)"/gm; @@ -56,7 +59,23 @@ export default class XMLParser { if (parentTagName && PlainTextElements.includes(parentTagName)) { parent.appendChild(document.createTextNode(text)); } else { - this.appendTextAndCommentNodes(document, parent, text); + let condCommMatch; + let condCommEndMatch; + const condCommRegexp = new RegExp(CONDITION_COMMENT_REGEXP, 'gi'); + const condCommEndRegexp = new RegExp(CONDITION_COMMENT_END_REGEXP, 'gi'); + // @Refer: https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/?redirectedfrom=MSDN + if ( + isStartTag && + (condCommMatch = condCommRegexp.exec(text)) && + condCommMatch[0] && + (condCommEndMatch = condCommEndRegexp.exec(data.substring(markupRegexp.lastIndex))) && + condCommEndMatch[0] + ) { + markupRegexp.lastIndex += condCommEndRegexp.lastIndex; + continue; + } else { + this.appendTextAndCommentNodes(document, parent, text); + } } } diff --git a/packages/happy-dom/test/xml-parser/XMLParser.test.ts b/packages/happy-dom/test/xml-parser/XMLParser.test.ts index f30c525f4..85dde35a9 100644 --- a/packages/happy-dom/test/xml-parser/XMLParser.test.ts +++ b/packages/happy-dom/test/xml-parser/XMLParser.test.ts @@ -410,5 +410,58 @@ describe('XMLParser', () => { const root4 = XMLParser.parse(window.document, (false)); expect(new XMLSerializer().serializeToString(root4)).toBe('false'); }); + + it('Parses conditional comments', () => { + const testHTML = [ + '', + + '', + + '', + + '', + + '', + + '', + + '\n' + + '\n' + + ' \n' + + ' Title\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n' + ]; + + for (const html of testHTML) { + const root = XMLParser.parse(window.document, html); + expect(new XMLSerializer().serializeToString(root)).toBe(html); + } + }); }); });