mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1196734 - Support packaged WebExtensions in WebIDE r=ochameau
This commit is contained in:
parent
905ba07ddd
commit
5a89b3ff45
@ -37,12 +37,22 @@ AppValidator.prototype._getPackagedManifestFile = function () {
|
||||
this.error(strings.GetStringFromName("validator.expectProjectFolder"));
|
||||
return null;
|
||||
}
|
||||
manifestFile.append("manifest.webapp");
|
||||
if (!manifestFile.exists() || !manifestFile.isFile()) {
|
||||
|
||||
let appManifestFile = manifestFile.clone();
|
||||
appManifestFile.append("manifest.webapp");
|
||||
|
||||
let jsonManifestFile = manifestFile.clone();
|
||||
jsonManifestFile.append("manifest.json");
|
||||
|
||||
let hasAppManifest = appManifestFile.exists() && appManifestFile.isFile();
|
||||
let hasJsonManifest = jsonManifestFile.exists() && jsonManifestFile.isFile();
|
||||
|
||||
if (!hasAppManifest && !hasJsonManifest) {
|
||||
this.error(strings.GetStringFromName("validator.wrongManifestFileName"));
|
||||
return null;
|
||||
}
|
||||
return manifestFile;
|
||||
|
||||
return hasAppManifest ? appManifestFile : jsonManifestFile;
|
||||
};
|
||||
|
||||
AppValidator.prototype._getPackagedManifestURL = function () {
|
||||
@ -191,10 +201,6 @@ AppValidator.prototype._getOriginURL = function () {
|
||||
};
|
||||
|
||||
AppValidator.prototype.validateLaunchPath = function (manifest) {
|
||||
// Addons don't use index page (yet?)
|
||||
if (manifest.role && manifest.role === "addon") {
|
||||
return promise.resolve();
|
||||
}
|
||||
let deferred = promise.defer();
|
||||
// The launch_path field has to start with a `/`
|
||||
if (manifest.launch_path && manifest.launch_path[0] !== "/") {
|
||||
@ -267,14 +273,20 @@ AppValidator.prototype.validate = function () {
|
||||
this.errors = [];
|
||||
this.warnings = [];
|
||||
return this._getManifest().
|
||||
then((function (manifest) {
|
||||
then((manifest) => {
|
||||
if (manifest) {
|
||||
this.manifest = manifest;
|
||||
|
||||
// Skip validations for add-ons
|
||||
if (manifest.role === "addon" || manifest.manifest_version) {
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
this.validateManifest(manifest);
|
||||
this.validateType(manifest);
|
||||
return this.validateLaunchPath(manifest);
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
};
|
||||
|
||||
exports.AppValidator = AppValidator;
|
||||
|
@ -659,7 +659,7 @@ let AppManager = exports.AppManager = {
|
||||
|
||||
// Addons don't have any document to load (yet?)
|
||||
// So that there is no need to run them, installing is enough
|
||||
if (project.manifest.role && project.manifest.role === "addon") {
|
||||
if (project.manifest.manifest_version || project.manifest.role === "addon") {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -18,7 +18,7 @@ project.installing=Installing…
|
||||
project.installed=Installed!
|
||||
validator.nonExistingFolder=The project folder doesn't exists
|
||||
validator.expectProjectFolder=The project folder ends up being a file
|
||||
validator.wrongManifestFileName=Packaged apps require a manifest file that can only be named 'manifest.webapp' at project root folder
|
||||
validator.wrongManifestFileName=A manifest file is required at project root folder, named either 'manifest.webapp' for packaged apps or 'manifest.json' for addons.
|
||||
validator.invalidManifestURL=Invalid manifest URL '%S'
|
||||
# LOCALIZATION NOTE (validator.invalidManifestJSON, validator.noAccessManifestURL):
|
||||
# %1$S is the error message, %2$S is the URI of the manifest.
|
||||
|
@ -10,6 +10,7 @@ Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/osfile.jsm");
|
||||
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||
Cu.import("resource://gre/modules/UserCustomizations.jsm");
|
||||
|
||||
let promise = require("promise");
|
||||
let DevToolsUtils = require("devtools/toolkit/DevToolsUtils");
|
||||
@ -479,23 +480,43 @@ WebappsActor.prototype = {
|
||||
.createInstance(Ci.nsIZipReader);
|
||||
zipReader.open(zipFile);
|
||||
|
||||
// Read app manifest `manifest.webapp` from `application.zip`
|
||||
let istream = zipReader.getInputStream("manifest.webapp");
|
||||
// Prefer manifest.webapp when available
|
||||
let hasWebappManifest = zipReader.hasEntry("manifest.webapp");
|
||||
let hasJsonManifest = zipReader.hasEntry("manifest.json");
|
||||
|
||||
if (!hasWebappManifest && !hasJsonManifest) {
|
||||
self._sendError(deferred, "Missing manifest.webapp or manifest.json", aId);
|
||||
return;
|
||||
}
|
||||
|
||||
let manifestName = hasWebappManifest ? "manifest.webapp" : "manifest.json";
|
||||
|
||||
// Read app manifest from `application.zip`
|
||||
let istream = zipReader.getInputStream(manifestName);
|
||||
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
|
||||
.createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
converter.charset = "UTF-8";
|
||||
let jsonString = converter.ConvertToUnicode(
|
||||
NetUtil.readInputStreamToString(istream, istream.available())
|
||||
);
|
||||
zipReader.close();
|
||||
|
||||
let manifest;
|
||||
try {
|
||||
manifest = JSON.parse(jsonString);
|
||||
} catch(e) {
|
||||
self._sendError(deferred, "Error Parsing manifest.webapp: " + e, aId);
|
||||
self._sendError(deferred, "Error Parsing " + manifestName + ": " + e, aId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (manifestName === "manifest.json") {
|
||||
if (!UserCustomizations.checkExtensionManifest(manifest)) {
|
||||
self._sendError(deferred, "Invalid manifest", aId);
|
||||
return;
|
||||
}
|
||||
manifest = UserCustomizations.convertManifest(manifest);
|
||||
}
|
||||
|
||||
// Completely forbid pushing apps asking for unsafe permissions
|
||||
if ("permissions" in manifest) {
|
||||
let list = UNSAFE_PERMISSIONS.split(",");
|
||||
@ -538,56 +559,57 @@ WebappsActor.prototype = {
|
||||
|
||||
// Only after security checks are made and after final app id is computed
|
||||
// we can move application.zip to the destination directory, and
|
||||
// extract manifest.webapp there.
|
||||
// write manifest.webapp there.
|
||||
let installDir = DOMApplicationRegistry._getAppDir(id);
|
||||
let manFile = installDir.clone();
|
||||
manFile.append("manifest.webapp");
|
||||
zipReader.extract("manifest.webapp", manFile);
|
||||
zipReader.close();
|
||||
zipFile.moveTo(installDir, "application.zip");
|
||||
|
||||
let origin = "app://" + id;
|
||||
let manifestURL = origin + "/manifest.webapp";
|
||||
let manFile = installDir.clone();
|
||||
manFile.append("manifest.webapp");
|
||||
DOMApplicationRegistry._writeFile(manFile.path, JSON.stringify(manifest))
|
||||
.then(() => {
|
||||
let origin = "app://" + id;
|
||||
let manifestURL = origin + "/manifest.webapp";
|
||||
|
||||
// Refresh application.zip content (e.g. reinstall app), as done here:
|
||||
// http://hg.mozilla.org/mozilla-central/annotate/aaefec5d34f8/dom/apps/src/Webapps.jsm#l1125
|
||||
// Do it in parent process for the simulator
|
||||
let jar = installDir.clone();
|
||||
jar.append("application.zip");
|
||||
Services.obs.notifyObservers(jar, "flush-cache-entry", null);
|
||||
// Refresh application.zip content (e.g. reinstall app), as done here:
|
||||
// http://hg.mozilla.org/mozilla-central/annotate/aaefec5d34f8/dom/apps/src/Webapps.jsm#l1125
|
||||
// Do it in parent process for the simulator
|
||||
let jar = installDir.clone();
|
||||
jar.append("application.zip");
|
||||
Services.obs.notifyObservers(jar, "flush-cache-entry", null);
|
||||
|
||||
// And then in app content process
|
||||
// This function will be evaluated in the scope of the content process
|
||||
// frame script. That will flush the jar cache for this app and allow
|
||||
// loading fresh updated resources if we reload its document.
|
||||
let FlushFrameScript = function (path) {
|
||||
let jar = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
jar.initWithPath(path);
|
||||
let obs = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
obs.notifyObservers(jar, "flush-cache-entry", null);
|
||||
};
|
||||
for (let frame of self._appFrames()) {
|
||||
if (frame.getAttribute("mozapp") == manifestURL) {
|
||||
let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
|
||||
mm.loadFrameScript("data:," +
|
||||
encodeURIComponent("(" + FlushFrameScript.toString() + ")" +
|
||||
"('" + jar.path + "')"), false);
|
||||
}
|
||||
}
|
||||
// And then in app content process
|
||||
// This function will be evaluated in the scope of the content process
|
||||
// frame script. That will flush the jar cache for this app and allow
|
||||
// loading fresh updated resources if we reload its document.
|
||||
let FlushFrameScript = function (path) {
|
||||
let jar = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
jar.initWithPath(path);
|
||||
let obs = Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
obs.notifyObservers(jar, "flush-cache-entry", null);
|
||||
};
|
||||
for (let frame of self._appFrames()) {
|
||||
if (frame.getAttribute("mozapp") == manifestURL) {
|
||||
let mm = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager;
|
||||
mm.loadFrameScript("data:," +
|
||||
encodeURIComponent("(" + FlushFrameScript.toString() + ")" +
|
||||
"('" + jar.path + "')"), false);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a fake app object with the minimum set of properties we need.
|
||||
let app = {
|
||||
origin: origin,
|
||||
installOrigin: origin,
|
||||
manifestURL: manifestURL,
|
||||
appStatus: appType,
|
||||
receipts: aReceipts,
|
||||
kind: DOMApplicationRegistry.kPackaged,
|
||||
}
|
||||
// Create a fake app object with the minimum set of properties we need.
|
||||
let app = {
|
||||
origin: origin,
|
||||
installOrigin: origin,
|
||||
manifestURL: manifestURL,
|
||||
appStatus: appType,
|
||||
receipts: aReceipts,
|
||||
kind: DOMApplicationRegistry.kPackaged,
|
||||
}
|
||||
|
||||
self._registerApp(deferred, app, id, aDir);
|
||||
self._registerApp(deferred, app, id, aDir);
|
||||
});
|
||||
} catch(e) {
|
||||
// If anything goes wrong, just send it back.
|
||||
self._sendError(deferred, e.toString(), aId);
|
||||
|
Loading…
Reference in New Issue
Block a user