tor-browser

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

translationExceptions.js (6529B)


      1 /* -*- indent-tabs-mode: nil; js-indent-level: 4 -*- */
      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 // TODO (Bug 1817084) Remove this file when we disable the extension
      7 
      8 "use strict";
      9 
     10 const kPermissionType = "translate";
     11 const kLanguagesPref = "browser.translation.neverForLanguages";
     12 
     13 function Tree(aId, aData) {
     14  this._data = aData;
     15  this._tree = document.getElementById(aId);
     16  this._tree.view = this;
     17 }
     18 
     19 Tree.prototype = {
     20  get tree() {
     21    return this._tree;
     22  },
     23  get isEmpty() {
     24    return !this._data.length;
     25  },
     26  get hasSelection() {
     27    return this.selection.count > 0;
     28  },
     29  getSelectedItems() {
     30    let result = [];
     31 
     32    let rc = this.selection.getRangeCount();
     33    for (let i = 0; i < rc; ++i) {
     34      let min = {},
     35        max = {};
     36      this.selection.getRangeAt(i, min, max);
     37      for (let j = min.value; j <= max.value; ++j) {
     38        result.push(this._data[j]);
     39      }
     40    }
     41 
     42    return result;
     43  },
     44 
     45  // nsITreeView implementation
     46  get rowCount() {
     47    return this._data.length;
     48  },
     49  getCellText(aRow) {
     50    return this._data[aRow];
     51  },
     52  isSeparator() {
     53    return false;
     54  },
     55  isSorted() {
     56    return false;
     57  },
     58  isContainer() {
     59    return false;
     60  },
     61  setTree() {},
     62  getImageSrc() {},
     63  getCellValue() {},
     64  cycleHeader() {},
     65  getRowProperties() {
     66    return "";
     67  },
     68  getColumnProperties() {
     69    return "";
     70  },
     71  getCellProperties() {
     72    return "";
     73  },
     74  QueryInterface: ChromeUtils.generateQI(["nsITreeView"]),
     75 };
     76 
     77 function Lang(aCode, label) {
     78  this.langCode = aCode;
     79  this._label = label;
     80 }
     81 
     82 Lang.prototype = {
     83  toString() {
     84    return this._label;
     85  },
     86 };
     87 
     88 var gTranslationExceptions = {
     89  onLoad() {
     90    if (this._siteTree) {
     91      // Re-using an open dialog, clear the old observers.
     92      this.uninit();
     93    }
     94 
     95    // Load site permissions into an array.
     96    this._sites = [];
     97    for (let perm of Services.perms.all) {
     98      if (
     99        perm.type == kPermissionType &&
    100        perm.capability == Services.perms.DENY_ACTION
    101      ) {
    102        this._sites.push(perm.principal.origin);
    103      }
    104    }
    105    Services.obs.addObserver(this, "perm-changed");
    106    this._sites.sort();
    107 
    108    this._siteTree = new Tree("sitesTree", this._sites);
    109    this.onSiteSelected();
    110 
    111    this._langs = this.getLanguageExceptions();
    112    Services.prefs.addObserver(kLanguagesPref, this);
    113    this._langTree = new Tree("languagesTree", this._langs);
    114    this.onLanguageSelected();
    115  },
    116 
    117  // Get the list of languages we don't translate as an array.
    118  getLanguageExceptions() {
    119    let langs = Services.prefs.getCharPref(kLanguagesPref);
    120    if (!langs) {
    121      return [];
    122    }
    123 
    124    let langArr = langs.split(",");
    125    let displayNames = Services.intl.getLanguageDisplayNames(
    126      undefined,
    127      langArr
    128    );
    129    let result = langArr.map((lang, i) => new Lang(lang, displayNames[i]));
    130    result.sort();
    131 
    132    return result;
    133  },
    134 
    135  observe(aSubject, aTopic, aData) {
    136    if (aTopic == "perm-changed") {
    137      if (aData == "cleared") {
    138        if (!this._sites.length) {
    139          return;
    140        }
    141        let removed = this._sites.splice(0, this._sites.length);
    142        this._siteTree.tree.rowCountChanged(0, -removed.length);
    143      } else {
    144        let perm = aSubject.QueryInterface(Ci.nsIPermission);
    145        if (perm.type != kPermissionType) {
    146          return;
    147        }
    148 
    149        if (aData == "added") {
    150          if (perm.capability != Services.perms.DENY_ACTION) {
    151            return;
    152          }
    153          this._sites.push(perm.principal.origin);
    154          this._sites.sort();
    155          let tree = this._siteTree.tree;
    156          tree.rowCountChanged(0, 1);
    157          tree.invalidate();
    158        } else if (aData == "deleted") {
    159          let index = this._sites.indexOf(perm.principal.origin);
    160          if (index == -1) {
    161            return;
    162          }
    163          this._sites.splice(index, 1);
    164          this._siteTree.tree.rowCountChanged(index, -1);
    165          this.onSiteSelected();
    166          return;
    167        }
    168      }
    169      this.onSiteSelected();
    170    } else if (aTopic == "nsPref:changed") {
    171      this._langs = this.getLanguageExceptions();
    172      let change = this._langs.length - this._langTree.rowCount;
    173      this._langTree._data = this._langs;
    174      let tree = this._langTree.tree;
    175      if (change) {
    176        tree.rowCountChanged(0, change);
    177      }
    178      tree.invalidate();
    179      this.onLanguageSelected();
    180    }
    181  },
    182 
    183  _handleButtonDisabling(aTree, aIdPart) {
    184    let empty = aTree.isEmpty;
    185    document.getElementById("removeAll" + aIdPart + "s").disabled = empty;
    186    document.getElementById("remove" + aIdPart).disabled =
    187      empty || !aTree.hasSelection;
    188  },
    189 
    190  onLanguageSelected() {
    191    this._handleButtonDisabling(this._langTree, "Language");
    192  },
    193 
    194  onSiteSelected() {
    195    this._handleButtonDisabling(this._siteTree, "Site");
    196  },
    197 
    198  onLanguageDeleted() {
    199    let langs = Services.prefs.getCharPref(kLanguagesPref);
    200    if (!langs) {
    201      return;
    202    }
    203 
    204    let removed = this._langTree.getSelectedItems().map(l => l.langCode);
    205 
    206    langs = langs.split(",").filter(l => !removed.includes(l));
    207    Services.prefs.setCharPref(kLanguagesPref, langs.join(","));
    208  },
    209 
    210  onAllLanguagesDeleted() {
    211    Services.prefs.setCharPref(kLanguagesPref, "");
    212  },
    213 
    214  onSiteDeleted() {
    215    let removedSites = this._siteTree.getSelectedItems();
    216    for (let origin of removedSites) {
    217      let principal =
    218        Services.scriptSecurityManager.createContentPrincipalFromOrigin(origin);
    219      Services.perms.removeFromPrincipal(principal, kPermissionType);
    220    }
    221  },
    222 
    223  onAllSitesDeleted() {
    224    if (this._siteTree.isEmpty) {
    225      return;
    226    }
    227 
    228    let removedSites = this._sites.splice(0, this._sites.length);
    229    this._siteTree.tree.rowCountChanged(0, -removedSites.length);
    230 
    231    for (let origin of removedSites) {
    232      let principal =
    233        Services.scriptSecurityManager.createContentPrincipalFromOrigin(origin);
    234      Services.perms.removeFromPrincipal(principal, kPermissionType);
    235    }
    236 
    237    this.onSiteSelected();
    238  },
    239 
    240  onSiteKeyPress(aEvent) {
    241    if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE) {
    242      this.onSiteDeleted();
    243    }
    244  },
    245 
    246  onLanguageKeyPress(aEvent) {
    247    if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE) {
    248      this.onLanguageDeleted();
    249    }
    250  },
    251 
    252  uninit() {
    253    Services.obs.removeObserver(this, "perm-changed");
    254    Services.prefs.removeObserver(kLanguagesPref, this);
    255  },
    256 };