fix(dom): return empty shallow clones of detached HTML documents

Clear the initialized HTML shell before returning a shallow Document clone.
This removes the unexpected doctype/root and allows callers to append a new
document element. Deep clones still copy the source children.

Cover omitted/false/undefined deep arguments, rootless and custom-root HTML,
doctype-only documents, XHTML/XML controls, and preserved source identity.
All 273 shared browser assertions pass; 15 upstream cases retain all 1442
passing subtests.

Validation: cargo fmt --all; workspace/all-targets/all-features Clippy with
-D warnings; cargo nextest run --no-fail-fast (19464 passed, 13 skipped).
This commit is contained in:
ldm0
2026-09-23 00:14:09 +08:00
parent 4787f31632
commit dbb70ca46b
2 changed files with 3 additions and 1 deletions
@@ -9,7 +9,7 @@ fn detached_document_shallow_clones_are_empty_and_accept_a_new_root() {
.expect("Document shallow clone probe should evaluate");
let result: serde_json::Value = serde_json::from_str(&result).unwrap();
assert_eq!(result["failures"], serde_json::json!([]), "{result}");
assert_eq!(result["checks"], 245);
assert_eq!(result["checks"], 273);
}
#[test]
@@ -31,6 +31,7 @@
equal(label + " doctype", copy.doctype, null);
equal(label + " HTML structure", copy.head === null && copy.body === null, true);
equal(label + " owner", copy.ownerDocument, null);
equal(label + " MIME", copy.contentType, source.contentType);
equal(label + " view", copy.defaultView, null);
const node = copy.createElement("probe");
let error = null;
@@ -44,6 +45,7 @@
equal(name + ": deep identity", deep !== source, true);
equal(name + ": deep equality", deep.isEqualNode(source), true);
equal(name + ": deep count", deep.childNodes.length, original.length);
equal(name + ": deep MIME", deep.contentType, source.contentType);
equal(name + ": deep children", Array.from(deep.childNodes).every((child, i) => child !== original[i] && child.ownerDocument === deep), true);
equal(name + ": source unchanged", source.childNodes.length === original.length && original.every((child, i) => child === source.childNodes[i] && child.parentNode === source), true);
}