File: at-scope-relative-syntax.html

package info (click to toggle)
thunderbird 1%3A143.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 4,703,968 kB
  • sloc: cpp: 7,770,492; javascript: 5,943,842; ansic: 3,918,754; python: 1,418,263; xml: 653,354; asm: 474,045; java: 183,079; sh: 111,238; makefile: 20,410; perl: 14,359; objc: 13,059; yacc: 4,583; pascal: 3,405; lex: 1,720; ruby: 999; exp: 762; sql: 715; awk: 580; php: 436; lisp: 430; sed: 69; csh: 10
file content (69 lines) | stat: -rw-r--r-- 2,299 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<!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>