diff --git a/packages/happy-dom/src/config/PlainTextElements.ts b/packages/happy-dom/src/config/PlainTextElements.ts new file mode 100644 index 000000000..dc5606eb3 --- /dev/null +++ b/packages/happy-dom/src/config/PlainTextElements.ts @@ -0,0 +1 @@ +export default ['style', 'script']; diff --git a/packages/happy-dom/src/xml-parser/XMLParser.ts b/packages/happy-dom/src/xml-parser/XMLParser.ts index 9cb8e787d..2d105fc83 100755 --- a/packages/happy-dom/src/xml-parser/XMLParser.ts +++ b/packages/happy-dom/src/xml-parser/XMLParser.ts @@ -11,6 +11,7 @@ import INode from '../nodes/node/INode'; import IElement from '../nodes/element/IElement'; import HTMLLinkElement from '../nodes/html-link-element/HTMLLinkElement'; import IDocumentFragment from '../nodes/document-fragment/IDocumentFragment'; +import PlainTextElements from '../config/PlainTextElements'; const MARKUP_REGEXP = /<(\/?)([a-z][-.0-9_a-z]*)\s*([^<>]*?)(\/?)>/gi; const COMMENT_REGEXP = /|<([!?])([^>]*)>/gi; @@ -51,7 +52,14 @@ export default class XMLParser { if (parent && match.index !== lastTextIndex) { const text = data.substring(lastTextIndex, match.index); - this.appendTextAndCommentNodes(document, parent, text); + if ( + parent.nodeType === Node.ELEMENT_NODE && + PlainTextElements.includes((parent).tagName.toLowerCase()) + ) { + parent.appendChild(document.createTextNode(text)); + } else { + this.appendTextAndCommentNodes(document, parent, text); + } } if (isStartTag) { diff --git a/packages/happy-dom/test/dom-parser/DOMParser.test.ts b/packages/happy-dom/test/dom-parser/DOMParser.test.ts index e662a789e..213697b9b 100644 --- a/packages/happy-dom/test/dom-parser/DOMParser.test.ts +++ b/packages/happy-dom/test/dom-parser/DOMParser.test.ts @@ -7,7 +7,14 @@ describe('DOMParser', () => { let window; beforeEach(() => { - window = new Window(); + window = new Window({ + settings: { + disableJavaScriptFileLoading: true, + disableJavaScriptEvaluation: true, + disableCSSFileLoading: true, + enableFileSystemHttpRequests: false + } + }); domParser = new window.DOMParser(); }); @@ -55,5 +62,28 @@ describe('DOMParser', () => { `.replace(/[\s]/gm, '') ); }); + + it('Correctly parses JS script w/ ` { + const newDocument = domParser.parseFromString( + ` + + + + `, + 'text/html' + ); + // Spurious comment `` should be solved + expect(new XMLSerializer().serializeToString(newDocument).replace(/\s{1,}/, ' ')).toBe( + ` + + + + `.replace(/\s{1,}/, ' ') + ); + }); }); });