69 lines
2.2 KiB
HTML
69 lines
2.2 KiB
HTML
<!doctype html>
|
|
<title>@scope and Nesting: Parsing inner style rules with relative selector syntax</title>
|
|
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scoped-rules">
|
|
<link rel="help" href="https://drafts.csswg.org/css-nesting/#nesting">
|
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/10196">
|
|
<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');
|
|
|
|
test_inner(['@scope' , '.nest', '@media screen'], method, '> .foo', '& > .foo');
|
|
test_inner(['.nest', '@scope', '@media screen'], method, '> .foo');
|
|
}
|
|
</script>
|