diff options
Diffstat (limited to 'toolkit/mozapps/extensions/content/selectAddons.js')
-rw-r--r-- | toolkit/mozapps/extensions/content/selectAddons.js | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/toolkit/mozapps/extensions/content/selectAddons.js b/toolkit/mozapps/extensions/content/selectAddons.js new file mode 100644 index 000000000..f80932b3f --- /dev/null +++ b/toolkit/mozapps/extensions/content/selectAddons.js @@ -0,0 +1,347 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + +/* 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/. */ + +"use strict"; + +Components.utils.import("resource://gre/modules/AddonManager.jsm"); +Components.utils.import("resource://gre/modules/addons/AddonRepository.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +const Cc = Components.classes; +const Ci = Components.interfaces; + +var gView = null; + +function showView(aView) { + gView = aView; + + gView.show(); + + // If the view's show method immediately showed a different view then don't + // do anything else + if (gView != aView) + return; + + let viewNode = document.getElementById(gView.nodeID); + viewNode.parentNode.selectedPanel = viewNode; + + // For testing dispatch an event when the view changes + var event = document.createEvent("Events"); + event.initEvent("ViewChanged", true, true); + viewNode.dispatchEvent(event); +} + +function showButtons(aCancel, aBack, aNext, aDone) { + document.getElementById("cancel").hidden = !aCancel; + document.getElementById("back").hidden = !aBack; + document.getElementById("next").hidden = !aNext; + document.getElementById("done").hidden = !aDone; +} + +function isAddonDistroInstalled(aID) { + let branch = Services.prefs.getBranch("extensions.installedDistroAddon."); + if (!branch.prefHasUserValue(aID)) + return false; + + return branch.getBoolPref(aID); +} + +function orderForScope(aScope) { + return aScope == AddonManager.SCOPE_PROFILE ? 1 : 0; +} + +var gAddons = {}; + +var gChecking = { + nodeID: "checking", + + _progress: null, + _addonCount: 0, + _completeCount: 0, + + show: function gChecking_show() { + showButtons(true, false, false, false); + this._progress = document.getElementById("checking-progress"); + + AddonManager.getAllAddons(aAddons => { + if (aAddons.length == 0) { + window.close(); + return; + } + + aAddons = aAddons.filter(function gChecking_filterAddons(aAddon) { + if (aAddon.type == "plugin" || aAddon.type == "service") + return false; + + if (aAddon.type == "theme") { + // Don't show application shipped themes + if (aAddon.scope == AddonManager.SCOPE_APPLICATION) + return false; + // Don't show already disabled themes + if (aAddon.userDisabled) + return false; + } + + return true; + }); + + this._addonCount = aAddons.length; + this._progress.value = 0; + this._progress.max = aAddons.length; + this._progress.mode = "determined"; + + AddonRepository.repopulateCache().then(() => { + for (let addonItem of aAddons) { + // Ignore disabled themes + if (addonItem.type != "theme" || !addonItem.userDisabled) { + gAddons[addonItem.id] = { + addon: addonItem, + install: null, + wasActive: addonItem.isActive + } + } + + addonItem.findUpdates(this, AddonManager.UPDATE_WHEN_NEW_APP_INSTALLED); + } + }); + }); + }, + + onUpdateAvailable: function gChecking_onUpdateAvailable(aAddon, aInstall) { + // If the add-on can be upgraded then remember the new version + if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE) + gAddons[aAddon.id].install = aInstall; + }, + + onUpdateFinished: function gChecking_onUpdateFinished(aAddon, aError) { + this._completeCount++; + this._progress.value = this._completeCount; + + if (this._completeCount < this._addonCount) + return; + + // Tycho: var addons = [gAddons[id] for (id in gAddons)]; + var addons = []; + for (let id in gAddons) { + addons.push(gAddons[id]) + } + + addons.sort(function sortAddons(a, b) { + let orderA = orderForScope(a.addon.scope); + let orderB = orderForScope(b.addon.scope); + + if (orderA != orderB) + return orderA - orderB; + + return String.localeCompare(a.addon.name, b.addon.name); + }); + + let rows = document.getElementById("select-rows"); + let lastAddon = null; + for (let entry of addons) { + if (lastAddon && + orderForScope(entry.addon.scope) != orderForScope(lastAddon.scope)) { + let separator = document.createElement("separator"); + rows.appendChild(separator); + } + + let row = document.createElement("row"); + row.setAttribute("id", entry.addon.id); + row.setAttribute("class", "addon"); + rows.appendChild(row); + row.setAddon(entry.addon, entry.install, entry.wasActive, + isAddonDistroInstalled(entry.addon.id)); + + if (entry.install) + entry.install.addListener(gUpdate); + + lastAddon = entry.addon; + } + + showView(gSelect); + } +}; + +var gSelect = { + nodeID: "select", + + show: function gSelect_show() { + this.updateButtons(); + }, + + updateButtons: function gSelect_updateButtons() { + for (let row = document.getElementById("select-rows").firstChild; + row; row = row.nextSibling) { + if (row.localName == "separator") + continue; + + if (row.action) { + showButtons(false, false, true, false); + return; + } + } + + showButtons(false, false, false, true); + }, + + next: function gSelect_next() { + showView(gConfirm); + }, + + done: function gSelect_done() { + window.close(); + } +}; + +var gConfirm = { + nodeID: "confirm", + + show: function gConfirm_show() { + showButtons(false, true, false, true); + + let box = document.getElementById("confirm-scrollbox").firstChild; + while (box) { + box.hidden = true; + while (box.lastChild != box.firstChild) + box.removeChild(box.lastChild); + box = box.nextSibling; + } + + for (let row = document.getElementById("select-rows").firstChild; + row; row = row.nextSibling) { + if (row.localName == "separator") + continue; + + let action = row.action; + if (!action) + continue; + + let list = document.getElementById(action + "-list"); + + list.hidden = false; + let item = document.createElement("hbox"); + item.setAttribute("id", row._addon.id); + item.setAttribute("class", "addon"); + item.setAttribute("type", row._addon.type); + item.setAttribute("name", row._addon.name); + if (action == "update" || action == "enable") + item.setAttribute("active", "true"); + list.appendChild(item); + + if (action == "update") + showButtons(false, true, true, false); + } + }, + + back: function gConfirm_back() { + showView(gSelect); + }, + + next: function gConfirm_next() { + showView(gUpdate); + }, + + done: function gConfirm_done() { + for (let row = document.getElementById("select-rows").firstChild; + row; row = row.nextSibling) { + if (row.localName != "separator") + row.apply(); + } + + window.close(); + } +} + +var gUpdate = { + nodeID: "update", + + _progress: null, + _waitingCount: 0, + _completeCount: 0, + _errorCount: 0, + + show: function gUpdate_show() { + showButtons(true, false, false, false); + + this._progress = document.getElementById("update-progress"); + + for (let row = document.getElementById("select-rows").firstChild; + row; row = row.nextSibling) { + if (row.localName != "separator") + row.apply(); + } + + this._progress.mode = "determined"; + this._progress.max = this._waitingCount; + this._progress.value = this._completeCount; + }, + + checkComplete: function gUpdate_checkComplete() { + this._progress.value = this._completeCount; + if (this._completeCount < this._waitingCount) + return; + + if (this._errorCount > 0) { + showView(gErrors); + return; + } + + window.close(); + }, + + onDownloadStarted: function gUpdate_onDownloadStarted(aInstall) { + this._waitingCount++; + }, + + onDownloadFailed: function gUpdate_onDownloadFailed(aInstall) { + this._errorCount++; + this._completeCount++; + this.checkComplete(); + }, + + onInstallFailed: function gUpdate_onInstallFailed(aInstall) { + this._errorCount++; + this._completeCount++; + this.checkComplete(); + }, + + onInstallEnded: function gUpdate_onInstallEnded(aInstall) { + this._completeCount++; + this.checkComplete(); + } +}; + +var gErrors = { + nodeID: "errors", + + show: function gErrors_show() { + showButtons(false, false, false, true); + }, + + done: function gErrors_done() { + window.close(); + } +}; + +window.addEventListener("load", function loadEventListener() { + showView(gChecking); }, false); + +// When closing the window cancel any pending or in-progress installs +window.addEventListener("unload", function unloadEventListener() { + for (let id in gAddons) { + let entry = gAddons[id]; + if (!entry.install) + return; + + aEntry.install.removeListener(gUpdate); + + if (entry.install.state != AddonManager.STATE_INSTALLED && + entry.install.state != AddonManager.STATE_DOWNLOAD_FAILED && + entry.install.state != AddonManager.STATE_INSTALL_FAILED) { + entry.install.cancel(); + } + } +}, false); |