Skip to content

Commit

Permalink
fix: [#1663] Fixes issue where setting document.documentElement.inner…
Browse files Browse the repository at this point in the history
…HTML isnt parsed correctly since v16 (#1671)
  • Loading branch information
capricorn86 authored Jan 7, 2025
1 parent 4975dc5 commit 00b34b4
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 3 deletions.
25 changes: 25 additions & 0 deletions packages/happy-dom/src/html-parser/HTMLParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,31 @@ export default class HTMLParser {
};
}

if (this.rootNode instanceof this.window.HTMLHtmlElement) {
const head = this.rootDocument.createElement('head');
const body = this.rootDocument.createElement('body');
while (this.rootNode[PropertySymbol.nodeArray].length > 0) {
this.rootNode[PropertySymbol.removeChild](
this.rootNode[PropertySymbol.nodeArray][
this.rootNode[PropertySymbol.nodeArray].length - 1
]
);
}

this.rootNode[PropertySymbol.appendChild](head);
this.rootNode[PropertySymbol.appendChild](body);

this.documentStructure = {
nodes: {
doctype: null,
documentElement: this.rootNode,
head,
body
},
level: HTMLDocumentStructureLevelEnum.documentElement
};
}

let match: RegExpExecArray;
let lastIndex = 0;

Expand Down
6 changes: 3 additions & 3 deletions packages/happy-dom/src/window/BrowserWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1701,14 +1701,14 @@ export default class BrowserWindow extends EventTarget implements INodeJSGlobal
this[PropertySymbol.mutationObservers] = [];

// Disconnects nodes from the document, so that they can be garbage collected.
const childNodes = this.document.body[PropertySymbol.nodeArray];
const childNodes = this.document[PropertySymbol.nodeArray];

while (childNodes.length > 0) {
// Makes sure that something won't be triggered by the disconnect.
if ((<HTMLElement>childNodes[0]).disconnectedCallback) {
delete (<HTMLElement>childNodes[0]).disconnectedCallback;
}
this.document.body.removeChild(childNodes[0]);
this.document[PropertySymbol.removeChild](childNodes[0]);
}

// Create some empty elements for scripts that are still running.
Expand All @@ -1717,7 +1717,7 @@ export default class BrowserWindow extends EventTarget implements INodeJSGlobal
const bodyElement = this.document.createElement('body');
htmlElement.appendChild(headElement);
htmlElement.appendChild(bodyElement);
this.document.body.appendChild(htmlElement);
this.document[PropertySymbol.appendChild](htmlElement);

if (this.location[PropertySymbol.destroy]) {
this.location[PropertySymbol.destroy]();
Expand Down
3 changes: 3 additions & 0 deletions packages/happy-dom/test/browser/BrowserPage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ describe('BrowserPage', () => {
const frame1 = BrowserFrameFactory.createChildFrame(page.mainFrame);
const frame2 = BrowserFrameFactory.createChildFrame(page.mainFrame);

// Should work even if the body is removed.
frame2.document.body.remove();

await page.close();

expect(browser.defaultContext.pages.length).toBe(0);
Expand Down
18 changes: 18 additions & 0 deletions packages/happy-dom/test/html-parser/HTMLParser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2104,5 +2104,23 @@ describe('HTMLParser', () => {
</body></html>`
);
});

it('Handles setting documentElement.innerHTML for #1663', () => {
document.documentElement.innerHTML = '<head></head><body></body>';
expect(document.documentElement.outerHTML).toBe('<html><head></head><body></body></html>');

document.documentElement.innerHTML = '<head></head><body>Test</body>';
expect(document.documentElement.outerHTML).toBe(
'<html><head></head><body>Test</body></html>'
);

document.documentElement.innerHTML = '';
expect(document.documentElement.outerHTML).toBe('<html><head></head><body></body></html>');

document.documentElement.innerHTML = '<body>Test</body>';
expect(document.documentElement.outerHTML).toBe(
'<html><head></head><body>Test</body></html>'
);
});
});
});

0 comments on commit 00b34b4

Please sign in to comment.