From 1e95e0af276363c185adc024b8fa19fe7d41f610 Mon Sep 17 00:00:00 2001 From: Mas0nShi Date: Thu, 23 Feb 2023 14:14:39 +0800 Subject: [PATCH] #519@patch: Fixes XMLParser Bug. --- .../happy-dom/src/xml-parser/XMLParser.ts | 27 +++++++++++++++- .../test/xml-parser/XMLParser.test.ts | 32 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/packages/happy-dom/src/xml-parser/XMLParser.ts b/packages/happy-dom/src/xml-parser/XMLParser.ts index fc704af04..7e552e867 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,29 @@ export default class XMLParser { if (parentTagName && PlainTextElements.includes(parentTagName)) { parent.appendChild(document.createTextNode(text)); } else { - this.appendTextAndCommentNodes(document, parent, text); + let condCommMatch; + let condCommEndMatch; + let needRewrite = false; + 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]) { + // Compatible with IE + while ((condCommEndMatch = condCommEndRegexp.exec(data))) { + if (condCommEndMatch[0]) { + needRewrite = true; + break; + } else { + throw new Error('conditional comments unclosed.'); + } + } + if (needRewrite) { + markupRegexp.lastIndex = condCommEndRegexp.lastIndex; + continue; // Re parse. + } + } 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..664d1aed6 100644 --- a/packages/happy-dom/test/xml-parser/XMLParser.test.ts +++ b/packages/happy-dom/test/xml-parser/XMLParser.test.ts @@ -410,5 +410,37 @@ describe('XMLParser', () => { const root4 = XMLParser.parse(window.document, (false)); expect(new XMLSerializer().serializeToString(root4)).toBe('false'); }); + + it('Parses conditional comments', () => { + const testHTML = [ + '', + + '', + + '', + + '', + + '', + + '' + ]; + + for (const html of testHTML) { + const root = XMLParser.parse(window.document, html); + expect(new XMLSerializer().serializeToString(root)).toBe(html); + } + }); }); });