Bug 605494 - UI for restartless addons [r=mfinkle]

This commit is contained in:
Wes Johnston 2011-01-04 17:20:30 -08:00
Родитель bbe35dc89a
Коммит f049ba389f
2 изменённых файлов: 141 добавлений и 78 удалений

Просмотреть файл

@ -690,7 +690,7 @@ var Browser = {
return null;
},
addTab: function(aURI, aBringFront, aOwner, aParams) {
addTab: function browser_addTab(aURI, aBringFront, aOwner, aParams) {
let params = aParams || {};
let newTab = new Tab(aURI, params);
newTab.owner = aOwner || null;
@ -1369,12 +1369,12 @@ nsBrowserAccess.prototype = {
return browser;
},
openURI: function(aURI, aOpener, aWhere, aContext) {
openURI: function browser_openURI(aURI, aOpener, aWhere, aContext) {
let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
return browser ? browser.contentWindow : null;
},
openURIInFrame: function(aURI, aOpener, aWhere, aContext) {
openURIInFrame: function browser_openURIInFrame(aURI, aOpener, aWhere, aContext) {
let browser = this._getBrowser(aURI, aOpener, aWhere, aContext);
return browser ? browser.QueryInterface(Ci.nsIFrameLoaderOwner) : null;
},

Просмотреть файл

@ -278,6 +278,42 @@ var ExtensionsView = {
this.hideOptions();
},
_createLocalAddon: function ev__createLocalAddon(aAddon) {
let strings = Elements.browserBundle;
let appManaged = (aAddon.scope == AddonManager.SCOPE_APPLICATION);
let opType = this._getOpTypeForOperations(aAddon.pendingOperations);
let updateable = (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
let uninstallable = (aAddon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
let blocked = "";
switch(aAddon.blocklistState) {
case Ci.nsIBlocklistService.STATE_BLOCKED:
blocked = strings.getString("addonBlocked.blocked")
break;
case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
blocked = strings.getString("addonBlocked.softBlocked");
break;
case Ci.nsIBlocklistService.STATE_OUTDATED:
blocked = srings.getString("addonBlocked.outdated");
break;
}
let listitem = this._createItem(aAddon, "local");
listitem.setAttribute("isDisabled", !aAddon.isActive);
listitem.setAttribute("appDisabled", aAddon.appDisabled);
listitem.setAttribute("appManaged", appManaged);
listitem.setAttribute("description", aAddon.description);
listitem.setAttribute("optionsURL", aAddon.optionsURL);
listitem.setAttribute("opType", opType);
listitem.setAttribute("updateable", updateable);
listitem.setAttribute("isReadonly", !uninstallable);
if (blocked)
listitem.setAttribute("blockedStatus", blocked);
listitem.addon = aAddon;
return listitem;
},
getAddonsFromLocal: function ev_getAddonsFromLocal() {
this.clearSection("local");
@ -286,41 +322,11 @@ var ExtensionsView = {
let strings = Strings.browser;
let anyUpdateable = false;
for (let i = 0; i < items.length; i++) {
let addon = items[i];
let appManaged = (addon.scope == AddonManager.SCOPE_APPLICATION);
let opType = self._getOpTypeForOperations(addon.pendingOperations);
let updateable = (addon.permissions & AddonManager.PERM_CAN_UPGRADE) > 0;
let uninstallable = (addon.permissions & AddonManager.PERM_CAN_UNINSTALL) > 0;
let blocked = "";
switch(addon.blocklistState) {
case Ci.nsIBlocklistService.STATE_BLOCKED:
blocked = strings.GetStringFromName("addonBlocked.blocked")
break;
case Ci.nsIBlocklistService.STATE_SOFTBLOCKED:
blocked = strings.GetStringFromName("addonBlocked.softBlocked");
break;
case Ci.nsIBlocklistService.STATE_OUTDATED:
blocked = srings.GetStringFromName("addonBlocked.outdated");
break;
}
if (updateable)
let listitem = self._createLocalAddon(items[i]);
if ((items[i].permissions & AddonManager.PERM_CAN_UPGRADE) > 0)
anyUpdateable = true;
let listitem = self._createItem(addon, "local");
listitem.setAttribute("isDisabled", !addon.isActive);
listitem.setAttribute("appDisabled", addon.appDisabled);
listitem.setAttribute("appManaged", appManaged);
listitem.setAttribute("description", addon.description);
listitem.setAttribute("optionsURL", addon.optionsURL ? addon.optionsURL : "");
listitem.setAttribute("opType", opType);
listitem.setAttribute("updateable", updateable);
listitem.setAttribute("isReadonly", !uninstallable);
if (blocked)
listitem.setAttribute("blockedStatus", blocked);
listitem.addon = addon;
self._list.insertBefore(listitem, self._repoItem);
self.addItem(listitem);
}
// Load the search engines
@ -349,7 +355,7 @@ var ExtensionsView = {
listitem.setAttribute("optionsURL", "");
listitem.setAttribute("opType", engine.hidden ? "needs-disable" : "");
listitem.setAttribute("updateable", "false");
self._list.insertBefore(listitem, self._repoItem);
self.addItem(listitem);
}
if (engines.length + items.length == 0)
@ -360,6 +366,19 @@ var ExtensionsView = {
});
},
addItem : function ev_addItem(aItem, aPosition) {
if (aPosition == "repo")
return this._list.appendChild(aItem);
else if (aPosition == "local")
return this._list.insertBefore(aItem, this._localItem.nextSibling);
else
return this._list.insertBefore(aItem, this._repoItem);
},
removeItem : function ev_moveItem(aItem) {
this._list.removeChild(aItem);
},
enable: function ev_enable(aItem) {
let opType;
if (aItem.getAttribute("type") == "search") {
@ -386,10 +405,13 @@ var ExtensionsView = {
aItem.addon.userDisabled = false;
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
if (opType == "needs-enable")
if (aItem.addon.pendingOperations & AddonManager.PENDING_ENABLE) {
this.showRestart();
else
this.hideRestart();
} else {
aItem.removeAttribute("isDisabled");
if (aItem.getAttribute("opType") == "needs-disable")
this.hideRestart();
};
}
aItem.setAttribute("opType", opType);
@ -408,10 +430,13 @@ var ExtensionsView = {
aItem.addon.userDisabled = true;
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
if (opType == "needs-disable")
if (aItem.addon.pendingOperations & AddonManager.PENDING_DISABLE) {
this.showRestart();
else
this.hideRestart();
} else {
aItem.setAttribute("isDisabled", !aItem.addon.isActive);
if (aItem.getAttribute("opType") == "needs-enable")
this.hideRestart();
}
}
aItem.setAttribute("opType", opType);
@ -427,18 +452,26 @@ var ExtensionsView = {
// the search-engine-modified observer in browser.js will take care of
// updating the list
} else {
if (!aItem.addon) {
this._list.removeChild(aItem);
return;
}
aItem.addon.uninstall();
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
if (opType == "needs-uninstall")
if (aItem.addon.pendingOperations & AddonManager.PENDING_UNINSTALL) {
this.showRestart();
// A disabled addon doesn't need a restart so it has no pending ops and
// can't be cancelled
if (!aItem.addon.isActive && opType == "")
opType = "needs-uninstall";
// A disabled addon doesn't need a restart so it has no pending ops and
// can't be cancelled
if (!aItem.addon.isActive && opType == "")
opType = "needs-uninstall";
aItem.setAttribute("opType", opType);
aItem.setAttribute("opType", opType);
} else {
this._list.removeChild(aItem);
}
}
},
@ -482,10 +515,7 @@ var ExtensionsView = {
item.setAttribute("hidebutton", "true");
item.setAttribute("hidethrobber", aHideThrobber);
if (aSection == "repo")
this._list.appendChild(item);
else
this._list.insertBefore(item, this._repoItem);
this.addItem(item, aSection);
return item;
},
@ -544,7 +574,7 @@ var ExtensionsView = {
if (aShowRating)
listitem.setAttribute("rating", addon.averageRating);
let item = this._list.appendChild(listitem);
let item = this.addItem(listitem, "repo");
// Hide any overflow add-ons. The user can see them later by pressing the
// "See More" button
@ -594,7 +624,7 @@ var ExtensionsView = {
whatare.setAttribute("button", strings.GetStringFromName("addonsWhatAre.button"));
whatare.setAttribute("onbuttoncommand", "BrowserUI.newTab('" + browseURL + "');");
this._list.appendChild(whatare);
this.addItem(whatare, "repo");
if (aRecommendedAddons.length == 0 && aBrowseAddons.length == 0) {
let msg = strings.GetStringFromName("addonsSearchNone.recommended");
@ -631,7 +661,7 @@ var ExtensionsView = {
showmore.setAttribute("hidepage", totalAddons > kAddonPageSize ? "false" : "true");
showmore.setAttribute("sitelabel", strings.GetStringFromName("addonsBrowseAll.browseSite"));
showmore.setAttribute("onsitecommand", "ExtensionsView.showMoreResults('" + browseURL + "');");
this._list.appendChild(showmore);
this.addItem(showmore, "repo");
let evt = document.createEvent("Events");
evt.initEvent("ViewChanged", true, false);
@ -674,7 +704,7 @@ var ExtensionsView = {
url = url.replace(/%TERMS%/g, encodeURIComponent(this.searchBox.value));
url = formatter.formatURL(url);
showmore.setAttribute("onsitecommand", "ExtensionsView.showMoreResults('" + url + "');");
this._list.appendChild(showmore);
this.addItem(showmore, "repo");
}
this.displaySectionMessage("repo", null, strings.GetStringFromName("addonsSearchSuccess2.button"), true);
@ -854,24 +884,53 @@ function AddonInstallListener() {
AddonInstallListener.prototype = {
onInstallEnded: function(aInstall, aAddon) {
if (aInstall.existingAddon && (aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE))
ExtensionsView.showRestart("update");
else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
ExtensionsView.showRestart("normal");
let needsRestart = false;
let mode = "";
if (aInstall.existingAddon && (aInstall.existingAddon.pendingOperations & AddonManager.PENDING_UPGRADE)) {
needsRestart = true;
mode = "update";
} else if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL) {
needsRestart = true;
mode = "normal";
}
// if we already have a mode, then we need to show a restart notification
// otherwise, we are likely a bootstrapped addon
if (needsRestart)
ExtensionsView.showRestart(mode);
this._showInstallCompleteAlert(true, needsRestart);
// only do this if the view has already been inited
if (!ExtensionsView._list)
return;
let element = ExtensionsView.getElementForAddon(aAddon.id);
if (element) {
element.setAttribute("opType", "needs-restart");
element.setAttribute("status", "success");
if (!element) {
element = ExtensionsView._createLocalAddon(aAddon);
ExtensionsView.addItem(element, "local");
}
// If we are updating an add-on, change the status
if (element.hasAttribute("updating")) {
let strings = Strings.browser;
element.setAttribute("updateStatus", strings.formatStringFromName("addonUpdate.updated", [aAddon.version], 1));
element.removeAttribute("updating");
if (needsRestart) {
element.setAttribute("opType", "needs-restart");
} else {
if (element.getAttribute("typeName") == "search") {
if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE)
document.getElementById("addons-update-all").disabled = false;
ExtensionsView.removeItem(element);
element = ExtensionsView._createLocalAddon(aAddon);
ExtensionsView.addItem(element, "local");
}
}
this._showInstallCompleteAlert(true);
element.setAttribute("status", "success");
// If we are updating an add-on, change the status
if (element.hasAttribute("updating")) {
let strings = Elements.browserBundle;
element.setAttribute("updateStatus", strings.getFormattedString("addonUpdate.updated", [aAddon.version]));
element.removeAttribute("updating");
}
},
onInstallFailed: function(aInstall, aError) {
@ -930,7 +989,7 @@ AddonInstallListener.prototype = {
this.onInstallFailed(aInstall, aError);
},
onDownloadCancelled: function(aInstall, aAddon) {
onDownloadCancelled: function(aInstall) {
let strings = Strings.browser;
let brandBundle = Strings.brand;
let brandShortName = brandBundle.GetStringFromName("brandShortName");
@ -941,9 +1000,9 @@ AddonInstallListener.prototype = {
let error = (host || aInstall.error == 0) ? "addonError" : "addonLocalError";
if (aInstall.error != 0)
error += aInstall.error;
else if (aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
else if (aInstall.addon && aInstall.addon.blocklistState == Ci.nsIBlocklistService.STATE_BLOCKED)
error += "Blocklisted";
else if (!aInstall.addon.isCompatible || !aInstall.addon.isPlatformCompatible)
else if (aInstall.addon && (!aInstall.addon.isCompatible || !aInstall.addon.isPlatformCompatible))
error += "Incompatible";
else {
ExtensionsView.hideAlerts();
@ -960,10 +1019,14 @@ AddonInstallListener.prototype = {
ExtensionsView.showAlert(messageString);
},
_showInstallCompleteAlert: function xpidm_showAlert(aSucceeded) {
_showInstallCompleteAlert: function xpidm_showAlert(aSucceeded, aNeedsRestart) {
let strings = Strings.browser;
let msg = aSucceeded ? strings.GetStringFromName("alertAddonsInstalled") :
strings.GetStringFromName("alertAddonsFail");
ExtensionsView.showAlert(msg);
let stringName = "alertAddonsFail";
if (aSucceeded) {
stringName = "alertAddonsInstalled";
if (!aNeedsRestart)
stringName += "NoRestart";
}
ExtensionsView.showAlert(strings.GetStringFromName(stringName));
},
};