tor-browser

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

browser_styleeditor_media_sidebar_links.js (5148B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 /**
      7 * Tests responsive mode links for `@media` sidebar width and height related
      8 * conditions.
      9 */
     10 
     11 loader.lazyRequireGetter(
     12  this,
     13  "ResponsiveUIManager",
     14  "resource://devtools/client/responsive/manager.js"
     15 );
     16 
     17 const TESTCASE_URI = TEST_BASE_HTTPS + "media-rules.html";
     18 const responsiveModeToggleClass = ".media-responsive-mode-toggle";
     19 
     20 add_task(async function () {
     21  // ensure that original RDM size is big enough so it doesn't match the
     22  // media queries by default.
     23  await pushPref("devtools.responsive.viewport.width", 1000);
     24  await pushPref("devtools.responsive.viewport.height", 1000);
     25 
     26  const { ui } = await openStyleEditorForURL(TESTCASE_URI);
     27 
     28  const editor = ui.editors[1];
     29  await openEditor(editor);
     30 
     31  const tab = gBrowser.selectedTab;
     32  testNumberOfLinks(editor);
     33  await testMediaLink(editor, tab, ui, 2, "width", 550);
     34  await testMediaLink(editor, tab, ui, 3, "height", 300);
     35 
     36  const onMediaChange = waitForManyEvents(ui, 1000);
     37  await closeRDM(tab);
     38 
     39  info("Wait for at-rules-list-changed events to settle on StyleEditorUI");
     40  await onMediaChange;
     41  doFinalChecks(editor);
     42 });
     43 
     44 function testNumberOfLinks(editor) {
     45  const sidebar = editor.details.querySelector(".stylesheet-sidebar");
     46  const conditions = sidebar.querySelectorAll(".at-rule-condition");
     47 
     48  info("Testing if media rules have the appropriate number of links");
     49  ok(
     50    !conditions[0].querySelector(responsiveModeToggleClass),
     51    "There should be no links in the first media rule."
     52  );
     53  ok(
     54    !conditions[1].querySelector(responsiveModeToggleClass),
     55    "There should be no links in the second media rule."
     56  );
     57  ok(
     58    conditions[2].querySelector(responsiveModeToggleClass),
     59    "There should be 1 responsive mode link in the media rule"
     60  );
     61  is(
     62    conditions[3].querySelectorAll(responsiveModeToggleClass).length,
     63    2,
     64    "There should be 2 responsive mode links in the media rule"
     65  );
     66 }
     67 
     68 async function testMediaLink(editor, tab, ui, itemIndex, type, value) {
     69  const sidebar = editor.details.querySelector(".stylesheet-sidebar");
     70  const conditions = sidebar.querySelectorAll(".at-rule-condition");
     71  const onRDMOpened = once(ui, "responsive-mode-opened");
     72 
     73  ok(
     74    sidebar
     75      .querySelectorAll(".at-rule-condition")
     76      [itemIndex].classList.contains("media-condition-unmatched"),
     77    `The ${type} condition is not matched when not in responsive mode`
     78  );
     79 
     80  info("Launching responsive mode");
     81  conditions[itemIndex].querySelector(responsiveModeToggleClass).click();
     82  await onRDMOpened;
     83  const rdmUI = ResponsiveUIManager.getResponsiveUIForTab(tab);
     84  await waitForResizeTo(rdmUI, type, value);
     85  rdmUI.transitionsEnabled = false;
     86 
     87  info("Wait for RDM ui to be fully loaded");
     88  await waitForRDMLoaded(rdmUI);
     89 
     90  // Ensure that the content has reflowed, which will ensure that all the
     91  // element classes are reported correctly.
     92  await promiseContentReflow(rdmUI);
     93 
     94  ok(
     95    ResponsiveUIManager.isActiveForTab(tab),
     96    "Responsive mode should be active."
     97  );
     98  await waitFor(() => {
     99    const el = sidebar.querySelectorAll(".at-rule-condition")[itemIndex];
    100    return !el.classList.contains("media-condition-unmatched");
    101  });
    102  ok(true, "media rule should now be matched after responsive mode is active");
    103 
    104  const dimension = (await getSizing(rdmUI))[type];
    105  is(dimension, value, `${type} should be properly set.`);
    106 }
    107 
    108 function doFinalChecks(editor) {
    109  const sidebar = editor.details.querySelector(".stylesheet-sidebar");
    110  let conditions = sidebar.querySelectorAll(".at-rule-condition");
    111  conditions = sidebar.querySelectorAll(".at-rule-condition");
    112  ok(
    113    conditions[2].classList.contains("media-condition-unmatched"),
    114    "The width condition should now be unmatched"
    115  );
    116  ok(
    117    conditions[3].classList.contains("media-condition-unmatched"),
    118    "The height condition should now be unmatched"
    119  );
    120 }
    121 
    122 /* Helpers */
    123 function waitForResizeTo(rdmUI, type, value) {
    124  return new Promise(resolve => {
    125    const onResize = data => {
    126      if (data[type] != value) {
    127        return;
    128      }
    129      rdmUI.off("content-resize", onResize);
    130      info(`Got content-resize to a ${type} of ${value}`);
    131      resolve();
    132    };
    133    info(`Waiting for content-resize to a ${type} of ${value}`);
    134    rdmUI.on("content-resize", onResize);
    135  });
    136 }
    137 
    138 function promiseContentReflow(ui) {
    139  return SpecialPowers.spawn(ui.getViewportBrowser(), [], async function () {
    140    return new Promise(resolve => {
    141      content.window.requestAnimationFrame(() => {
    142        content.window.requestAnimationFrame(resolve);
    143      });
    144    });
    145  });
    146 }
    147 
    148 async function getSizing(rdmUI) {
    149  const browser = rdmUI.getViewportBrowser();
    150  const sizing = await SpecialPowers.spawn(browser, [], async function () {
    151    return {
    152      width: content.innerWidth,
    153      height: content.innerHeight,
    154    };
    155  });
    156  return sizing;
    157 }
    158 
    159 function openEditor(editor) {
    160  getLinkFor(editor).click();
    161 
    162  return editor.getSourceEditor();
    163 }
    164 
    165 function getLinkFor(editor) {
    166  return editor.summary.querySelector(".stylesheet-name");
    167 }