tor-browser

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

browser-pagestyle.js (4198B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
      2 * This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 var gPageStyleMenu = {
      7  _getStyleSheetInfo(browser) {
      8    let actor =
      9      browser.browsingContext.currentWindowGlobal?.getActor("PageStyle");
     10    let styleSheetInfo;
     11    if (actor) {
     12      styleSheetInfo = actor.getSheetInfo();
     13    } else {
     14      // Fallback if the actor is missing or we don't have a window global.
     15      // It's unlikely things will work well but let's be optimistic,
     16      // rather than throwing exceptions immediately.
     17      styleSheetInfo = {
     18        filteredStyleSheets: [],
     19        preferredStyleSheetSet: true,
     20      };
     21    }
     22    return styleSheetInfo;
     23  },
     24 
     25  fillPopup(menuPopup) {
     26    let styleSheetInfo = this._getStyleSheetInfo(gBrowser.selectedBrowser);
     27    var noStyle = menuPopup.firstElementChild;
     28    var persistentOnly = noStyle.nextElementSibling;
     29    var sep = persistentOnly.nextElementSibling;
     30    while (sep.nextElementSibling) {
     31      menuPopup.removeChild(sep.nextElementSibling);
     32    }
     33 
     34    let styleSheets = styleSheetInfo.filteredStyleSheets;
     35    var currentStyleSheets = {};
     36    var styleDisabled =
     37      !!gBrowser.selectedBrowser.browsingContext?.authorStyleDisabledDefault;
     38    var haveAltSheets = false;
     39    var altStyleSelected = false;
     40 
     41    for (let currentStyleSheet of styleSheets) {
     42      if (!currentStyleSheet.disabled) {
     43        altStyleSelected = true;
     44      }
     45 
     46      haveAltSheets = true;
     47 
     48      let lastWithSameTitle = null;
     49      if (currentStyleSheet.title in currentStyleSheets) {
     50        lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
     51      }
     52 
     53      if (!lastWithSameTitle) {
     54        let menuItem = document.createXULElement("menuitem");
     55        menuItem.setAttribute("type", "radio");
     56        menuItem.setAttribute("label", currentStyleSheet.title);
     57        menuItem.setAttribute("data", currentStyleSheet.title);
     58        menuItem.toggleAttribute(
     59          "checked",
     60          !currentStyleSheet.disabled && !styleDisabled
     61        );
     62        menuItem.addEventListener("command", event =>
     63          this.switchStyleSheet(event.currentTarget.getAttribute("data"))
     64        );
     65        menuPopup.appendChild(menuItem);
     66        currentStyleSheets[currentStyleSheet.title] = menuItem;
     67      } else if (currentStyleSheet.disabled) {
     68        lastWithSameTitle.removeAttribute("checked");
     69      }
     70    }
     71 
     72    noStyle.toggleAttribute("checked", styleDisabled);
     73    persistentOnly.toggleAttribute(
     74      "checked",
     75      !altStyleSelected && !styleDisabled
     76    );
     77    persistentOnly.hidden = styleSheetInfo.preferredStyleSheetSet
     78      ? haveAltSheets
     79      : false;
     80    sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
     81  },
     82 
     83  /**
     84   * Send a message to all PageStyleParents by walking the BrowsingContext tree.
     85   *
     86   * @param message
     87   *        The string message to send to each PageStyleChild.
     88   * @param data
     89   *        The data to send to each PageStyleChild within the message.
     90   */
     91  _sendMessageToAll(message, data) {
     92    let contextsToVisit = [gBrowser.selectedBrowser.browsingContext];
     93    while (contextsToVisit.length) {
     94      let currentContext = contextsToVisit.pop();
     95      let global = currentContext.currentWindowGlobal;
     96 
     97      if (!global) {
     98        continue;
     99      }
    100 
    101      let actor = global.getActor("PageStyle");
    102      actor.sendAsyncMessage(message, data);
    103 
    104      contextsToVisit.push(...currentContext.children);
    105    }
    106  },
    107 
    108  /**
    109   * Switch the stylesheet of all documents in the current browser.
    110   *
    111   * @param title The title of the stylesheet to switch to.
    112   */
    113  switchStyleSheet(title) {
    114    let sheetData = this._getStyleSheetInfo(gBrowser.selectedBrowser);
    115    for (let sheet of sheetData.filteredStyleSheets) {
    116      sheet.disabled = sheet.title !== title;
    117    }
    118    this._sendMessageToAll("PageStyle:Switch", { title });
    119  },
    120 
    121  /**
    122   * Disable all stylesheets. Called with View > Page Style > No Style.
    123   */
    124  disableStyle() {
    125    this._sendMessageToAll("PageStyle:Disable", {});
    126  },
    127 };