tor-browser

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

devices.js (4694B)


      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 { LocalizationHelper } = require("resource://devtools/shared/l10n.js");
      8 const L10N = new LocalizationHelper(
      9  "devtools/client/locales/device.properties"
     10 );
     11 
     12 const { RemoteSettings } = ChromeUtils.importESModule(
     13  "resource://services-settings/remote-settings.sys.mjs"
     14 );
     15 
     16 loader.lazyRequireGetter(
     17  this,
     18  "asyncStorage",
     19  "resource://devtools/shared/async-storage.js"
     20 );
     21 
     22 const LOCAL_DEVICES = "devtools.devices.local";
     23 
     24 /* This is a catalog of common web-enabled devices and their properties,
     25 * intended for (mobile) device emulation.
     26 *
     27 * The properties of a device are:
     28 * - name: brand and model(s).
     29 * - width: viewport width.
     30 * - height: viewport height.
     31 * - pixelRatio: ratio from viewport to physical screen pixels.
     32 * - userAgent: UA string of the device's browser.
     33 * - touch: whether it has a touch screen.
     34 * - os: default OS, such as "ios", "fxos", "android".
     35 *
     36 * The device types are:
     37 *   ["phones", "tablets", "laptops", "televisions", "consoles", "watches"].
     38 *
     39 * To propose new devices for the shared catalog, see
     40 * https://firefox-source-docs.mozilla.org/devtools/responsive/devices.html#adding-and-removing-devices.
     41 *
     42 * You can easily add more devices to this catalog from your own code (e.g. an
     43 * addon) like so:
     44 *
     45 *   var myPhone = { name: "My Phone", ... };
     46 *   require("devtools/client/shared/devices").addDevice(myPhone, "phones");
     47 */
     48 
     49 // Local devices catalog that addons can add to.
     50 let localDevices;
     51 let localDevicesLoaded = false;
     52 
     53 /**
     54 * Load local devices from storage.
     55 */
     56 async function loadLocalDevices() {
     57  if (localDevicesLoaded) {
     58    return;
     59  }
     60  let devicesJSON = await asyncStorage.getItem(LOCAL_DEVICES);
     61  if (!devicesJSON) {
     62    devicesJSON = "{}";
     63  }
     64  localDevices = JSON.parse(devicesJSON);
     65  localDevicesLoaded = true;
     66 }
     67 
     68 /**
     69 * Add a device to the local catalog.
     70 * Returns `true` if the device is added, `false` otherwise.
     71 */
     72 async function addDevice(device, type = "phones") {
     73  await loadLocalDevices();
     74  let list = localDevices[type];
     75  if (!list) {
     76    list = localDevices[type] = [];
     77  }
     78 
     79  // Ensure the new device is has a unique name
     80  const exists = list.some(entry => entry.name == device.name);
     81  if (exists) {
     82    return false;
     83  }
     84 
     85  list.push(Object.assign({}, device));
     86  await asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
     87 
     88  return true;
     89 }
     90 
     91 /**
     92 * Edit a device from the local catalog.
     93 * Returns `true` if the device is edited, `false` otherwise.
     94 */
     95 async function editDevice(oldDevice, newDevice, type = "phones") {
     96  await loadLocalDevices();
     97  const list = localDevices[type];
     98  if (!list) {
     99    return false;
    100  }
    101 
    102  const index = list.findIndex(entry => entry.name == oldDevice.name);
    103  if (index == -1) {
    104    return false;
    105  }
    106 
    107  // Replace old device info with new one
    108  list.splice(index, 1, newDevice);
    109  await asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
    110 
    111  return true;
    112 }
    113 
    114 /**
    115 * Remove a device from the local catalog.
    116 * Returns `true` if the device is removed, `false` otherwise.
    117 */
    118 async function removeDevice(device, type = "phones") {
    119  await loadLocalDevices();
    120  const list = localDevices[type];
    121  if (!list) {
    122    return false;
    123  }
    124 
    125  const index = list.findIndex(entry => entry.name == device.name);
    126  if (index == -1) {
    127    return false;
    128  }
    129 
    130  list.splice(index, 1);
    131  await asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
    132 
    133  return true;
    134 }
    135 
    136 /**
    137 * Remove all local devices.  Useful to clear everything when testing.
    138 */
    139 async function removeLocalDevices() {
    140  await asyncStorage.removeItem(LOCAL_DEVICES);
    141  localDevices = {};
    142 }
    143 
    144 /**
    145 * Get the complete devices catalog.
    146 */
    147 async function getDevices() {
    148  const records = await RemoteSettings("devtools-devices").get();
    149  const devicesByType = new Map();
    150  for (const record of records) {
    151    const { type } = record;
    152    if (!devicesByType.has(type)) {
    153      devicesByType.set(type, []);
    154    }
    155    devicesByType.get(type).push(record);
    156  }
    157 
    158  await loadLocalDevices();
    159  for (const type in localDevices) {
    160    if (!devicesByType.has(type)) {
    161      devicesByType.set(type, []);
    162    }
    163    devicesByType.get(type).push(...localDevices[type]);
    164  }
    165  return devicesByType;
    166 }
    167 
    168 /**
    169 * Get the localized string for a device type.
    170 */
    171 function getDeviceString(deviceType) {
    172  return L10N.getStr("device." + deviceType);
    173 }
    174 
    175 module.exports = {
    176  addDevice,
    177  editDevice,
    178  removeDevice,
    179  removeLocalDevices,
    180  getDevices,
    181  getDeviceString,
    182 };