Skip to content

Commit

Permalink
fix: Document.cloneNode(true) produces null .body & .head (closes #157)
Browse files Browse the repository at this point in the history
  • Loading branch information
b-fuze committed Jan 30, 2024
1 parent a4e2812 commit c331b2c
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
25 changes: 25 additions & 0 deletions src/dom/document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,31 @@ export class Document extends Node {
return node;
}

// FIXME: This is a bad solution. The correct solution
// would be to make `.body` and `.head` dynamic getters,
// but that would be a breaking change since `.body`
// and `.head` would need to be typed as `Element | null`.
// Currently they're typed as `Element` which is incorrect...
cloneNode(deep?: boolean): Document {
const doc = super.cloneNode(deep) as Document;

for (const child of doc.documentElement?.childNodes || []) {
switch (child.nodeName) {
case "BODY": {
doc.body = child as Element;
break;
}

case "HEAD": {
doc.head = child as Element;
break;
}
}
}

return doc;
}

querySelector(selectors: string): Element | null {
return this._nwapi.first(selectors, this);
}
Expand Down
19 changes: 19 additions & 0 deletions test/units/Document-cloneNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { DOMParser, Document } from "../../deno-dom-wasm.ts";
import { assertStrictEquals as assertEquals } from "https://deno.land/std@0.85.0/testing/asserts.ts";

Deno.test("Document.cloneNode has non-null .body & .head when they exist", () => {
const doc = new DOMParser().parseFromString(
`<div></div>`,
"text/html",
)!;
const docClone = doc.cloneNode(true);

assertEquals(docClone.body?.localName, "body");
assertEquals(docClone.head?.localName, "head");

const emptyDoc = new Document();
const emptyDocClone = emptyDoc.cloneNode(true);

assertEquals(emptyDocClone.body, null);
assertEquals(emptyDocClone.head, null);
});

0 comments on commit c331b2c

Please sign in to comment.