Bug 1382689 Fix "Remove" button on details page for a legacy extension
Also updated addon listeners in extensions.js to use Set instead of
arrays and added a way to listen to AddonListener events on any addon.
MozReview-Commit-ID: Ev3kJgcr30G
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -102,17 +102,17 @@ XPCOMUtils.defineLazyGetter(gStrings, "a
});
XPCOMUtils.defineLazyPreferenceGetter(this, "legacyWarningExceptions",
PREF_LEGACY_EXCEPTIONS, "",
raw => raw.split(","));
XPCOMUtils.defineLazyPreferenceGetter(this, "legacyExtensionsEnabled",
PREF_LEGACY_ENABLED, true,
- () => gLegacyView.refresh());
+ () => gLegacyView.refreshVisibility());
document.addEventListener("load", initialize, true);
window.addEventListener("unload", shutdown);
function promiseEvent(event, target, capture = false) {
return new Promise(resolve => {
target.addEventListener(event, resolve, {capture, once: true});
});
@@ -478,17 +478,17 @@ if (window.QueryInterface(Ci.nsIInterfac
.sessionHistory) {
var gHistory = HTML5History;
} else {
gHistory = FakeHistory;
}
var gEventManager = {
_listeners: {},
- _installListeners: [],
+ _installListeners: new Set(),
initialize() {
const ADDON_EVENTS = ["onEnabling", "onEnabled", "onDisabling",
"onDisabled", "onUninstalling", "onUninstalled",
"onInstalled", "onOperationCancelled",
"onUpdateAvailable", "onUpdateFinished",
"onCompatibilityUpdateAvailable",
"onPropertyChanged"];
@@ -564,60 +564,56 @@ var gEventManager = {
shutdown() {
AddonManager.removeManagerListener(this);
AddonManager.removeInstallListener(this);
AddonManager.removeAddonListener(this);
},
registerAddonListener(aListener, aAddonId) {
if (!(aAddonId in this._listeners))
- this._listeners[aAddonId] = [];
- else if (this._listeners[aAddonId].indexOf(aListener) != -1)
- return;
- this._listeners[aAddonId].push(aListener);
+ this._listeners[aAddonId] = new Set();
+ this._listeners[aAddonId].add(aListener);
},
unregisterAddonListener(aListener, aAddonId) {
if (!(aAddonId in this._listeners))
return;
- var index = this._listeners[aAddonId].indexOf(aListener);
- if (index == -1)
- return;
- this._listeners[aAddonId].splice(index, 1);
+ this._listeners[aAddonId].delete(aListener);
},
registerInstallListener(aListener) {
- if (this._installListeners.indexOf(aListener) != -1)
- return;
- this._installListeners.push(aListener);
+ this._installListeners.add(aListener);
},
unregisterInstallListener(aListener) {
- var i = this._installListeners.indexOf(aListener);
- if (i == -1)
- return;
- this._installListeners.splice(i, 1);
+ this._installListeners.delete(aListener);
},
delegateAddonEvent(aEvent, aParams) {
var addon = aParams.shift();
if (!(addon.id in this._listeners))
return;
- var listeners = this._listeners[addon.id];
- for (let listener of listeners) {
+ function tryListener(listener) {
if (!(aEvent in listener))
- continue;
+ return;
try {
listener[aEvent].apply(listener, aParams);
} catch (e) {
// this shouldn't be fatal
Cu.reportError(e);
}
}
+
+ for (let listener of this._listeners[addon.id]) {
+ tryListener(listener);
+ }
+ for (let listener of this._listeners["ANY"]) {
+ tryListener(listener);
+ }
},
delegateInstallEvent(aEvent, aParams) {
var existingAddon = aEvent == "onExternalInstall" ? aParams[1] : aParams[0].existingAddon;
// If the install is an update then send the event to all listeners
// registered for the existing add-on
if (existingAddon)
this.delegateAddonEvent(aEvent, [existingAddon].concat(aParams));
@@ -2783,17 +2779,27 @@ var gLegacyView = {
initialize() {
this.node = document.getElementById("legacy-view");
this._listBox = document.getElementById("legacy-list");
this._categoryItem = gCategories.get("addons://legacy/");
document.getElementById("legacy-learnmore").href = SUPPORT_URL + "webextensions";
- this.refresh();
+ gEventManager.registerAddonListener(this, "ANY");
+
+ this.refreshVisibility();
+ },
+
+ shutdown() {
+ gEventManager.unregisterAddonListener(this, "ANY");
+ },
+
+ onUninstalled() {
+ this.refreshVisibility();
},
async show(type, request) {
let addons = await AddonManager.getAddonsByTypes(["extension"]);
addons = addons.filter(a => !a.hidden &&
(isDisabledLegacy(a) || isDisabledUnsigned(a)));
while (this._listBox.itemCount > 0)
@@ -2819,17 +2825,17 @@ var gLegacyView = {
getSelectedAddon() {
var item = this._listBox.selectedItem;
if (item)
return item.mAddon;
return null;
},
- async refresh() {
+ async refreshVisibility() {
if (legacyExtensionsEnabled) {
this._categoryItem.disabled = true;
return;
}
let extensions = await AddonManager.getAddonsByTypes(["extension"]);
let haveUnsigned = false;
@@ -2847,16 +2853,26 @@ var gLegacyView = {
this._categoryItem.disabled = false;
let name = gStrings.ext.GetStringFromName(`type.${haveUnsigned ? "unsupported" : "legacy"}.name`);
this._categoryItem.setAttribute("name", name);
this._categoryItem.tooltiptext = name;
} else {
this._categoryItem.disabled = true;
}
},
+
+ getListItemForID(aId) {
+ var listitem = this._listBox.firstChild;
+ while (listitem) {
+ if (listitem.getAttribute("status") == "installed" && listitem.mAddon.id == aId)
+ return listitem;
+ listitem = listitem.nextSibling;
+ }
+ return null;
+ }
};
var gListView = {
node: null,
_listBox: null,
_emptyNotice: null,
_type: null,
--- a/toolkit/mozapps/extensions/test/browser/browser_legacy.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_legacy.js
@@ -106,17 +106,17 @@ add_task(async function() {
is(mgrWin.gLegacyView._categoryItem.disabled, true, "Legacy category is hidden");
// Now add a legacy extension
provider.createAddons(disabledAddon);
// The legacy category does not watch for new installs since new
// legacy extensions cannot be installed while legacy extensions
// are disabled, so manually refresh it here.
- await mgrWin.gLegacyView.refresh();
+ await mgrWin.gLegacyView.refreshVisibility();
// Make sure we re-render the extensions list, after that we should
// still just have the original two entries.
await catUtils.openType("plugin");
await catUtils.openType("extension");
checkList("addon-list",
["webextension@tests.mozilla.org", "mozilla@tests.mozilla.org"]);
@@ -151,17 +151,17 @@ add_task(async function() {
provider.createAddons(unsignedAddons);
SpecialPowers.pushPrefEnv({
set: [
["xpinstall.signatures.required", true],
],
});
// The entry on the left side should now read "Unsupported"
- await mgrWin.gLegacyView.refresh();
+ await mgrWin.gLegacyView.refreshVisibility();
is(catItem.disabled, false, "Legacy category is visible");
is(catItem.getAttribute("name"), get_string("type.unsupported.name"),
"Category label with unsigned extensions is correct");
// The main extensions list should still have the original two
// good extensions and the legacy banner.
await catUtils.openType("extension");
checkList("addon-list",
@@ -181,17 +181,17 @@ add_task(async function() {
// Disable unsigned extensions
SpecialPowers.pushPrefEnv({
set: [
["xpinstall.signatures.required", false],
],
});
// The name of the pane should go back to "Legacy Extensions"
- await mgrWin.gLegacyView.refresh();
+ await mgrWin.gLegacyView.refreshVisibility();
is(catItem.disabled, false, "Legacy category is visible");
is(catItem.getAttribute("name"), get_string("type.legacy.name"),
"Category label with no unsigned extensions is correct");
// The unsigned extension should be present in the main extensions pane
await catUtils.openType("extension");
checkList("addon-list", [
"webextension@tests.mozilla.org",