mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-08 00:07:30 +09:00
Move WebExtensions enabled Add-ons Manager
This commit is contained in:
parent
d7d16e7fbb
commit
358cd0404a
1100 changed files with 133 additions and 106 deletions
|
|
@ -1,240 +0,0 @@
|
|||
/* 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";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Log.jsm");
|
||||
|
||||
const XPINSTALL_MIMETYPE = "application/x-xpinstall";
|
||||
|
||||
const MSG_INSTALL_ENABLED = "WebInstallerIsInstallEnabled";
|
||||
const MSG_INSTALL_ADDONS = "WebInstallerInstallAddonsFromWebpage";
|
||||
const MSG_INSTALL_CALLBACK = "WebInstallerInstallCallback";
|
||||
|
||||
|
||||
var log = Log.repository.getLogger("AddonManager.InstallTrigger");
|
||||
log.level = Log.Level[Preferences.get("extensions.logging.enabled", false) ? "Warn" : "Trace"];
|
||||
|
||||
function CallbackObject(id, callback, urls, mediator) {
|
||||
this.id = id;
|
||||
this.callback = callback;
|
||||
this.urls = new Set(urls);
|
||||
this.callCallback = function(url, status) {
|
||||
try {
|
||||
this.callback(url, status);
|
||||
}
|
||||
catch (e) {
|
||||
log.warn("InstallTrigger callback threw an exception: " + e);
|
||||
}
|
||||
|
||||
this.urls.delete(url);
|
||||
if (this.urls.size == 0)
|
||||
mediator._callbacks.delete(id);
|
||||
};
|
||||
}
|
||||
|
||||
function RemoteMediator(window) {
|
||||
window.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let utils = window.getInterface(Ci.nsIDOMWindowUtils);
|
||||
this._windowID = utils.currentInnerWindowID;
|
||||
|
||||
this.mm = window
|
||||
.getInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
this.mm.addWeakMessageListener(MSG_INSTALL_CALLBACK, this);
|
||||
|
||||
this._lastCallbackID = 0;
|
||||
this._callbacks = new Map();
|
||||
}
|
||||
|
||||
RemoteMediator.prototype = {
|
||||
receiveMessage: function(message) {
|
||||
if (message.name == MSG_INSTALL_CALLBACK) {
|
||||
let payload = message.data;
|
||||
let callbackHandler = this._callbacks.get(payload.callbackID);
|
||||
if (callbackHandler) {
|
||||
callbackHandler.callCallback(payload.url, payload.status);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
enabled: function(url) {
|
||||
let params = {
|
||||
mimetype: XPINSTALL_MIMETYPE
|
||||
};
|
||||
return this.mm.sendSyncMessage(MSG_INSTALL_ENABLED, params)[0];
|
||||
},
|
||||
|
||||
install: function(installs, principal, callback, window) {
|
||||
let callbackID = this._addCallback(callback, installs.uris);
|
||||
|
||||
installs.mimetype = XPINSTALL_MIMETYPE;
|
||||
installs.triggeringPrincipal = principal;
|
||||
installs.callbackID = callbackID;
|
||||
|
||||
if (Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT) {
|
||||
// When running in the main process this might be a frame inside an
|
||||
// in-content UI page, walk up to find the first frame element in a chrome
|
||||
// privileged document
|
||||
let element = window.frameElement;
|
||||
let ssm = Services.scriptSecurityManager;
|
||||
while (element && !ssm.isSystemPrincipal(element.ownerDocument.nodePrincipal))
|
||||
element = element.ownerDocument.defaultView.frameElement;
|
||||
|
||||
if (element) {
|
||||
let listener = Cc["@mozilla.org/addons/integration;1"].
|
||||
getService(Ci.nsIMessageListener);
|
||||
return listener.wrappedJSObject.receiveMessage({
|
||||
name: MSG_INSTALL_ADDONS,
|
||||
target: element,
|
||||
data: installs,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to sending through the message manager
|
||||
let messageManager = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIContentFrameMessageManager);
|
||||
|
||||
return messageManager.sendSyncMessage(MSG_INSTALL_ADDONS, installs)[0];
|
||||
},
|
||||
|
||||
_addCallback: function(callback, urls) {
|
||||
if (!callback || typeof callback != "function")
|
||||
return -1;
|
||||
|
||||
let callbackID = this._windowID + "-" + ++this._lastCallbackID;
|
||||
let callbackObject = new CallbackObject(callbackID, callback, urls, this);
|
||||
this._callbacks.set(callbackID, callbackObject);
|
||||
return callbackID;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
|
||||
function InstallTrigger() {
|
||||
}
|
||||
|
||||
InstallTrigger.prototype = {
|
||||
// Here be magic. We've declared ourselves as providing the
|
||||
// nsIDOMGlobalPropertyInitializer interface, and are registered in the
|
||||
// "JavaScript-global-property" category in the XPCOM category manager. This
|
||||
// means that for newly created windows, XPCOM will createinstance this
|
||||
// object, and then call init, passing in the window for which we need to
|
||||
// provide an instance. We then initialize ourselves and return the webidl
|
||||
// version of this object using the webidl-provided _create method, which
|
||||
// XPCOM will then duly expose as a property value on the window. All this
|
||||
// indirection is necessary because webidl does not (yet) support statics
|
||||
// (bug 863952). See bug 926712 for more details about this implementation.
|
||||
init: function(window) {
|
||||
this._window = window;
|
||||
this._principal = window.document.nodePrincipal;
|
||||
this._url = window.document.documentURIObject;
|
||||
|
||||
try {
|
||||
this._mediator = new RemoteMediator(window);
|
||||
} catch (ex) {
|
||||
// If we can't set up IPC (e.g., because this is a top-level window
|
||||
// or something), then don't expose InstallTrigger.
|
||||
return null;
|
||||
}
|
||||
|
||||
return window.InstallTriggerImpl._create(window, this);
|
||||
},
|
||||
|
||||
enabled: function() {
|
||||
return this._mediator.enabled(this._url.spec);
|
||||
},
|
||||
|
||||
updateEnabled: function() {
|
||||
return this.enabled();
|
||||
},
|
||||
|
||||
install: function(installs, callback) {
|
||||
let installData = {
|
||||
uris: [],
|
||||
hashes: [],
|
||||
names: [],
|
||||
icons: [],
|
||||
};
|
||||
|
||||
for (let name of Object.keys(installs)) {
|
||||
let item = installs[name];
|
||||
if (typeof item === "string") {
|
||||
item = { URL: item };
|
||||
}
|
||||
if (!item.URL) {
|
||||
throw new this._window.Error("Missing URL property for '" + name + "'");
|
||||
}
|
||||
|
||||
let url = this._resolveURL(item.URL);
|
||||
if (!this._checkLoadURIFromScript(url)) {
|
||||
throw new this._window.Error("Insufficient permissions to install: " + url.spec);
|
||||
}
|
||||
|
||||
let iconUrl = null;
|
||||
if (item.IconURL) {
|
||||
iconUrl = this._resolveURL(item.IconURL);
|
||||
if (!this._checkLoadURIFromScript(iconUrl)) {
|
||||
iconUrl = null; // If page can't load the icon, just ignore it
|
||||
}
|
||||
}
|
||||
|
||||
installData.uris.push(url.spec);
|
||||
installData.hashes.push(item.Hash || null);
|
||||
installData.names.push(name);
|
||||
installData.icons.push(iconUrl ? iconUrl.spec : null);
|
||||
}
|
||||
|
||||
return this._mediator.install(installData, this._principal, callback, this._window);
|
||||
},
|
||||
|
||||
startSoftwareUpdate: function(url, flags) {
|
||||
let filename = Services.io.newURI(url, null, null)
|
||||
.QueryInterface(Ci.nsIURL)
|
||||
.filename;
|
||||
let args = {};
|
||||
args[filename] = { "URL": url };
|
||||
return this.install(args);
|
||||
},
|
||||
|
||||
installChrome: function(type, url, skin) {
|
||||
return this.startSoftwareUpdate(url);
|
||||
},
|
||||
|
||||
_resolveURL: function(url) {
|
||||
return Services.io.newURI(url, null, this._url);
|
||||
},
|
||||
|
||||
_checkLoadURIFromScript: function(uri) {
|
||||
let secman = Services.scriptSecurityManager;
|
||||
try {
|
||||
secman.checkLoadURIWithPrincipal(this._principal,
|
||||
uri,
|
||||
secman.DISALLOW_INHERIT_PRINCIPAL);
|
||||
return true;
|
||||
}
|
||||
catch (e) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
classID: Components.ID("{9df8ef2b-94da-45c9-ab9f-132eb55fddf1}"),
|
||||
contractID: "@mozilla.org/addons/installtrigger;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIDOMGlobalPropertyInitializer])
|
||||
};
|
||||
|
||||
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([InstallTrigger]);
|
||||
Loading…
Add table
Add a link
Reference in a new issue