Files
ladybird/Tests/LibWeb/Text/input/css/constructed-stylesheet-shared-cache-shadow-scope.html
Andreas Kling caad205467 LibWeb: Share singleton constructed stylesheet rule caches
Share the style cache for shadow roots whose only active author sheet is
the same constructed stylesheet. Matching already carries the effective
shadow root separately, so the cache can be reused while selectors such
as :host and ::slotted() still evaluate against each consuming shadow
root.

Keep the optimization conservative by falling back to the existing
per-scope cache whenever the shadow root has multiple active sheets, a
non-constructed sheet, or a page user stylesheet. Drop the shared cache
when the stylesheet rules or media query match state change.

Add coverage for two shadow roots adopting the same constructed sheet,
including :host, ::slotted(), and replaceSync() invalidation.
2026-04-28 13:07:52 +02:00

46 lines
2.1 KiB
HTML

<!DOCTYPE html>
<script src="../include.js"></script>
<div id="host-a" class="primary"><span id="slotted-a" class="slot-target">a</span></div>
<div id="host-b" class="secondary"><span id="slotted-b" class="slot-target">b</span></div>
<script>
test(() => {
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
:host(.primary) .target { color: rgb(0, 128, 0); }
:host(.secondary) .target { color: rgb(0, 0, 255); }
::slotted(.slot-target) { background-color: rgb(255, 255, 0); }
`);
const hostA = document.getElementById("host-a");
const hostB = document.getElementById("host-b");
const slottedA = document.getElementById("slotted-a");
const slottedB = document.getElementById("slotted-b");
const shadowA = hostA.attachShadow({ mode: "open" });
const shadowB = hostB.attachShadow({ mode: "open" });
shadowA.innerHTML = "<span class='target'>a</span><slot></slot>";
shadowB.innerHTML = "<span class='target'>b</span><slot></slot>";
shadowA.adoptedStyleSheets = [sheet];
shadowB.adoptedStyleSheets = [sheet];
const targetA = shadowA.querySelector(".target");
const targetB = shadowB.querySelector(".target");
println(`Initial A target: ${getComputedStyle(targetA).color}`);
println(`Initial B target: ${getComputedStyle(targetB).color}`);
println(`Initial A slotted: ${getComputedStyle(slottedA).backgroundColor}`);
println(`Initial B slotted: ${getComputedStyle(slottedB).backgroundColor}`);
sheet.replaceSync(`
:host(.primary) .target { color: rgb(128, 0, 128); }
:host(.secondary) .target { color: rgb(255, 165, 0); }
::slotted(.slot-target) { background-color: rgb(0, 255, 255); }
`);
println(`After replace A target: ${getComputedStyle(targetA).color}`);
println(`After replace B target: ${getComputedStyle(targetB).color}`);
println(`After replace A slotted: ${getComputedStyle(slottedA).backgroundColor}`);
println(`After replace B slotted: ${getComputedStyle(slottedB).backgroundColor}`);
});
</script>