205 lines
8.2 KiB
HTML
205 lines
8.2 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset=utf-8>
|
|
<title>ParentNode.replaceChildren</title>
|
|
<link rel=help href="https://dom.spec.whatwg.org/#dom-parentnode-replacechildren">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="pre-insertion-validation-hierarchy.js"></script>
|
|
<script>
|
|
preInsertionValidateHierarchy("replaceChildren");
|
|
|
|
function test_replacechildren(node, nodeName) {
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
parent.replaceChildren();
|
|
assert_array_equals(parent.childNodes, []);
|
|
}, `${nodeName}.replaceChildren() without any argument, on a parent having no child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
parent.replaceChildren(null);
|
|
assert_equals(parent.childNodes[0].textContent, 'null');
|
|
}, `${nodeName}.replaceChildren() with null as an argument, on a parent having no child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
parent.replaceChildren(undefined);
|
|
assert_equals(parent.childNodes[0].textContent, 'undefined');
|
|
}, `${nodeName}.replaceChildren() with undefined as an argument, on a parent having no child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
parent.replaceChildren('text');
|
|
assert_equals(parent.childNodes[0].textContent, 'text');
|
|
}, `${nodeName}.replaceChildren() with only text as an argument, on a parent having no child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
const x = document.createElement('x');
|
|
parent.replaceChildren(x);
|
|
assert_array_equals(parent.childNodes, [x]);
|
|
}, `${nodeName}.replaceChildren() with only one element as an argument, on a parent having no child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
const child = document.createElement('test');
|
|
parent.appendChild(child);
|
|
parent.replaceChildren();
|
|
assert_array_equals(parent.childNodes, []);
|
|
}, `${nodeName}.replaceChildren() without any argument, on a parent having a child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
const child = document.createElement('test');
|
|
parent.appendChild(child);
|
|
parent.replaceChildren(null);
|
|
assert_equals(parent.childNodes.length, 1);
|
|
assert_equals(parent.childNodes[0].textContent, 'null');
|
|
}, `${nodeName}.replaceChildren() with null as an argument, on a parent having a child.`);
|
|
|
|
test(() => {
|
|
const parent = node.cloneNode();
|
|
const x = document.createElement('x');
|
|
const child = document.createElement('test');
|
|
parent.appendChild(child);
|
|
parent.replaceChildren(x, 'text');
|
|
assert_equals(parent.childNodes.length, 2);
|
|
assert_equals(parent.childNodes[0], x);
|
|
assert_equals(parent.childNodes[1].textContent, 'text');
|
|
}, `${nodeName}.replaceChildren() with one element and text as argument, on a parent having a child.`);
|
|
|
|
async_test(t => {
|
|
let phase = 0;
|
|
|
|
const previousParent = node.cloneNode();
|
|
const insertions = [
|
|
document.createElement("test1"),
|
|
document.createElement("test2")
|
|
];
|
|
previousParent.append(...insertions);
|
|
|
|
const parent = node.cloneNode();
|
|
const children = [
|
|
document.createElement("test3"),
|
|
document.createElement("test4")
|
|
];
|
|
parent.append(...children);
|
|
|
|
const previousObserver = new MutationObserver(mutations => {
|
|
t.step(() => {
|
|
assert_equals(phase, 0);
|
|
assert_equals(mutations.length, 2);
|
|
for (const [i, mutation] of Object.entries(mutations)) {
|
|
assert_equals(mutation.type, "childList");
|
|
assert_equals(mutation.addedNodes.length, 0);
|
|
assert_equals(mutation.removedNodes.length, 1);
|
|
assert_equals(mutation.removedNodes[0], insertions[i]);
|
|
}
|
|
phase = 1;
|
|
});
|
|
});
|
|
previousObserver.observe(previousParent, { childList: true });
|
|
|
|
const observer = new MutationObserver(mutations => {
|
|
t.step(() => {
|
|
assert_equals(phase, 1, "phase");
|
|
assert_equals(mutations.length, 1, "mutations.length");
|
|
const mutation = mutations[0];
|
|
assert_equals(mutation.type, "childList", "mutation.type");
|
|
assert_equals(mutation.addedNodes.length, 2, "added nodes length");
|
|
assert_array_equals([...mutation.addedNodes], insertions, "added nodes");
|
|
assert_equals(mutation.removedNodes.length, 2, "removed nodes length");
|
|
assert_array_equals([...mutation.removedNodes], children, "removed nodes");
|
|
});
|
|
t.done();
|
|
});
|
|
observer.observe(parent, { childList: true });
|
|
|
|
parent.replaceChildren(...previousParent.children);
|
|
}, `${nodeName}.replaceChildren() should move nodes in the right order`);
|
|
}
|
|
|
|
test_replacechildren(document.createElement('div'), 'Element');
|
|
test_replacechildren(document.createDocumentFragment(), 'DocumentFragment');
|
|
|
|
async_test(t => {
|
|
let root = document.createElement("div");
|
|
root.innerHTML = "<div id='a'>text<div id='b'>text2</div></div>";
|
|
const a = root.firstChild;
|
|
const b = a.lastChild;
|
|
const txt = b.previousSibling;
|
|
const txt2 = b.firstChild;
|
|
|
|
const observer = new MutationObserver((mutations) => {
|
|
|
|
assert_equals(mutations.length, 2, "mutations.length");
|
|
|
|
assert_equals(mutations[0].target.id, "a", "Target of the removal");
|
|
assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes");
|
|
assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node");
|
|
assert_equals(mutations[0].removedNodes[0], txt, "Should have removed txt node");
|
|
|
|
assert_equals(mutations[1].target.id, "b", "Target of the replaceChildren");
|
|
assert_equals(mutations[1].removedNodes.length, 1, "Should have removed 1 node");
|
|
assert_equals(mutations[1].removedNodes[0], txt2, "Should have removed txt2 node");
|
|
assert_equals(mutations[1].addedNodes.length, 1, "Should have added a node");
|
|
assert_equals(mutations[1].addedNodes[0], txt, "Should have added txt node");
|
|
|
|
observer.disconnect();
|
|
t.done();
|
|
});
|
|
|
|
observer.observe(a, {
|
|
subtree: true,
|
|
childList: true
|
|
});
|
|
|
|
b.replaceChildren(txt);
|
|
}, "There should be a MutationRecord for the node removed from another parent node.");
|
|
|
|
async_test(t => {
|
|
// This is almost the same test as above, but passes two nodes to replaceChildren.
|
|
|
|
let root = document.createElement("div");
|
|
root.innerHTML = "<div id='a'><div id='c'></div>text<div id='b'>text2</div></div>";
|
|
const a = root.firstChild;
|
|
const b = a.lastChild;
|
|
const c = a.firstChild;
|
|
const txt = b.previousSibling;
|
|
const txt2 = b.firstChild;
|
|
|
|
const observer = new MutationObserver((mutations) => {
|
|
|
|
assert_equals(mutations.length, 3, "mutations.length");
|
|
|
|
assert_equals(mutations[0].target.id, "a", "Target of the removal");
|
|
assert_equals(mutations[0].addedNodes.length, 0, "Should not have added nodes");
|
|
assert_equals(mutations[0].removedNodes.length, 1, "Should have 1 removed node");
|
|
assert_equals(mutations[0].removedNodes[0], c, "Should have removed c node");
|
|
|
|
assert_equals(mutations[1].target.id, "a", "Target of the removal");
|
|
assert_equals(mutations[1].addedNodes.length, 0, "Should not have added nodes");
|
|
assert_equals(mutations[1].removedNodes.length, 1, "Should have 1 removed node");
|
|
assert_equals(mutations[1].removedNodes[0], txt, "Should have removed txt node");
|
|
|
|
assert_equals(mutations[2].target.id, "b", "Target of the replaceChildren");
|
|
assert_equals(mutations[2].removedNodes.length, 1, "Should have removed 1 node");
|
|
assert_equals(mutations[2].removedNodes[0], txt2, "Should have removed txt2 node");
|
|
assert_equals(mutations[2].addedNodes.length, 2, "Should have added a node");
|
|
assert_equals(mutations[2].addedNodes[0], c, "Should have added c node");
|
|
assert_equals(mutations[2].addedNodes[1], txt, "Should have added txt node");
|
|
|
|
observer.disconnect();
|
|
t.done();
|
|
});
|
|
|
|
observer.observe(a, {
|
|
subtree: true,
|
|
childList: true
|
|
});
|
|
|
|
b.replaceChildren(c, txt);
|
|
}, "There should be MutationRecords for the nodes removed from another parent node.");
|
|
</script>
|
|
|
|
</html>
|