From eeab1cbd50bdb860552e6edebf0da9e259860908 Mon Sep 17 00:00:00 2001 From: Mason Freed Date: Fri, 14 Jul 2023 22:09:47 -0700 Subject: [PATCH] Add declarative DOM Parts syntax This CL adds the ability to construct DOM Parts during document parsing via "fake" processing instructions:

Email:
In this example, will be left in the document, but a ChildNodePart will also be constructed with previous/next endpoints of those two comment nodes. And the will be left in place, but a NodePart will be attached to the element. Note that is exactly equivalent to , and both are tested in the new WPT. This CL also: - adds a virtual test suite that makes sure no functionality breaks or leaks when DOMPartAPI is disabled. - revamps the WPT, adding a `assertEqualParts()` that checks a given parts list via the type of parts and the metadata. This is then used everywhere. - add testing of declarative DOM Parts for three cases: 1. main document parsing (passes with this CL) 2. template parsing (doesn't yet pass) 3. cloned templates (not even sure if this should ever pass) Bug: 1453291,1465062 Change-Id: I2eaef72a21fc2deaa251deb0731b5ff55ef19d8c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4686189 Reviewed-by: David Baron Auto-Submit: Mason Freed Commit-Queue: Stefan Zager Reviewed-by: Stefan Zager Cr-Commit-Position: refs/heads/main@{#1170849} --- .../basic-dom-part-objects.tentative.html | 363 +++++++++++------- 1 file changed, 233 insertions(+), 130 deletions(-) diff --git a/dom/parts/basic-dom-part-objects.tentative.html b/dom/parts/basic-dom-part-objects.tentative.html index db41c9e40eaf9a..a60ec8b0a161cd 100644 --- a/dom/parts/basic-dom-part-objects.tentative.html +++ b/dom/parts/basic-dom-part-objects.tentative.html @@ -4,34 +4,54 @@ - - -
- Declarative syntax -

FirstMiddleLast

- Email:
-
+ + + + + -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'); - assert_true(!!(target && a && b && c)); - - const nodePartB = addCleanup(t,new NodePart(root,b)); - const nodePartA = addCleanup(t,new NodePart(root,a)); - const nodePartC = addCleanup(t,new NodePart(root,c)); - assert_array_equals(root.getParts(),[nodePartA,nodePartB,nodePartC]); - b.remove(); - assert_array_equals(root.getParts(),[nodePartA,nodePartC]); - document.body.appendChild(b); - assert_array_equals(root.getParts(),[nodePartA,nodePartC,nodePartB]); - target.insertBefore(b,a); - assert_array_equals(root.getParts(),[nodePartB,nodePartA,nodePartC]); - nodePartA.disconnect(); - nodePartB.disconnect(); - nodePartC.disconnect(); - assert_array_equals(root.getParts(),[]); - - const childPartAC = addCleanup(t,new ChildNodePart(root,a,c)); - assert_array_equals(root.getParts(),[childPartAC]); - a.remove(); - assert_array_equals(root.getParts(),[],'Removing endpoints invalidates the part'); - target.insertBefore(a,b); // Restore - assert_array_equals(root.getParts(),[childPartAC]); - - target.insertBefore(c,a); - assert_array_equals(root.getParts(),[],'Endpoints out of order'); - target.appendChild(c); // Restore - assert_array_equals(root.getParts(),[childPartAC]); - - document.body.appendChild(c); - assert_array_equals(root.getParts(),[],'Children need to have same parent'); - target.appendChild(c); // Restore - assert_array_equals(root.getParts(),[childPartAC]); - - target.remove(); - assert_array_equals(root.getParts(),[],'Parent needs to be connected'); - 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'); - +
+ +
+ Declarative syntax - The template below (with id=declarative) should have + IDENTICAL STRUCTURE. There are three cases to test: + 1. Main document parsing (this chunk) + 2. Template parsing (the template below) + 3. Template/fragment cloning (the clone of the template below) +

+ + First + Middle + Last + +

+ Email: + + Here are some invalid parts that should not get parsed: + + + + +
+
+ + +