Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

<!doctype html>
<title>@scope and Nesting: Parsing inner style rules with relative selector syntax</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<main id=main></main>
<script>
function create_rule_string(prelude, inner) {
if (prelude.length === 0) {
return `${inner} {}`;
}
let outermost = prelude[0];
let rest = create_rule_string(prelude.slice(1), inner);
return `${outermost} { ${rest} }`;
}
function create_rule_by_string(style, prelude, inner) {
style.textContent = create_rule_string(prelude, inner);
}
function create_rule_by_insertion(style, prelude, inner) {
let current = style.sheet;
for (const p of prelude) {
let idx = current.insertRule(`${p} {}`);
current = current.cssRules[idx];
}
current.insertRule(`${inner} {}`);
}
function innermost_selector(depth, rules) {
let r = rules;
let d = depth + 1;
while (d != 0) {
assert_equals(r.cssRules.length, 1);
r = r.cssRules[0];
d--;
}
return r.selectorText;
}
const create_method = {
"string": create_rule_by_string,
"insertRule": create_rule_by_insertion,
};
function test_inner(prelude, method, actual, expected) {
if (expected === undefined) {
expected = actual;
}
test(t => {
t.add_cleanup(() => main.replaceChildren());
const style = document.createElement('style');
main.append(style);
create_method[method](style, prelude, actual);
const innerSelector = innermost_selector(prelude.length, style.sheet);
assert_equals(innerSelector, expected);
}, `${actual} in ${prelude} created by ${method} valid`);
}
for (const method of Object.keys(create_method)) {
test_inner(['@scope' , '.nest'], method, '> .foo', '& > .foo');
test_inner(['.nest', '@scope'], method, '> .foo', ':scope > .foo');
test_inner(['@scope' , '.nest', '@media screen'], method, '> .foo', '& > .foo');
test_inner(['.nest', '@scope', '@media screen'], method, '> .foo', ':scope > .foo');
}
</script>