Skip to content

Commit

Permalink
Make :has-slotted apply to flattened nodes
Browse files Browse the repository at this point in the history
Differential Revision: https://phabricator.services.mozilla.com/D234801

bugzilla-url: https://bugzilla.mozilla.org/show_bug.cgi?id=1942520
gecko-commit: 272eec5fa63492a4762d43a936fe7a240b2d1938
gecko-reviewers: emilio
  • Loading branch information
Keith Cirkel authored and moz-wptsync-bot committed Jan 21, 2025
1 parent 6446dd4 commit 6b0e6d9
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 38 deletions.
4 changes: 2 additions & 2 deletions css/css-scoping/has-slotted-flattened-001.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@
}
</style>
<slot></slot>
</template><slot></slot></div>
</template><slot><div></div></slot></div>
</template>
</div>
</div>
27 changes: 11 additions & 16 deletions css/css-scoping/has-slotted-flattened-002.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,14 @@
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10586">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<p>Test passes if there is a filled green square.</p>
<div id="ancestor"><template shadowrootmode="open">
<div id="host"><template shadowrootmode="open">
<style>
slot {
display: block;
width: 100px;
height: 100px;
background-color: green;
}
:has-slotted {
background-color: red;
}
</style>
<slot></slot>
</template></div>
</template></div>
<div id="ancestor"><template shadowrootmode="open"><div id="host"><template shadowrootmode="open"><style>
slot {
display: block;
width: 100px;
height: 100px;
background-color: green;
}
:has-slotted {
background-color: red;
}
</style><slot></slot></template></div></template></div>
32 changes: 12 additions & 20 deletions css/css-scoping/has-slotted-flattened-003.tentative.html
Original file line number Diff line number Diff line change
@@ -1,25 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>:has-slotted flattened through multiple slots</title>
<title>:has-slotted populated, flattened through multiple slots</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10586">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<p>Test passes if there is a filled green square.</p>
<div id="ancestor">
<template shadowrootmode="open">
<div id="host"><template shadowrootmode="open">
<style>
slot {
display: block;
width: 100px;
height: 100px;
background-color: red;
}
:has-slotted {
background-color: green;
}
</style>
<slot></slot>
</template><slot></slot></div>
</template>
<div></div>
</div>
<div id="ancestor"><template shadowrootmode="open"><div id="host"><template shadowrootmode="open"><style>
slot {
display: block;
width: 100px;
height: 100px;
background-color: red;
}
:has-slotted {
background-color: green;
}
</style><slot></slot></template><slot></slot></div></template><div></div></div>
17 changes: 17 additions & 0 deletions css/css-scoping/has-slotted-flattened-004.tentative.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!doctype html>
<meta charset="utf-8">
<title>:has-slotted negative test: empty nested slot</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10586">
<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
<p>Test passes if there is a filled green square.</p>
<div id="ancestor"><template shadowrootmode="open"><div id="host"><template shadowrootmode="open"><style>
slot {
display: block;
width: 100px;
height: 100px;
background-color: green;
}
:has-slotted {
background-color: red;
}
</style><slot></slot></template><slot></slot></div></template></div>
47 changes: 47 additions & 0 deletions css/css-scoping/has-slotted-manual-assignment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<!doctype html>
<meta charset="utf-8" />
<title>:has-slotted with manual assignment</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10586" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<test-element id="host"></test-element>
<script>
customElements.define('test-element', class extends HTMLElement {
connectedCallback() {
this.attachShadow({mode: 'open', slotAssignment: 'manual'});
this.shadowRoot.append(document.createElement('slot'))
}
assign(...nodes) {
this.shadowRoot.querySelector('slot').assign(...nodes)
}
});

const slot = host.shadowRoot.querySelector('slot');

test(function () {
assert_equals(slot.assignedNodes().length, 0, "slot element should not match :has-slotted");
assert_equals(host.shadowRoot.querySelectorAll(':has-slotted').length, 0, "slot element should not match :has-slotted");
assert_false(slot.matches(':has-slotted'), "slot element should not match :has-slotted");
}, ":has-slotted does not match or querySelector with no manual assigned nodes");

test(function () {
host.append(document.createElement("div"));
assert_equals(slot.assignedNodes().length, 0, "slot element should not match :has-slotted");
assert_equals(host.shadowRoot.querySelectorAll(':has-slotted').length, 0, "slot element should not match :has-slotted");
assert_false(slot.matches(':has-slotted'), "slot element should not match :has-slotted");
}, ":has-slotted does not match or querySelector with no manual assigned nodes - 2");

