tor-browser

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

browser_rules_at_starting-style.js (20274B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test that the rule-view properly handles @starting-style rules.
      7 
      8 const TEST_URI = `
      9  <style>
     10    @property --my-registered-color {
     11      syntax: "<color>";
     12      inherits: true;
     13      initial-value: blue;
     14    }
     15 
     16    @property --my-unset-registered-color {
     17      syntax: "<color>";
     18      inherits: true;
     19      initial-value: lavender;
     20    }
     21 
     22    h1, [data-test="top-level"] {
     23      color: tomato;
     24      transition: all 1s;
     25 
     26      @starting-style {
     27        color: gold;
     28      }
     29    }
     30 
     31    @starting-style {
     32      body, [data-test="in-starting-style"] {
     33        color: navy;
     34      }
     35 
     36      @layer {
     37        body, [data-test="in-starting-style-layer"] {
     38          color: hotpink;
     39        }
     40      }
     41 
     42      h1, [data-test="in-starting-style"] {
     43        background-color: salmon;
     44      }
     45 
     46      main, [data-test="in-starting-style"] {
     47        --my-color: black !important;
     48        --my-overridden-color: black;
     49        --my-registered-color: black !important;
     50        --check-my-color: var(--my-color);
     51        --check-my-overridden-color: var(--my-overridden-color);
     52        --check-my-registered-color: var(--my-registered-color);
     53        --check-my-unset-registered-color: var(--my-unset-registered-color);
     54        background-color: dodgerblue;
     55        padding-top: 1px;
     56        margin-top: 1px !important;
     57        outline-color: dodgerblue;
     58      }
     59 
     60      @layer {
     61        main, [data-test="in-starting-style-layer"] {
     62          background-color: forestgreen;
     63          padding-top: 4px;
     64          margin-top: 4px;
     65          outline-color: forestgreen !important;
     66        }
     67      }
     68 
     69      @layer {
     70        main, [data-test="in-starting-style-layer-2"] {
     71          background-color: cyan;
     72          padding-top: 5px;
     73          margin-top: 5px;
     74          outline-color: cyan !important;
     75        }
     76      }
     77    }
     78 
     79    main, [data-test="top-level"] {
     80      --my-color: white;
     81      --my-overridden-color: white !important;
     82      --my-registered-color: white;
     83      --empty-start: 1px;
     84      --check-my-overridden-color: var(--my-overridden-color);
     85      --check-my-registered-color: var(--my-registered-color);
     86      --check-empty-start: var(--empty-start);
     87      color: var(--my-color);
     88      background-color: firebrick;
     89      padding-top: 2px !important;
     90      margin-top: 2px;
     91      transition: all 1s 1000s;
     92      outline-color: firebrick;
     93      outline-width: 5px;
     94      outline-style: solid;
     95      outline-offset: 10px;
     96 
     97      @starting-style {
     98        --empty-start: ;
     99        background-color: goldenrod;
    100        padding-top: 3px;
    101        margin-top: 3px;
    102        outline-color: goldenrod;
    103      }
    104    }
    105  </style>
    106  <h1>Hello @starting-style!</h1>
    107  <main>Testing override</main>`;
    108 
    109 add_task(async function () {
    110  await pushPref("layout.css.starting-style-at-rules.enabled", true);
    111  await addTab(
    112    "https://example.com/document-builder.sjs?html=" +
    113      encodeURIComponent(TEST_URI)
    114  );
    115  const { inspector, view } = await openRuleView();
    116 
    117  await selectNode("body", inspector);
    118  await checkRuleViewContent(view, [
    119    {
    120      selector: `element`,
    121      ancestorRulesData: null,
    122      selectorEditable: false,
    123      declarations: [],
    124    },
    125    {
    126      selector: `body, ~~[data-test="in-starting-style"]~~`,
    127      ancestorRulesData: ["@starting-style {"],
    128      declarations: [{ name: "color", value: "navy" }],
    129    },
    130    {
    131      selector: `body, ~~[data-test="in-starting-style-layer"]~~`,
    132      ancestorRulesData: ["@starting-style {", "  @layer {"],
    133      declarations: [{ name: "color", value: "hotpink", overridden: true }],
    134    },
    135    { header: "@property" },
    136  ]);
    137 
    138  await selectNode("h1", inspector);
    139  await checkRuleViewContent(view, [
    140    {
    141      selector: `element`,
    142      ancestorRulesData: null,
    143      selectorEditable: false,
    144      declarations: [],
    145    },
    146    {
    147      selector: `h1, ~~[data-test="in-starting-style"]~~`,
    148      ancestorRulesData: ["@starting-style {"],
    149      declarations: [{ name: "background-color", value: "salmon" }],
    150    },
    151    {
    152      selector: ``,
    153      ancestorRulesData: [
    154        `h1, [data-test="top-level"] {`,
    155        "  @starting-style {",
    156      ],
    157      declarations: [{ name: "color", value: "gold" }],
    158    },
    159    {
    160      selector: `h1, ~~[data-test="top-level"]~~`,
    161      ancestorRulesData: null,
    162      declarations: [
    163        { name: "color", value: "tomato" },
    164        { name: "transition", value: "all 1s" },
    165      ],
    166    },
    167    { header: "@property" },
    168  ]);
    169 
    170  await selectNode("main", inspector);
    171  await checkRuleViewContent(view, [
    172    {
    173      selector: `element`,
    174      ancestorRulesData: null,
    175      selectorEditable: false,
    176      declarations: [],
    177    },
    178    {
    179      selector: ``,
    180      ancestorRulesData: [
    181        `main, [data-test="top-level"] {`,
    182        "  @starting-style {",
    183      ],
    184      declarations: [
    185        { name: "--empty-start", value: "" },
    186        {
    187          name: "background-color",
    188          value: "goldenrod",
    189          // background-color value in last starting-style rule is not overridden
    190          overridden: false,
    191        },
    192        {
    193          name: "padding-top",
    194          value: "3px",
    195          // padding-top value in last starting-style rule is overridden by the !important
    196          // set on the top level rule
    197          overridden: true,
    198        },
    199        {
    200          name: "margin-top",
    201          value: "3px",
    202          // margin-top value in last starting-style rule is overridden by the !important set
    203          // on another starting-style rule
    204          overridden: true,
    205        },
    206        {
    207          name: "outline-color",
    208          value: "goldenrod",
    209          // outline-color value in last starting-style rule is overridden by the !important
    210          // set on another starting-style rule
    211          overridden: true,
    212        },
    213      ],
    214    },
    215    {
    216      selector: `main, ~~[data-test="top-level"]~~`,
    217      ancestorRulesData: null,
    218      declarations: [
    219        { name: "--my-color", value: "white" },
    220        { name: "--my-overridden-color", value: "white !important" },
    221        { name: "--my-registered-color", value: "white" },
    222        { name: "--empty-start", value: "1px" },
    223        {
    224          name: "--check-my-overridden-color",
    225          value: "var(--my-overridden-color)",
    226        },
    227        {
    228          name: "--check-my-registered-color",
    229          value: "var(--my-registered-color)",
    230        },
    231        { name: "--check-empty-start", value: "var(--empty-start)" },
    232        { name: "color", value: "var(--my-color)" },
    233        {
    234          name: "background-color",
    235          value: "firebrick",
    236          // background-color value in top level rule is not overridden, even if the
    237          // property is also set in a starting style rule
    238          overridden: false,
    239        },
    240        {
    241          name: "padding-top",
    242          value: "2px !important",
    243          // padding-top value in top level rule is not overridden
    244          overridden: false,
    245        },
    246        {
    247          name: "margin-top",
    248          value: "2px",
    249          // margin-top value in top level rule is not overridden
    250          overridden: false,
    251        },
    252        { name: "transition", value: "all 1s 1000s" },
    253        {
    254          name: "outline-color",
    255          value: "firebrick",
    256          // outline-color value in top level rule is not overridden
    257          overridden: false,
    258        },
    259        { name: "outline-width", value: "5px" },
    260        { name: "outline-style", value: "solid" },
    261        { name: "outline-offset", value: "10px" },
    262      ],
    263    },
    264    {
    265      selector: `main, ~~[data-test="in-starting-style"]~~`,
    266      ancestorRulesData: ["@starting-style {"],
    267      declarations: [
    268        { name: "--my-color", value: "black !important" },
    269        { name: "--my-overridden-color", value: "black", overridden: true },
    270        { name: "--my-registered-color", value: "black !important" },
    271        { name: "--check-my-color", value: "var(--my-color)" },
    272        {
    273          name: "--check-my-overridden-color",
    274          value: "var(--my-overridden-color)",
    275          overridden: true,
    276        },
    277        {
    278          name: "--check-my-registered-color",
    279          value: "var(--my-registered-color)",
    280          overridden: true,
    281        },
    282        {
    283          name: "--check-my-unset-registered-color",
    284          value: "var(--my-unset-registered-color)",
    285        },
    286        {
    287          name: "background-color",
    288          value: "dodgerblue",
    289          // background-color value in top-level starting style rule is overridden
    290          overridden: true,
    291        },
    292        {
    293          name: "padding-top",
    294          value: "1px",
    295          // padding-top value in top-level starting style rule is overridden
    296          overridden: true,
    297        },
    298        {
    299          name: "margin-top",
    300          value: "1px !important",
    301          // margin-top value in top-level starting style rule is not overridden,
    302          // since it's declared with !important
    303          overridden: false,
    304        },
    305        {
    306          name: "outline-color",
    307          value: "dodgerblue",
    308          // outline-color value in top-level starting style rule is overridden
    309          overridden: true,
    310        },
    311      ],
    312    },
    313    {
    314      selector: `main, ~~[data-test="in-starting-style-layer-2"]~~`,
    315      ancestorRulesData: [`@starting-style {`, "  @layer {"],
    316      declarations: [
    317        {
    318          name: "background-color",
    319          value: "cyan",
    320          // background-color value in second layer in starting style rule is overridden
    321          overridden: true,
    322        },
    323        {
    324          name: "padding-top",
    325          value: "5px",
    326          // padding-top value in second layer in starting style rule is overridden
    327          overridden: true,
    328        },
    329        {
    330          name: "margin-top",
    331          value: "5px",
    332          // margin-top value in second layer in starting style rule is overridden
    333          overridden: true,
    334        },
    335        {
    336          name: "outline-color",
    337          value: "cyan !important",
    338          // outline-color value in second layer in starting style rule is overridden even
    339          // if it was declared with !important
    340          overridden: true,
    341        },
    342      ],
    343    },
    344    {
    345      selector: `main, ~~[data-test="in-starting-style-layer"]~~`,
    346      ancestorRulesData: [`@starting-style {`, "  @layer {"],
    347      declarations: [
    348        {
    349          name: "background-color",
    350          value: "forestgreen",
    351          // background-color value in first layer in starting style rule is overridden
    352          overridden: true,
    353        },
    354        {
    355          name: "padding-top",
    356          value: "4px",
    357          // padding-top value in first layer in starting style rule is overridden
    358          overridden: true,
    359        },
    360        {
    361          name: "margin-top",
    362          value: "4px",
    363          // margin-top value in first layer in starting style rule is overridden
    364          overridden: true,
    365        },
    366        {
    367          name: "outline-color",
    368          value: "forestgreen !important",
    369          // outline-color value in first layer in starting style rule is not overridden
    370          // as it's declared with !important
    371          overridden: false,
    372        },
    373      ],
    374    },
    375    { header: "@property" },
    376  ]);
    377 
    378  info(
    379    "Check that CSS variables set in starting-style are not impacting the var() tooltip"
    380  );
    381  ok(
    382    !isPropertyOverridden(view, 2, { "--my-color": "white" }),
    383    "--my-color value in top level rule is not overridden"
    384  );
    385 
    386  info(
    387    "Check var() in regular rule for a variable set in both regular and starting-style rule"
    388  );
    389  await assertVariableTooltipForProperty(
    390    view,
    391    `main, [data-test="top-level"]`,
    392    "color",
    393    {
    394      header:
    395        // prettier-ignore
    396        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="white" class="color-swatch-container">' +
    397          '<span class="inspector-swatch inspector-colorswatch" style="background-color:white">' +
    398          '</span>' +
    399          '<span class="ruleview-color">white</span>' +
    400        '</span>',
    401      // Computed value isn't displayed when it's the same as we put in the header
    402      computed: null,
    403      // The starting-style value is displayed in the tooltip
    404      startingStyle:
    405        // prettier-ignore
    406        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="black" class="color-swatch-container">' +
    407          '<span class="inspector-swatch inspector-colorswatch" style="background-color:black">' +
    408          '</span>' +
    409          '<span class="ruleview-color">black</span>' +
    410        '</span>',
    411    }
    412  );
    413 
    414  info(
    415    "Check var() in starting-style rule for a variable set in both regular and starting-style rule"
    416  );
    417  await assertVariableTooltipForProperty(
    418    view,
    419    `main, [data-test="in-starting-style"]`,
    420    "--check-my-color",
    421    {
    422      // The displayed value is the one set in the starting-style rule
    423      header:
    424        // prettier-ignore
    425        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="black" class="color-swatch-container">' +
    426          '<span class="inspector-swatch inspector-colorswatch" style="background-color:black">' +
    427          '</span>' +
    428          '<span class="ruleview-color">black</span>' +
    429        '</span>',
    430      // Computed value isn't displayed in starting-style rule
    431      computed: null,
    432      // The starting-style section is not displayed when hovering starting-style rule
    433      startingStyle: null,
    434    }
    435  );
    436 
    437  info(
    438    "Check var() in both regular and starting-style rule for a variable overridden in regular rule"
    439  );
    440  ok(
    441    isPropertyOverridden(view, 3, { "--my-overridden-color": "black" }),
    442    "--my-overridden-color in top-level starting style rule is overridden"
    443  );
    444  await assertVariableTooltipForProperty(
    445    view,
    446    `main, [data-test="top-level"]`,
    447    "--check-my-overridden-color",
    448    {
    449      header:
    450        // prettier-ignore
    451        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="white" class="color-swatch-container">' +
    452          '<span class="inspector-swatch inspector-colorswatch" style="background-color:white">' +
    453          '</span>' +
    454          '<span class="ruleview-color">white</span>' +
    455        '</span>',
    456      // Computed value isn't displayed when it's the same as we put in the header
    457      computed: null,
    458      // The starting-style rule is overridden, so we don't show a starting-style section in the tooltip
    459      startingStyle: null,
    460    }
    461  );
    462  await assertVariableTooltipForProperty(
    463    view,
    464    `main, [data-test="in-starting-style"]`,
    465    "--check-my-overridden-color",
    466    {
    467      // the value is the one from the regular rule, not the one from the starting-style rule
    468      header:
    469        // prettier-ignore
    470        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="white" class="color-swatch-container">' +
    471          '<span class="inspector-swatch inspector-colorswatch" style="background-color:white">' +
    472          '</span>' +
    473          '<span class="ruleview-color">white</span>' +
    474        '</span>',
    475      // Computed value isn't displayed in starting-style rule
    476      computed: null,
    477      startingStyle: null,
    478    }
    479  );
    480 
    481  info(
    482    "Check var() for a registered property in both regular and starting-style rule"
    483  );
    484  await assertVariableTooltipForProperty(
    485    view,
    486    `main, [data-test="top-level"]`,
    487    "--check-my-registered-color",
    488    {
    489      header:
    490        // prettier-ignore
    491        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="white" class="color-swatch-container">' +
    492          '<span class="inspector-swatch inspector-colorswatch" style="background-color:white">' +
    493          '</span>' +
    494          '<span class="ruleview-color">white</span>' +
    495        '</span>',
    496      computed:
    497        // prettier-ignore
    498        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="rgb(255, 255, 255)" class="color-swatch-container">' +
    499          '<span class="inspector-swatch inspector-colorswatch" style="background-color:rgb(255, 255, 255)">' +
    500          '</span>' +
    501          '<span class="ruleview-color">rgb(255, 255, 255)</span>' +
    502        '</span>',
    503      // The starting-style value is displayed in the tooltip
    504      startingStyle:
    505        // prettier-ignore
    506        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="black" class="color-swatch-container">' +
    507          '<span class="inspector-swatch inspector-colorswatch" style="background-color:black">' +
    508          '</span>' +
    509          '<span class="ruleview-color">black</span>' +
    510        '</span>',
    511      // registered property data is displayed
    512      registeredProperty: {
    513        syntax: `"&lt;color&gt;"`,
    514        inherits: "true",
    515        "initial-value":
    516          // prettier-ignore
    517          `<span xmlns="http://www.w3.org/1999/xhtml" data-color="blue" class="color-swatch-container">` +
    518            `<span ` +
    519              `class="inspector-swatch inspector-colorswatch" ` +
    520              `style="background-color:blue">` +
    521            `</span>` +
    522            `<span class="ruleview-color">blue</span>` +
    523          `</span>`,
    524      },
    525    }
    526  );
    527 
    528  await assertVariableTooltipForProperty(
    529    view,
    530    `main, [data-test="in-starting-style"]`,
    531    "--check-my-registered-color",
    532    {
    533      // The displayed value is the one set in the starting-style rule
    534      header:
    535        // prettier-ignore
    536        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="black" class="color-swatch-container">' +
    537          '<span class="inspector-swatch inspector-colorswatch" style="background-color:black">' +
    538          '</span>' +
    539          '<span class="ruleview-color">black</span>' +
    540        '</span>',
    541      // Computed value isn't displayed in starting-style rule
    542      computed: null,
    543      // The starting-style section is not displayed when hovering starting-style rule
    544      startingStyle: null,
    545      // registered property data is displayed
    546      registeredProperty: {
    547        syntax: `"&lt;color&gt;"`,
    548        inherits: "true",
    549        "initial-value":
    550          // prettier-ignore
    551          `<span xmlns="http://www.w3.org/1999/xhtml" data-color="blue" class="color-swatch-container">` +
    552            `<span ` +
    553              `class="inspector-swatch inspector-colorswatch" ` +
    554              `style="background-color:blue">` +
    555            `</span>` +
    556            `<span class="ruleview-color">blue</span>` +
    557          `</span>`,
    558      },
    559    }
    560  );
    561 
    562  info("Check var() for a unset registered property in starting-style rule");
    563  await assertVariableTooltipForProperty(
    564    view,
    565    `main, [data-test="in-starting-style"]`,
    566    "--check-my-unset-registered-color",
    567    {
    568      // The displayed value is the registered property initial value
    569      header:
    570        // prettier-ignore
    571        '<span xmlns="http://www.w3.org/1999/xhtml" data-color="lavender" class="color-swatch-container">' +
    572          '<span class="inspector-swatch inspector-colorswatch" style="background-color:lavender">' +
    573          '</span>' +
    574          '<span class="ruleview-color">lavender</span>' +
    575        '</span>',
    576      // The starting-style section is not displayed when hovering starting-style rule
    577      startingStyle: null,
    578      // registered property data is displayed
    579      registeredProperty: {
    580        syntax: `"&lt;color&gt;"`,
    581        inherits: "true",
    582        "initial-value":
    583          // prettier-ignore
    584          '<span xmlns="http://www.w3.org/1999/xhtml" data-color="lavender" class="color-swatch-container">' +
    585            '<span class="inspector-swatch inspector-colorswatch" style="background-color:lavender">' +
    586            '</span>' +
    587            '<span class="ruleview-color">lavender</span>' +
    588          '</span>',
    589      },
    590    }
    591  );
    592 
    593  info("Check var() for a empty variable in regular rule");
    594  await assertVariableTooltipForProperty(
    595    view,
    596    `main, [data-test="top-level"]`,
    597    "--check-empty-start",
    598    {
    599      header: "1px",
    600      // The starting-style value is displayed in the tooltip
    601      startingStyle: "&lt;empty&gt;",
    602      startingStyleClasses: ["empty-css-variable"],
    603    }
    604  );
    605 });
    606 
    607 function isPropertyOverridden(view, ruleIndex, property) {
    608  return getTextProperty(
    609    view,
    610    ruleIndex,
    611    property
    612  ).editor.element.classList.contains("ruleview-overridden");
    613 }