tor-browser

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

browser_computed_matched-selectors-order.js (28204B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Tests for the order of matched selector in the computed view.
      7 const TEST_URI = URL_ROOT + "doc_matched_selectors.html";
      8 
      9 add_task(async function () {
     10  await pushPref("layout.css.starting-style-at-rules.enabled", true);
     11  await addTab(TEST_URI);
     12  const { inspector, view } = await openComputedView();
     13 
     14  const checkMatchedSelectors = options =>
     15    checkBackgroundColorMatchedSelectors(inspector, view, options);
     16 
     17  info("matching rules with different specificity");
     18  await checkMatchedSelectors({
     19    elementAttributes: {
     20      id: "specificity",
     21      class: "mySection",
     22    },
     23    style: `
     24      #specificity.mySection {
     25        --spec_highest: var(--winning-color);
     26        background-color: var(--spec_highest);
     27      }
     28      #specificity {
     29        background-color: var(--spec_lowest);
     30      }`,
     31    expectedMatchedSelectors: [
     32      // Higher specificity wins
     33      { selector: "#specificity.mySection", value: "var(--spec_highest)" },
     34      { selector: "#specificity", value: "var(--spec_lowest)" },
     35    ],
     36  });
     37 
     38  info("matching rules with same specificity");
     39  await checkMatchedSelectors({
     40    elementAttributes: {
     41      id: "order-of-appearance",
     42    },
     43    style: `
     44      #order-of-appearance {
     45        background-color: var(--appearance-order_first);
     46      }
     47      #order-of-appearance {
     48        --appearance-order_second: var(--winning-color);
     49        background-color: var(--appearance-order_second);
     50      }`,
     51    expectedMatchedSelectors: [
     52      // Last rule in stylesheet wins
     53      {
     54        selector: "#order-of-appearance",
     55        value: "var(--appearance-order_second)",
     56      },
     57      {
     58        selector: "#order-of-appearance",
     59        value: "var(--appearance-order_first)",
     60      },
     61    ],
     62  });
     63 
     64  info("matching rules on element with style attribute");
     65  await checkMatchedSelectors({
     66    elementAttributes: {
     67      id: "style-attr",
     68      style: "background-color: var(--style-attr_in-attr)",
     69    },
     70    style: `
     71      main {
     72        --style-attr_in-attr: var(--winning-color);
     73      }
     74 
     75      #style-attr {
     76        background-color: var(--style-attr_in-rule);
     77      }
     78    `,
     79    expectedMatchedSelectors: [
     80      // style attribute wins
     81      { selector: "element", value: "var(--style-attr_in-attr)" },
     82      { selector: "#style-attr", value: "var(--style-attr_in-rule)" },
     83    ],
     84  });
     85 
     86  info("matching rules on different layers");
     87  await checkMatchedSelectors({
     88    elementAttributes: {
     89      id: "layers",
     90      class: "layers",
     91    },
     92    style: `
     93      @layer second {
     94        .layers {
     95          --layers_in-second: var(--winning-color);
     96          background-color: var(--layers_in-second);
     97        }
     98      }
     99      @layer first {
    100        #layers {
    101          background-color: var(--layers_in-first);
    102        }
    103      }
    104    `,
    105    expectedMatchedSelectors: [
    106      // rule in last declared layer wins
    107      { selector: ".layers", value: "var(--layers_in-second)" },
    108      { selector: "#layers", value: "var(--layers_in-first)" },
    109    ],
    110  });
    111 
    112  info("matching rules on same layer, with same specificity");
    113  await checkMatchedSelectors({
    114    elementAttributes: {
    115      id: "same-layers-order-of-appearance",
    116    },
    117    style: `
    118      @layer second {
    119        #same-layers-order-of-appearance {
    120          background-color: var(--same-layers-appearance-order_first);
    121        }
    122 
    123        #same-layers-order-of-appearance {
    124          --same-layers-appearance-order_second: var(--winning-color);
    125          background-color: var(--same-layers-appearance-order_second);
    126        }
    127      }
    128    `,
    129    expectedMatchedSelectors: [
    130      // last rule in the layer wins
    131      {
    132        selector: "#same-layers-order-of-appearance",
    133        value: "var(--same-layers-appearance-order_second)",
    134      },
    135      {
    136        selector: "#same-layers-order-of-appearance",
    137        value: "var(--same-layers-appearance-order_first)",
    138      },
    139    ],
    140  });
    141 
    142  info("matching rules some in layers, some not");
    143  await checkMatchedSelectors({
    144    elementAttributes: {
    145      id: "in-layer-and-no-layer",
    146    },
    147    style: `
    148      @layer second {
    149        #in-layer-and-no-layer {
    150          background-color: var(--in-layer-and-no-layer_in-second);
    151        }
    152      }
    153 
    154      @layer first {
    155        #in-layer-and-no-layer {
    156          background-color: var(--in-layer-and-no-layer_in-first);
    157        }
    158      }
    159 
    160      #in-layer-and-no-layer {
    161        --in-layer-and-no-layer_no-layer: var(--winning-color);
    162        background-color: var(--in-layer-and-no-layer_no-layer);
    163      }`,
    164    expectedMatchedSelectors: [
    165      // rule not in layer wins
    166      {
    167        selector: "#in-layer-and-no-layer",
    168        value: "var(--in-layer-and-no-layer_no-layer)",
    169      },
    170      {
    171        selector: "#in-layer-and-no-layer",
    172        value: "var(--in-layer-and-no-layer_in-second)",
    173      },
    174      {
    175        selector: "#in-layer-and-no-layer",
    176        value: "var(--in-layer-and-no-layer_in-first)",
    177      },
    178    ],
    179  });
    180 
    181  info(
    182    "matching rules with different specificity and one property declared with !important"
    183  );
    184  await checkMatchedSelectors({
    185    elementAttributes: {
    186      id: "important-specificity",
    187      class: "myImportantSection",
    188    },
    189    style: `
    190      #important-specificity.myImportantSection {
    191        background-color: var(--important-spec_highest);
    192      }
    193      #important-specificity {
    194        --important-spec_lowest-important: var(--winning-color);
    195        background-color: var(--important-spec_lowest-important) !important;
    196      }`,
    197    expectedMatchedSelectors: [
    198      // lesser specificity, but value was set with !important
    199      {
    200        selector: "#important-specificity",
    201        value: "var(--important-spec_lowest-important)",
    202      },
    203      {
    204        selector: "#important-specificity.myImportantSection",
    205        value: "var(--important-spec_highest)",
    206      },
    207    ],
    208  });
    209 
    210  info(
    211    "matching rules with different specificity and all properties declared with !important"
    212  );
    213  await checkMatchedSelectors({
    214    elementAttributes: {
    215      id: "all-important-specificity",
    216      class: "myAllImportantSection",
    217    },
    218    style: `
    219      #all-important-specificity.myAllImportantSection {
    220        --all-important-spec_highest-important: var(--winning-color);
    221        background-color: var(--all-important-spec_highest-important) !important;
    222      }
    223      #all-important-specificity {
    224        background-color: var(--all-important-spec_lowest-important) !important;
    225      }`,
    226    expectedMatchedSelectors: [
    227      // all values !important, so highest specificity rule wins
    228      {
    229        selector: "#all-important-specificity.myAllImportantSection",
    230        value: "var(--all-important-spec_highest-important)",
    231      },
    232      {
    233        selector: "#all-important-specificity",
    234        value: "var(--all-important-spec_lowest-important)",
    235      },
    236    ],
    237  });
    238 
    239  info(
    240    "matching rules with same specificity and one property declared with !important"
    241  );
    242  await checkMatchedSelectors({
    243    elementAttributes: {
    244      id: "important-order-of-appearance",
    245    },
    246    style: `
    247      #important-order-of-appearance {
    248        --important-appearance-order_first-important: var(--winning-color);
    249        background-color: var(--important-appearance-order_first-important) !important;
    250      }
    251      #important-order-of-appearance {
    252        background-color: var(--important-appearance-order_second);
    253      }`,
    254    expectedMatchedSelectors: [
    255      // same specificity, but this value was set with !important
    256      {
    257        selector: "#important-order-of-appearance",
    258        value: "var(--important-appearance-order_first-important)",
    259      },
    260      {
    261        selector: "#important-order-of-appearance",
    262        value: "var(--important-appearance-order_second)",
    263      },
    264    ],
    265  });
    266 
    267  info(
    268    "matching rules with same specificity and all properties declared with !important"
    269  );
    270  await checkMatchedSelectors({
    271    elementAttributes: {
    272      id: "all-important-order-of-appearance",
    273    },
    274    style: `
    275      #all-important-order-of-appearance {
    276        background-color: var(--all-important-appearance-order_first-important) !important;
    277      }
    278      #all-important-order-of-appearance {
    279        --all-important-appearance-order_second-important: var(--winning-color);
    280        background-color: var(--all-important-appearance-order_second-important) !important;
    281      }`,
    282    expectedMatchedSelectors: [
    283      // all values !important, so latest rule in stylesheet wins
    284      {
    285        selector: "#all-important-order-of-appearance",
    286        value: "var(--all-important-appearance-order_second-important)",
    287      },
    288      {
    289        selector: "#all-important-order-of-appearance",
    290        value: "var(--all-important-appearance-order_first-important)",
    291      },
    292    ],
    293  });
    294 
    295  info(
    296    "matching rules with important property on element with style attribute"
    297  );
    298  await checkMatchedSelectors({
    299    elementAttributes: {
    300      id: "important-style-attr",
    301      style: "background-color: var(--important-style-attr_in-attr);",
    302    },
    303    style: `
    304      #important-style-attr {
    305        --important-style-attr_in-rule-important: var(--winning-color);
    306        background-color: var(--important-style-attr_in-rule-important) !important;
    307      }`,
    308    expectedMatchedSelectors: [
    309      // important property wins over style attribute
    310      {
    311        selector: "#important-style-attr",
    312        value: "var(--important-style-attr_in-rule-important)",
    313      },
    314      {
    315        selector: "element",
    316        value: "var(--important-style-attr_in-attr)",
    317      },
    318    ],
    319  });
    320 
    321  info(
    322    "matching rules with important property on element with style attribute and important value"
    323  );
    324  await checkMatchedSelectors({
    325    elementAttributes: {
    326      id: "all-important-style-attr",
    327      style:
    328        "background-color: var(--all-important-style-attr_in-attr-important) !important;",
    329    },
    330    style: `
    331      main {
    332        --all-important-style-attr_in-attr-important: var(--winning-color);
    333      }
    334      #all-important-style-attr {
    335        background-color: var(--all-important-style-attr_in-rule-important);
    336      }`,
    337    expectedMatchedSelectors: [
    338      // both values are important, so style attribute wins
    339      {
    340        selector: "element",
    341        value: "var(--all-important-style-attr_in-attr-important)",
    342      },
    343      {
    344        selector: "#all-important-style-attr",
    345        value: "var(--all-important-style-attr_in-rule-important)",
    346      },
    347    ],
    348  });
    349 
    350  info(
    351    "matching rules on different layer, with same specificity and important values"
    352  );
    353  await checkMatchedSelectors({
    354    elementAttributes: {
    355      id: "important-layers",
    356    },
    357    style: `
    358      @layer second {
    359        #important-layers {
    360          background-color: var(--important-layers_in-second);
    361        }
    362      }
    363      @layer first {
    364        #important-layers {
    365          --important-layers_in-first-important: var(--winning-color);
    366          background-color: var(--important-layers_in-first-important) !important;
    367        }
    368      }`,
    369    expectedMatchedSelectors: [
    370      // rule with important property wins
    371      {
    372        selector: "#important-layers",
    373        value: "var(--important-layers_in-first-important)",
    374      },
    375      {
    376        selector: "#important-layers",
    377        value: "var(--important-layers_in-second)",
    378      },
    379    ],
    380  });
    381 
    382  info(
    383    "matching rules on different layer, with same specificity and all important values"
    384  );
    385  await checkMatchedSelectors({
    386    elementAttributes: {
    387      id: "all-important-layers",
    388    },
    389    style: `
    390      @layer second {
    391        #all-important-layers {
    392          background-color: var(--all-important-layers_in-second-important) !important;
    393        }
    394      }
    395      @layer first {
    396        #all-important-layers {
    397          --all-important-layers_in-first-important: var(--winning-color);
    398          background-color: var(--all-important-layers_in-first-important) !important;
    399        }
    400      }`,
    401    expectedMatchedSelectors: [
    402      // all properties are important, rule from first declared layer wins
    403      {
    404        selector: "#all-important-layers",
    405        value: "var(--all-important-layers_in-first-important)",
    406      },
    407      {
    408        selector: "#all-important-layers",
    409        value: "var(--all-important-layers_in-second-important)",
    410      },
    411    ],
    412  });
    413 
    414  info(
    415    "matching rules on same layer, with same specificity and important values"
    416  );
    417  await checkMatchedSelectors({
    418    elementAttributes: {
    419      id: "important-same-layers-order-of-appearance",
    420    },
    421    style: `
    422      @layer second {
    423        #important-same-layers-order-of-appearance {
    424          --important-same-layers-appearance-order_first-important: var(--winning-color);
    425          background-color: var(--important-same-layers-appearance-order_first-important) !important;
    426        }
    427 
    428        #important-same-layers-order-of-appearance {
    429          background-color: var(--important-same-layers-appearance-order_second);
    430        }
    431      }`,
    432    expectedMatchedSelectors: [
    433      // rule with important property wins
    434      {
    435        selector: "#important-same-layers-order-of-appearance",
    436        value: "var(--important-same-layers-appearance-order_first-important)",
    437      },
    438      {
    439        selector: "#important-same-layers-order-of-appearance",
    440        value: "var(--important-same-layers-appearance-order_second)",
    441      },
    442    ],
    443  });
    444 
    445  info(
    446    "matching rules on same layer, with same specificity and all important values"
    447  );
    448  await checkMatchedSelectors({
    449    elementAttributes: {
    450      id: "all-important-same-layers-order-of-appearance",
    451    },
    452    style: `
    453      @layer second {
    454        #all-important-same-layers-order-of-appearance {
    455          background-color: var(--all-important-same-layers-appearance-order_first-important) !important;
    456        }
    457 
    458        #all-important-same-layers-order-of-appearance {
    459          --all-important-same-layers-appearance-order_second-important: var(--winning-color);
    460          background-color: var(--all-important-same-layers-appearance-order_second-important) !important;
    461        }
    462      }`,
    463    expectedMatchedSelectors: [
    464      // last rule with important property wins
    465      {
    466        selector: "#all-important-same-layers-order-of-appearance",
    467        value:
    468          "var(--all-important-same-layers-appearance-order_second-important)",
    469      },
    470      {
    471        selector: "#all-important-same-layers-order-of-appearance",
    472        value:
    473          "var(--all-important-same-layers-appearance-order_first-important)",
    474      },
    475    ],
    476  });
    477 
    478  info("matching rules ,some in layers, some not, important values in layers");
    479  await checkMatchedSelectors({
    480    elementAttributes: {
    481      id: "important-in-layer-and-no-layer",
    482    },
    483    style: `
    484      @layer second {
    485        #important-in-layer-and-no-layer {
    486          background-color: var(--important-in-layer-and-no-layer_in-second);
    487        }
    488      }
    489 
    490      @layer first {
    491        #important-in-layer-and-no-layer {
    492          --important-in-layer-and-no-layer_in-first-important: var(--winning-color);
    493          background-color: var(--important-in-layer-and-no-layer_in-first-important) !important;
    494        }
    495      }
    496 
    497      #important-in-layer-and-no-layer {
    498        background-color: var(--important-in-layer-and-no-layer_no-layer);
    499      }`,
    500    expectedMatchedSelectors: [
    501      // rule with important property wins
    502      {
    503        selector: "#important-in-layer-and-no-layer",
    504        value: "var(--important-in-layer-and-no-layer_in-first-important)",
    505      },
    506      // then rule not in layer
    507      {
    508        selector: "#important-in-layer-and-no-layer",
    509        value: "var(--important-in-layer-and-no-layer_no-layer)",
    510      },
    511      {
    512        selector: "#important-in-layer-and-no-layer",
    513        value: "var(--important-in-layer-and-no-layer_in-second)",
    514      },
    515    ],
    516  });
    517 
    518  info("matching rules ,some in layers, some not, all important values");
    519  await checkMatchedSelectors({
    520    elementAttributes: {
    521      id: "all-important-in-layer-and-no-layer",
    522    },
    523    style: `
    524      @layer second {
    525        #all-important-in-layer-and-no-layer {
    526          background-color: var(--all-important-in-layer-and-no-layer_in-second-important) !important;
    527        }
    528      }
    529 
    530      @layer first {
    531        #all-important-in-layer-and-no-layer {
    532          --all-important-in-layer-and-no-layer_in-first-important: var(--winning-color);
    533          background-color: var(--all-important-in-layer-and-no-layer_in-first-important) !important;
    534        }
    535      }
    536 
    537      #all-important-in-layer-and-no-layer {
    538        background-color: var(--all-important-in-layer-and-no-layer_no-layer-important) !important;
    539      }`,
    540    expectedMatchedSelectors: [
    541      // important properties in first declared layer wins
    542      {
    543        selector: "#all-important-in-layer-and-no-layer",
    544        value: "var(--all-important-in-layer-and-no-layer_in-first-important)",
    545      },
    546      // then following important rules in layers
    547      {
    548        selector: "#all-important-in-layer-and-no-layer",
    549        value: "var(--all-important-in-layer-and-no-layer_in-second-important)",
    550      },
    551      // then important rules not in layers
    552      {
    553        selector: "#all-important-in-layer-and-no-layer",
    554        value: "var(--all-important-in-layer-and-no-layer_no-layer-important)",
    555      },
    556    ],
    557  });
    558 
    559  info(
    560    "matching rules ,some in layers, some not, and style attribute all important values"
    561  );
    562  await checkMatchedSelectors({
    563    elementAttributes: {
    564      id: "all-important-in-layer-no-layer-style-attr",
    565      style:
    566        "background-color: var(--all-important-in-layer-no-layer-style-attr_in-attr-important) !important",
    567    },
    568    style: `
    569      main {
    570        --all-important-in-layer-no-layer-style-attr_in-attr-important: var(--winning-color);
    571      }
    572 
    573      @layer second {
    574        #all-important-in-layer-no-layer-style-attr {
    575          background-color: var(--all-important-in-layer-no-layer-style-attr_in-second-important) !important;
    576        }
    577      }
    578 
    579      @layer first {
    580        #all-important-in-layer-no-layer-style-attr {
    581          background-color: var(--all-important-in-layer-no-layer-style-attr_in-first-important) !important;
    582        }
    583      }
    584 
    585      #all-important-in-layer-no-layer-style-attr {
    586        background-color: var(--all-important-in-layer-no-layer-style-attr_no-layer-important) !important;
    587      }`,
    588    expectedMatchedSelectors: [
    589      // important properties in style attribute wins
    590      {
    591        selector: "element",
    592        value:
    593          "var(--all-important-in-layer-no-layer-style-attr_in-attr-important)",
    594      },
    595      // then important property in first declared layer
    596      {
    597        selector: "#all-important-in-layer-no-layer-style-attr",
    598        value:
    599          "var(--all-important-in-layer-no-layer-style-attr_in-first-important)",
    600      },
    601      // then following important property in layers
    602      {
    603        selector: "#all-important-in-layer-no-layer-style-attr",
    604        value:
    605          "var(--all-important-in-layer-no-layer-style-attr_in-second-important)",
    606      },
    607      // then important property not in layers
    608      {
    609        selector: "#all-important-in-layer-no-layer-style-attr",
    610        value:
    611          "var(--all-important-in-layer-no-layer-style-attr_no-layer-important)",
    612      },
    613    ],
    614  });
    615 
    616  info(
    617    "matching rules on same layer but different rules and all important values"
    618  );
    619  await checkMatchedSelectors({
    620    elementAttributes: {
    621      id: "all-important-same-layer-different-rule",
    622    },
    623    style: `
    624      @layer first {
    625        #all-important-same-layer-different-rule {
    626          background-color: var(--all-important-same-layer-different-rule_first-important) !important;
    627        }
    628      }
    629 
    630      @layer first {
    631        #all-important-same-layer-different-rule {
    632          --all-important-same-layer-different-rule_second-important: var(--winning-color);
    633          background-color: var(--all-important-same-layer-different-rule_second-important) !important;
    634        }
    635      }`,
    636    expectedMatchedSelectors: [
    637      // last rule for the layer with important property wins
    638      {
    639        selector: "#all-important-same-layer-different-rule",
    640        value:
    641          "var(--all-important-same-layer-different-rule_second-important)",
    642      },
    643      {
    644        selector: "#all-important-same-layer-different-rule",
    645        value: "var(--all-important-same-layer-different-rule_first-important)",
    646      },
    647    ],
    648  });
    649 
    650  info(
    651    "matching rules on same layer but different nested rules and all important values"
    652  );
    653  await checkMatchedSelectors({
    654    elementAttributes: {
    655      id: "all-important-same-nested-layer-different-rule",
    656    },
    657    style: `
    658      @layer first {
    659        @layer {
    660          @layer second {
    661            #all-important-same-nested-layer-different-rule {
    662              background-color: var(--all-important-same-nested-layer-different-rule_first-important) !important;
    663            }
    664          }
    665 
    666          @layer second {
    667            #all-important-same-nested-layer-different-rule {
    668              --all-important-same-nested-layer-different-rule_second-important: var(--winning-color);
    669              background-color: var(--all-important-same-nested-layer-different-rule_second-important) !important;
    670            }
    671          }
    672        }
    673      }`,
    674    expectedMatchedSelectors: [
    675      // last rule for the layer with important property wins
    676      {
    677        selector: "#all-important-same-nested-layer-different-rule",
    678        value:
    679          "var(--all-important-same-nested-layer-different-rule_second-important)",
    680      },
    681      {
    682        selector: "#all-important-same-nested-layer-different-rule",
    683        value:
    684          "var(--all-important-same-nested-layer-different-rule_first-important)",
    685      },
    686    ],
    687  });
    688 
    689  info("matching rules on different nameless layers and all important values");
    690  await checkMatchedSelectors({
    691    elementAttributes: {
    692      id: "all-important-different-nameless-layers",
    693    },
    694    style: `
    695      @layer {
    696        @layer first {
    697          #all-important-different-nameless-layers {
    698            --all-important-different-nameless-layers_first-important: var(--winning-color);
    699            background-color: var(--all-important-different-nameless-layers_first-important) !important;
    700          }
    701        }
    702      }
    703      @layer {
    704        @layer first {
    705          #all-important-different-nameless-layers {
    706            background-color: var(--all-important-different-nameless-layers_second-important) !important;
    707          }
    708        }
    709      }`,
    710    expectedMatchedSelectors: [
    711      // rule with important property in first declared layer wins
    712      {
    713        selector: "#all-important-different-nameless-layers",
    714        value: "var(--all-important-different-nameless-layers_first-important)",
    715      },
    716      {
    717        selector: "#all-important-different-nameless-layers",
    718        value:
    719          "var(--all-important-different-nameless-layers_second-important)",
    720      },
    721    ],
    722  });
    723 
    724  info("matching rules on different imported layers");
    725  // no provided style as rules are defined in doc_matched_selectors_imported_*.css
    726  await checkMatchedSelectors({
    727    elementAttributes: {
    728      id: "imported-layers",
    729    },
    730    expectedMatchedSelectors: [
    731      // rule in last declared layer wins
    732      {
    733        selector: "#imported-layers",
    734        value: "var(--imported-layers_in-anonymous-second)",
    735      },
    736      {
    737        selector: "#imported-layers",
    738        value: "var(--imported-layers_in-nested-importedSecond)",
    739      },
    740      {
    741        selector: "#imported-layers",
    742        value: "var(--imported-layers_in-anonymous-first)",
    743      },
    744      {
    745        selector: "#imported-layers",
    746        value: "var(--imported-layers_in-importedSecond)",
    747      },
    748      {
    749        selector: "#imported-layers",
    750        value: "var(--imported-layers_in-importedFirst-second)",
    751      },
    752      {
    753        selector: "#imported-layers",
    754        value: "var(--imported-layers_in-importedFirst-first)",
    755      },
    756    ],
    757  });
    758 
    759  info("matching rules on different imported layers all with important values");
    760  // no provided style as rules are defined in doc_matched_selectors_imported_*.css
    761  await checkMatchedSelectors({
    762    elementAttributes: {
    763      id: "all-important-imported-layers",
    764    },
    765    expectedMatchedSelectors: [
    766      // last important property in first declared layer wins
    767      {
    768        selector: "#all-important-imported-layers",
    769        value:
    770          "var(--all-important-imported-layers_in-importedFirst-second-important)",
    771      },
    772      // then earlier important property for first declared layer
    773      {
    774        selector: "#all-important-imported-layers",
    775        value:
    776          "var(--all-important-imported-layers_in-importedFirst-first-important)",
    777      },
    778      {
    779        selector: "#all-important-imported-layers",
    780        value:
    781          "var(--all-important-imported-layers_in-importedSecond-important)",
    782      },
    783      {
    784        selector: "#all-important-imported-layers",
    785        value:
    786          "var(--all-important-imported-layers_in-anonymous-first-important)",
    787      },
    788      {
    789        selector: "#all-important-imported-layers",
    790        value:
    791          "var(--all-important-imported-layers_in-nested-importedSecond-important)",
    792      },
    793      {
    794        selector: "#all-important-imported-layers",
    795        value:
    796          "var(--all-important-imported-layers_in-anonymous-second-important)",
    797      },
    798    ],
    799  });
    800 
    801  info("Check that attribute styles declarations are displayed");
    802  await selectNode("#align", inspector);
    803  await checkMatchedSelectorForProperty(view, {
    804    property: "text-align",
    805    expectedComputedValue: "left",
    806    expectedMatchedSelectors: [
    807      {
    808        selector: "element",
    809        value: "left",
    810      },
    811      {
    812        selector: "#align",
    813        value: "center",
    814      },
    815      {
    816        selector: "element attributes style",
    817        value: "-moz-right",
    818      },
    819    ],
    820  });
    821 
    822  await selectNode("#align-child", inspector);
    823  await checkMatchedSelectorForProperty(view, {
    824    property: "text-align",
    825    expectedComputedValue: "-moz-center",
    826    expectedMatchedSelectors: [
    827      {
    828        selector: "element attributes style",
    829        value: "-moz-center",
    830      },
    831      {
    832        selector: "#align",
    833        value: "left",
    834        match: false,
    835      },
    836      {
    837        selector: "#align",
    838        value: "center",
    839        match: false,
    840      },
    841      {
    842        selector: "#align attributes style",
    843        value: "-moz-right",
    844        match: false,
    845      },
    846    ],
    847  });
    848 });
    849 
    850 async function checkBackgroundColorMatchedSelectors(
    851  inspector,
    852  view,
    853  { elementAttributes, style, expectedMatchedSelectors }
    854 ) {
    855  const elementId = await SpecialPowers.spawn(
    856    gBrowser.selectedBrowser,
    857    [elementAttributes, style],
    858    (attr, _style) => {
    859      const sectionEl = content.document.createElement("section");
    860      for (const [name, value] of Object.entries(attr)) {
    861        sectionEl.setAttribute(name, value);
    862      }
    863 
    864      if (_style) {
    865        const styleEl = content.document.createElement("style");
    866        styleEl.innerText = _style;
    867        styleEl.setAttribute("id", `style-${sectionEl.id}`);
    868        content.document.head.append(styleEl);
    869      }
    870      content.document.querySelector("main").append(sectionEl);
    871 
    872      return sectionEl.id;
    873    }
    874  );
    875  const selector = `#${elementId}`;
    876  await selectNode(selector, inspector);
    877 
    878  const bgColorComputedValue = await getComputedStyleProperty(
    879    selector,
    880    null,
    881    "background-color"
    882  );
    883  is(
    884    bgColorComputedValue,
    885    "rgb(0, 0, 255)",
    886    `The created element does have a "blue" background-color`
    887  );
    888 
    889  await checkMatchedSelectorForProperty(view, {
    890    property: "background-color",
    891    expectedComputedValue: "rgb(0, 0, 255)",
    892    expectedMatchedSelectors,
    893  });
    894 
    895  // cleanup
    896  await SpecialPowers.spawn(gBrowser.selectedBrowser, [elementId], id => {
    897    // Remove added element and stylesheet
    898    content.document.getElementById(id).remove();
    899    // Some test cases don't insert a style element
    900    content.document.getElementById(`style-${id}`)?.remove();
    901  });
    902 }