Bug 1031527 - Remove dup fd from ParamTraits<MagicGrallocBufferHandle>::Read(). r...
[gecko.git] / browser / components / preferences / translation.js
blob2fe0f4df3c2805d8c32ca6afe23e99979c29a830
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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/. */
6 "use strict";
8 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
10 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
11 Cu.import("resource://gre/modules/Services.jsm");
13 XPCOMUtils.defineLazyGetter(this, "gLangBundle", () =>
14   Services.strings.createBundle("chrome://global/locale/languageNames.properties"));
16 const kPermissionType = "translate";
17 const kLanguagesPref = "browser.translation.neverForLanguages";
19 function Tree(aId, aData)
21   this._data = aData;
22   this._tree = document.getElementById(aId);
23   this._tree.treeBoxObject.view = this;
26 Tree.prototype = {
27   get boxObject() this._tree.treeBoxObject,
28   get isEmpty() !this._data.length,
29   get hasSelection() this.selection.count > 0,
30   getSelectedItems: function() {
31     let result = [];
33     let rc = this.selection.getRangeCount();
34     for (let i = 0; i < rc; ++i) {
35       let min = {}, 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     }
41     return result;
42   },
44   // nsITreeView implementation
45   get rowCount() this._data.length,
46   getCellText: function (aRow, aColumn) this._data[aRow],
47   isSeparator: function(aIndex) false,
48   isSorted: function() false,
49   isContainer: function(aIndex) false,
50   setTree: function(aTree) {},
51   getImageSrc: function(aRow, aColumn) {},
52   getProgressMode: function(aRow, aColumn) {},
53   getCellValue: function(aRow, aColumn) {},
54   cycleHeader: function(column) {},
55   getRowProperties: function(row) "",
56   getColumnProperties: function(column) "",
57   getCellProperties: function(row, column) "",
58   QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView])
61 function Lang(aCode)
63   this.langCode = aCode;
64   this._label = gLangBundle.GetStringFromName(aCode);
67 Lang.prototype = {
68   toString: function() this._label
71 let gTranslationExceptions = {
72   onLoad: function() {
73     if (this._siteTree) {
74       // Re-using an open dialog, clear the old observers.
75       this.uninit();
76     }
78     // Load site permissions into an array.
79     this._sites = [];
80     let enumerator = Services.perms.enumerator;
81     while (enumerator.hasMoreElements()) {
82       let perm = enumerator.getNext().QueryInterface(Ci.nsIPermission);
84       if (perm.type == kPermissionType &&
85           perm.capability == Services.perms.DENY_ACTION) {
86         this._sites.push(perm.host);
87       }
88     }
89     Services.obs.addObserver(this, "perm-changed", false);
90     this._sites.sort();
92     this._siteTree = new Tree("sitesTree", this._sites);
93     this.onSiteSelected();
95     this._langs = this.getLanguageExceptions();
96     Services.prefs.addObserver(kLanguagesPref, this, false);
97     this._langTree = new Tree("languagesTree", this._langs);
98     this.onLanguageSelected();
99   },
101   // Get the list of languages we don't translate as an array.
102   getLanguageExceptions: function() {
103     let langs = Services.prefs.getCharPref(kLanguagesPref);
104     if (!langs)
105       return [];
107     let result = langs.split(",").map(code => new Lang(code));
108     result.sort();
110     return result;
111   },
113   observe: function(aSubject, aTopic, aData) {
114     if (aTopic == "perm-changed") {
115       if (aData == "cleared") {
116         if (!this._sites.length)
117           return;
118         let removed = this._sites.splice(0, this._sites.length);
119         this._siteTree.boxObject.rowCountChanged(0, - removed.length);
120       }
121       else {
122         let perm = aSubject.QueryInterface(Ci.nsIPermission);
123         if (perm.type != kPermissionType)
124           return;
126         if (aData == "added") {
127           if (perm.capability != Services.perms.DENY_ACTION)
128             return;
129           this._sites.push(perm.host);
130           this._sites.sort();
131           let boxObject = this._siteTree.boxObject;
132           boxObject.rowCountChanged(0, 1);
133           boxObject.invalidate();
134         }
135         else if (aData == "deleted") {
136           let index = this._sites.indexOf(perm.host);
137           if (index == -1)
138             return;
139           this._sites.splice(index, 1);
140           this._siteTree.boxObject.rowCountChanged(index, -1);
141           this.onSiteSelected();
142           return;
143         }
144       }
145       this.onSiteSelected();
146     }
147     else if (aTopic == "nsPref:changed") {
148       this._langs = this.getLanguageExceptions();
149       let change = this._langs.length - this._langTree.rowCount;
150       this._langTree._data = this._langs;
151       let boxObject = this._langTree.boxObject;
152       if (change)
153         boxObject.rowCountChanged(0, change);
154       boxObject.invalidate();
155       this.onLanguageSelected();
156     }
157   },
159   _handleButtonDisabling: function(aTree, aIdPart) {
160     let empty = aTree.isEmpty;
161     document.getElementById("removeAll" + aIdPart + "s").disabled = empty;
162     document.getElementById("remove" + aIdPart).disabled =
163       empty || !aTree.hasSelection;
164   },
166   onLanguageSelected: function() {
167     this._handleButtonDisabling(this._langTree, "Language");
168   },
170   onSiteSelected: function() {
171     this._handleButtonDisabling(this._siteTree, "Site");
172   },
174   onLanguageDeleted: function() {
175     let langs = Services.prefs.getCharPref(kLanguagesPref);
176     if (!langs)
177       return;
179     let removed = this._langTree.getSelectedItems().map(l => l.langCode);
181     langs = langs.split(",").filter(l => removed.indexOf(l) == -1);
182     Services.prefs.setCharPref(kLanguagesPref, langs.join(","));
183   },
185   onAllLanguagesDeleted: function() {
186     Services.prefs.setCharPref(kLanguagesPref, "");
187   },
189   onSiteDeleted: function() {
190     let removedSites = this._siteTree.getSelectedItems();
191     for (let host of removedSites)
192       Services.perms.remove(host, kPermissionType);
193   },
195   onAllSitesDeleted: function() {
196     if (this._siteTree.isEmpty)
197       return;
199     let removedSites = this._sites.splice(0, this._sites.length);
200     this._siteTree.boxObject.rowCountChanged(0, -removedSites.length);
202     for (let host of removedSites)
203       Services.perms.remove(host, kPermissionType);
205     this.onSiteSelected();
206   },
208   onSiteKeyPress: function(aEvent) {
209     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
210       this.onSiteDeleted();
211   },
213   onLanguageKeyPress: function() {
214     if (aEvent.keyCode == KeyEvent.DOM_VK_DELETE)
215       this.onLanguageDeleted();
216   },
218   onWindowKeyPress: function(aEvent) {
219     if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
220       window.close();
221   },
223   uninit: function() {
224     Services.obs.removeObserver(this, "perm-changed");
225     Services.prefs.removeObserver(kLanguagesPref, this);
226   }