tor-browser

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

browser_css_getInfo.js (7675B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const CSSCompleter = require("resource://devtools/client/shared/sourceeditor/css-autocompleter.js");
      7 
      8 const source = [
      9  ".devtools-toolbar {",
     10  "  -moz-appearance: none;",
     11  "           padding:4px 3px;border-bottom-width: 1px;",
     12  "  border-bottom-style: solid;",
     13  "}",
     14  "",
     15  "#devtools-menu.devtools-menulist,",
     16  ".devtools-toolbarbutton#devtools-menu {",
     17  "  -moz-appearance: none;",
     18  "  align-items: center;",
     19  "  min-width: 78px;",
     20  "  min-height: 22px;",
     21  "  text-shadow: 0 -1px 0 hsla(210,8%,5%,.45);",
     22  "  border: 1px solid hsla(210,8%,5%,.45);",
     23  "  border-radius: 3px;",
     24  "  background: linear-gradient(hsla(212,7%,57%,.35),",
     25  "              hsla(212,7%,57%,.1)) padding-box;",
     26  "  margin: 0 3px;",
     27  "  color: inherit;",
     28  "}",
     29  "",
     30  ".devtools-toolbarbutton > hbox.toolbarbutton-menubutton-button {",
     31  "  flex-direction: row;",
     32  "}",
     33  "",
     34  ".devtools-menulist:active,",
     35  "#devtools-toolbarbutton:focus {",
     36  "  outline: 1px dotted hsla(210,30%,85%,0.7);",
     37  "  outline-offset   :  -4px;",
     38  "}",
     39  "",
     40  ".devtools-toolbarbutton:not([label]) {",
     41  "  min-width: 32px;",
     42  "}",
     43  "",
     44  ".devtools-toolbarbutton:not([label]) > .toolbarbutton-text, .devtools-toolbar {",
     45  "  display: none;",
     46  "}",
     47  ".multiline > ",
     48  ".complex + ",
     49  "#selector {}",
     50 ].join("\n");
     51 
     52 // Format of test cases :
     53 // [
     54 //  {line, ch}, - The caret position at which the getInfo call should be made
     55 //  expectedState, - The expected state at the caret
     56 //  expectedSelector, - The expected selector for the state
     57 //  expectedProperty, - The expected property name for states value and property
     58 //  expectedValue, - If state is value, then the expected value
     59 // ]
     60 
     61 /* eslint-disable max-len */
     62 const tests = [
     63  [{ line: 0, ch: 13 }, CSSCompleter.CSS_STATE_SELECTOR, ".devtools-toolbar"],
     64  [
     65    { line: 8, ch: 13 },
     66    CSSCompleter.CSS_STATE_PROPERTY,
     67    [
     68      "#devtools-menu.devtools-menulist",
     69      ".devtools-toolbarbutton#devtools-menu ",
     70    ],
     71    "-moz-appearance",
     72  ],
     73  [
     74    { line: 28, ch: 25 },
     75    CSSCompleter.CSS_STATE_VALUE,
     76    [".devtools-menulist:active", "#devtools-toolbarbutton:focus "],
     77    "outline-offset",
     78    "-4px",
     79  ],
     80  [{ line: 4, ch: 1 }, CSSCompleter.CSS_STATE_NULL],
     81  [{ line: 5, ch: 0 }, CSSCompleter.CSS_STATE_NULL],
     82  [
     83    { line: 31, ch: 13 },
     84    CSSCompleter.CSS_STATE_SELECTOR,
     85    ".devtools-toolbarbutton:not([label])",
     86  ],
     87  [
     88    { line: 35, ch: 23 },
     89    CSSCompleter.CSS_STATE_SELECTOR,
     90    ".devtools-toolbarbutton:not([label]) > .toolbarbutton-text",
     91  ],
     92  [{ line: 35, ch: 70 }, CSSCompleter.CSS_STATE_SELECTOR, ".devtools-toolbar"],
     93  [
     94    { line: 27, ch: 14 },
     95    CSSCompleter.CSS_STATE_VALUE,
     96    [".devtools-menulist:active", "#devtools-toolbarbutton:focus "],
     97    "outline",
     98    "1px dotted hsla(210,30%,85%,0.7)",
     99  ],
    100  [
    101    { line: 16, ch: 16 },
    102    CSSCompleter.CSS_STATE_VALUE,
    103    [
    104      "#devtools-menu.devtools-menulist",
    105      ".devtools-toolbarbutton#devtools-menu ",
    106    ],
    107    "background",
    108    "linear-gradient(hsla(212,7%,57%,.35),\n              hsla(212,7%,57%,.1)) padding-box",
    109  ],
    110  [
    111    { line: 16, ch: 3 },
    112    CSSCompleter.CSS_STATE_VALUE,
    113    [
    114      "#devtools-menu.devtools-menulist",
    115      ".devtools-toolbarbutton#devtools-menu ",
    116    ],
    117    "background",
    118    "linear-gradient(hsla(212,7%,57%,.35),\n              hsla(212,7%,57%,.1)) padding-box",
    119  ],
    120  [
    121    { line: 15, ch: 25 },
    122    CSSCompleter.CSS_STATE_VALUE,
    123    [
    124      "#devtools-menu.devtools-menulist",
    125      ".devtools-toolbarbutton#devtools-menu ",
    126    ],
    127    "background",
    128    "linear-gradient(hsla(212,7%,57%,.35),\n              hsla(212,7%,57%,.1)) padding-box",
    129  ],
    130  [
    131    { line: 38, ch: 5 },
    132    CSSCompleter.CSS_STATE_SELECTOR,
    133    ".multiline > \n.complex + \n#selector",
    134  ],
    135  [
    136    { line: 39, ch: 5 },
    137    CSSCompleter.CSS_STATE_SELECTOR,
    138    ".multiline > \n.complex + \n#selector",
    139  ],
    140  [
    141    { line: 40, ch: 5 },
    142    CSSCompleter.CSS_STATE_SELECTOR,
    143    ".multiline > \n.complex + \n#selector",
    144  ],
    145 ];
    146 /* eslint-enable max-len */
    147 
    148 const TEST_URI =
    149  "data:text/html;charset=UTF-8," +
    150  encodeURIComponent(
    151    [
    152      "<!DOCTYPE html>",
    153      "<html>",
    154      " <head>",
    155      "  <title>CSS contextual information tests.</title>",
    156      "  <style type='text/css'>",
    157      "#progress {",
    158      "  width: 500px; height: 30px;",
    159      "  border: 1px solid black;",
    160      "  position: relative",
    161      "}",
    162      "#progress div {",
    163      "  width: 0%; height: 100%;",
    164      "  background: green;",
    165      "  position: absolute;",
    166      "  z-index: -1; top: 0",
    167      "}",
    168      "#progress.failed div {",
    169      "  background: red !important;",
    170      "}",
    171      "#progress.failed:after {",
    172      "  content: 'Some tests failed';",
    173      "  color: white",
    174      "}",
    175      "#progress:before {",
    176      "  content: 'Running test ' attr(data-progress) ' of " +
    177        tests.length +
    178        "';",
    179      "  color: white;",
    180      "  text-shadow: 0 0 2px darkgreen;",
    181      "}",
    182      "  </style>",
    183      " </head>",
    184      " <body>",
    185      "  <h2>State machine tests for CSS autocompleter.</h2><br>",
    186      "  <div id='progress' data-progress='0'>",
    187      "   <div></div>",
    188      "  </div>",
    189      " </body>",
    190      " </html>",
    191    ].join("\n")
    192  );
    193 
    194 add_task(async function test() {
    195  const tab = await addTab(TEST_URI);
    196  const browser = tab.linkedBrowser;
    197 
    198  const completer = new CSSCompleter({
    199    cssProperties: getClientCssProperties(),
    200  });
    201  const matches = (arr, toCheck) => !arr.some((x, i) => x != toCheck[i]);
    202  const checkState = (expected, actual) => {
    203    if (expected[0] == CSSCompleter.CSS_STATE_NULL && actual == null) {
    204      return true;
    205    } else if (
    206      expected[0] == actual.state &&
    207      expected[0] == CSSCompleter.CSS_STATE_SELECTOR &&
    208      expected[1] == actual.selector
    209    ) {
    210      return true;
    211    } else if (
    212      expected[0] == actual.state &&
    213      expected[0] == CSSCompleter.CSS_STATE_PROPERTY &&
    214      matches(expected[1], actual.selectors) &&
    215      expected[2] == actual.propertyName
    216    ) {
    217      return true;
    218    } else if (
    219      expected[0] == actual.state &&
    220      expected[0] == CSSCompleter.CSS_STATE_VALUE &&
    221      matches(expected[1], actual.selectors) &&
    222      expected[2] == actual.propertyName &&
    223      expected[3] == actual.value
    224    ) {
    225      return true;
    226    }
    227    return false;
    228  };
    229 
    230  let i = 0;
    231  for (const expected of tests) {
    232    ++i;
    233    const caret = expected.splice(0, 1)[0];
    234    await SpecialPowers.spawn(
    235      browser,
    236      [[i, tests.length]],
    237      function ([idx, len]) {
    238        const progress = content.document.getElementById("progress");
    239        const progressDiv = content.document.querySelector("#progress > div");
    240        progress.dataset.progress = idx;
    241        progressDiv.style.width = (100 * idx) / len + "%";
    242      }
    243    );
    244    const actual = completer.getInfoAt(source, caret);
    245    if (checkState(expected, actual)) {
    246      ok(true, "Test " + i + " passed. ");
    247    } else {
    248      ok(
    249        false,
    250        "Test " +
    251          i +
    252          " failed. Expected state : " +
    253          JSON.stringify(expected) +
    254          " " +
    255          "but found [" +
    256          JSON.stringify([
    257            actual.state,
    258            actual.selector || actual.selectors,
    259            actual.propertyName,
    260            actual.value,
    261          ]) +
    262          "."
    263      );
    264      await SpecialPowers.spawn(browser, [], function () {
    265        const progress = content.document.getElementById("progress");
    266        progress.classList.add("failed");
    267      });
    268    }
    269  }
    270  gBrowser.removeCurrentTab();
    271 });