mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1446585
: Remove support for resource entries in bootstrapped chrome.manifest files. r=aswan,MattN,k88hudson
MozReview-Commit-ID: EjymzU6koYX --HG-- extra : rebase_source : 7b4fc250b5be0f2c16f3797eafb61e7c3955309d
This commit is contained in:
parent
883c7e5fce
commit
5edc701bb6
12
browser/extensions/activity-stream/bootstrap.js
vendored
12
browser/extensions/activity-stream/bootstrap.js
vendored
@ -9,6 +9,12 @@ Cu.importGlobalProperties(["fetch"]);
|
||||
ChromeUtils.defineModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
const RESOURCE_HOST = "activity-stream";
|
||||
|
||||
const BROWSER_READY_NOTIFICATION = "sessionstore-windows-restored";
|
||||
const RESOURCE_BASE = "resource://activity-stream";
|
||||
|
||||
@ -148,6 +154,10 @@ function observe(subject, topic, data) {
|
||||
this.install = function install(data, reason) {};
|
||||
|
||||
this.startup = function startup(data, reason) {
|
||||
resProto.setSubstitutionWithFlags(RESOURCE_HOST,
|
||||
Services.io.newURI("chrome/content/", null, data.resourceURI),
|
||||
resProto.ALLOW_CONTENT_ACCESS);
|
||||
|
||||
// Cache startup data which contains stuff like the version number, etc.
|
||||
// so we can use it when we init
|
||||
startupData = data;
|
||||
@ -163,6 +173,8 @@ this.startup = function startup(data, reason) {
|
||||
};
|
||||
|
||||
this.shutdown = function shutdown(data, reason) {
|
||||
resProto.setSubstitution(RESOURCE_HOST, null);
|
||||
|
||||
// Uninitialize Activity Stream
|
||||
startupData = null;
|
||||
startupReason = null;
|
||||
|
11
browser/extensions/formautofill/bootstrap.js
vendored
11
browser/extensions/formautofill/bootstrap.js
vendored
@ -20,6 +20,12 @@ ChromeUtils.defineModuleGetter(this, "formAutofillParent",
|
||||
ChromeUtils.defineModuleGetter(this, "FormAutofillUtils",
|
||||
"resource://formautofill/FormAutofillUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
const RESOURCE_HOST = "formautofill";
|
||||
|
||||
function insertStyleSheet(domWindow, url) {
|
||||
let doc = domWindow.document;
|
||||
let styleSheetAttr = `href="${url}" type="text/css"`;
|
||||
@ -80,6 +86,9 @@ function startup(data) {
|
||||
return;
|
||||
}
|
||||
|
||||
resProto.setSubstitution(RESOURCE_HOST,
|
||||
Services.io.newURI("chrome/res/", null, data.resourceURI));
|
||||
|
||||
if (data.hasOwnProperty("instanceID") && data.instanceID) {
|
||||
if (AddonManagerPrivate.isDBLoaded()) {
|
||||
addUpgradeListener(data.instanceID);
|
||||
@ -121,6 +130,8 @@ function startup(data) {
|
||||
}
|
||||
|
||||
function shutdown() {
|
||||
resProto.setSubstitution(RESOURCE_HOST, null);
|
||||
|
||||
Services.mm.removeMessageListener("FormAutoComplete:MaybeOpenPopup", onMaybeOpenPopup);
|
||||
|
||||
let enumerator = Services.wm.getEnumerator("navigator:browser");
|
||||
|
@ -22,6 +22,10 @@ ChromeUtils.defineModuleGetter(this, "DownloadPaths",
|
||||
ChromeUtils.defineModuleGetter(this, "FileUtils",
|
||||
"resource://gre/modules/FileUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
do_get_profile();
|
||||
|
||||
// ================================================
|
||||
@ -50,6 +54,9 @@ if (!extensionDir.exists()) {
|
||||
}
|
||||
Components.manager.addBootstrappedManifestLocation(extensionDir);
|
||||
|
||||
let resURI = Services.io.newURI("chrome/res/", null, Services.io.newURI(bootstrapURI));
|
||||
resProto.setSubstitution("formautofill", resURI);
|
||||
|
||||
// Returns a reference to a temporary file that is guaranteed not to exist and
|
||||
// is cleaned up later. See FileTestUtils.getTempFile for details.
|
||||
function getTempFile(leafName) {
|
||||
|
12
browser/extensions/onboarding/bootstrap.js
vendored
12
browser/extensions/onboarding/bootstrap.js
vendored
@ -13,6 +13,12 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
UIState: "resource://services-sync/UIState.jsm",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
const RESOURCE_HOST = "onboarding";
|
||||
|
||||
const {PREF_STRING, PREF_BOOL, PREF_INT} = Ci.nsIPrefBranch;
|
||||
|
||||
const BROWSER_READY_NOTIFICATION = "browser-delayed-startup-finished";
|
||||
@ -197,6 +203,10 @@ function install(aData, aReason) {}
|
||||
function uninstall(aData, aReason) {}
|
||||
|
||||
function startup(aData, aReason) {
|
||||
resProto.setSubstitutionWithFlags(RESOURCE_HOST,
|
||||
Services.io.newURI("chrome/content/", null, aData.resourceURI),
|
||||
resProto.ALLOW_CONTENT_ACCESS);
|
||||
|
||||
// Cache startup data which contains stuff like the version number, etc.
|
||||
// so we can use it when we init the telemetry
|
||||
startupData = aData;
|
||||
@ -211,6 +221,8 @@ function startup(aData, aReason) {
|
||||
}
|
||||
|
||||
function shutdown(aData, aReason) {
|
||||
resProto.setSubstitution(RESOURCE_HOST, null);
|
||||
|
||||
startupData = null;
|
||||
// Stop waiting for browser to be ready
|
||||
if (waitingForBrowserReady) {
|
||||
|
@ -9,6 +9,10 @@ ChromeUtils.import("resource://gre/modules/Preferences.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "resProto",
|
||||
"@mozilla.org/network/protocol;1?name=resource",
|
||||
"nsISubstitutingProtocolHandler");
|
||||
|
||||
// Load our bootstrap extension manifest so we can access our chrome/resource URIs.
|
||||
// Cargo culted from formautofill system add-on
|
||||
const EXTENSION_ID = "onboarding@mozilla.org";
|
||||
@ -16,12 +20,19 @@ let extensionDir = Services.dirsvc.get("GreD", Ci.nsIFile);
|
||||
extensionDir.append("browser");
|
||||
extensionDir.append("features");
|
||||
extensionDir.append(EXTENSION_ID);
|
||||
let resourceURI;
|
||||
// If the unpacked extension doesn't exist, use the packed version.
|
||||
if (!extensionDir.exists()) {
|
||||
extensionDir.leafName += ".xpi";
|
||||
|
||||
resourceURI = "jar:" + Services.io.newFileURI(extensionDir).spec + "!/chrome/content/";
|
||||
} else {
|
||||
resourceURI = Services.io.newFileURI(extensionDir).spec + "/chrome/content/";
|
||||
}
|
||||
Components.manager.addBootstrappedManifestLocation(extensionDir);
|
||||
|
||||
resProto.setSubstitution("onboarding", Services.io.newURI(resourceURI));
|
||||
|
||||
const TOURSET_VERSION = 1;
|
||||
const NEXT_TOURSET_VERSION = 2;
|
||||
const PREF_TOUR_TYPE = "browser.onboarding.tour-type";
|
||||
|
@ -1,151 +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";
|
||||
|
||||
var EXPORTED_SYMBOLS = ["ChromeManifestParser"];
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
const MSG_JAR_FLUSH = "AddonJarFlush";
|
||||
|
||||
|
||||
/**
|
||||
* Sends local and remote notifications to flush a JAR file cache entry
|
||||
*
|
||||
* @param aJarFile
|
||||
* The ZIP/XPI/JAR file as a nsIFile
|
||||
*/
|
||||
function flushJarCache(aJarFile) {
|
||||
Services.obs.notifyObservers(aJarFile, "flush-cache-entry");
|
||||
Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageBroadcaster)
|
||||
.broadcastAsyncMessage(MSG_JAR_FLUSH, aJarFile.path);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses chrome manifest files.
|
||||
*/
|
||||
var ChromeManifestParser = {
|
||||
|
||||
/**
|
||||
* Reads and parses a chrome manifest file located at a specified URI, and all
|
||||
* secondary manifests it references.
|
||||
*
|
||||
* @param aURI
|
||||
* A nsIURI pointing to a chrome manifest.
|
||||
* Typically a file: or jar: URI.
|
||||
* @return Array of objects describing each manifest instruction, in the form:
|
||||
* { type: instruction-type, baseURI: string-uri, args: [arguments] }
|
||||
**/
|
||||
parseSync(aURI) {
|
||||
function parseLine(aLine) {
|
||||
let line = aLine.trim();
|
||||
if (line.length == 0 || line.charAt(0) == "#")
|
||||
return;
|
||||
let tokens = line.split(/\s+/);
|
||||
let type = tokens.shift();
|
||||
if (type == "manifest") {
|
||||
let uri = NetUtil.newURI(tokens.shift(), null, aURI);
|
||||
data = data.concat(this.parseSync(uri));
|
||||
} else {
|
||||
data.push({type, baseURI, args: tokens});
|
||||
}
|
||||
}
|
||||
|
||||
let contents = "";
|
||||
try {
|
||||
if (aURI.scheme == "jar")
|
||||
contents = this._readFromJar(aURI);
|
||||
else
|
||||
contents = this._readFromFile(aURI);
|
||||
} catch (e) {
|
||||
// Silently fail.
|
||||
}
|
||||
|
||||
if (!contents)
|
||||
return [];
|
||||
|
||||
let baseURI = NetUtil.newURI(".", null, aURI).spec;
|
||||
|
||||
let data = [];
|
||||
let lines = contents.split("\n");
|
||||
lines.forEach(parseLine.bind(this));
|
||||
return data;
|
||||
},
|
||||
|
||||
_readFromJar(aURI) {
|
||||
let data = "";
|
||||
let entries = [];
|
||||
let readers = [];
|
||||
|
||||
try {
|
||||
// Deconstrict URI, which can be nested jar: URIs.
|
||||
let uri = aURI.clone();
|
||||
while (uri instanceof Ci.nsIJARURI) {
|
||||
entries.push(uri.JAREntry);
|
||||
uri = uri.JARFile;
|
||||
}
|
||||
|
||||
// Open the base jar.
|
||||
let reader = Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(Ci.nsIZipReader);
|
||||
reader.open(uri.QueryInterface(Ci.nsIFileURL).file);
|
||||
readers.push(reader);
|
||||
|
||||
// Open the nested jars.
|
||||
for (let i = entries.length - 1; i > 0; i--) {
|
||||
let innerReader = Cc["@mozilla.org/libjar/zip-reader;1"].
|
||||
createInstance(Ci.nsIZipReader);
|
||||
innerReader.openInner(reader, entries[i]);
|
||||
readers.push(innerReader);
|
||||
reader = innerReader;
|
||||
}
|
||||
|
||||
// First entry is the actual file we want to read.
|
||||
let zis = reader.getInputStream(entries[0]);
|
||||
data = NetUtil.readInputStreamToString(zis, zis.available());
|
||||
} finally {
|
||||
// Close readers in reverse order.
|
||||
for (let i = readers.length - 1; i >= 0; i--) {
|
||||
readers[i].close();
|
||||
flushJarCache(readers[i].file);
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
},
|
||||
|
||||
_readFromFile(aURI) {
|
||||
let file = aURI.QueryInterface(Ci.nsIFileURL).file;
|
||||
if (!file.exists() || !file.isFile())
|
||||
return "";
|
||||
|
||||
let data = "";
|
||||
let fis = Cc["@mozilla.org/network/file-input-stream;1"].
|
||||
createInstance(Ci.nsIFileInputStream);
|
||||
try {
|
||||
fis.init(file, -1, -1, false);
|
||||
data = NetUtil.readInputStreamToString(fis, fis.available());
|
||||
} finally {
|
||||
fis.close();
|
||||
}
|
||||
return data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detects if there were any instructions of a specified type in a given
|
||||
* chrome manifest.
|
||||
*
|
||||
* @param aManifest
|
||||
* Manifest data, as returned by ChromeManifestParser.parseSync().
|
||||
* @param aType
|
||||
* Instruction type to filter by.
|
||||
* @return True if any matching instructions were found in the manifest.
|
||||
*/
|
||||
hasType(aManifest, aType) {
|
||||
return aManifest.some(entry => entry.type == aType);
|
||||
}
|
||||
};
|
@ -16,7 +16,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
AddonRepository: "resource://gre/modules/addons/AddonRepository.jsm",
|
||||
AddonSettings: "resource://gre/modules/addons/AddonSettings.jsm",
|
||||
AppConstants: "resource://gre/modules/AppConstants.jsm",
|
||||
ChromeManifestParser: "resource://gre/modules/ChromeManifestParser.jsm",
|
||||
Extension: "resource://gre/modules/Extension.jsm",
|
||||
Langpack: "resource://gre/modules/Extension.jsm",
|
||||
LightweightThemeManager: "resource://gre/modules/LightweightThemeManager.jsm",
|
||||
@ -45,8 +44,6 @@ const {nsIBlocklistService} = Ci;
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetters(this, {
|
||||
Blocklist: ["@mozilla.org/extensions/blocklist;1", "nsIBlocklistService"],
|
||||
ChromeRegistry: ["@mozilla.org/chrome/chrome-registry;1", "nsIChromeRegistry"],
|
||||
ResProtocolHandler: ["@mozilla.org/network/protocol;1?name=resource", "nsIResProtocolHandler"],
|
||||
AddonPolicyService: ["@mozilla.org/addons/policy-service;1", "nsIAddonPolicyService"],
|
||||
aomStartup: ["@mozilla.org/addons/addon-manager-startup;1", "amIAddonManagerStartup"],
|
||||
});
|
||||
@ -1908,66 +1905,6 @@ var XPIProvider = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Resolve a URI back to physical file.
|
||||
*
|
||||
* Of course, this works only for URIs pointing to local resources.
|
||||
*
|
||||
* @param aURI
|
||||
* URI to resolve
|
||||
* @return
|
||||
* resolved nsIFileURL
|
||||
*/
|
||||
_resolveURIToFile(aURI) {
|
||||
switch (aURI.scheme) {
|
||||
case "jar":
|
||||
case "file":
|
||||
if (aURI instanceof Ci.nsIJARURI) {
|
||||
return this._resolveURIToFile(aURI.JARFile);
|
||||
}
|
||||
return aURI;
|
||||
|
||||
case "chrome":
|
||||
aURI = ChromeRegistry.convertChromeURL(aURI);
|
||||
return this._resolveURIToFile(aURI);
|
||||
|
||||
case "resource":
|
||||
aURI = Services.io.newURI(ResProtocolHandler.resolveURI(aURI));
|
||||
return this._resolveURIToFile(aURI);
|
||||
|
||||
case "view-source":
|
||||
aURI = Services.io.newURI(aURI.pathQueryRef);
|
||||
return this._resolveURIToFile(aURI);
|
||||
|
||||
case "about":
|
||||
if (aURI.spec == "about:blank") {
|
||||
// Do not attempt to map about:blank
|
||||
return null;
|
||||
}
|
||||
|
||||
let chan;
|
||||
try {
|
||||
chan = NetUtil.newChannel({
|
||||
uri: aURI,
|
||||
loadUsingSystemPrincipal: true
|
||||
});
|
||||
} catch (ex) {
|
||||
return null;
|
||||
}
|
||||
// Avoid looping
|
||||
if (chan.URI.equals(aURI)) {
|
||||
return null;
|
||||
}
|
||||
// We want to clone the channel URI to avoid accidentially keeping
|
||||
// unnecessary references to the channel or implementation details
|
||||
// around.
|
||||
return this._resolveURIToFile(chan.URI.clone());
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the XPI provider initializes the install locations and prefs.
|
||||
*
|
||||
@ -4386,13 +4323,6 @@ var XPIProvider = {
|
||||
if (CHROME_TYPES.has(aAddon.type) && aMethod == "shutdown" && aReason != BOOTSTRAP_REASONS.APP_SHUTDOWN) {
|
||||
logger.debug("Removing manifest for " + aFile.path);
|
||||
Components.manager.removeBootstrappedManifestLocation(aFile);
|
||||
|
||||
let manifest = getURIForResourceInFile(aFile, "chrome.manifest");
|
||||
for (let line of ChromeManifestParser.parseSync(manifest)) {
|
||||
if (line.type == "resource") {
|
||||
ResProtocolHandler.setSubstitution(line.args[0], null);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.setTelemetry(aAddon.id, aMethod + "_MS", new Date() - timeStart);
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ EXTRA_PP_COMPONENTS += [
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'AddonManager.jsm',
|
||||
'ChromeManifestParser.jsm',
|
||||
'LightweightThemeManager.jsm',
|
||||
]
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
resource test-addon-1 .
|
@ -1,24 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>addon6@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
|
||||
<!-- Front End MetaData -->
|
||||
<em:name>Test 6</em:name>
|
||||
<em:description>Test Description</em:description>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>xpcshell@tests.mozilla.org</em:id>
|
||||
<em:minVersion>1</em:minVersion>
|
||||
<em:maxVersion>2</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
</Description>
|
||||
</RDF>
|
Binary file not shown.
@ -3,11 +3,18 @@
|
||||
*/
|
||||
/* exported startup, shutdown, install, uninstall */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsISubstitutingProtocolHandler);
|
||||
|
||||
function install(data, reason) {}
|
||||
function startup(data, reason) {
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
resProto.setSubstitution("my-addon", data.resourceURI);
|
||||
Services.ppmm.loadProcessScript(
|
||||
"resource://my-addon/frame-script.js", false);
|
||||
}
|
||||
function shutdown(data, reason) {}
|
||||
function shutdown(data, reason) {
|
||||
resProto.setSubstitution("my-addon", null);
|
||||
}
|
||||
function uninstall(data, reason) {}
|
||||
|
@ -1 +0,0 @@
|
||||
resource my-addon .
|
Binary file not shown.
@ -3,11 +3,18 @@
|
||||
*/
|
||||
/* exported startup, shutdown, install, uninstall */
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"]
|
||||
.getService(Ci.nsISubstitutingProtocolHandler);
|
||||
|
||||
function install(data, reason) {}
|
||||
function startup(data, reason) {
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
resProto.setSubstitution("my-addon", data.resourceURI);
|
||||
Services.ppmm.loadProcessScript(
|
||||
"resource://my-addon/frame-script.js", false);
|
||||
}
|
||||
function shutdown(data, reason) {}
|
||||
function shutdown(data, reason) {
|
||||
resProto.setSubstitution("my-addon", null);
|
||||
}
|
||||
function uninstall(data, reason) {}
|
||||
|
@ -1 +0,0 @@
|
||||
resource my-addon .
|
@ -10,6 +10,7 @@ function test() {
|
||||
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["extensions.checkUpdateSecurity", false],
|
||||
["xpinstall.signatures.required", false]
|
||||
]});
|
||||
|
||||
run_next_test();
|
||||
|
@ -1,108 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests ChromeManifestParser.js
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/ChromeManifestParser.jsm");
|
||||
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
|
||||
|
||||
startupManager();
|
||||
|
||||
installAllFiles([do_get_addon("test_chromemanifest_1"),
|
||||
do_get_addon("test_chromemanifest_2"),
|
||||
do_get_addon("test_chromemanifest_3"),
|
||||
do_get_addon("test_chromemanifest_4")],
|
||||
function() {
|
||||
|
||||
restartManager();
|
||||
run_test_1();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_1() {
|
||||
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
|
||||
"addon2@tests.mozilla.org",
|
||||
"addon3@tests.mozilla.org",
|
||||
"addon4@tests.mozilla.org"],
|
||||
function([a1, a2, a3, a4]) {
|
||||
// addon1
|
||||
let a1Uri = a1.getResourceURI("/").spec;
|
||||
let expected = [
|
||||
{type: "content", baseURI: a1Uri, args: ["test-addon-1", "chrome/content"]},
|
||||
{type: "locale", baseURI: a1Uri, args: ["test-addon-1", "en-US", "locale/en-US"]},
|
||||
{type: "locale", baseURI: a1Uri, args: ["test-addon-1", "fr-FR", "locale/fr-FR"]},
|
||||
{type: "overlay", baseURI: a1Uri, args: ["chrome://browser/content/browser.xul", "chrome://test-addon-1/content/overlay.xul"]}
|
||||
];
|
||||
let manifestURI = a1.getResourceURI("chrome.manifest");
|
||||
let manifest = ChromeManifestParser.parseSync(manifestURI);
|
||||
|
||||
Assert.ok(Array.isArray(manifest));
|
||||
Assert.equal(manifest.length, expected.length);
|
||||
for (let i = 0; i < manifest.length; i++) {
|
||||
Assert.equal(JSON.stringify(manifest[i]), JSON.stringify(expected[i]));
|
||||
}
|
||||
|
||||
// addon2
|
||||
let a2Uri = a2.getResourceURI("/").spec;
|
||||
expected = [
|
||||
{type: "content", baseURI: a2Uri, args: ["test-addon-1", "chrome/content"]},
|
||||
{type: "locale", baseURI: a2Uri, args: ["test-addon-1", "en-US", "locale/en-US"]},
|
||||
{type: "locale", baseURI: a2Uri, args: ["test-addon-1", "fr-FR", "locale/fr-FR"]},
|
||||
{type: "overlay", baseURI: a2Uri, args: ["chrome://browser/content/browser.xul", "chrome://test-addon-1/content/overlay.xul"]},
|
||||
{type: "binary-component", baseURI: a2Uri, args: ["components/something.so"]}
|
||||
];
|
||||
manifestURI = a2.getResourceURI("chrome.manifest");
|
||||
manifest = ChromeManifestParser.parseSync(manifestURI);
|
||||
|
||||
Assert.ok(Array.isArray(manifest));
|
||||
Assert.equal(manifest.length, expected.length);
|
||||
for (let i = 0; i < manifest.length; i++) {
|
||||
Assert.equal(JSON.stringify(manifest[i]), JSON.stringify(expected[i]));
|
||||
}
|
||||
|
||||
// addon3
|
||||
let a3Uri = a3.getResourceURI("/").spec;
|
||||
expected = [
|
||||
{type: "content", baseURI: a3Uri, args: ["test-addon-1", "chrome/content"]},
|
||||
{type: "locale", baseURI: a3Uri, args: ["test-addon-1", "en-US", "locale/en-US"]},
|
||||
{type: "locale", baseURI: a3Uri, args: ["test-addon-1", "fr-FR", "locale/fr-FR"]},
|
||||
{type: "overlay", baseURI: a3Uri, args: ["chrome://browser/content/browser.xul", "chrome://test-addon-1/content/overlay.xul"]},
|
||||
{type: "binary-component", baseURI: a3Uri, args: ["components/something.so"]},
|
||||
{type: "locale", baseURI: "jar:" + a3.getResourceURI("/inner.jar").spec + "!/", args: ["test-addon-1", "en-NZ", "locale/en-NZ"]},
|
||||
];
|
||||
manifestURI = a3.getResourceURI("chrome.manifest");
|
||||
manifest = ChromeManifestParser.parseSync(manifestURI);
|
||||
|
||||
Assert.ok(Array.isArray(manifest));
|
||||
Assert.equal(manifest.length, expected.length);
|
||||
for (let i = 0; i < manifest.length; i++) {
|
||||
Assert.equal(JSON.stringify(manifest[i]), JSON.stringify(expected[i]));
|
||||
}
|
||||
|
||||
// addon4
|
||||
let a4Uri = a4.getResourceURI("/").spec;
|
||||
expected = [
|
||||
{type: "content", baseURI: a4Uri, args: ["test-addon-1", "chrome/content"]},
|
||||
{type: "locale", baseURI: a4Uri, args: ["test-addon-1", "en-US", "locale/en-US"]},
|
||||
{type: "locale", baseURI: a4Uri, args: ["test-addon-1", "fr-FR", "locale/fr-FR"]},
|
||||
{type: "overlay", baseURI: a4Uri, args: ["chrome://browser/content/browser.xul", "chrome://test-addon-1/content/overlay.xul"]},
|
||||
{type: "binary-component", baseURI: a4.getResourceURI("components/").spec, args: ["mycomponent.dll"]},
|
||||
{type: "binary-component", baseURI: a4.getResourceURI("components/other/").spec, args: ["thermalnuclearwar.dll"]}
|
||||
];
|
||||
manifestURI = a4.getResourceURI("chrome.manifest");
|
||||
manifest = ChromeManifestParser.parseSync(manifestURI);
|
||||
|
||||
Assert.ok(Array.isArray(manifest));
|
||||
Assert.equal(manifest.length, expected.length);
|
||||
for (let i = 0; i < manifest.length; i++) {
|
||||
Assert.equal(JSON.stringify(manifest[i]), JSON.stringify(expected[i]));
|
||||
}
|
||||
|
||||
executeSoon(do_test_finished);
|
||||
});
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Tests that resource protocol substitutions are set and unset for bootstrapped add-ons.
|
||||
|
||||
const profileDir = gProfD.clone();
|
||||
profileDir.append("extensions");
|
||||
|
||||
|
||||
function run_test() {
|
||||
do_test_pending();
|
||||
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
|
||||
|
||||
let resourceProtocol = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
startupManager();
|
||||
|
||||
installAllFiles([do_get_addon("test_chromemanifest_6")],
|
||||
function() {
|
||||
|
||||
AddonManager.getAddonByID("addon6@tests.mozilla.org", function(addon) {
|
||||
Assert.notEqual(addon, null);
|
||||
Assert.ok(addon.isActive);
|
||||
Assert.ok(resourceProtocol.hasSubstitution("test-addon-1"));
|
||||
|
||||
prepare_test({
|
||||
"addon6@tests.mozilla.org": [
|
||||
["onDisabling", false],
|
||||
"onDisabled"
|
||||
]
|
||||
});
|
||||
|
||||
Assert.equal(addon.operationsRequiringRestart &
|
||||
AddonManager.OP_NEEDS_RESTART_DISABLE, 0);
|
||||
addon.userDisabled = true;
|
||||
ensure_test_completed();
|
||||
Assert.ok(!resourceProtocol.hasSubstitution("test-addon-1"));
|
||||
|
||||
prepare_test({
|
||||
"addon6@tests.mozilla.org": [
|
||||
["onEnabling", false],
|
||||
"onEnabled"
|
||||
]
|
||||
});
|
||||
|
||||
Assert.equal(addon.operationsRequiringRestart &
|
||||
AddonManager.OP_NEEDS_RESTART_ENABLE, 0);
|
||||
addon.userDisabled = false;
|
||||
ensure_test_completed();
|
||||
Assert.ok(resourceProtocol.hasSubstitution("test-addon-1"));
|
||||
|
||||
executeSoon(do_test_finished);
|
||||
});
|
||||
});
|
||||
}
|
@ -118,7 +118,7 @@ function run_test_4() {
|
||||
gExpectedFile.append("addon2@tests.mozilla.org.xpi");
|
||||
|
||||
a2.uninstall();
|
||||
Assert.equal(gCacheFlushCount, 2);
|
||||
Assert.equal(gCacheFlushCount, 1);
|
||||
gExpectedFile = null;
|
||||
gCacheFlushCount = 0;
|
||||
|
||||
|
@ -20,6 +20,19 @@ const userExtensions = userAppDir.clone();
|
||||
userExtensions.append(APP_ID);
|
||||
userExtensions.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetters(this, {
|
||||
ChromeRegistry: ["@mozilla.org/chrome/chrome-registry;1", "nsIChromeRegistry"],
|
||||
});
|
||||
|
||||
function hasChromeEntry(package) {
|
||||
try {
|
||||
void ChromeRegistry.convertChromeURL(Services.io.newURI(`chrome://${package}/content/`));
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function() {
|
||||
await promiseWriteInstallRDFToXPI({
|
||||
id: "langpack-foo@addons.mozilla.org",
|
||||
@ -33,7 +46,7 @@ add_task(async function() {
|
||||
name: "Invalid install.rdf extension",
|
||||
}, userExtensions, undefined, {
|
||||
"chrome.manifest": `
|
||||
resource foo-langpack ./
|
||||
content foo-langpack ./
|
||||
`,
|
||||
});
|
||||
|
||||
@ -48,30 +61,27 @@ add_task(async function() {
|
||||
name: "Invalid install.rdf extension",
|
||||
}, userExtensions, undefined, {
|
||||
"chrome.manifest": `
|
||||
resource foo ./
|
||||
content foo ./
|
||||
`,
|
||||
});
|
||||
|
||||
const resProto = Services.io.getProtocolHandler("resource");
|
||||
resProto.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
|
||||
equal(resProto.hasSubstitution("foo-langpack"), false,
|
||||
equal(hasChromeEntry("foo-langpack"), false,
|
||||
"Should not foo-langpack resource before AOM startup");
|
||||
equal(resProto.hasSubstitution("foo"), false,
|
||||
equal(hasChromeEntry("foo"), false,
|
||||
"Should not foo resource before AOM startup");
|
||||
|
||||
await promiseStartupManager();
|
||||
|
||||
equal(resProto.hasSubstitution("foo-langpack"), false,
|
||||
equal(hasChromeEntry("foo-langpack"), false,
|
||||
"Should not have registered chrome manifest for invalid extension");
|
||||
equal(resProto.hasSubstitution("foo"), true,
|
||||
equal(hasChromeEntry("foo"), true,
|
||||
"Should have registered chrome manifest for valid extension");
|
||||
|
||||
await promiseRestartManager();
|
||||
|
||||
equal(resProto.hasSubstitution("foo-langpack"), false,
|
||||
equal(hasChromeEntry("foo-langpack"), false,
|
||||
"Should still not have registered chrome manifest for invalid extension after restart");
|
||||
equal(resProto.hasSubstitution("foo"), true,
|
||||
equal(hasChromeEntry("foo"), true,
|
||||
"Should still have registered chrome manifest for valid extension after restart");
|
||||
|
||||
await promiseShutdownManager();
|
||||
|
@ -94,7 +94,6 @@ tags = blocklist
|
||||
[test_bootstrap.js]
|
||||
skip-if = true # Bug 1358846 Bug 1365021 Bug 676992
|
||||
[test_bootstrap_const.js]
|
||||
[test_bootstrap_resource.js]
|
||||
[test_bug299716.js]
|
||||
# Bug 676992: test consistently hangs on Android
|
||||
skip-if = os == "android"
|
||||
@ -216,7 +215,6 @@ tags = blocklist
|
||||
[test_bug953156.js]
|
||||
[test_checkcompatibility.js]
|
||||
[test_childprocess.js]
|
||||
[test_ChromeManifestParser.js]
|
||||
[test_compatoverrides.js]
|
||||
[test_corrupt.js]
|
||||
[test_corrupt_strictcompat.js]
|
||||
|
@ -122,7 +122,7 @@ static const ManifestDirective kParsingTable[] = {
|
||||
nullptr, &nsChromeRegistry::ManifestOverride,
|
||||
},
|
||||
{
|
||||
"resource", 2, false, true, true, true, true,
|
||||
"resource", 2, false, true, true, false, true,
|
||||
nullptr, &nsChromeRegistry::ManifestResource,
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user