blob: 926db23e76f8ed4faf2f98d6b20c7b3bfa54c594 [file] [edit]
<!DOCTYPE html>
<title>@scope - implicit scope root in constructed stylesheet adopted by a document</title>
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scope-limits">
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scoped-rules">
<link rel="help" href="https://drafts.csswg.org/cssom/#extensions-to-the-document-or-shadow-root-interface">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id="outer" class="b">
<div id="inner" class="a"></div>
<div class="limit">
<div id="limited" class="a"></div>
</div>
</div>
<script>
function adopt(t, text) {
const sheet = new CSSStyleSheet();
sheet.replaceSync(text);
document.adoptedStyleSheets = [sheet];
t.add_cleanup(() => { document.adoptedStyleSheets = []; });
return sheet;
}
function createShadowRoot(t) {
const host = document.createElement("div");
document.body.append(host);
t.add_cleanup(() => host.remove());
const root = host.attachShadow({ mode: "open" });
root.innerHTML = `<div class="a"></div>`;
return root;
}
const zIndex = element => getComputedStyle(element).zIndex;
test(t => {
adopt(t, `@scope { .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
}, "Implicit @scope in a constructed stylesheet adopted by a document matches descendants");
test(t => {
adopt(t, `@scope { html { z-index: 1; } }`);
assert_equals(zIndex(document.documentElement), "1");
}, "Implicit @scope in a constructed stylesheet adopted by a document matches the root element");
test(t => {
adopt(t, `@scope { :scope { z-index: 1; } }`);
assert_equals(zIndex(document.documentElement), "auto");
assert_equals(zIndex(document.body), "auto");
}, ":scope in implicit @scope in a constructed stylesheet adopted by a document does not match any element");
test(t => {
adopt(t, `@scope { z-index: 1; }`);
assert_equals(zIndex(document.documentElement), "auto");
assert_equals(zIndex(document.body), "auto");
}, "Scoped declarations in implicit @scope in a constructed stylesheet adopted by a document do not match any element");
test(t => {
adopt(t, `@scope { :scope .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
}, "Explicit :scope with a descendant combinator in implicit @scope in a constructed stylesheet adopted by a document");
test(t => {
adopt(t, `@scope { & .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
}, "& with a descendant combinator in implicit @scope in a constructed stylesheet adopted by a document");
test(t => {
adopt(t, `@scope { > html { z-index: 1; } > body { z-index: 1; } }`);
assert_equals(zIndex(document.documentElement), "1");
assert_equals(zIndex(document.body), "auto");
}, "Child combinator in implicit @scope in a constructed stylesheet adopted by a document matches only the root element");
test(t => {
adopt(t, `@scope to (.limit) { .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
assert_equals(zIndex(limited), "auto");
}, "Implicit @scope with a scope end in a constructed stylesheet adopted by a document");
test(t => {
adopt(t, `
@scope { .a { z-index: 1; } }
.a { z-index: 2; }
`);
assert_equals(zIndex(inner), "1");
}, "Implicit @scope in a constructed stylesheet adopted by a document wins over unscoped rules by proximity");
test(t => {
adopt(t, `
@scope (#outer) { .a { z-index: 2; } }
@scope { .a { z-index: 1; } }
`);
assert_equals(zIndex(inner), "2");
}, "Implicit @scope in a constructed stylesheet adopted by a document loses to a closer scoping root by proximity");
test(t => {
adopt(t, `@scope { @scope (.b) { .a { z-index: 1; } } }`);
assert_equals(zIndex(inner), "1");
}, "Nested @scope inside implicit @scope in a constructed stylesheet adopted by a document");
test(t => {
const root = createShadowRoot(t);
adopt(t, `@scope { .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
assert_equals(zIndex(root.querySelector(".a")), "auto");
}, "Implicit @scope in a constructed stylesheet adopted by a document does not match in shadow trees");
test(t => {
const root = createShadowRoot(t);
const sheet = adopt(t, `@scope { .a { z-index: 1; } }`);
root.adoptedStyleSheets = [sheet];
assert_equals(zIndex(inner), "1");
assert_equals(zIndex(root.querySelector(".a")), "1");
}, "Implicit @scope in a constructed stylesheet adopted by both a document and a shadow root");
test(t => {
adopt(t, `@scope { .a { z-index: 1; } }`);
assert_equals(zIndex(inner), "1");
document.adoptedStyleSheets = [];
assert_equals(zIndex(inner), "auto");
}, "Implicit @scope in a constructed stylesheet stops matching once the document no longer adopts it");
</script>