tor-browser

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

layer-cssom-order-reverse.html (3689B)


      1 <!DOCTYPE html>
      2 <title>CSS Cascade Layers: at-rule and style invalidation on layer order changes</title>
      3 <link rel="help" href="https://drafts.csswg.org/css-cascade-5/#layering">
      4 <link rel="author" href="mailto:xiaochengh@chromium.org">
      5 <link rel="stylesheet" href="/fonts/ahem.css">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 <style>
      9 #reference {
     10  color: green;
     11  font: 20px/1 ahem;
     12  width: max-content;
     13 }
     14 </style>
     15 
     16 <div id=target>Lorem ipsum</div>
     17 <div id=reference>Lorem ipsum</div>
     18 
     19 <script>
     20 const testCases = [
     21  {
     22    title: 'Insert layer invalidates style',
     23    sheets: [
     24      '',
     25      `
     26        @layer first {
     27          #target { color: green; }
     28        }
     29        @layer second {
     30          #target { color: red; }
     31        }
     32      `,
     33    ],
     34    update: function(sheets) {
     35      sheets[0].insertRule('@layer second {}', 0);
     36    },
     37    property: 'color',
     38  },
     39  {
     40    title: 'Delete layer invalidates style',
     41    sheets: [
     42      '@layer second {}',
     43      `
     44        @layer first {
     45          #target { color: red; }
     46        }
     47        @layer second {
     48          #target { color: green; }
     49        }
     50      `,
     51    ],
     52    update: function(sheets) {
     53      sheets[0].deleteRule(0);
     54    },
     55    property: 'color',
     56  },
     57  {
     58    title: 'Insert layer invalidates @font-face',
     59    sheets: [
     60      '',
     61      `
     62        @layer first {
     63          @font-face {
     64            font-family: custom;
     65            src: local('Ahem'), url('/fonts/Ahem.ttf');
     66          }
     67        }
     68        @layer second {
     69          @font-face {
     70            font-family: custom;
     71            src: url('/fonts/noto/noto-sans-v8-latin-regular.woff') format('woff');
     72          }
     73        }
     74        #target { font: 20px/1 custom; width: max-content; }
     75      `,
     76    ],
     77    update: async function(sheets) {
     78      await document.fonts.load('20px/1 ahem');
     79      await document.fonts.load('20px/1 custom');
     80      document.body.offsetLeft; // Force style recalc
     81      sheets[0].insertRule('@layer second {}', 0);
     82      await document.fonts.load('20px/1 custom');
     83    },
     84    property: 'width',
     85  },
     86  {
     87    title: 'Delete layer invalidates @font-face',
     88    sheets: [
     89      '@layer second {}',
     90      `
     91        @layer first {
     92          @font-face {
     93            font-family: custom;
     94            src: url('/fonts/noto/noto-sans-v8-latin-regular.woff') format('woff');
     95          }
     96        }
     97        @layer second {
     98          @font-face {
     99            font-family: custom;
    100            src: local('Ahem'), url('/fonts/Ahem.ttf');
    101          }
    102        }
    103        #target { font: 20px/1 custom; width: max-content; }
    104      `,
    105    ],
    106    update: async function(sheets) {
    107      await document.fonts.load('20px/1 ahem');
    108      await document.fonts.load('20px/1 custom');
    109      document.body.offsetLeft; // Force style recalc
    110      sheets[0].deleteRule(0);
    111      await document.fonts.load('20px/1 custom');
    112    },
    113    property: 'width',
    114  },
    115 ];
    116 
    117 for (let testCase of testCases) {
    118  promise_test(async test => {
    119    const styleElements = testCase.sheets.map(sheet => {
    120      const element = document.createElement('style');
    121      element.appendChild(document.createTextNode(sheet));
    122      document.head.appendChild(element);
    123      return element;
    124    });
    125    test.add_cleanup(() => {
    126      for (let element of styleElements)
    127        element.remove();
    128    });
    129 
    130    const sheets = styleElements.map(element => element.sheet);
    131    await testCase.update(sheets);
    132    const actual = getComputedStyle(target).getPropertyValue(testCase.property);
    133    const expected = getComputedStyle(reference).getPropertyValue(testCase.property);
    134    assert_equals(actual, expected);
    135 }, testCase.title);
    136 }
    137 </script>