tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

parsing.html (3184B)


      1 <!doctype html>
      2 <title>CSS Selectors parsing</title>
      3 <link rel="author" title="Adam Argyle" href="mailto:argyle@google.com">
      4 <link rel="author" title="Tab Atkins-Bittner" href="https://tabatkins.com/contact/">
      5 <link rel="help" href="https://drafts.csswg.org/css-nesting-1/">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 
      9 <style id="test-sheet"></style>
     10 <script>
     11  let [ss] = document.styleSheets
     12 
     13  function resetStylesheet() {
     14    while (ss.rules.length)
     15      ss.removeRule(0)
     16  }
     17 
     18  function testNestedSelector(sel, {expected=sel, parent=".foo"}={}) {
     19    resetStylesheet();
     20    const ruleText = `${parent} { ${sel} { color: green; }}`
     21    test(()=>{
     22      ss.insertRule(ruleText);
     23      assert_equals(ss.rules.length, 1, "Outer rule should exist.");
     24      const rule = ss.rules[0];
     25      assert_equals(rule.cssRules.length, 1, "Inner rule should exist.");
     26      const innerRule = rule.cssRules[0];
     27      assert_equals(innerRule.selectorText, expected, `Inner rule's selector should be "${expected}".`);
     28    }, ruleText);
     29  }
     30 
     31  function testInvalidNestingSelector(sel, {parent=".foo"}={}) {
     32    resetStylesheet();
     33    const ruleText = `${parent} { ${sel} { color: green; }}`
     34    test(()=>{
     35      ss.insertRule(ruleText);
     36      assert_equals(ss.rules.length, 1, "Outer rule should exist.");
     37      const rule = ss.rules[0];
     38      assert_equals(rule.cssRules.length, 0, "Inner rule should not exist.");
     39    }, "INVALID: " + ruleText);
     40  }
     41 
     42  // basic usage
     43  testNestedSelector("&");
     44  testNestedSelector("&.bar");
     45  testNestedSelector("& .bar");
     46  testNestedSelector("& > .bar");
     47 
     48  // relative selector
     49  testNestedSelector("> .bar", {expected:"& > .bar"});
     50  testNestedSelector("> & .bar", {expected:"& > & .bar"});
     51  testNestedSelector("+ .bar &", {expected:"& + .bar &"});
     52  testNestedSelector("+ .bar, .foo, > .baz", {expected:"& + .bar, & .foo, & > .baz"});
     53 
     54  // implicit relative (and not)
     55  testNestedSelector(".foo", {expected:"& .foo"});
     56  testNestedSelector(".test > & .bar");
     57  testNestedSelector(".foo, .foo &", {expected:"& .foo, .foo &"});
     58  testNestedSelector(".foo, .bar", {expected:"& .foo, & .bar"});
     59  testNestedSelector(":is(.bar, .baz)", {expected:"& :is(.bar, .baz)"});
     60  testNestedSelector("&:is(.bar, .baz)");
     61  testNestedSelector(":is(.bar, &.baz)");
     62  testNestedSelector("&:is(.bar, &.baz)");
     63 
     64  // Mixing nesting selector with other simple selectors
     65  testNestedSelector("div&");
     66  testInvalidNestingSelector("&div"); // type selector must be first
     67  testNestedSelector(".class&");
     68  testNestedSelector("&.class");
     69  testNestedSelector("[attr]&");
     70  testNestedSelector("&[attr]");
     71  testNestedSelector("#id&");
     72  testNestedSelector("&#id");
     73  testNestedSelector(":hover&");
     74  testNestedSelector("&:hover");
     75  testNestedSelector(":is(div)&");
     76  testNestedSelector("&:is(div)");
     77 
     78  // Multiple nesting selectors
     79  testNestedSelector("& .bar & .baz & .qux");
     80  testNestedSelector("&&");
     81 
     82  // Selector list in inner rule
     83  testNestedSelector("& > section, & > article");
     84 
     85  // Selector list in both inner and outer rule.
     86  testNestedSelector("& + .baz, &.qux", {parent:".foo, .bar"});
     87 </script>