tor-browser

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

at-function-cssom.html (11173B)


      1 <!DOCTYPE html>
      2 <title>CSS Custom Functions: CSSOM</title>
      3 <link rel="help" href="https://drafts.csswg.org/css-mixins-1/#cssom">
      4 <script src="/resources/testharness.js"></script>
      5 <script src="/resources/testharnessreport.js"></script>
      6 
      7 <script>
      8 
      9 test(t => {
     10  let sheet = new CSSStyleSheet();
     11  sheet.replaceSync(`
     12    @function --foo() {}
     13  `);
     14  assert_equals(sheet.cssRules.length, 1);
     15  let functionRule = sheet.cssRules[0];
     16  assert_true(functionRule instanceof CSSFunctionRule);
     17  assert_equals(functionRule.cssRules.length, 0);
     18 }, 'Empty CSSFunctionRule');
     19 
     20 test(t => {
     21  let sheet = new CSSStyleSheet();
     22  sheet.replaceSync(`
     23    @function --foo() {
     24      result: 100px;
     25    }
     26  `);
     27  assert_equals(sheet.cssRules.length, 1);
     28  let functionRule = sheet.cssRules[0];
     29  assert_true(functionRule instanceof CSSFunctionRule);
     30  assert_equals(functionRule.cssRules.length, 1);
     31  let declarationsRule = functionRule.cssRules[0];
     32  assert_true(declarationsRule instanceof CSSFunctionDeclarations);
     33  let descriptors = declarationsRule.style;
     34  assert_true(descriptors instanceof CSSFunctionDescriptors);
     35 }, 'Single CSSFunctionDeclarations');
     36 
     37 test(t => {
     38  let sheet = new CSSStyleSheet();
     39  sheet.replaceSync(`
     40    @function --foo() {
     41      result: 100px;
     42    }
     43  `);
     44  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
     45  assert_true(descriptors instanceof CSSFunctionDescriptors);
     46  assert_equals(descriptors.result, '100px');
     47 }, 'CSSFunctionDescriptors (result)');
     48 
     49 test(t => {
     50  let sheet = new CSSStyleSheet();
     51  sheet.replaceSync(`
     52    @function --foo() {
     53      result: 100px;
     54      result: 101px;
     55    }
     56  `);
     57  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
     58  assert_true(descriptors instanceof CSSFunctionDescriptors);
     59  assert_equals(descriptors.result, '101px');
     60 }, 'CSSFunctionDescriptors (result, repeated)');
     61 
     62 test(t => {
     63  let sheet = new CSSStyleSheet();
     64  sheet.replaceSync(`
     65    @function --foo() {
     66      --x: 1px;
     67      --y: 2px;
     68    }
     69  `);
     70  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
     71  assert_true(descriptors instanceof CSSFunctionDescriptors);
     72  assert_equals(descriptors.getPropertyValue('--x'), '1px');
     73  assert_equals(descriptors.getPropertyValue('--y'), '2px');
     74  assert_equals(descriptors.getPropertyValue('--unknown'), '');
     75  assert_equals(descriptors.result, '');
     76 }, 'CSSFunctionDescriptors (local variables)');
     77 
     78 test(t => {
     79  let sheet = new CSSStyleSheet();
     80  sheet.replaceSync(`
     81    @function --foo() {
     82      --x: 1px;
     83      --y: 2px;
     84      --x: 3px;
     85    }
     86  `);
     87  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
     88  assert_true(descriptors instanceof CSSFunctionDescriptors);
     89  assert_equals(descriptors.getPropertyValue('--x'), '3px');
     90  assert_equals(descriptors.getPropertyValue('--y'), '2px');
     91  assert_equals(descriptors.getPropertyValue('--unknown'), '');
     92  assert_equals(descriptors.result, '');
     93 }, 'CSSFunctionDescriptors (local variables, repeated)');
     94 
     95 test(t => {
     96  let sheet = new CSSStyleSheet();
     97  sheet.replaceSync(`
     98    @function --foo() {
     99      --x: 1px;
    100      --y: 2px;
    101      result: 3px;
    102    }
    103  `);
    104  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    105  assert_true(descriptors instanceof CSSFunctionDescriptors);
    106  assert_equals(descriptors.getPropertyValue('--x'), '1px');
    107  assert_equals(descriptors.getPropertyValue('--y'), '2px');
    108  assert_equals(descriptors.getPropertyValue('--unknown'), '');
    109  assert_equals(descriptors.result, '3px');
    110 }, 'CSSFunctionDescriptors (local variables and result)');
    111 
    112 test(t => {
    113  let sheet = new CSSStyleSheet();
    114  sheet.replaceSync(`
    115    @function --foo() {
    116      --x: 1px;
    117      --y: 2px;
    118      result: 3px;
    119    }
    120  `);
    121  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    122  assert_true(descriptors instanceof CSSFunctionDescriptors);
    123  assert_equals(descriptors.cssText, '--x: 1px; --y: 2px; result: 3px;');
    124 }, 'CSSFunctionDescriptors serialization');
    125 
    126 test(t => {
    127  let sheet = new CSSStyleSheet();
    128  sheet.replaceSync(`
    129    @function --foo() {
    130      --x: 1px;
    131      syntax: "<length>";
    132      --y: 2px;
    133      color: red;
    134      unknown: unknown;
    135      result: 3px;
    136    }
    137  `);
    138  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    139  assert_true(descriptors instanceof CSSFunctionDescriptors);
    140  assert_equals(descriptors.length, 3);
    141  assert_equals(descriptors.cssText, '--x: 1px; --y: 2px; result: 3px;');
    142 }, 'Unknown descriptors');
    143 
    144 test(t => {
    145  let sheet = new CSSStyleSheet();
    146  sheet.replaceSync(`
    147    @function --foo() {
    148      --x: 1px;
    149    }
    150  `);
    151  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    152  assert_true(descriptors instanceof CSSFunctionDescriptors);
    153  assert_equals(descriptors.length, 1);
    154  descriptors.cssText = '--x: 1px; color: red; result: 3px; --y: 2px;';
    155  assert_equals(descriptors.length, 3);
    156  assert_equals(descriptors.cssText, '--x: 1px; result: 3px; --y: 2px;');
    157 }, 'Unknown descriptors (mutation)');
    158 
    159 test(t => {
    160  let sheet = new CSSStyleSheet();
    161  sheet.replaceSync(`
    162    @function --foo() {
    163     --x: 1px;
    164     result: 2px;
    165    }
    166  `);
    167  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    168  assert_true(descriptors instanceof CSSFunctionDescriptors);
    169  assert_equals(descriptors.length, 2);
    170  assert_equals(descriptors.item(0), '--x');
    171  assert_equals(descriptors.item(1), 'result');
    172 }, 'item()');
    173 
    174 // https://webidl.spec.whatwg.org/#dfn-indexed-property-getter
    175 test(t => {
    176  let sheet = new CSSStyleSheet();
    177  sheet.replaceSync(`
    178    @function --foo() {
    179     --x: 1px;
    180     result: 2px;
    181    }
    182  `);
    183  let descriptors = sheet.cssRules[0]?.cssRules[0]?.style;
    184  assert_true(descriptors instanceof CSSFunctionDescriptors);
    185  assert_array_equals(Array.from(descriptors), ['--x', 'result']);;
    186 }, 'Indexed property getter');
    187 
    188 // Conditional rules
    189 
    190 test(t => {
    191  let sheet = new CSSStyleSheet();
    192  sheet.replaceSync(`
    193    @function --foo() {
    194      @supports (width: 100px) {
    195        result: 100px;
    196      }
    197      result: 200px;
    198    }
    199  `);
    200  assert_equals(sheet.cssRules.length, 1);
    201  let functionRule = sheet.cssRules[0];
    202  assert_true(functionRule instanceof CSSFunctionRule);
    203  assert_equals(functionRule.cssRules.length, 2);
    204  let supportsRule = functionRule.cssRules[0];
    205  assert_true(supportsRule instanceof CSSSupportsRule);
    206  assert_true(supportsRule.cssRules[0] instanceof CSSFunctionDeclarations);
    207  assert_equals(supportsRule.cssRules[0].style?.result, '100px');
    208 
    209  let declarationsRule = functionRule.cssRules[1];
    210  assert_true(declarationsRule instanceof CSSFunctionDeclarations);
    211  let descriptors = declarationsRule.style;
    212  assert_true(descriptors instanceof CSSFunctionDescriptors);
    213  assert_equals(descriptors.result, '200px');
    214 }, '@supports in body');
    215 
    216 // CSSFunctionRule
    217 
    218 test(t => {
    219  let sheet = new CSSStyleSheet();
    220  sheet.replaceSync(`
    221    @function --foo() {}
    222  `);
    223  assert_equals(sheet.cssRules.length, 1);
    224  let functionRule = sheet.cssRules[0];
    225  assert_true(functionRule instanceof CSSFunctionRule);
    226  assert_equals(functionRule.name, '--foo');
    227 }, 'CSSFunctionRule.name');
    228 
    229 test(t => {
    230  let sheet = new CSSStyleSheet();
    231  sheet.replaceSync(`
    232    @function --f0() {}
    233    @function --f1(--x) {}
    234    @function --f2(--x <length>) {}
    235    @function --f3(--x: 10px) {}
    236    @function --f4(--x <length>: 10px) {}
    237    @function --f5(--x type(<length> | auto): 10px, --y, --z: red) {}
    238  `);
    239  assert_equals(sheet.cssRules.length, 6);
    240  assert_object_equals(sheet.cssRules[0].getParameters(), []);
    241  assert_object_equals(sheet.cssRules[1].getParameters(), [
    242    {name: '--x', type: '*'},
    243  ]);
    244  assert_object_equals(sheet.cssRules[2].getParameters(), [
    245    {name: '--x', type: '<length>'},
    246  ]);
    247  assert_object_equals(sheet.cssRules[3].getParameters(), [
    248    {name: '--x', type: '*', defaultValue: '10px'},
    249  ]);
    250  assert_object_equals(sheet.cssRules[4].getParameters(), [
    251    {name: '--x', type: '<length>', defaultValue: '10px'},
    252  ]);
    253  assert_object_equals(sheet.cssRules[5].getParameters(), [
    254    {name: '--x', type: '<length> | auto', defaultValue: '10px'},
    255    {name: '--y', type: '*'},
    256    {name: '--z', type: '*', defaultValue: 'red'},
    257  ], '--f5');
    258 }, 'CSSFunctionRule.getParameters()');
    259 
    260 test(t => {
    261  let sheet = new CSSStyleSheet();
    262  sheet.replaceSync(`
    263    @function --f0() {}
    264    @function --f1() returns <length> {}
    265    @function --f2() returns <length>+ {}
    266    @function --f3() returns type(*) {}
    267    @function --f4() returns type(<length> | auto) {}
    268  `);
    269  assert_equals(sheet.cssRules.length, 5);
    270  assert_equals(sheet.cssRules[0]?.returnType, '*');
    271  assert_equals(sheet.cssRules[1]?.returnType, '<length>');
    272  assert_equals(sheet.cssRules[2]?.returnType, '<length>+');
    273  assert_equals(sheet.cssRules[3]?.returnType, '*');
    274  assert_equals(sheet.cssRules[4]?.returnType, '<length> | auto');
    275 }, 'CSSFunctionRule.returnType');
    276 
    277 test(t => {
    278  let sheet = new CSSStyleSheet();
    279  // U+0009 CHARACTER TABULATION
    280  sheet.replaceSync(`@function --escaped-\\9 -tab(--param-\\9 -tab) { --local-\\9 -tab: 1px; }`);
    281  assert_equals(sheet.cssRules.length, 1);
    282  let rule = sheet.cssRules[0];
    283  assert_equals(rule.name, '--escaped-\t-tab');
    284  assert_equals(rule.getParameters()[0]?.name, '--param-\t-tab');
    285  assert_equals(rule.cssRules[0].style.getPropertyValue('--local-\t-tab'), '1px');
    286 }, 'CSSFunctionRule escapes');
    287 
    288 function test_cssText(actual, expected) {
    289  expected ??= actual;
    290  let name = actual.match(/@function (--[-\w]+)/)[1];
    291  test(t => {
    292    let sheet = new CSSStyleSheet();
    293    sheet.replaceSync(actual);
    294    assert_equals(sheet.cssRules[0]?.cssText, expected);
    295  }, `CSSFunctionRule.cssText (${name})`);
    296 }
    297 
    298 // The function name is used by the test description; please make sure it's
    299 // unique among all test_cssText cases.
    300 test_cssText(`@function --empty() { }`);
    301 
    302 test_cssText(`@function --ret-length() returns <length> { }`);
    303 test_cssText(`@function --ret-length-auto() returns type(<length> | auto) { }`);
    304 
    305 test_cssText(`@function --param-single(--x) { }`);
    306 test_cssText(`@function --param-typed(--x <length>) { }`);
    307 test_cssText(`@function --param-typed-default(--x <length>: 10px) { }`);
    308 test_cssText(`@function --param-default(--x: 10px) { }`);
    309 test_cssText(`@function --param-multi(--x, --y) { }`);
    310 test_cssText(`@function --param-multi-mixed(--x: 10px, --y, --z <length>) { }`);
    311 
    312 test_cssText(`@function --body-result() { result: 10px; }`);
    313 test_cssText(`@function --body-locals() { --x: 1px; --y: 2px; result: 10px; }`);
    314 
    315 // Cases that don't round-trip as-is:
    316 test_cssText(`@function --param-type-fn(--x type(<length>)) { }`,
    317             `@function --param-type-fn(--x <length>) { }`);
    318 test_cssText(`@function --param-type-fn-uni(--x type(*)) { }`,
    319             `@function --param-type-fn-uni(--x) { }`);
    320 test_cssText(`@function --ret-type-fn() returns type(*) { }`,
    321             `@function --ret-type-fn() { }`);
    322 test_cssText(`@function --ret-type-fn-uni() returns type(*) { }`,
    323             `@function --ret-type-fn-uni() { }`);
    324 test_cssText(`@function --body-result-multi() { result: 10px; result: 20px; }`,
    325             `@function --body-result-multi() { result: 20px; }`);
    326 
    327 // Escapes (U+0009 CHARACTER TABULATION):
    328 test_cssText(`@function --escaped-\\9 -tab(--param-\\9 -tab) { --local-\\9 -tab: 1px; }`);
    329 </script>