tor-browser

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

test_inspector-inactive-property-helper.html (5542B)


      1 <!DOCTYPE HTML>
      2 <html>
      3  <head>
      4    <meta charset="utf-8">
      5    <title>Test for InactivePropertyHelper</title>
      6    <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
      7    <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
      8    <script type="application/javascript">
      9 "use strict";
     10 SimpleTest.waitForExplicitFinish();
     11 
     12 (async function() {
     13  const { require } = ChromeUtils.importESModule("resource://devtools/shared/loader/Loader.sys.mjs");
     14  const { getInactiveCssDataForProperty } = require("devtools/server/actors/utils/inactive-property-helper");
     15  const { DocumentWalker } = require("devtools/server/actors/inspector/document-walker");
     16 
     17  const CUSTOM_HIGHLIGHT_API = "dom.customHighlightAPI.enabled";
     18  const TEXT_FRAGMENTS = "dom.text_fragments.enabled";
     19 
     20  Services.prefs.setBoolPref(CUSTOM_HIGHLIGHT_API, true);
     21  Services.prefs.setBoolPref(TEXT_FRAGMENTS, true);
     22 
     23  SimpleTest.registerCleanupFunction(() => {
     24    Services.prefs.clearUserPref(CUSTOM_HIGHLIGHT_API);
     25    Services.prefs.clearUserPref(TEXT_FRAGMENTS);
     26  });
     27 
     28  const FOLDER = "./inactive-property-helper";
     29 
     30  // Each file should `export default` an array of objects, representing each test case.
     31  // A single test case is an object of the following shape:
     32  // - {String} info: a summary of the test case
     33  // - {String} property: the CSS property that should be tested
     34  // - {String|undefined} tagName: the tagName of the element we're going to test.
     35  //                               Optional only if there's a createTestElement property.
     36  // - {Function|undefined} createTestElement: A function that takes a node as a parameter
     37  //                                           where elements used for the test case will
     38  //                                           be appended. The function should return the
     39  //                                           element that will be passed to
     40  //                                           getInactiveCssDataForProperty.
     41  //                                           Optional only if there's a tagName property
     42  // - {Array<String>} rules: An array of the rules that will be applied on the element.
     43  //                          This can't be empty as getInactiveCssDataForProperty needs a rule.
     44  // - {Integer|undefined} ruleIndex: If there are multiples rules in `rules`, the index
     45  //                                  of the one that should be tested in getInactiveCssDataForProperty.
     46  // - {Boolean} isActive: should the property be active (e.g. getInactiveCssDataForProperty returns null).
     47  const testFiles = [
     48    "align-content.mjs",
     49    "at-position-try-rules.mjs",
     50    "anchor-name.mjs",
     51    "block-container-properties.mjs",
     52    "block-flex-grid-container-properties.mjs",
     53    "border-image.mjs",
     54    "border-spacing.mjs",
     55    "box-sizing.mjs",
     56    "column-span.mjs",
     57    "content-visibility.mjs",
     58    "cue-pseudo-element.mjs",
     59    "first-letter-pseudo-element.mjs",
     60    "first-line-pseudo-element.mjs",
     61    "flex-grid-item-properties.mjs",
     62    "float.mjs",
     63    "gap.mjs",
     64    "grid-container-properties.mjs",
     65    "grid-with-absolute-properties.mjs",
     66    "multicol-container-properties.mjs",
     67    "highlight-pseudo-elements.mjs",
     68    "margin-padding.mjs",
     69    "max-min-width-height.mjs",
     70    "place-items-content.mjs",
     71    "placeholder-pseudo-element.mjs",
     72    "positioned.mjs",
     73    "replaced-element-properties.mjs",
     74    "resize.mjs",
     75    "scroll-padding.mjs",
     76    "self-position-properties.mjs",
     77    "vertical-align.mjs",
     78    "table.mjs",
     79    "table-cell.mjs",
     80    "text-overflow.mjs",
     81    "text-wrap.mjs",
     82    "width-height-ruby.mjs",
     83  ].map(file => `${FOLDER}/${file}`);
     84 
     85  // Import all the test cases
     86  const tests =
     87    (await Promise.all(testFiles.map(f => import(f).then(data => data.default)))).flat();
     88 
     89  for (const {
     90    info: summary,
     91    property,
     92    tagName,
     93    createTestElement,
     94    pseudoElement,
     95    rules,
     96    ruleIndex,
     97    isActive,
     98    expectedMsgId,
     99  } of tests) {
    100    // Create an element which will contain the test elements.
    101    const main = document.createElement("main");
    102    document.firstElementChild.appendChild(main);
    103 
    104    // Apply the CSS rules to the document.
    105    const style = document.createElement("style");
    106    main.append(style);
    107    for (const dataRule of rules) {
    108      style.sheet.insertRule(dataRule);
    109    }
    110    const rule = style.sheet.cssRules[ruleIndex || 0];
    111 
    112    // Create the test elements
    113    let el;
    114    if (createTestElement) {
    115      el = createTestElement(main);
    116    } else {
    117      el = document.createElement(tagName);
    118      main.append(el);
    119 
    120      // When checking a pseudo element, we need to retrieve it, walking the DOM from
    121      // its "real" node.
    122      if (pseudoElement) {
    123        const walker = new DocumentWalker(
    124          el,
    125          el.ownerGlobal
    126        );
    127 
    128        const pseudoNodeName = `_moz_generated_content_${pseudoElement.replaceAll(":", "")}`;
    129        for (let next = walker.firstChild(); next; next = walker.nextSibling()) {
    130          if (next.nodeName === pseudoNodeName) {
    131            el = next;
    132            break;
    133          }
    134        }
    135      }
    136    }
    137 
    138    const inactiveCssData = getInactiveCssDataForProperty(el, getComputedStyle(el, pseudoElement), rule, property);
    139    is(inactiveCssData === null, isActive, summary);
    140    if (expectedMsgId) {
    141      is(inactiveCssData.msgId, expectedMsgId, `${summary} - returned expected msgId`);
    142    }
    143 
    144    main.remove();
    145  }
    146  SimpleTest.finish();
    147 })();
    148    </script>
    149  </head>
    150  <body></body>
    151 </html>