Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

<!DOCTYPE html>
<title>@scope - proximity to root</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
function test_scope(script_element, callback_fn, description) {
test((t) => {
// The provided <script> element must be an immedate subsequent sibling of
// a <template> element.
let template_element = script_element.previousElementSibling;
assert_equals(template_element.tagName, 'TEMPLATE');
t.add_cleanup(() => {
while (main.firstChild)
main.firstChild.remove()
});
main.append(template_element.content.cloneNode(true));
callback_fn();
}, description);
}
function assert_green(selector) {
assert_equals(getComputedStyle(main.querySelector(selector)).backgroundColor, 'rgb(0, 128, 0)');
}
function assert_not_green(selector) {
assert_equals(getComputedStyle(main.querySelector(selector)).backgroundColor, 'rgb(0, 0, 0)');
}
</script>
<style>
main * {
background-color: black;
}
</style>
<main id=main>
</main>
<template>
<style>
.item {
padding: 0px;
border: 5px solid red;
}
@scope (.light) {
[id] { border-color: rgb(100, 100, 100); }
}
@scope (.dark) {
[id] { border-color: rgb(200, 200, 200); }
}
</style>
<div class=light>
<div id=item1>
<div class=dark>
<div id=item2>
<div class=light>
<div id=item3>
<div class=dark>
<div id=item4></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
test_scope(document.currentScript, () => {
assert_equals(getComputedStyle(item1).borderColor, 'rgb(100, 100, 100)');
assert_equals(getComputedStyle(item2).borderColor, 'rgb(200, 200, 200)');
assert_equals(getComputedStyle(item3).borderColor, 'rgb(100, 100, 100)');
assert_equals(getComputedStyle(item4).borderColor, 'rgb(200, 200, 200)');
}, 'Alternating light/dark');
</script>
<template>
<style>
@scope (.b) {
[id] { border-color:green; }
}
@scope (.a) {
[id] { border-color:red; }
}
</style>
<div class=a>
<div class=b>
<span id=item></span>
</div>
</div>
</template>
<script>
test_scope(document.currentScript, () => {
assert_equals(getComputedStyle(item).borderColor, 'rgb(0, 128, 0)');
}, 'Proximity wins over order of appearance');
</script>
<template>
<style>
@scope (.a) {
span[id] { border-color:green; }
}
@scope (.b) {
[id] { border-color:red; }
}
</style>
<div class=a>
<div class=b>
<span id=item></span>
</div>
</div>
</template>
<script>
test_scope(document.currentScript, () => {
assert_equals(getComputedStyle(item).borderColor, 'rgb(0, 128, 0)');
}, 'Specificity wins over proximity');
</script>
<template>
<style>
@scope (.foo) {
.bar span[id] { border-color:green; }
}
</style>
<div class=foo>
<div class="foo bar">
<span id=item></span>
</div>
</div>
</template>
<script>
test_scope(document.currentScript, () => {
assert_equals(getComputedStyle(item).borderColor, 'rgb(0, 128, 0)');
}, 'Identical root with further proximity is not ignored');
</script>
<template>
<style>
@scope (.scope) {
:where(&) { border-color:green; }
}
@scope (#outer) {
:where(:scope) :where(#inner) { border-color:red; }
}
</style>
<div id=outer class=scope>
<div>
<div id=inner class=scope>
</div>
</div>
</div>
</template>
<script>
test_scope(document.currentScript, () => {
assert_equals(getComputedStyle(inner).borderColor, 'rgb(0, 128, 0)');
}, 'Most proximate match wins under multiple scoping roots');
</script>