Skip to content

Commit 23e2f4d

Browse files
noamrchromium-wpt-export-bot
authored andcommitted
<template for> with empty "for" attribute patches "in place"
- Added behind a new flag (DeclarativeFragment) - When for is empty, we use the template itself as the marker - the template is attached at start, and removed when done. Some existing test has a subtest where the existing behavior is asserted. Separated that to own test with .txt expectations. See https://github.com/WICG/declarative-partial-updates/blob/frag-alternatives/fragment-include-explainer.md Chromestatus / I2P: https://chromestatus.com/feature/5188900898340864 Bug: 535664974 Change-Id: Id691865a6884273eab493bc7b0f6eee153835626 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8116632 Commit-Queue: Noam Rosenthal <nrosenthal@google.com> Reviewed-by: Dominic Farolino <dom@chromium.org> Cr-Commit-Position: refs/heads/main@{#1665490}
1 parent 481bfd4 commit 23e2f4d

3 files changed

Lines changed: 94 additions & 14 deletions

File tree

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Declarative Fragment: empty for attribute (in-place streaming)</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<script>
7+
function getText(containerId) {
8+
const container = document.getElementById(containerId).cloneNode(true);
9+
for (const script of container.querySelectorAll("script")) {
10+
script.remove();
11+
}
12+
return container.textContent.trim().replace(/\s+/g, ' ');
13+
}
14+
</script>
15+
<body>
16+
<div id="container1">
17+
<span>Before</span>
18+
<template for>
19+
<span id="target1">Inside 1</span>
20+
<span id="target2">Inside 2</span>
21+
</template>
22+
<span>After</span>
23+
</div>
24+
25+
<div id="container2">
26+
<span id="before-span">Before</span>
27+
<template for id="tpl-test">
28+
<span>A</span><script>
29+
window.step1 = getText("container2");
30+
const tpl = document.getElementById("tpl-test");
31+
const beforeSpan = document.getElementById("before-span");
32+
document.getElementById("container2").insertBefore(tpl, beforeSpan);
33+
</script><span>B</span><script>
34+
window.step2 = getText("container2");
35+
const tpl2 = document.getElementById("tpl-test");
36+
if (tpl2) {
37+
tpl2.remove();
38+
}
39+
</script><span>C</span><script>
40+
window.step3 = getText("container2");
41+
</script></template>
42+
<span>After</span>
43+
</div>
44+
45+
<script>
46+
test(() => {
47+
const container = document.getElementById('container1');
48+
// Verify children insertion and order
49+
assert_equals(container.innerHTML.trim().replace(/\s+/g, ' '), '<span>Before</span> <span id="target1">Inside 1</span> <span id="target2">Inside 2</span> <span>After</span>');
50+
// Verify that the template is not in the DOM
51+
assert_equals(container.querySelector('template'), null);
52+
}, "In-place template with empty for attribute is removed and its children are inserted before it");
53+
54+
test(() => {
55+
assert_equals(window.step1, "Before A");
56+
assert_equals(window.step2, "BBefore A");
57+
assert_equals(window.step3, "BBefore AC");
58+
59+
const container = document.getElementById("container2");
60+
assert_equals(getText("container2"), "BBefore AC After");
61+
assert_equals(container.querySelector('template'), null);
62+
}, "In-place template moving and removal during streaming");
63+
</script>
64+
</body>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>HTML partial updates: template for with empty for attribute (in-place patching)</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<body>
7+
<div id="container">
8+
<span>Before</span>
9+
<template id="empty-for-template" for="">
10+
<span id="ok-empty">Allowed</span>
11+
</template>
12+
<span>After</span>
13+
</div>
14+
15+
<script>
16+
test(() => {
17+
const container = document.getElementById('container');
18+
19+
// Verify that empty-for-template behaves as a regular template:
20+
// - It remains in the DOM.
21+
// - Its children are inside the template's content fragment.
22+
const emptyForTemplate = document.getElementById('empty-for-template');
23+
assert_not_equals(emptyForTemplate, null);
24+
assert_equals(emptyForTemplate.tagName, "TEMPLATE");
25+
assert_not_equals(emptyForTemplate.content.querySelector('#ok-empty'), null);
26+
27+
assert_equals(container.innerHTML.trim().replace(/\s+/g, ' '), '<span>Before</span> <template id="empty-for-template" for=""> <span id="ok-empty">Allowed</span> </template> <span>After</span>');
28+
}, "A template with an empty for attribute is ignored and attached to the DOM");
29+
</script>
30+
</body>

html/dom/partial-updates/tentative/template-for-multiple-cases.html

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -177,20 +177,6 @@
177177
`<?start name="a#b">New <?start> content <?end> after<?end>`,
178178
`<template for="a#b">X</template>`,
179179
`X`,
180-
);
181-
add_test_scenario(
182-
"Empty marker name with <?start> and <?end>",
183-
`<?start name="">Old<?end>`,
184-
`<template for="">New</template>`,
185-
`<?start name=""?>Old<?end ?>`,
186-
{tail: true}
187-
);
188-
add_test_scenario(
189-
"Empty marker name with <?marker>",
190-
`<?marker name="">Old`,
191-
`<template for="">New</template>`,
192-
`<?marker name=""?>Old`,
193-
{tail: true}
194180
);
195181
</script>
196182
</body>

0 commit comments

Comments
 (0)