tor-browser

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

browser_rules_inherited-element-backed-pseudo-elements.js (15089B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests that inherited element-backed pseudo element rules are properly displayed in
      7 // the Rules view and that declarations are properly overridden.
      8 
      9 const TEST_URI = `
     10  <style>
     11    details {
     12      --x: blue;
     13      color: gold;
     14 
     15      summary { color: violet; }
     16 
     17      &::details-content {
     18        --x: tomato;
     19        color: dodgerblue;
     20        background-color: rgb(200 0 0 / 0.1);
     21      }
     22    }
     23 
     24    /* use :where() to have a lower specificity than the details rule above */
     25    :where(body > details)::details-content {
     26      color: forestgreen;
     27    }
     28 
     29    p {
     30      outline-color: var(--x);
     31 
     32      &::after {
     33        content: " meow";
     34        color: green;
     35      }
     36    }
     37 
     38    details#in-summary {
     39      color: cyan;
     40 
     41      & summary {
     42        color: hotpink;
     43      }
     44 
     45      &::details-content {
     46        --x: rebeccapurple;
     47        color: brown;
     48      }
     49    }
     50 
     51    details#vip::details-content {
     52      color: blue !important;
     53    }
     54 
     55    details#vip::details-content {
     56      color: red;
     57    }
     58  </style>
     59  <details open>
     60    <summary>
     61      Top-level summary
     62      <details id=in-summary open>
     63        <summary>nested summary</summary>
     64        details in summary
     65        <p>child of details in summary</p>
     66      </details>
     67    </summary>
     68    top-level details
     69    <summary id=non-functional-summary>not a real summary</summary>
     70    <p>in top-level details</p>
     71    /* don't use an id so the "inherited from" section would have the same text as the
     72       section for the parent details. This will assert that we do get separate inhertied
     73       section for those different "levels" */
     74    <details class=in-details open>
     75      <summary>nested details summary</summary>
     76      nested details
     77      <p>child of nested details</p>
     78    </details>
     79  </details>
     80  <details id=vip open>
     81    <summary>s</summary>
     82    <article>hello</hello>
     83  </details>
     84 `;
     85 
     86 add_task(async function () {
     87  await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
     88  const { inspector, view } = await openRuleView();
     89 
     90  info(
     91    "Check that there's no inherited ::details-content header when top-level <summary> is selected"
     92  );
     93  await selectNode("summary", inspector);
     94  await checkRuleViewContent(view, [
     95    {
     96      selector: `element`,
     97      ancestorRulesData: null,
     98      selectorEditable: false,
     99      declarations: [],
    100    },
    101    {
    102      selector: `& summary`,
    103      ancestorRulesData: ["details {"],
    104      declarations: [{ name: "color", value: "violet" }],
    105    },
    106    {
    107      header: "Inherited from details",
    108    },
    109    {
    110      selector: `details`,
    111      inherited: true,
    112      declarations: [
    113        { name: "--x", value: "blue" },
    114        { name: "color", value: "gold", overridden: true },
    115      ],
    116    },
    117  ]);
    118 
    119  info(
    120    "Check that there are expected inherited headers when children of top-level <details> is selected"
    121  );
    122  await selectNode("body > details > p", inspector);
    123  await checkRuleViewContent(view, [
    124    {
    125      header: "Pseudo-elements",
    126    },
    127    {
    128      selector: `&::after`,
    129      ancestorRulesData: [`p {`],
    130      declarations: [
    131        { name: "content", value: `" meow"` },
    132        { name: "color", value: "green" },
    133      ],
    134    },
    135    {
    136      header: "This Element",
    137    },
    138    {
    139      selector: `element`,
    140      ancestorRulesData: null,
    141      selectorEditable: false,
    142      declarations: [],
    143    },
    144    {
    145      selector: `p`,
    146      declarations: [{ name: "outline-color", value: "var(--x)" }],
    147    },
    148    {
    149      header: "Inherited from details::details-content",
    150    },
    151    {
    152      selector: `&::details-content`,
    153      ancestorRulesData: [`details {`],
    154      inherited: true,
    155      declarations: [
    156        { name: "--x", value: "tomato" },
    157        { name: "color", value: "dodgerblue" },
    158      ],
    159    },
    160    {
    161      selector: `:where(body > details)::details-content`,
    162      inherited: true,
    163      declarations: [
    164        {
    165          name: "color",
    166          value: "forestgreen",
    167          // overridden because lower specificity than ::details-content
    168          overridden: true,
    169        },
    170      ],
    171    },
    172    {
    173      header: "Inherited from details",
    174    },
    175    {
    176      selector: `details`,
    177      inherited: true,
    178      declarations: [
    179        {
    180          name: "--x",
    181          value: "blue",
    182          overridden: true,
    183        },
    184        {
    185          name: "color",
    186          value: "gold",
    187          // overridden by color: dodgerblue on ::details-content
    188          overridden: true,
    189        },
    190      ],
    191    },
    192  ]);
    193 
    194  checkCSSVariableOutput(
    195    view,
    196    "p",
    197    "outline-color",
    198    "inspector-variable",
    199    "tomato"
    200  );
    201 
    202  info("Check rules and declarations for details in summary");
    203  await selectNode("details#in-summary", inspector);
    204  await checkRuleViewContent(view, [
    205    {
    206      header: "Pseudo-elements",
    207    },
    208    {
    209      selector: `&::details-content`,
    210      ancestorRulesData: ["details#in-summary {"],
    211      declarations: [
    212        { name: "--x", value: "rebeccapurple" },
    213        { name: "color", value: "brown" },
    214      ],
    215    },
    216    {
    217      selector: `&::details-content`,
    218      ancestorRulesData: ["details {"],
    219      declarations: [
    220        { name: "--x", value: "tomato", overridden: true },
    221        { name: "color", value: "dodgerblue", overridden: true },
    222        { name: "background-color", value: "rgb(200 0 0 / 0.1)" },
    223      ],
    224    },
    225    {
    226      header: "This Element",
    227    },
    228    {
    229      selector: `element`,
    230      ancestorRulesData: null,
    231      selectorEditable: false,
    232      declarations: [],
    233    },
    234    {
    235      selector: `details#in-summary`,
    236      declarations: [{ name: "color", value: "cyan" }],
    237    },
    238    {
    239      selector: `details`,
    240      declarations: [
    241        { name: "--x", value: "blue" },
    242        { name: "color", value: "gold", overridden: true },
    243      ],
    244    },
    245    {
    246      header: "Inherited from summary",
    247    },
    248    {
    249      selector: `& summary`,
    250      ancestorRulesData: ["details {"],
    251      inherited: true,
    252      declarations: [{ name: "color", value: "violet", overridden: true }],
    253    },
    254  ]);
    255 
    256  info("Check rules and declarations for nested summary");
    257  await selectNode("details#in-summary summary", inspector);
    258 
    259  await checkRuleViewContent(view, [
    260    {
    261      selector: `element`,
    262      ancestorRulesData: null,
    263      selectorEditable: false,
    264      declarations: [],
    265    },
    266    {
    267      selector: `& summary`,
    268      ancestorRulesData: ["details#in-summary {"],
    269      declarations: [{ name: "color", value: "hotpink" }],
    270    },
    271    {
    272      selector: `& summary`,
    273      ancestorRulesData: ["details {"],
    274      declarations: [{ name: "color", value: "violet", overridden: true }],
    275    },
    276    {
    277      header: "Inherited from details#in-summary",
    278    },
    279    {
    280      selector: `details#in-summary`,
    281      inherited: true,
    282      declarations: [{ name: "color", value: "cyan", overridden: true }],
    283    },
    284    {
    285      selector: `details`,
    286      inherited: true,
    287      declarations: [
    288        { name: "--x", value: "blue" },
    289        { name: "color", value: "gold", overridden: true },
    290      ],
    291    },
    292  ]);
    293 
    294  info("Check rules and declarations for nested <details> child");
    295  await selectNode("details#in-summary p", inspector);
    296  await checkRuleViewContent(view, [
    297    {
    298      header: "Pseudo-elements",
    299    },
    300    {
    301      selector: `&::after`,
    302      ancestorRulesData: [`p {`],
    303      declarations: [
    304        { name: "content", value: `" meow"` },
    305        { name: "color", value: "green" },
    306      ],
    307    },
    308    {
    309      header: "This Element",
    310    },
    311    {
    312      selector: `element`,
    313      ancestorRulesData: null,
    314      selectorEditable: false,
    315      declarations: [],
    316    },
    317    {
    318      selector: `p`,
    319      declarations: [{ name: "outline-color", value: "var(--x)" }],
    320    },
    321    {
    322      header: "Inherited from details#in-summary::details-content",
    323    },
    324    {
    325      selector: `&::details-content`,
    326      ancestorRulesData: [`details#in-summary {`],
    327      inherited: true,
    328      declarations: [
    329        { name: "--x", value: "rebeccapurple" },
    330        {
    331          name: "color",
    332          value: "brown",
    333        },
    334      ],
    335    },
    336    {
    337      selector: `&::details-content`,
    338      ancestorRulesData: [`details {`],
    339      inherited: true,
    340      declarations: [
    341        { name: "--x", value: "tomato", overridden: true },
    342        {
    343          name: "color",
    344          value: "dodgerblue",
    345          overridden: true,
    346        },
    347      ],
    348    },
    349    {
    350      header: "Inherited from details#in-summary",
    351    },
    352    {
    353      selector: `details#in-summary`,
    354      inherited: true,
    355      declarations: [{ name: "color", value: "cyan", overridden: true }],
    356    },
    357    {
    358      selector: `details`,
    359      inherited: true,
    360      declarations: [
    361        { name: "--x", value: "blue", overridden: true },
    362        { name: "color", value: "gold", overridden: true },
    363      ],
    364    },
    365    {
    366      header: "Inherited from summary",
    367    },
    368    {
    369      selector: `& summary`,
    370      ancestorRulesData: [`details {`],
    371      inherited: true,
    372      declarations: [
    373        {
    374          name: "color",
    375          value: "violet",
    376          overridden: true,
    377        },
    378      ],
    379    },
    380  ]);
    381 
    382  checkCSSVariableOutput(
    383    view,
    384    "p",
    385    "outline-color",
    386    "inspector-variable",
    387    "rebeccapurple"
    388  );
    389 
    390  info("Check rules and declarations for second summary inside details");
    391  // when a <details> element has multiple <summary> children, only the first one is
    392  // actually interactive. The other ones are placed inside the ::details-content
    393  await selectNode("summary#non-functional-summary", inspector);
    394  await checkRuleViewContent(view, [
    395    { selector: `element`, selectorEditable: false, declarations: [] },
    396    {
    397      selector: `& summary`,
    398      ancestorRulesData: [`details {`],
    399      declarations: [{ name: "color", value: "violet" }],
    400    },
    401    {
    402      header: "Inherited from details::details-content",
    403    },
    404    {
    405      selector: `&::details-content`,
    406      ancestorRulesData: [`details {`],
    407      inherited: true,
    408      declarations: [
    409        { name: "--x", value: "tomato" },
    410        { name: "color", value: "dodgerblue", overridden: true },
    411      ],
    412    },
    413    {
    414      selector: `:where(body > details)::details-content`,
    415      inherited: true,
    416      declarations: [
    417        {
    418          name: "color",
    419          value: "forestgreen",
    420          overridden: true,
    421        },
    422      ],
    423    },
    424    {
    425      header: "Inherited from details",
    426    },
    427    {
    428      selector: `details`,
    429      inherited: true,
    430      declarations: [
    431        {
    432          name: "--x",
    433          value: "blue",
    434          overridden: true,
    435        },
    436        {
    437          name: "color",
    438          value: "gold",
    439          overridden: true,
    440        },
    441      ],
    442    },
    443  ]);
    444 
    445  info("Check rules and declarations for details in details");
    446  await selectNode("details.in-details", inspector);
    447  await checkRuleViewContent(view, [
    448    {
    449      header: "Pseudo-elements",
    450    },
    451    {
    452      selector: `&::details-content`,
    453      ancestorRulesData: ["details {"],
    454      declarations: [
    455        { name: "--x", value: "tomato" },
    456        { name: "color", value: "dodgerblue" },
    457        { name: "background-color", value: "rgb(200 0 0 / 0.1)" },
    458      ],
    459    },
    460    {
    461      header: "This Element",
    462    },
    463    {
    464      selector: `element`,
    465      selectorEditable: false,
    466      ancestorRulesData: null,
    467      declarations: [],
    468    },
    469    {
    470      selector: `details`,
    471      declarations: [
    472        { name: "--x", value: "blue" },
    473        { name: "color", value: "gold" },
    474      ],
    475    },
    476    {
    477      header: "Inherited from details::details-content",
    478    },
    479    {
    480      selector: `:where(body > details)::details-content`,
    481      inherited: true,
    482      declarations: [{ name: "color", value: "forestgreen", overridden: true }],
    483    },
    484  ]);
    485 
    486  info("Check rules and declarations for children of details in details");
    487  await selectNode("details.in-details p", inspector);
    488  await checkRuleViewContent(view, [
    489    {
    490      header: "Pseudo-elements",
    491    },
    492    {
    493      selector: `&::after`,
    494      ancestorRulesData: [`p {`],
    495      declarations: [
    496        { name: "content", value: `" meow"` },
    497        { name: "color", value: "green" },
    498      ],
    499    },
    500    {
    501      header: "This Element",
    502    },
    503    {
    504      selector: `element`,
    505      selectorEditable: false,
    506      ancestorRulesData: null,
    507      declarations: [],
    508    },
    509    {
    510      selector: `p`,
    511      declarations: [{ name: "outline-color", value: "var(--x)" }],
    512    },
    513    {
    514      // this is for the body > details > details::details-content pseudo
    515      header: "Inherited from details::details-content",
    516    },
    517    {
    518      selector: `&::details-content`,
    519      ancestorRulesData: [`details {`],
    520      inherited: true,
    521      declarations: [
    522        { name: "--x", value: "tomato" },
    523        {
    524          name: "color",
    525          value: "dodgerblue",
    526        },
    527      ],
    528    },
    529    {
    530      // this is for the body > details::details-content pseudo
    531      header: "Inherited from details::details-content",
    532    },
    533    {
    534      selector: `:where(body > details)::details-content`,
    535      inherited: true,
    536      declarations: [{ name: "color", value: "forestgreen", overridden: true }],
    537    },
    538    {
    539      header: "Inherited from details",
    540    },
    541    {
    542      selector: `details`,
    543      inherited: true,
    544      declarations: [
    545        {
    546          name: "--x",
    547          value: "blue",
    548          overridden: true,
    549        },
    550        {
    551          name: "color",
    552          value: "gold",
    553          overridden: true,
    554        },
    555      ],
    556    },
    557  ]);
    558 
    559  info(
    560    "Check that properties in inherited element-backed pseudo element rules are properly picked when using !important"
    561  );
    562  await selectNode("#vip article", inspector);
    563  await checkRuleViewContent(view, [
    564    {
    565      selector: `element`,
    566      selectorEditable: false,
    567      ancestorRulesData: null,
    568      declarations: [],
    569    },
    570    {
    571      header: "Inherited from details#vip::details-content",
    572    },
    573    {
    574      selector: `details#vip::details-content`,
    575      inherited: true,
    576      declarations: [{ name: "color", value: "red", overridden: true }],
    577    },
    578    {
    579      selector: `details#vip::details-content`,
    580      inherited: true,
    581      declarations: [{ name: "color", value: "blue !important" }],
    582    },
    583    {
    584      selector: `&::details-content`,
    585      ancestorRulesData: [`details {`],
    586      inherited: true,
    587      declarations: [
    588        { name: "--x", value: "tomato" },
    589        { name: "color", value: "dodgerblue", overridden: true },
    590      ],
    591    },
    592    {
    593      selector: `:where(body > details)::details-content`,
    594      inherited: true,
    595      declarations: [{ name: "color", value: "forestgreen", overridden: true }],
    596    },
    597    {
    598      header: "Inherited from details#vip",
    599    },
    600    {
    601      selector: `details`,
    602      inherited: true,
    603      declarations: [
    604        {
    605          name: "--x",
    606          value: "blue",
    607          overridden: true,
    608        },
    609        {
    610          name: "color",
    611          value: "gold",
    612          overridden: true,
    613        },
    614      ],
    615    },
    616  ]);
    617 });