Add children and replaceChildren support to ChildNodePart
This also changes IsValid for ChildNodePart to return false if the
endpoints are the same. It seems like there needs to be a "gap"
between them or things get weird when you do replaceChildren.
Bug: 1453291
Change-Id: I0b7b0a1d7e47a3e315d20cfa09d0e55c2c06f346
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4681916
Commit-Queue: Mason Freed <masonf@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1169613}
diff --git a/dom/parts/basic-dom-part-objects.tentative.html b/dom/parts/basic-dom-part-objects.tentative.html
index 7b051f2..db41c9e 100644
--- a/dom/parts/basic-dom-part-objects.tentative.html
+++ b/dom/parts/basic-dom-part-objects.tentative.html
@@ -7,12 +7,10 @@
<template id=template>
<div id=target style="display:none">
Imperative test element
- <span id=a>A</span>
- <span id=b>B
- <span id=sub>B-sub</span>
- </span>
- <span id=c>C</span>
- </div>
+ <span id=a>A</span><span id=b>B
+ <span id=sub>B-sub1</span>
+ <span id=sub>B-sub2</span>
+ </span><span id=c>C</span></div>
</template>
<div style="display:none">
@@ -107,7 +105,7 @@
const childNodePart = addCleanup(t,new ChildNodePart(root,target.children[0], target.children[2]));
const nodePart3 = addCleanup(t,new NodePart(childNodePart,target.children[1].firstChild,{metadata: ['this is','part 3']}));
const nodePart2 = addCleanup(t,new NodePart(childNodePart,target.children[1].firstChild,{metadata: ['this','is part 2']}));
- const childNodePart2 = addCleanup(t,new ChildNodePart(childNodePart,target.children[1].firstElementChild,target.children[1].firstElementChild,{metadata: ['childnodepart2']}));
+ const childNodePart2 = addCleanup(t,new ChildNodePart(childNodePart,target.children[1].firstElementChild,target.children[1].firstElementChild.nextSibling,{metadata: ['childnodepart2']}));
assert_array_equals(root.getParts(),[nodePart,childNodePart]);
assert_array_equals(childNodePart.getParts(),[childNodePart2,nodePart3,nodePart2],'Parts on the same Node are returned in the order they were constructed');
assert_array_equals(childNodePart2.getParts(),[]);
@@ -225,4 +223,31 @@
document.body.appendChild(target); // Restore
assert_array_equals(root.getParts(),[childPartAC]);
}, 'DOM mutation support');
+
+
+test((t) => {
+ const root = document.getPartRoot();
+ assert_equals(root.getParts().length,0,'Test harness check: tests should clean up parts');
+ const target = document.querySelector('#target');
+ const a = document.querySelector('#a');
+ const b = document.querySelector('#b');
+ const c = document.querySelector('#c');
+ const otherNode = document.createElement('div');
+
+ const childPartAA = addCleanup(t,new ChildNodePart(root,a,a));
+ const childPartAB = addCleanup(t,new ChildNodePart(root,a,b));
+ const childPartAC = addCleanup(t,new ChildNodePart(root,a,c));
+ assert_throws_dom('InvalidStateError',() => childPartAA.replaceChildren(otherNode),'Can\'t replace children if part is invalid');
+ assert_array_equals(childPartAA.children,[],'Invalid parts should return empty children');
+ assert_array_equals(childPartAB.children,[],'Children should not include endpoints');
+ assert_array_equals(childPartAC.children,[b],'Children should not include endpoints');
+ childPartAB.replaceChildren(otherNode);
+ assert_array_equals(childPartAB.children,[otherNode],'Replacechildren should work');
+ assert_array_equals(childPartAC.children,[otherNode,b],'replaceChildren should leave endpoints alone');
+ childPartAC.replaceChildren(otherNode);
+ assert_array_equals(childPartAC.children,[otherNode],'Replacechildren with existing children should work');
+ assert_array_equals(childPartAB.children,[]);
+ childPartAC.replaceChildren(b);
+ assert_array_equals(target.children,[a,b,c]);
+}, 'ChildNodePart children manipulation');
</script>