test(function () {
host.assign(...host.children);
assert_equals(slot.assignedNodes().length, 1, "slot element should match :has-slotted with 1 child node");
assert_equals(host.shadowRoot.querySelectorAll(':has-slotted').length, 1, "slot element should match :has-slotted with 1 child node");
assert_true(slot.matches(':has-slotted'), "slot element should match :has-slotted with 1 child node");
}, ":has-slotted does match when a child is manually assigned");

test(function () {
host.assign();
assert_equals(slot.assignedNodes().length, 0, "slot element should not match :has-slotted after empty");
assert_equals(host.shadowRoot.querySelectorAll(':has-slotted').length, 0, "slot element should not match :has-slotted after empty");
assert_false(slot.matches(':has-slotted'), "slot element should not match :has-slotted after empty");
}, ":has-slotted no longer matches when no children become manually assigned");
</script>
53 changes: 53 additions & 0 deletions css/css-scoping/has-slotted-query-selector.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!doctype html>
<meta charset="utf-8" />
<title>:has-slotted and query-selector</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/pull/10586" />
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="ancestor"><template shadowrootmode="open"><div id="host"><template shadowrootmode="open"><style>
slot {
color: rgb(0, 0, 0);
}
:has-slotted {
color: rgb(0, 255, 0);
}
</style><slot></slot></template><slot></slot></div></template></div>
<script>
const host = ancestor.shadowRoot.querySelector('#host');
for(const container of [host, ancestor]) {
host.replaceChildren(document.createElement('slot'));
ancestor.replaceChildren();
const slot = host.shadowRoot.querySelector("slot");

test(function () {
assert_equals(slot.assignedNodes({flatten: true}).length, 0, "slot should have 0 nodes");
assert_false(slot.matches(":has-slotted"), "slot element should not match :has-slotted");
assert_equals(getComputedStyle(slot).color, "rgb(0, 0, 0)", "slot element should not match :has-slotted");
assert_equals(host.shadowRoot.querySelectorAll(":has-slotted").length, 0, "slot element should not match :has-slotted");
}, ":has-slotted does not match or querySelector when there are no assigned nodes" + (container == ancestor ? " (flattened)" : ""));

test(function () {
container.append(document.createElement("div"));
assert_equals(slot.assignedNodes({flatten: true}).length, 1, "slot should have 1 node");
assert_true(slot.matches(":has-slotted"), "slot element should match :has-slotted with 1 child node");
assert_equals(getComputedStyle(slot).color, "rgb(0, 255, 0)", "slot element should match :has-slotted with 1 child node");
assert_equals(host.shadowRoot.querySelectorAll(":has-slotted").length, 1, "slot element should match :has-slotted with 1 child node");
}, ":has-slotted must match/querySelector when an element is assigned" + (container == ancestor ? " (flattened)" : ""));

test(function () {
container.replaceChildren();
assert_equals(slot.assignedNodes({flatten: true}).length, 0, "slot should have 0 nodes");
assert_false(slot.matches(":has-slotted"), "slot element should not match :has-slotted after empty");
assert_equals(getComputedStyle(slot).color, "rgb(0, 0, 0)", "slot element should not match :has-slotted after empty");
assert_equals(host.shadowRoot.querySelectorAll(":has-slotted").length, 0, "slot element should not match :has-slotted after empty");
}, ":has-slotted does not when child nodes are replaced" + (container == ancestor ? " (flattened)" : ""));

test(function () {
container.append(document.createTextNode(""));
assert_equals(slot.assignedNodes({flatten: true}).length, 1, "slot should have 1 node");
assert_true(slot.matches(":has-slotted"), "slot element should match :has-slotted with 1 text node");
assert_equals(getComputedStyle(slot).color, "rgb(0, 255, 0)", "slot element should match :has-slotted with 1 text node");
assert_equals(host.shadowRoot.querySelectorAll(":has-slotted").length, 1, "slot element should match :has-slotted with 1 text node");
}, ":has-slotted must match/querySelector when a text node is assigned" + (container == ancestor ? " (flattened)" : ""));
}
</script>

0 comments on commit 6b0e6d9

Please sign in to comment.