diff options
Diffstat (limited to 'browser/components/preferences/blocklists.js')
-rw-r--r-- | browser/components/preferences/blocklists.js | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/browser/components/preferences/blocklists.js b/browser/components/preferences/blocklists.js new file mode 100644 index 000000000..bc39eb6bd --- /dev/null +++ b/browser/components/preferences/blocklists.js @@ -0,0 +1,209 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +Components.utils.import("resource://gre/modules/Services.jsm"); +const BASE_LIST_ID = "base"; +const CONTENT_LIST_ID = "content"; +const TRACK_SUFFIX = "-track-digest256"; +const TRACKING_TABLE_PREF = "urlclassifier.trackingTable"; +const LISTS_PREF_BRANCH = "browser.safebrowsing.provider.mozilla.lists."; +const UPDATE_TIME_PREF = "browser.safebrowsing.provider.mozilla.nextupdatetime"; + +var gBlocklistManager = { + _type: "", + _blockLists: [], + _brandShortName : null, + _bundle: null, + _tree: null, + + _view: { + _rowCount: 0, + get rowCount() { + return this._rowCount; + }, + getCellText: function (row, column) { + if (column.id == "listCol") { + let list = gBlocklistManager._blockLists[row]; + let desc = list.description ? list.description : ""; + let text = gBlocklistManager._bundle.getFormattedString("mozNameTemplate", + [list.name, desc]); + return text; + } + return ""; + }, + + isSeparator: function(index) { return false; }, + isSorted: function() { return false; }, + isContainer: function(index) { return false; }, + setTree: function(tree) {}, + getImageSrc: function(row, column) {}, + getProgressMode: function(row, column) {}, + getCellValue: function(row, column) { + if (column.id == "selectionCol") + return gBlocklistManager._blockLists[row].selected; + return undefined; + }, + cycleHeader: function(column) {}, + getRowProperties: function(row) { return ""; }, + getColumnProperties: function(column) { return ""; }, + getCellProperties: function(row, column) { + if (column.id == "selectionCol") { + return "checkmark"; + } + + return ""; + } + }, + + onWindowKeyPress: function (event) { + if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) { + window.close(); + } else if (event.keyCode == KeyEvent.DOM_VK_RETURN) { + gBlocklistManager.onApplyChanges(); + } + }, + + onLoad: function () { + this._bundle = document.getElementById("bundlePreferences"); + let params = window.arguments[0]; + this.init(params); + }, + + init: function (params) { + if (this._type) { + // reusing an open dialog, clear the old observer + this.uninit(); + } + + this._type = "tracking"; + this._brandShortName = params.brandShortName; + + let blocklistsText = document.getElementById("blocklistsText"); + while (blocklistsText.hasChildNodes()) { + blocklistsText.removeChild(blocklistsText.firstChild); + } + blocklistsText.appendChild(document.createTextNode(params.introText)); + + document.title = params.windowTitle; + + let treecols = document.getElementsByTagName("treecols")[0]; + treecols.addEventListener("click", event => { + if (event.target.nodeName != "treecol" || event.button != 0) { + return; + } + }); + + this._loadBlockLists(); + }, + + uninit: function () {}, + + onListSelected: function () { + for (let list of this._blockLists) { + list.selected = false; + } + this._blockLists[this._tree.currentIndex].selected = true; + + this._updateTree(); + }, + + onApplyChanges: function () { + let activeList = this._getActiveList(); + let selected = null; + for (let list of this._blockLists) { + if (list.selected) { + selected = list; + break; + } + } + + if (activeList !== selected.id) { + const Cc = Components.classes, Ci = Components.interfaces; + let msg = this._bundle.getFormattedString("blocklistChangeRequiresRestart", + [this._brandShortName]); + let title = this._bundle.getFormattedString("shouldRestartTitle", + [this._brandShortName]); + let shouldProceed = Services.prompt.confirm(window, title, msg); + if (shouldProceed) { + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); + Services.obs.notifyObservers(cancelQuit, "quit-application-requested", + "restart"); + shouldProceed = !cancelQuit.data; + + if (shouldProceed) { + let trackingTable = Services.prefs.getCharPref(TRACKING_TABLE_PREF); + if (selected.id != CONTENT_LIST_ID) { + trackingTable = trackingTable.replace("," + CONTENT_LIST_ID + TRACK_SUFFIX, ""); + } else { + trackingTable += "," + CONTENT_LIST_ID + TRACK_SUFFIX; + } + Services.prefs.setCharPref(TRACKING_TABLE_PREF, trackingTable); + Services.prefs.setCharPref(UPDATE_TIME_PREF, 42); + + Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | + Ci.nsIAppStartup.eRestart); + } + } + + // Don't close the dialog in case we didn't quit. + return; + } + window.close(); + }, + + _loadBlockLists: function () { + this._blockLists = []; + + // Load blocklists into a table. + let branch = Services.prefs.getBranch(LISTS_PREF_BRANCH); + let itemArray = branch.getChildList(""); + for (let itemName of itemArray) { + try { + this._createOrUpdateBlockList(itemName); + } catch (e) { + // Ignore bogus or missing list name. + continue; + } + } + + this._updateTree(); + }, + + _createOrUpdateBlockList: function (itemName) { + let branch = Services.prefs.getBranch(LISTS_PREF_BRANCH); + let key = branch.getCharPref(itemName); + let value = this._bundle.getString(key); + + let suffix = itemName.slice(itemName.lastIndexOf(".")); + let id = itemName.replace(suffix, ""); + let list = this._blockLists.find(el => el.id === id); + if (!list) { + list = { id }; + this._blockLists.push(list); + } + list.selected = this._getActiveList() === id; + + // Get the property name from the suffix (e.g. ".name" -> "name"). + let prop = suffix.slice(1); + list[prop] = value; + + return list; + }, + + _updateTree: function () { + this._tree = document.getElementById("blocklistsTree"); + this._view._rowCount = this._blockLists.length; + this._tree.view = this._view; + }, + + _getActiveList: function () { + let trackingTable = Services.prefs.getCharPref(TRACKING_TABLE_PREF); + return trackingTable.includes(CONTENT_LIST_ID) ? CONTENT_LIST_ID : BASE_LIST_ID; + } +}; + +function initWithParams(params) { + gBlocklistManager.init(params); +} |