mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 562495 - Support the new add-ons manager [r=dtownsend]
This commit is contained in:
parent
532ae3fcec
commit
732bb72489
@ -148,11 +148,6 @@ pref("layout.css.devPixelsPerPx", "1");
|
||||
pref("layout.spellcheckDefault", 1);
|
||||
|
||||
/* extension manager and xpinstall */
|
||||
pref("xpinstall.dialog.confirm", "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul");
|
||||
pref("xpinstall.dialog.progress.skin", "chrome://browser/content/browser.xul");
|
||||
pref("xpinstall.dialog.progress.chrome", "chrome://browser/content/browser.xul");
|
||||
pref("xpinstall.dialog.progress.type.skin", "navigator:browser");
|
||||
pref("xpinstall.dialog.progress.type.chrome", "navigator:browser");
|
||||
pref("xpinstall.whitelist.add", "addons.mozilla.org");
|
||||
|
||||
pref("extensions.autoupdate.enabled", true);
|
||||
|
@ -15,7 +15,7 @@
|
||||
<binding id="extension-local" extends="chrome://browser/content/bindings.xml#richlistitem">
|
||||
<content orient="vertical">
|
||||
<xul:hbox align="start">
|
||||
<xul:image xbl:inherits="src=iconURL"/>
|
||||
<xul:image class="addon-image" xbl:inherits="src=iconURL"/>
|
||||
<xul:vbox flex="1">
|
||||
<xul:hbox align="center">
|
||||
<xul:label class="title" xbl:inherits="value=name" crop="end" flex="1"/>
|
||||
|
@ -474,7 +474,7 @@ var Browser = {
|
||||
window.controllers.appendController(BrowserUI);
|
||||
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.addObserver(gXPInstallObserver, "xpinstall-install-blocked", false);
|
||||
os.addObserver(gXPInstallObserver, "addon-install-blocked", false);
|
||||
os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
|
||||
|
||||
// clear out tabs the user hasn't touched lately on memory crunch
|
||||
@ -623,7 +623,7 @@ var Browser = {
|
||||
this._pluginObserver.stop();
|
||||
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.removeObserver(gXPInstallObserver, "xpinstall-install-blocked");
|
||||
os.removeObserver(gXPInstallObserver, "addon-install-blocked");
|
||||
os.removeObserver(gSessionHistoryObserver, "browser:purge-session-history");
|
||||
os.removeObserver(MemoryObserver, "memory-pressure");
|
||||
os.removeObserver(BrowserSearch, "browser-search-engine-modified");
|
||||
@ -2485,13 +2485,18 @@ const gXPInstallObserver = {
|
||||
{
|
||||
var brandBundle = document.getElementById("bundle_brand");
|
||||
switch (aTopic) {
|
||||
case "xpinstall-install-blocked":
|
||||
var installInfo = aSubject.QueryInterface(Ci.nsIXPIInstallInfo);
|
||||
case "addon-install-blocked":
|
||||
var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
|
||||
var host = installInfo.originatingURI.host;
|
||||
var brandShortName = brandBundle.getString("brandShortName");
|
||||
var notificationName, messageString, buttons;
|
||||
var strings = Elements.browserBundle;
|
||||
if (!gPrefService.getBoolPref("xpinstall.enabled")) {
|
||||
var enabled = true;
|
||||
try {
|
||||
enabled = gPrefService.getBoolPref("xpinstall.enabled");
|
||||
}
|
||||
catch (e) {}
|
||||
if (!enabled) {
|
||||
notificationName = "xpinstall-disabled";
|
||||
if (gPrefService.prefIsLocked("xpinstall.enabled")) {
|
||||
messageString = strings.getString("xpinstallDisabledMessageLocked");
|
||||
@ -2521,9 +2526,8 @@ const gXPInstallObserver = {
|
||||
accessKey: null,
|
||||
popup: null,
|
||||
callback: function() {
|
||||
// Kick off the xpinstall
|
||||
var mgr = Cc["@mozilla.org/xpinstall/install-manager;1"].createInstance(Ci.nsIXPInstallManager);
|
||||
mgr.initManagerWithInstallInfo(installInfo);
|
||||
// Kick off the install
|
||||
installInfo.install();
|
||||
return false;
|
||||
}
|
||||
}];
|
||||
|
@ -43,10 +43,13 @@ const PREF_GETADDONS_MAXRESULTS = "extensions.getAddons.maxResults";
|
||||
|
||||
const URI_GENERIC_ICON_XPINSTALL = "chrome://browser/skin/images/alert-addons-30.png";
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "AddonManager", function() {
|
||||
Cu.import("resource://gre/modules/AddonManager.jsm");
|
||||
return AddonManager;
|
||||
});
|
||||
|
||||
var ExtensionsView = {
|
||||
_extmgr: null,
|
||||
_pref: null,
|
||||
_rdf: null,
|
||||
_ios: null,
|
||||
_strings: {},
|
||||
_repo: null,
|
||||
@ -59,38 +62,16 @@ var ExtensionsView = {
|
||||
_restartCount: 0,
|
||||
_observerIndex: -1,
|
||||
|
||||
_isXPInstallEnabled: function ev__isXPInstallEnabled() {
|
||||
let enabled = false;
|
||||
let locked = false;
|
||||
try {
|
||||
enabled = this._pref.getBoolPref("xpinstall.enabled");
|
||||
if (enabled)
|
||||
return true;
|
||||
locked = this._pref.prefIsLocked("xpinstall.enabled");
|
||||
}
|
||||
catch (e) { }
|
||||
|
||||
return false;
|
||||
_getOpTypeForOperations: function ev__getOpTypeForOperations(aOperations) {
|
||||
if (aOperations & AddonManager.PENDING_UNINSTALL)
|
||||
return "needs-uninstall";
|
||||
if (aOperations & AddonManager.PENDING_ENABLE)
|
||||
return "needs-enable";
|
||||
if (aOperations & AddonManager.PENDING_DISABLE)
|
||||
return "needs-disable";
|
||||
return "";
|
||||
},
|
||||
|
||||
_getIDFromURI: function ev__getIDFromURI(aURI) {
|
||||
if (aURI.substring(0, PREFIX_ITEM_URI.length) == PREFIX_ITEM_URI)
|
||||
return aURI.substring(PREFIX_ITEM_URI.length);
|
||||
return aURI;
|
||||
},
|
||||
|
||||
_getRDFProperty: function ev__getRDFProperty(aID, aName) {
|
||||
let resource = this._rdf.GetResource(PREFIX_ITEM_URI + aID);
|
||||
if (resource) {
|
||||
let ds = this._extmgr.datasource;
|
||||
|
||||
let target = ds.GetTarget(resource, this._rdf.GetResource(PREFIX_NS_EM + aName), true);
|
||||
if (target && target instanceof Ci.nsIRDFLiteral)
|
||||
return target.Value;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
|
||||
_createItem: function ev__createItem(aAddon, aTypeName) {
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("id", PREFIX_ITEM_URI + aAddon.id);
|
||||
@ -135,10 +116,10 @@ var ExtensionsView = {
|
||||
}
|
||||
},
|
||||
|
||||
getElementForAddon: function ev_getElementForAddon(aID) {
|
||||
let element = document.getElementById(PREFIX_ITEM_URI + aID);
|
||||
getElementForAddon: function ev_getElementForAddon(aKey) {
|
||||
let element = document.getElementById(PREFIX_ITEM_URI + aKey);
|
||||
if (!element && this._list)
|
||||
element = this._list.getElementsByAttribute("xpiURL", aID)[0];
|
||||
element = this._list.getElementsByAttribute("xpiURL", aKey)[0];
|
||||
return element;
|
||||
},
|
||||
|
||||
@ -223,19 +204,15 @@ var ExtensionsView = {
|
||||
},
|
||||
|
||||
init: function ev_init() {
|
||||
if (this._extmgr)
|
||||
if (this._ios)
|
||||
return;
|
||||
|
||||
this._extmgr = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
|
||||
this._ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
this._dloadmgr = new XPInstallDownloadManager();
|
||||
this._observerIndex = this._extmgr.addInstallListener(this._dloadmgr);
|
||||
|
||||
// Now look and see if we're being opened by XPInstall
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.addObserver(this._dloadmgr, "xpinstall-download-started", false);
|
||||
this._dloadmgr = new AddonInstallListener();
|
||||
AddonManager.addInstallListener(this._dloadmgr);
|
||||
|
||||
// Watch for add-on update notifications
|
||||
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.addObserver(this, "addon-update-started", false);
|
||||
os.addObserver(this, "addon-update-ended", false);
|
||||
|
||||
@ -257,7 +234,6 @@ var ExtensionsView = {
|
||||
return;
|
||||
|
||||
this._pref = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
|
||||
this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
|
||||
this._search = Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsIBrowserSearchService);
|
||||
|
||||
let repository = "@mozilla.org/extensions/addon-repository;1";
|
||||
@ -282,10 +258,10 @@ var ExtensionsView = {
|
||||
}
|
||||
|
||||
let strings = Elements.browserBundle;
|
||||
this._strings["addonType.2"] = strings.getString("addonType.2");
|
||||
this._strings["addonType.4"] = strings.getString("addonType.4");
|
||||
this._strings["addonType.8"] = strings.getString("addonType.8");
|
||||
this._strings["addonType.1024"] = strings.getString("addonType.1024");
|
||||
this._strings["addonType.extension"] = strings.getString("addonType.2");
|
||||
this._strings["addonType.theme"] = strings.getString("addonType.4");
|
||||
this._strings["addonType.locale"] = strings.getString("addonType.8");
|
||||
this._strings["addonType.search"] = strings.getString("addonType.1024");
|
||||
|
||||
let self = this;
|
||||
setTimeout(function() {
|
||||
@ -295,12 +271,11 @@ var ExtensionsView = {
|
||||
},
|
||||
|
||||
uninit: function ev_uninit() {
|
||||
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.removeObserver(this._dloadmgr, "xpinstall-download-started");
|
||||
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.removeObserver(this, "addon-update-started");
|
||||
os.removeObserver(this, "addon-update-ended");
|
||||
|
||||
this._extmgr.removeInstallListenerAt(this._observerIndex);
|
||||
AddonManager.removeInstallListener(this._dloadmgr);
|
||||
},
|
||||
|
||||
hideOnSelect: function ev_handleEvent(aEvent) {
|
||||
@ -312,76 +287,71 @@ var ExtensionsView = {
|
||||
getAddonsFromLocal: function ev_getAddonsFromLocal() {
|
||||
this.clearSection("local");
|
||||
|
||||
let items = this._extmgr.getItemList(Ci.nsIUpdateItem.TYPE_ANY, {});
|
||||
let self = this;
|
||||
AddonManager.getAddonsByTypes(["extension", "theme", "locale"], function(items) {
|
||||
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_UPDATE) > 0;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let addon = items[i];
|
||||
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);
|
||||
listitem.setAttribute("opType", opType);
|
||||
listitem.setAttribute("updateable", updateable);
|
||||
listitem.addon = addon;
|
||||
self._list.insertBefore(listitem, self._repoItem);
|
||||
}
|
||||
|
||||
// Some information is not directly accessible from the extmgr
|
||||
let isDisabled = this._getRDFProperty(addon.id, "isDisabled") == "true";
|
||||
let appDisabled = this._getRDFProperty(addon.id, "appDisabled");
|
||||
let appManaged = this._getRDFProperty(addon.id, "appManaged");
|
||||
let desc = this._getRDFProperty(addon.id, "description");
|
||||
let optionsURL = this._getRDFProperty(addon.id, "optionsURL");
|
||||
let opType = this._getRDFProperty(addon.id, "opType");
|
||||
let updateable = this._getRDFProperty(addon.id, "updateable");
|
||||
// Load the search engines
|
||||
let defaults = self._search.getDefaultEngines({ }).map(function (e) e.name);
|
||||
function isDefault(aEngine)
|
||||
defaults.indexOf(aEngine.name) != -1
|
||||
|
||||
let listitem = this._createItem(addon, "local");
|
||||
listitem.setAttribute("isDisabled", isDisabled);
|
||||
listitem.setAttribute("appDisabled", appDisabled);
|
||||
listitem.setAttribute("appManaged", appManaged);
|
||||
listitem.setAttribute("description", desc);
|
||||
listitem.setAttribute("optionsURL", optionsURL);
|
||||
listitem.setAttribute("opType", opType);
|
||||
listitem.setAttribute("updateable", updateable);
|
||||
this._list.insertBefore(listitem, this._repoItem);
|
||||
}
|
||||
let strings = Elements.browserBundle;
|
||||
let defaultDescription = strings.getString("addonsSearchEngine.description");
|
||||
|
||||
// Load the search engines
|
||||
let defaults = this._search.getDefaultEngines({ }).map(function (e) e.name);
|
||||
function isDefault(aEngine)
|
||||
defaults.indexOf(aEngine.name) != -1
|
||||
let engines = self._search.getEngines({ });
|
||||
for (let e = 0; e < engines.length; e++) {
|
||||
let engine = engines[e];
|
||||
let addon = {};
|
||||
addon.id = engine.name;
|
||||
addon.type = "search";
|
||||
addon.name = engine.name;
|
||||
addon.version = "";
|
||||
addon.iconURL = engine.iconURI ? engine.iconURI.spec : "";
|
||||
|
||||
let strings = Elements.browserBundle;
|
||||
let defaultDescription = strings.getString("addonsSearchEngine.description");
|
||||
let listitem = self._createItem(addon, "searchplugin");
|
||||
listitem._engine = engine;
|
||||
listitem.setAttribute("isDisabled", engine.hidden ? "true" : "false");
|
||||
listitem.setAttribute("appDisabled", "false");
|
||||
listitem.setAttribute("appManaged", isDefault(engine));
|
||||
listitem.setAttribute("description", engine.description || defaultDescription);
|
||||
listitem.setAttribute("optionsURL", "");
|
||||
listitem.setAttribute("opType", engine.hidden ? "needs-disable" : "");
|
||||
listitem.setAttribute("updateable", "false");
|
||||
self._list.insertBefore(listitem, self._repoItem);
|
||||
}
|
||||
|
||||
let engines = this._search.getEngines({ });
|
||||
for (let e = 0; e < engines.length; e++) {
|
||||
let engine = engines[e];
|
||||
let addon = {};
|
||||
addon.id = engine.name;
|
||||
addon.type = 1024;
|
||||
addon.name = engine.name;
|
||||
addon.version = "";
|
||||
addon.iconURL = engine.iconURI ? engine.iconURI.spec : "";
|
||||
|
||||
let listitem = this._createItem(addon, "searchplugin");
|
||||
listitem._engine = engine;
|
||||
listitem.setAttribute("isDisabled", engine.hidden ? "true" : "false");
|
||||
listitem.setAttribute("appDisabled", "false");
|
||||
listitem.setAttribute("appManaged", isDefault(engine));
|
||||
listitem.setAttribute("description", engine.description || defaultDescription);
|
||||
listitem.setAttribute("optionsURL", "");
|
||||
listitem.setAttribute("opType", engine.hidden ? "needs-disable" : "");
|
||||
listitem.setAttribute("updateable", "false");
|
||||
this._list.insertBefore(listitem, this._repoItem);
|
||||
}
|
||||
|
||||
if (engines.length + items.length == 0) {
|
||||
this.displaySectionMessage("local", strings.getString("addonsLocalNone.label"), null, true);
|
||||
document.getElementById("addons-update-all").disabled = true;
|
||||
}
|
||||
if (engines.length + items.length == 0) {
|
||||
self.displaySectionMessage("local", strings.getString("addonsLocalNone.label"), null, true);
|
||||
document.getElementById("addons-update-all").disabled = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
enable: function ev_enable(aItem) {
|
||||
let opType;
|
||||
if (aItem.getAttribute("type") == "1024") {
|
||||
if (aItem.getAttribute("type") == "search") {
|
||||
aItem._engine.hidden = false;
|
||||
opType = "needs-enable";
|
||||
} else {
|
||||
let id = this._getIDFromURI(aItem.id);
|
||||
this._extmgr.enableItem(id);
|
||||
opType = this._getRDFProperty(id, "opType");
|
||||
aItem.addon.userDisabled = false;
|
||||
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
|
||||
|
||||
if (opType == "needs-enable")
|
||||
this.showRestart();
|
||||
@ -394,13 +364,12 @@ var ExtensionsView = {
|
||||
|
||||
disable: function ev_disable(aItem) {
|
||||
let opType;
|
||||
if (aItem.getAttribute("type") == "1024") {
|
||||
if (aItem.getAttribute("type") == "search") {
|
||||
aItem._engine.hidden = true;
|
||||
opType = "needs-disable";
|
||||
} else {
|
||||
let id = this._getIDFromURI(aItem.id);
|
||||
this._extmgr.disableItem(id);
|
||||
opType = this._getRDFProperty(id, "opType");
|
||||
aItem.addon.userDisabled = true;
|
||||
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
|
||||
|
||||
if (opType == "needs-disable")
|
||||
this.showRestart();
|
||||
@ -413,7 +382,7 @@ var ExtensionsView = {
|
||||
|
||||
uninstall: function ev_uninstall(aItem) {
|
||||
let opType;
|
||||
if (aItem.getAttribute("type") == "1024") {
|
||||
if (aItem.getAttribute("type") == "search") {
|
||||
// Make sure the engine isn't hidden before removing it, to make sure it's
|
||||
// visible if the user later re-adds it (works around bug 341833)
|
||||
aItem._engine.hidden = false;
|
||||
@ -421,9 +390,8 @@ var ExtensionsView = {
|
||||
// the search-engine-modified observer in browser.js will take care of
|
||||
// updating the list
|
||||
} else {
|
||||
let id = this._getIDFromURI(aItem.id);
|
||||
this._extmgr.uninstallItem(id);
|
||||
opType = this._getRDFProperty(id, "opType");
|
||||
aItem.addon.uninstall();
|
||||
opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
|
||||
|
||||
if (opType == "needs-uninstall")
|
||||
this.showRestart();
|
||||
@ -432,69 +400,19 @@ var ExtensionsView = {
|
||||
},
|
||||
|
||||
cancelUninstall: function ev_cancelUninstall(aItem) {
|
||||
let id = this._getIDFromURI(aItem.id);
|
||||
this._extmgr.cancelUninstallItem(id);
|
||||
aItem.addon.cancelUninstall();
|
||||
|
||||
this.hideRestart();
|
||||
|
||||
let opType = this._getRDFProperty(id, "opType");
|
||||
let opType = this._getOpTypeForOperations(aItem.addon.pendingOperations);
|
||||
aItem.setAttribute("opType", opType);
|
||||
},
|
||||
|
||||
_installCallback: function ev__installCallback(aItem, aStatus) {
|
||||
if (aStatus == -210) {
|
||||
// User cancelled
|
||||
aItem.removeAttribute("opType");
|
||||
}
|
||||
else if (aStatus < 0) {
|
||||
// Some other error
|
||||
aItem.removeAttribute("opType");
|
||||
let bundles = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
|
||||
let strings = bundles.createBundle("chrome://global/locale/xpinstall/xpinstall.properties");
|
||||
|
||||
try {
|
||||
var msg = strings.GetStringFromName("error" + aStatus);
|
||||
} catch (ex) {
|
||||
msg = strings.formatStringFromName("unknown.error", [aStatus]);
|
||||
}
|
||||
aItem.setAttribute("error", msg);
|
||||
}
|
||||
else {
|
||||
// Success
|
||||
aItem.setAttribute("opType", "needs-restart");
|
||||
}
|
||||
},
|
||||
|
||||
installFromRepo: function ev_installFromRepo(aItem) {
|
||||
if (!this._isXPInstallEnabled())
|
||||
return;
|
||||
|
||||
if (aItem.hasAttribute("eula")) {
|
||||
var eula = {
|
||||
name: aSelectedItem.getAttribute("name"),
|
||||
text: aSelectedItem.getAttribute("eula"),
|
||||
accepted: false
|
||||
};
|
||||
|
||||
// TODO: eula
|
||||
//window.openDialog("chrome://mozapps/content/extensions/eula.xul", "_blank",
|
||||
// "chrome,dialog,modal,centerscreen,resizable=no", eula);
|
||||
//if (!eula.accepted)
|
||||
// return;
|
||||
}
|
||||
|
||||
var details = {
|
||||
URL: aItem.getAttribute("xpiURL"),
|
||||
Hash: aItem.getAttribute("xpiHash"),
|
||||
IconURL: aItem.getAttribute("iconURL"),
|
||||
toString: function () { return this.URL; }
|
||||
};
|
||||
|
||||
var params = [];
|
||||
params[aItem.getAttribute("name")] = details;
|
||||
|
||||
let self = this;
|
||||
InstallTrigger.install(params, function(aURL, aStatus) { self._installCallback(aItem, aStatus); });
|
||||
AddonManager.getInstallForURL(aItem.getAttribute("xpiURL"),
|
||||
function(aInstall) { aInstall.install(); },
|
||||
"application/x-xpinstall",
|
||||
aItem.getAttribute("xpiHash"));
|
||||
|
||||
// display the progress bar early
|
||||
let opType = aItem.getAttribute("opType");
|
||||
@ -502,10 +420,6 @@ var ExtensionsView = {
|
||||
aItem.setAttribute("opType", "needs-install");
|
||||
},
|
||||
|
||||
installFromXPI: function ev_installAddons(aItems, aManager) {
|
||||
this._extmgr.addDownloads(aItems, aItems.length, aManager);
|
||||
},
|
||||
|
||||
_isSafeURI: function ev_isSafeURI(aURL) {
|
||||
try {
|
||||
var uri = this._ios.newURI(aURL, null, null);
|
||||
@ -594,6 +508,10 @@ var ExtensionsView = {
|
||||
if (urlproperties.some(function (p) !this._isSafeURI(addon[p]), this))
|
||||
continue;
|
||||
|
||||
// Convert the numeric type to a string
|
||||
let types = {"2":"extension", "4":"theme", "8":"locale"};
|
||||
addon.type = types[addon.type];
|
||||
|
||||
let listitem = this._createItem(addon, "search");
|
||||
listitem.setAttribute("description", addon.summary);
|
||||
listitem.setAttribute("homepageURL", addon.homepageURL);
|
||||
@ -668,9 +586,6 @@ var ExtensionsView = {
|
||||
},
|
||||
|
||||
updateAll: function ev_updateAll() {
|
||||
if (!this._isXPInstallEnabled())
|
||||
return;
|
||||
|
||||
let aus = Cc["@mozilla.org/browser/addon-update-service;1"].getService(Ci.nsITimerCallback);
|
||||
aus.notify(null);
|
||||
|
||||
@ -682,9 +597,11 @@ var ExtensionsView = {
|
||||
if (!document)
|
||||
return;
|
||||
|
||||
let addon = aSubject.QueryInterface(Ci.nsIUpdateItem);
|
||||
let json = aSubject.QueryInterface(Ci.nsISupportsString).data;
|
||||
let addon = JSON.parse(json);
|
||||
|
||||
let strings = Elements.browserBundle;
|
||||
let element = document.getElementById(PREFIX_ITEM_URI + addon.id);
|
||||
let element = this.getElementForAddon(addon.id);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
@ -693,35 +610,23 @@ var ExtensionsView = {
|
||||
element.setAttribute("updateStatus", strings.getString("addonUpdate.checking"));
|
||||
break;
|
||||
case "addon-update-ended":
|
||||
let status = parseInt(aData);
|
||||
let updateable = false;
|
||||
let statusMsg = null;
|
||||
const nsIAUCL = Ci.nsIAddonUpdateCheckListener;
|
||||
switch (status) {
|
||||
case nsIAUCL.STATUS_UPDATE:
|
||||
switch (aData) {
|
||||
case "update":
|
||||
statusMsg = strings.getFormattedString("addonUpdate.updating", [addon.version]);
|
||||
updateable = true;
|
||||
break;
|
||||
case nsIAUCL.STATUS_VERSIONINFO:
|
||||
case "compatibility":
|
||||
statusMsg = strings.getString("addonUpdate.compatibility");
|
||||
break;
|
||||
case nsIAUCL.STATUS_FAILURE:
|
||||
case "error":
|
||||
statusMsg = strings.getString("addonUpdate.error");
|
||||
break;
|
||||
case nsIAUCL.STATUS_DISABLED:
|
||||
statusMsg = strings.getString("addonUpdate.disabled");
|
||||
break;
|
||||
case nsIAUCL.STATUS_APP_MANAGED:
|
||||
case nsIAUCL.STATUS_NO_UPDATE:
|
||||
case "no-update":
|
||||
// Ignore if no updated was found. Just let the message go blank.
|
||||
//statusMsg = strings.getString("addonUpdate.noupdate");
|
||||
break;
|
||||
case nsIAUCL.STATUS_NOT_MANAGED:
|
||||
statusMsg = strings.getString("addonUpdate.notsupported");
|
||||
break;
|
||||
case nsIAUCL.STATUS_READ_ONLY:
|
||||
statusMsg = strings.getString("addonUpdate.notsupported");
|
||||
break;
|
||||
default:
|
||||
// Ignore if no updated was found. Just let the message go blank.
|
||||
//statusMsg = strings.getString("addonUpdate.noupdate");
|
||||
@ -732,7 +637,7 @@ var ExtensionsView = {
|
||||
else
|
||||
element.removeAttribute("updateStatus");
|
||||
|
||||
// Tag the add-on so the XPInstallDownloadManager knows it's an update
|
||||
// Tag the add-on so the AddonInstallListener knows it's an update
|
||||
if (updateable)
|
||||
element.setAttribute("updating", "true");
|
||||
break;
|
||||
@ -782,87 +687,27 @@ var AddonSearchResults = {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// XPInstall download helper
|
||||
function XPInstallDownloadManager() {
|
||||
function AddonInstallListener() {
|
||||
}
|
||||
|
||||
XPInstallDownloadManager.prototype = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch (aTopic) {
|
||||
case "xpinstall-download-started":
|
||||
var params = aSubject.QueryInterface(Components.interfaces.nsISupportsArray);
|
||||
var paramBlock = params.GetElementAt(0).QueryInterface(Components.interfaces.nsISupportsInterfacePointer);
|
||||
paramBlock = paramBlock.data.QueryInterface(Components.interfaces.nsIDialogParamBlock);
|
||||
var manager = params.GetElementAt(1).QueryInterface(Components.interfaces.nsISupportsInterfacePointer);
|
||||
manager = manager.data.QueryInterface(Components.interfaces.nsIObserver);
|
||||
this.addDownloads(paramBlock, manager);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
addDownloads: function (aParams, aManager) {
|
||||
let count = aParams.GetInt(1);
|
||||
let items = [];
|
||||
for (var i = 0; i < count;) {
|
||||
let displayName = aParams.GetString(i++);
|
||||
let url = aParams.GetString(i++);
|
||||
let iconURL = aParams.GetString(i++);
|
||||
let uri = ExtensionsView._ios.newURI(url, null, null);
|
||||
let isTheme = uri.QueryInterface(Ci.nsIURL).fileExtension.toLowerCase() == "jar";
|
||||
let type = isTheme ? Ci.nsIUpdateItem.TYPE_THEME : Ci.nsIUpdateItem.TYPE_EXTENSION;
|
||||
if (!iconURL) {
|
||||
iconURL = isTheme ? "chrome://mozapps/skin/extensions/themeGeneric.png" :
|
||||
"chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
|
||||
}
|
||||
|
||||
let item = Cc["@mozilla.org/updates/item;1"].createInstance(Ci.nsIUpdateItem);
|
||||
item.init(url, " ", "app-profile", "", "", displayName, url, "", iconURL, "", "", type, "");
|
||||
items.push(item);
|
||||
|
||||
// Advance the enumerator
|
||||
let certName = aParams.GetString(i++);
|
||||
}
|
||||
|
||||
this._failed = [];
|
||||
this._succeeded = [];
|
||||
this._updating = false;
|
||||
|
||||
ExtensionsView.installFromXPI(items, aManager);
|
||||
|
||||
if (ExtensionsView.visible)
|
||||
return;
|
||||
|
||||
let strings = Elements.browserBundle;
|
||||
let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
|
||||
alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.getString("alertAddons"),
|
||||
strings.getString("alertAddonsInstalling"), false, "", null);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAddonInstallListener
|
||||
onDownloadStarted: function(aAddon) { },
|
||||
onDownloadEnded: function(aAddon) { },
|
||||
onInstallStarted: function(aAddon) { },
|
||||
onCompatibilityCheckStarted: function(aAddon) { },
|
||||
onCompatibilityCheckEnded: function(aAddon, aStatus) { },
|
||||
|
||||
_failed: [],
|
||||
_succeeded: [],
|
||||
AddonInstallListener.prototype = {
|
||||
_updating: false,
|
||||
onInstallEnded: function(aAddon, aStatus) {
|
||||
// Track success/failure for each addon
|
||||
if (Components.isSuccessCode(aStatus))
|
||||
this._succeeded.push(aAddon.id);
|
||||
else
|
||||
this._failed.push(aAddon.id);
|
||||
onInstallEnded: function(aInstall, aAddon) {
|
||||
// XXX fix updating stuff
|
||||
if (aAddon.pendingOperations & AddonManager.PENDING_INSTALL)
|
||||
ExtensionsView.showRestart(this._updating ? "update" : "normal");
|
||||
|
||||
this._showAlert(true);
|
||||
|
||||
if (!ExtensionsView.visible)
|
||||
return;
|
||||
|
||||
var element = ExtensionsView.getElementForAddon(aAddon.id);
|
||||
let element = ExtensionsView.getElementForAddon(aInstall.sourceURL);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
element.setAttribute("status", (Components.isSuccessCode(aStatus) ? "success" : "fail"));
|
||||
element.setAttribute("opType", "needs-restart");
|
||||
element.setAttribute("status", "success");
|
||||
|
||||
// If we are updating an add-on, change the status
|
||||
if (element.hasAttribute("updating")) {
|
||||
@ -875,19 +720,64 @@ XPInstallDownloadManager.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
onInstallsCompleted: function() {
|
||||
let strings = Elements.browserBundle;
|
||||
onInstallFailed: function(aInstall, aError) {
|
||||
this._showAlert(false);
|
||||
|
||||
// If even one add-on succeeded, display the restart notif
|
||||
if (this._succeeded.length > 0)
|
||||
ExtensionsView.showRestart(this._updating ? "update" : "normal");
|
||||
if (ExtensionsView.visible) {
|
||||
let element = ExtensionsView.getElementForAddon(aInstall.sourceURL);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
element.removeAttribute("opType");
|
||||
let bundles = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
|
||||
let strings = bundles.createBundle("chrome://global/locale/xpinstall/xpinstall.properties");
|
||||
|
||||
let error = null;
|
||||
switch (aError) {
|
||||
case AddonManager.ERROR_NETWORK_FAILURE:
|
||||
error = "error-228";
|
||||
break;
|
||||
case AddonManager.ERROR_INCORRECT_HASH:
|
||||
error = "error-261";
|
||||
break;
|
||||
case AddonManager.ERROR_CORRUPT_FILE:
|
||||
error = "error-207";
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
var msg = strings.GetStringFromName(error);
|
||||
} catch (ex) {
|
||||
msg = strings.formatStringFromName("unknown.error", [aError]);
|
||||
}
|
||||
element.setAttribute("error", msg);
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadProgress: function xpidm_onDownloadProgress(aInstall) {
|
||||
var element = ExtensionsView.getElementForAddon(aInstall.sourceURL);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
let opType = element.getAttribute("opType");
|
||||
if (!opType)
|
||||
element.setAttribute("opType", "needs-install");
|
||||
|
||||
let progress = Math.round((aInstall.progress / aInstall.maxProgress) * 100);
|
||||
element.setAttribute("progress", progress);
|
||||
},
|
||||
|
||||
onDownloadFailed: function(aInstall, aError) {
|
||||
this.onInstallFailed(aInstall, aError);
|
||||
},
|
||||
|
||||
_showAlert: function xpidm_showAlert(aSucceeded) {
|
||||
if (ExtensionsView.visible)
|
||||
return;
|
||||
|
||||
let message = strings.getString("alertAddonsInstalled");
|
||||
if (this._succeeded.length == 0 && this._failed.length > 0)
|
||||
message = strings.getString("alertAddonsFail");
|
||||
let strings = Elements.browserBundle;
|
||||
let message = aSucceeded ? strings.getString("alertAddonsInstalled") :
|
||||
strings.getString("alertAddonsFail");
|
||||
|
||||
let observer = {
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
@ -899,27 +789,5 @@ XPInstallDownloadManager.prototype = {
|
||||
let alerts = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
|
||||
alerts.showAlertNotification(URI_GENERIC_ICON_XPINSTALL, strings.getString("alertAddons"),
|
||||
message, true, "", observer);
|
||||
},
|
||||
|
||||
onDownloadProgress: function xpidm_onDownloadProgress(aAddon, aValue, aMaxValue) {
|
||||
var element = ExtensionsView.getElementForAddon(aAddon.id);
|
||||
if (!element)
|
||||
return;
|
||||
|
||||
let opType = element.getAttribute("opType");
|
||||
if (!opType) {
|
||||
element.setAttribute("opType", "needs-install");
|
||||
}
|
||||
var progress = Math.round((aValue / aMaxValue) * 100);
|
||||
element.setAttribute("progress", progress);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
QueryInterface: function(aIID) {
|
||||
if (!aIID.equals(Ci.nsIAddonInstallListener) &&
|
||||
!aIID.equals(Ci.nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
@ -43,9 +43,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "gObs",
|
||||
"@mozilla.org/observer-service;1",
|
||||
"nsIObserverService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gExtMgr",
|
||||
"@mozilla.org/extensions/manager;1",
|
||||
"nsIExtensionManager");
|
||||
XPCOMUtils.defineLazyGetter(this, "AddonManager", function() {
|
||||
Components.utils.import("resource://gre/modules/AddonManager.jsm");
|
||||
return AddonManager;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "gIO",
|
||||
"@mozilla.org/network/io-service;1",
|
||||
@ -96,10 +97,18 @@ AddonUpdateService.prototype = {
|
||||
|
||||
gIO.offline = false;
|
||||
|
||||
// Extension Manager will check for empty list and auto-check all add-ons
|
||||
let items = [];
|
||||
let listener = new UpdateCheckListener();
|
||||
gExtMgr.update(items, items.length, Ci.nsIExtensionManager.UPDATE_CHECK_NEWVERSION, listener);
|
||||
AddonManager.getAddonsByTypes(null, function(aAddonList) {
|
||||
aAddonList.forEach(function(aAddon) {
|
||||
if (aAddon.permissions & AddonManager.PERM_CAN_UPGRADE) {
|
||||
let data = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
data.data = JSON.stringify({ id: aAddon.id, name: aAddon.name });
|
||||
gObs.notifyObservers(data, "addon-update-started", null);
|
||||
|
||||
let listener = new UpdateCheckListener();
|
||||
aAddon.findUpdates(listener, AddonManager.UPDATE_WHEN_USER_REQUESTED);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -109,48 +118,37 @@ AddonUpdateService.prototype = {
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
function UpdateCheckListener() {
|
||||
this._addons = [];
|
||||
this._status = null;
|
||||
this._version = null;
|
||||
}
|
||||
|
||||
UpdateCheckListener.prototype = {
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAddonUpdateCheckListener
|
||||
onUpdateStarted: function ucl_onUpdateStarted() {
|
||||
onCompatibilityUpdateAvailable: function(aAddon) {
|
||||
this._status = "compatibility";
|
||||
},
|
||||
|
||||
onUpdateEnded: function ucl_onUpdateEnded() {
|
||||
if (!this._addons.length)
|
||||
return;
|
||||
|
||||
// If we have some updateable add-ons, let's download them
|
||||
let items = [];
|
||||
for (let i = 0; i < this._addons.length; i++)
|
||||
items.push(gExtMgr.getItemForID(this._addons[i]));
|
||||
|
||||
// Start the actual downloads
|
||||
gExtMgr.addDownloads(items, items.length, null);
|
||||
|
||||
// Remember that we downloaded new updates so we don't check again
|
||||
gNeedsRestart = true;
|
||||
onUpdateAvailable: function(aAddon, aInstall) {
|
||||
this._status = "update";
|
||||
this._version = aInstall.version;
|
||||
aInstall.install();
|
||||
},
|
||||
|
||||
onAddonUpdateStarted: function ucl_onAddonUpdateStarted(aAddon) {
|
||||
gObs.notifyObservers(aAddon, "addon-update-started", null);
|
||||
onNoUpdateAvailable: function(aAddon) {
|
||||
if (!this._status)
|
||||
this._status = "no-update";
|
||||
},
|
||||
|
||||
onAddonUpdateEnded: function ucl_onAddonUpdateEnded(aAddon, aStatus) {
|
||||
gObs.notifyObservers(aAddon, "addon-update-ended", aStatus);
|
||||
|
||||
// Save the add-on id if we can download an update
|
||||
if (aStatus == Ci.nsIAddonUpdateCheckListener.STATUS_UPDATE)
|
||||
this._addons.push(aAddon.id);
|
||||
},
|
||||
onUpdateFinished: function(aAddon, aError) {
|
||||
let data = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
if (this._version)
|
||||
data.data = JSON.stringify({ id: aAddon.id, name: aAddon.name, version: this._version });
|
||||
else
|
||||
data.data = JSON.stringify({ id: aAddon.id, name: aAddon.name });
|
||||
|
||||
QueryInterface: function ucl_QueryInterface(aIID) {
|
||||
if (!aIID.equals(Ci.nsIAddonUpdateCheckListener) &&
|
||||
!aIID.equals(Ci.nsISupports))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
if (aError)
|
||||
this._status = "error";
|
||||
|
||||
gObs.notifyObservers(data, "addon-update-ended", this._status);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -40,23 +40,27 @@ const Ci = Components.interfaces;
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// XPInstall Dialog Service
|
||||
// Web Install Prompt service
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
function XPInstallDialogService() { }
|
||||
function WebInstallPrompt() { }
|
||||
|
||||
XPInstallDialogService.prototype = {
|
||||
WebInstallPrompt.prototype = {
|
||||
classDescription: "XPInstall Dialog Service",
|
||||
contractID: "@mozilla.org/embedui/xpinstall-dialog-service;1",
|
||||
contractID: "@mozilla.org/addons/web-install-confirm;1",
|
||||
classID: Components.ID("{c1242012-27d8-477e-a0f1-0b098ffc329b}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIXPIDialogService, Ci.nsIXPIProgressDialog]),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.amIWebInstallPrompt]),
|
||||
|
||||
confirmInstall: function(aParent, aPackages, aCount) {
|
||||
confirm: function(aWindow, aURL, aInstalls) {
|
||||
// first check if the extensions panel is open : fast path to return true
|
||||
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||
let browser = wm.getMostRecentWindow("navigator:browser");
|
||||
if (browser.ExtensionsView.visible)
|
||||
return true;
|
||||
if (browser.ExtensionsView.visible) {
|
||||
aInstalls.forEach(function(install) {
|
||||
install.install();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
|
||||
let bundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
|
||||
@ -66,41 +70,16 @@ XPInstallDialogService.prototype = {
|
||||
let title = bundle.GetStringFromName("addonsConfirmInstall.title");
|
||||
let button = bundle.GetStringFromName("addonsConfirmInstall.install");
|
||||
|
||||
return prompt.confirmEx(null, title, aPackages[0], flags, button, null, null, null, {value: false}) == 0;
|
||||
},
|
||||
|
||||
openProgressDialog: function(aPackages, aCount, aManager) {
|
||||
// Create a param block with the packages
|
||||
let dpb = Cc["@mozilla.org/embedcomp/dialogparam;1"].createInstance(Ci.nsIDialogParamBlock);
|
||||
dpb.SetInt(0, 2); // OK and Cancel buttons
|
||||
dpb.SetInt(1, aPackages.length); // Number of strings
|
||||
dpb.SetNumberStrings(aPackages.length); // Add strings
|
||||
for (let i = 0; i < aPackages.length; ++i)
|
||||
dpb.SetString(i, aPackages[i]);
|
||||
|
||||
let dpbWrap = Cc["@mozilla.org/supports-interface-pointer;1"].createInstance(Ci.nsISupportsInterfacePointer);
|
||||
dpbWrap.data = dpb;
|
||||
dpbWrap.dataIID = Ci.nsIDialogParamBlock;
|
||||
|
||||
let obsWrap = Cc["@mozilla.org/supports-interface-pointer;1"].createInstance(Ci.nsISupportsInterfacePointer);
|
||||
obsWrap.data = aManager;
|
||||
obsWrap.dataIID = Ci.nsIObserver;
|
||||
|
||||
let params = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
|
||||
params.AppendElement(dpbWrap);
|
||||
params.AppendElement(obsWrap);
|
||||
|
||||
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
os.notifyObservers(params, "xpinstall-download-started", null);
|
||||
|
||||
// Give the nsXPInstallManager a progress dialog
|
||||
aManager.observe(this, "xpinstall-progress", "open");
|
||||
},
|
||||
|
||||
onStateChange: function(aIndex, aState, aError) { },
|
||||
onProgress: function(aIndex, aValue, aMax) { }
|
||||
aInstalls.forEach(function(install) {
|
||||
let result = (prompt.confirmEx(aWindow, title, install.name, flags, button, null, null, null, {value: false}) == 0);
|
||||
if (result)
|
||||
install.install();
|
||||
else
|
||||
install.cancel();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function NSGetModule(aCompMgr, aFileSpec) {
|
||||
return XPCOMUtils.generateModule([XPInstallDialogService]);
|
||||
return XPCOMUtils.generateModule([WebInstallPrompt]);
|
||||
}
|
||||
|
@ -391,6 +391,10 @@ toolbarbutton.page-button {
|
||||
}
|
||||
}
|
||||
|
||||
.addon-image {
|
||||
list-style-image: url("chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png");
|
||||
}
|
||||
|
||||
.addon-rating[rating] {
|
||||
width: 78px;
|
||||
height: 18px;
|
||||
|
Loading…
Reference in New Issue
Block a user