tor-browser

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

nested-declarations-cssom.html (7588B)


      1 <!DOCTYPE html>
      2 <title>CSS Nesting: CSSNestedDeclarations CSSOM</title>
      3 <link rel="help" href="https://drafts.csswg.org/css-nesting-1/#nested-declarations-rule">
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 <script>
      7  test(() => {
      8    let s = new CSSStyleSheet();
      9    s.replaceSync(`
     10      .a {
     11        & { --x:1; }
     12        --x:2;
     13      }
     14    `);
     15    assert_equals(s.cssRules.length, 1);
     16    let outer = s.cssRules[0];
     17    assert_equals(outer.cssRules.length, 2);
     18    assert_equals(outer.cssRules[0].cssText, `& { --x: 1; }`);
     19    assert_equals(outer.cssRules[1].cssText, `--x: 2;`);
     20  }, 'Trailing declarations');
     21 
     22  test(() => {
     23    let s = new CSSStyleSheet();
     24    s.replaceSync(`
     25      .a {
     26        --a:1;
     27        --b:1;
     28        & { --c:1; }
     29        --d:1;
     30        --e:1;
     31        & { --f:1; }
     32        --g:1;
     33        --h:1;
     34        --i:1;
     35        & { --j:1; }
     36        --k:1;
     37        --l:1;
     38      }
     39    `);
     40    assert_equals(s.cssRules.length, 1);
     41    let outer = s.cssRules[0];
     42    assert_equals(outer.cssRules.length, 6);
     43    assert_equals(outer.cssRules[0].cssText, `& { --c: 1; }`);
     44    assert_equals(outer.cssRules[1].cssText, `--d: 1; --e: 1;`);
     45    assert_equals(outer.cssRules[2].cssText, `& { --f: 1; }`);
     46    assert_equals(outer.cssRules[3].cssText, `--g: 1; --h: 1; --i: 1;`);
     47    assert_equals(outer.cssRules[4].cssText, `& { --j: 1; }`);
     48    assert_equals(outer.cssRules[5].cssText, `--k: 1; --l: 1;`);
     49  }, 'Mixed declarations');
     50 
     51  test(() => {
     52    let s = new CSSStyleSheet();
     53    s.replaceSync(`
     54      .a {
     55        & { --x:1; }
     56        --y:2;
     57        --z:3;
     58      }
     59    `);
     60    assert_equals(s.cssRules.length, 1);
     61    let outer = s.cssRules[0];
     62    assert_equals(outer.cssRules.length, 2);
     63    let nested_declarations = outer.cssRules[1];
     64    assert_true(nested_declarations instanceof CSSNestedDeclarations);
     65    assert_equals(nested_declarations.style.length, 2);
     66    assert_equals(nested_declarations.style.getPropertyValue('--x'), '');
     67    assert_equals(nested_declarations.style.getPropertyValue('--y'), '2');
     68    assert_equals(nested_declarations.style.getPropertyValue('--z'), '3');
     69  }, 'CSSNestedDeclarations.style');
     70 
     71  test(() => {
     72    let s = new CSSStyleSheet();
     73    s.replaceSync(`
     74      .a {
     75        @media (width > 100px) {
     76          --x:1;
     77          --y:1;
     78          .b { }
     79          --z:1;
     80        }
     81        --w:1;
     82      }
     83    `);
     84    assert_equals(s.cssRules.length, 1);
     85    let outer = s.cssRules[0];
     86    assert_equals(outer.cssRules.length, 2);
     87 
     88    // @media
     89    let media = outer.cssRules[0];
     90    assert_equals(media.cssRules.length, 3);
     91    assert_true(media.cssRules[0] instanceof CSSNestedDeclarations);
     92    assert_equals(media.cssRules[0].cssText, `--x: 1; --y: 1;`);
     93    assert_equals(media.cssRules[1].cssText, `& .b { }`);
     94    assert_true(media.cssRules[2] instanceof CSSNestedDeclarations);
     95    assert_equals(media.cssRules[2].cssText, `--z: 1;`);
     96 
     97    assert_true(outer.cssRules[1] instanceof CSSNestedDeclarations);
     98    assert_equals(outer.cssRules[1].cssText, `--w: 1;`);
     99  }, 'Nested group rule');
    100 
    101  test(() => {
    102    let s = new CSSStyleSheet();
    103    s.replaceSync(`
    104      .a {
    105        @scope (.foo) {
    106          --x:1;
    107          --y:1;
    108          .b { }
    109          --z:1;
    110        }
    111        --w:1;
    112      }
    113    `);
    114    assert_equals(s.cssRules.length, 1);
    115    let outer = s.cssRules[0];
    116    if (window.CSSScopeRule) {
    117      assert_equals(outer.cssRules.length, 2);
    118 
    119      // @scope
    120      let scope = outer.cssRules[0];
    121      assert_true(scope instanceof CSSScopeRule);
    122      assert_equals(scope.cssRules.length, 3);
    123      assert_true(scope.cssRules[0] instanceof CSSNestedDeclarations);
    124      assert_equals(scope.cssRules[0].cssText, `--x: 1; --y: 1;`);
    125      assert_equals(scope.cssRules[1].cssText, `.b { }`); // Implicit :scope here.
    126      assert_true(scope.cssRules[2] instanceof CSSNestedDeclarations);
    127      assert_equals(scope.cssRules[2].cssText, `--z: 1;`);
    128 
    129      assert_true(outer.cssRules[1] instanceof CSSNestedDeclarations);
    130      assert_equals(outer.cssRules[1].cssText, `--w: 1;`);
    131    } else {
    132      assert_equals(outer.cssRules.length, 0);
    133    }
    134  }, 'Nested @scope rule');
    135 
    136  test(() => {
    137    let s = new CSSStyleSheet();
    138    s.replaceSync(`
    139      a {
    140        & { --x:1; }
    141        width: 100px;
    142        height: 200px;
    143        color:hover {}
    144        --y: 2;
    145      }
    146    `);
    147    assert_equals(s.cssRules.length, 1);
    148    let outer = s.cssRules[0];
    149    assert_equals(outer.cssRules.length, 4);
    150    assert_equals(outer.cssRules[0].cssText, `& { --x: 1; }`);
    151    assert_equals(outer.cssRules[1].cssText, `width: 100px; height: 200px;`);
    152    assert_equals(outer.cssRules[2].cssText, `& color:hover { }`);
    153    assert_equals(outer.cssRules[3].cssText, `--y: 2;`);
    154  }, 'Inner rule starting with an ident');
    155 
    156  test(() => {
    157    let s = new CSSStyleSheet();
    158    s.replaceSync('.a {}');
    159    assert_equals(s.cssRules.length, 1);
    160    let a_rule = s.cssRules[0];
    161    assert_equals(a_rule.cssRules.length, 0);
    162    a_rule.insertRule(`
    163      width: 100px;
    164      height: 200px;
    165    `);
    166    assert_equals(a_rule.cssRules.length, 1);
    167    assert_true(a_rule.cssRules[0] instanceof CSSNestedDeclarations);
    168    assert_equals(a_rule.cssRules[0].cssText, `width: 100px; height: 200px;`);
    169  }, 'Inserting a CSSNestedDeclaration rule into style rule');
    170 
    171  test(() => {
    172    let s = new CSSStyleSheet();
    173    s.replaceSync('.a { @media (width > 100px) {} }');
    174    assert_equals(s.cssRules.length, 1);
    175    assert_equals(s.cssRules[0].cssRules.length, 1);
    176    let media_rule = s.cssRules[0].cssRules[0];
    177    assert_true(media_rule instanceof CSSMediaRule);
    178    assert_equals(media_rule.cssRules.length, 0);
    179    media_rule.insertRule(`
    180      width: 100px;
    181      height: 200px;
    182    `);
    183    assert_equals(media_rule.cssRules.length, 1);
    184    assert_true(media_rule.cssRules[0] instanceof CSSNestedDeclarations);
    185    assert_equals(media_rule.cssRules[0].cssText, `width: 100px; height: 200px;`);
    186  }, 'Inserting a CSSNestedDeclaration rule into nested group rule');
    187 
    188  test(() => {
    189    let s = new CSSStyleSheet();
    190    s.replaceSync('@media (width > 100px) {}');
    191    assert_equals(s.cssRules.length, 1);
    192    let media_rule = s.cssRules[0];
    193    assert_true(media_rule instanceof CSSMediaRule);
    194    assert_equals(media_rule.cssRules.length, 0);
    195    assert_throws_dom('SyntaxError', () => {
    196      media_rule.insertRule(`
    197        width: 100px;
    198        height: 200px;
    199      `);
    200    });
    201  }, 'Attempting to insert a CSSNestedDeclaration rule into top-level @media rule');
    202 
    203  test(() => {
    204    let sheet = new CSSStyleSheet();
    205    assert_throws_dom('SyntaxError', () => {
    206      sheet.insertRule(`
    207        width: 100px;
    208        height: 200px;
    209      `);
    210    });
    211  }, 'Attempting to insert a CSSNestedDeclaration rule into a stylesheet');
    212 
    213  test(() => {
    214    let s = new CSSStyleSheet();
    215    s.replaceSync('.a {}');
    216    assert_equals(s.cssRules.length, 1);
    217    let a_rule = s.cssRules[0];
    218    assert_equals(a_rule.cssRules.length, 0);
    219    assert_throws_dom('SyntaxError', () => {
    220      a_rule.insertRule('');
    221    });
    222  }, 'Attempting to insert a CSSNestedDeclaration rule, empty block');
    223 
    224  test(() => {
    225    let s = new CSSStyleSheet();
    226    s.replaceSync('.a {}');
    227    assert_equals(s.cssRules.length, 1);
    228    let a_rule = s.cssRules[0];
    229    assert_equals(a_rule.cssRules.length, 0);
    230    assert_throws_dom('SyntaxError', () => {
    231    a_rule.insertRule(`
    232      xwidth: 100px;
    233      xheight: 200px;
    234    `);
    235    });
    236  }, 'Attempting to insert a CSSNestedDeclaration rule, all invalid declarations');
    237 </script>