tor-browser

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

browser_rules_style-editor-link.js (8275B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 // Test the links from the rule-view to the styleeditor
      7 
      8 const STYLESHEET_DATA_URL_CONTENTS = `#first {
      9 color: blue
     10 }`;
     11 const STYLESHEET_DATA_URL = `data:text/css,${encodeURIComponent(
     12  STYLESHEET_DATA_URL_CONTENTS
     13 )}`;
     14 
     15 const EXTERNAL_STYLESHEET_FILE_NAME = "doc_style_editor_link.css";
     16 const EXTERNAL_STYLESHEET_URL = URL_ROOT_SSL + EXTERNAL_STYLESHEET_FILE_NAME;
     17 
     18 const DOCUMENT_HTML = encodeURIComponent(`
     19  <html>
     20    <head>
     21      <title>Rule view style editor link test</title>
     22      <style type="text/css">
     23        html { color: #000000; }
     24        div { font-variant: small-caps; color: #000000; }
     25        .nomatches {color: #ff0000;}
     26      </style>
     27      <style>
     28        div { font-weight: bold; }
     29      </style>
     30      <link rel="stylesheet" type="text/css" href="${STYLESHEET_DATA_URL}">
     31      <link rel="stylesheet" type="text/css" href="${EXTERNAL_STYLESHEET_URL}">
     32    </head>
     33    <body>
     34      <div id="first" style="margin: 10em;font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">
     35        <h1>Some header text</h1>
     36        <p id="salutation" style="font-size: 12pt">hi.</p>
     37        <p id="body" style="font-size: 12pt">I am a test-case. This text exists
     38        solely to provide some things to
     39        <span style="color: yellow" class="highlight">
     40        highlight</span> and <span style="font-weight: bold">count</span>
     41        style list-items in the box at right. If you are reading this,
     42        you should go do something else instead. Maybe read a book. Or better
     43        yet, write some test-cases for another bit of code.
     44        <span style="font-style: italic">some text</span></p>
     45        <p id="closing">more text</p>
     46        <p>even more text</p>
     47      </div>
     48    </body>
     49  </html>
     50 `);
     51 
     52 const DOCUMENT_DATA_URL = "data:text/html;charset=utf-8," + DOCUMENT_HTML;
     53 const EXAMPLE_ORG_DOCUMENT_URL =
     54  "https://example.org/document-builder.sjs?html=" + DOCUMENT_HTML;
     55 
     56 add_task(async function () {
     57  await addTab(DOCUMENT_DATA_URL);
     58  const { toolbox, inspector, view } = await openRuleView();
     59 
     60  await testAllStylesheets(inspector, view, toolbox);
     61 
     62  info("Navigate to the example.org document");
     63  await navigateTo(EXAMPLE_ORG_DOCUMENT_URL);
     64  await testAllStylesheets(inspector, view, toolbox);
     65 });
     66 
     67 add_task(async function () {
     68  info("Check that link to the style editor works after tab reload");
     69  await addTab(EXAMPLE_ORG_DOCUMENT_URL);
     70  const { toolbox, inspector, view } = await openRuleView();
     71 
     72  info("Reload the example.org document");
     73  // Use navigateTo as it waits for the inspector to be ready.
     74  await navigateTo(EXAMPLE_ORG_DOCUMENT_URL);
     75  await testAllStylesheets(inspector, view, toolbox);
     76 });
     77 
     78 async function testAllStylesheets(inspector, view, toolbox) {
     79  await selectNode("div", inspector);
     80  await testRuleViewLinkLabel(view);
     81  await testDisabledStyleEditor(view, toolbox);
     82  await testFirstInlineStyleSheet(view, toolbox);
     83  await testSecondInlineStyleSheet(view, toolbox);
     84  await testExternalStyleSheet(view, toolbox);
     85 
     86  info("Switch back to the inspector panel");
     87  await toolbox.selectTool("inspector");
     88  await selectNode("body", inspector);
     89 }
     90 
     91 async function testFirstInlineStyleSheet(view, toolbox) {
     92  info("Testing inline stylesheet");
     93 
     94  info("Listening for toolbox switch to the styleeditor");
     95  const onSwitch = waitForStyleEditor(toolbox);
     96 
     97  info("Clicking an inline stylesheet");
     98  clickLinkByIndex(view, 4);
     99  const editor = await onSwitch;
    100 
    101  ok(true, "Switched to the style-editor panel in the toolbox");
    102 
    103  await validateStyleEditorSheet(toolbox, editor, 0);
    104 }
    105 
    106 async function testSecondInlineStyleSheet(view, toolbox) {
    107  info("Testing second inline stylesheet");
    108 
    109  const styleEditorPanel = toolbox.getCurrentPanel();
    110  const onEditorSelected = styleEditorPanel.UI.once("editor-selected");
    111 
    112  info("Switching back to the inspector panel in the toolbox");
    113  await toolbox.selectTool("inspector");
    114  const onToolSelected = toolbox.once("styleeditor-selected");
    115 
    116  info("Clicking on second inline stylesheet link");
    117  clickLinkByIndex(view, 3);
    118 
    119  info("Wait for the stylesheet editor to be selected");
    120  const editor = await onEditorSelected;
    121  await onToolSelected;
    122 
    123  is(
    124    toolbox.currentToolId,
    125    "styleeditor",
    126    "The style editor is selected again"
    127  );
    128  await validateStyleEditorSheet(toolbox, editor, 1);
    129 }
    130 
    131 async function testExternalStyleSheet(view, toolbox) {
    132  info("Testing external stylesheet");
    133  const styleEditorPanel = toolbox.getCurrentPanel();
    134  const onEditorSelected = styleEditorPanel.UI.once("editor-selected");
    135 
    136  info("Switching back to the inspector panel in the toolbox");
    137  await toolbox.selectTool("inspector");
    138  const onToolSelected = toolbox.once("styleeditor-selected");
    139 
    140  info("Clicking on an external stylesheet link");
    141  clickLinkByIndex(view, 1);
    142 
    143  info("Wait for the stylesheet editor to be selected");
    144  const editor = await onEditorSelected;
    145  await onToolSelected;
    146 
    147  is(
    148    toolbox.currentToolId,
    149    "styleeditor",
    150    "The style editor is selected again"
    151  );
    152  await validateStyleEditorSheet(toolbox, editor, 2);
    153 }
    154 
    155 async function validateStyleEditorSheet(toolbox, editor, expectedSheetIndex) {
    156  info("validating style editor stylesheet");
    157  is(
    158    editor.styleSheet.styleSheetIndex,
    159    expectedSheetIndex,
    160    "loaded stylesheet index matches document stylesheet"
    161  );
    162 
    163  const href = editor.styleSheet.href || editor.styleSheet.nodeHref;
    164 
    165  const expectedHref = await SpecialPowers.spawn(
    166    gBrowser.selectedBrowser,
    167    [expectedSheetIndex],
    168    _expectedSheetIndex => {
    169      return (
    170        content.document.styleSheets[_expectedSheetIndex].href ||
    171        content.document.location.href
    172      );
    173    }
    174  );
    175 
    176  is(href, expectedHref, "loaded stylesheet href matches document stylesheet");
    177 }
    178 
    179 async function testDisabledStyleEditor(view, toolbox) {
    180  info("Testing with the style editor disabled");
    181 
    182  info("Switching to the inspector panel in the toolbox");
    183  await toolbox.selectTool("inspector");
    184 
    185  info("Disabling the style editor");
    186  Services.prefs.setBoolPref("devtools.styleeditor.enabled", false);
    187  gDevTools.emit("tool-unregistered", "styleeditor");
    188 
    189  info("Clicking on a link");
    190  testUnselectableRuleViewLink(view, 1);
    191  clickLinkByIndex(view, 1);
    192  // Wait for a bit just to make sure the click didn't had an impact
    193  await wait(2000);
    194 
    195  is(toolbox.currentToolId, "inspector", "The click should have no effect");
    196 
    197  info("Enabling the style editor");
    198  Services.prefs.setBoolPref("devtools.styleeditor.enabled", true);
    199  gDevTools.emit("tool-registered", "styleeditor");
    200 
    201  Services.prefs.clearUserPref("devtools.styleeditor.enabled");
    202 }
    203 
    204 async function testRuleViewLinkLabel(view) {
    205  info("Checking the data URL link label");
    206  let link = await waitFor(() => getRuleViewLinkByIndex(view, 1));
    207  let labelElem = link.querySelector(".ruleview-rule-source-label");
    208  let value = labelElem.textContent;
    209  let tooltipText = labelElem.getAttribute("title");
    210 
    211  is(
    212    value,
    213    STYLESHEET_DATA_URL_CONTENTS + ":1",
    214    "Rule view data URL stylesheet display value matches contents"
    215  );
    216  is(
    217    tooltipText,
    218    `View source in Style Editor → ${STYLESHEET_DATA_URL}:1`,
    219    "Rule view data URL stylesheet tooltip text matches the full URI path"
    220  );
    221 
    222  info("Checking the external link label");
    223  link = await waitFor(() => getRuleViewLinkByIndex(view, 2));
    224  labelElem = link.querySelector(".ruleview-rule-source-label");
    225  value = labelElem.textContent;
    226  tooltipText = labelElem.getAttribute("title");
    227 
    228  is(
    229    value,
    230    `${EXTERNAL_STYLESHEET_FILE_NAME}:1`,
    231    "Rule view external stylesheet display value matches filename and line number"
    232  );
    233  is(
    234    tooltipText,
    235    `View source in Style Editor → ${EXTERNAL_STYLESHEET_URL}:1`,
    236    "Rule view external stylesheet tooltip text matches the full URI path"
    237  );
    238 }
    239 
    240 function testUnselectableRuleViewLink(view, index) {
    241  const link = getRuleViewLinkByIndex(view, index);
    242  const unselectable = link.hasAttribute("unselectable");
    243 
    244  ok(unselectable, "Rule view is unselectable");
    245 }
    246 
    247 function clickLinkByIndex(view, index) {
    248  const link = getRuleViewLinkByIndex(view, index);
    249  link.scrollIntoView();
    250  link.click();
    251 }