tor-browser

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

compatibility-user-settings.js (4566B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const { RemoteSettings } = ChromeUtils.importESModule(
      8  "resource://services-settings/remote-settings.sys.mjs"
      9 );
     10 
     11 loader.lazyRequireGetter(
     12  this,
     13  ["TARGET_BROWSER_ID", "TARGET_BROWSER_STATUS", "TARGET_BROWSER_PREF"],
     14  "resource://devtools/shared/compatibility/constants.js",
     15  true
     16 );
     17 
     18 class TargetBrowserFilter {
     19  async filterEntry(record) {
     20    if (
     21      !TARGET_BROWSER_ID.includes(record.browserid) ||
     22      !TARGET_BROWSER_STATUS.includes(record.status)
     23    ) {
     24      return null;
     25    }
     26    return {
     27      id: record.browserid,
     28      name: record.name,
     29      version: record.version,
     30      status: record.status,
     31    };
     32  }
     33 }
     34 
     35 /**
     36 * Returns the full list of browsers in the RemoteSetting devtools-compatibility-browsers
     37 * collection (which is a flat copy of MDN compat data), sorted by browser and version.
     38 *
     39 * @returns Promise<Array<Object>> : Objects in the array have the following shape:
     40 *          - {string} id: The browser id (e.g. `firefox`,`safari_ios`). Should be one of TARGET_BROWSER_ID
     41 *          - {string} name: The browser display name (e.g. `Firefox`,`Safari for IOS`, …)
     42 *          - {string} version: The browser version (e.g. `99`,`15.3`, `1.0.4`, …)
     43 *          - {string} status: The browser status (e.g. `current`,`beta`, …). Should be one of TARGET_BROWSER_STATUS
     44 */
     45 async function getBrowsersList() {
     46  const records = await RemoteSettings("devtools-compatibility-browsers", {
     47    filterCreator: async () => new TargetBrowserFilter(),
     48  }).get();
     49 
     50  const numericCollator = new Intl.Collator([], { numeric: true });
     51  records.sort((a, b) => {
     52    if (a.id == b.id) {
     53      return numericCollator.compare(a.version, b.version);
     54    }
     55    return a.id > b.id ? 1 : -1;
     56  });
     57 
     58  // MDN compat data might have browser data that have the same id and status.
     59  // e.g. https://github.com/mdn/browser-compat-data/commit/53453400ecb2a85e7750d99e2e0a1611648d1d56#diff-31a16f09157f13354db27821261604aa
     60  // In this case, only keep the newer version to keep uniqueness by id and status.
     61  // This needs to be done after sorting since we rely on the order of the records.
     62  return records.filter((record, index, arr) => {
     63    const nextRecord = arr[index + 1];
     64    // If the next record in the array is the same browser and has the same status, filter
     65    // out this one since it's a lower version.
     66    if (
     67      nextRecord &&
     68      record.id === nextRecord.id &&
     69      record.status === nextRecord.status
     70    ) {
     71      return false;
     72    }
     73 
     74    return true;
     75  });
     76 }
     77 
     78 /**
     79 * Returns the list of browsers for which we should check compatibility issues.
     80 *
     81 * @returns Promise<Array<Object>> : Objects in the array have the following shape:
     82 *          - {string} id: The browser id (e.g. `firefox`,`safari_ios`). Should be one of TARGET_BROWSER_ID
     83 *          - {string} name: The browser display name (e.g. `Firefox`,`Safari for IOS`, …)
     84 *          - {string} version: The browser version (e.g. `99`,`15.3`, `1.0.4`, …)
     85 *          - {string} status: The browser status (e.g. `current`,`beta`, …). Should be one of TARGET_BROWSER_STATUS
     86 */
     87 async function getTargetBrowsers() {
     88  const targetsString = Services.prefs.getCharPref(TARGET_BROWSER_PREF, "");
     89  const browsers = await getBrowsersList();
     90 
     91  // If not value are stored in the pref, it means the user did not chose specific browsers,
     92  // so we need to return the full list.
     93  if (!targetsString) {
     94    return browsers;
     95  }
     96 
     97  const selectedBrowsersAndStatuses = JSON.parse(targetsString);
     98  return browsers.filter(
     99    browser =>
    100      !!selectedBrowsersAndStatuses.find(
    101        ({ id, status }) => browser.id == id && browser.status == status
    102      )
    103  );
    104 }
    105 
    106 /**
    107 * Store the list of browser id and status that should be used for checking compatibility
    108 * issues.
    109 *
    110 * @param {object[]} browsers
    111 * @param {string} browsers[].id: The browser id. Should be one of TARGET_BROWSER_ID
    112 * @param {string} browsers[].status: The browser status. Should be one of TARGET_BROWSER_STATUS
    113 */
    114 function setTargetBrowsers(browsers) {
    115  Services.prefs.setCharPref(
    116    TARGET_BROWSER_PREF,
    117    JSON.stringify(
    118      // Only store the id and the status
    119      browsers.map(browser => ({
    120        id: browser.id,
    121        status: browser.status,
    122      }))
    123    )
    124  );
    125 }
    126 
    127 module.exports = {
    128  getBrowsersList,
    129  getTargetBrowsers,
    130  setTargetBrowsers,
    131 };