author | Dave Townsend <dtownsend@oxymoronical.com> |
Fri, 07 Aug 2015 15:53:46 -0700 | |
changeset 256995 | 896476b65693c0ef789afa2d5cf92ba181beade5 |
parent 256994 | b958b84f2fa0121763910a4257f19a548a65bcd5 |
child 256996 | 7ece2ae55806cd2c3e88690baab3d70979350a3a |
push id | 29198 |
push user | philringnalda@gmail.com |
push date | Sun, 09 Aug 2015 22:45:16 +0000 |
treeherder | mozilla-central@a431fb8b9a40 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | billm |
bugs | 1190692 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
deleted file mode 100644 --- a/browser/components/extensions/prepare.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# 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/. - -import argparse -import json -import uuid -import sys -import os.path - -parser = argparse.ArgumentParser(description='Create install.rdf from manifest.json') -parser.add_argument('--locale') -parser.add_argument('--profile') -parser.add_argument('--uuid') -parser.add_argument('dir') -args = parser.parse_args() - -manifestFile = os.path.join(args.dir, 'manifest.json') -manifest = json.load(open(manifestFile)) - -locale = args.locale -if not locale: - locale = manifest.get('default_locale', 'en-US') - -def process_locale(s): - if s.startswith('__MSG_') and s.endswith('__'): - tag = s[6:-2] - path = os.path.join(args.dir, '_locales', locale, 'messages.json') - data = json.load(open(path)) - return data[tag]['message'] - else: - return s - -id = args.uuid -if not id: - id = '{' + str(uuid.uuid4()) + '}' - -name = process_locale(manifest['name']) -desc = process_locale(manifest['description']) -version = manifest['version'] - -installFile = open(os.path.join(args.dir, 'install.rdf'), 'w') -print >>installFile, '<?xml version="1.0"?>' -print >>installFile, '<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"' -print >>installFile, ' xmlns:em="http://www.mozilla.org/2004/em-rdf#">' -print >>installFile -print >>installFile, ' <Description about="urn:mozilla:install-manifest">' -print >>installFile, ' <em:id>{}</em:id>'.format(id) -print >>installFile, ' <em:type>2</em:type>' -print >>installFile, ' <em:name>{}</em:name>'.format(name) -print >>installFile, ' <em:description>{}</em:description>'.format(desc) -print >>installFile, ' <em:version>{}</em:version>'.format(version) -print >>installFile, ' <em:bootstrap>true</em:bootstrap>' - -print >>installFile, ' <em:targetApplication>' -print >>installFile, ' <Description>' -print >>installFile, ' <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>' -print >>installFile, ' <em:minVersion>4.0</em:minVersion>' -print >>installFile, ' <em:maxVersion>50.0</em:maxVersion>' -print >>installFile, ' </Description>' -print >>installFile, ' </em:targetApplication>' - -print >>installFile, ' </Description>' -print >>installFile, '</RDF>' -installFile.close() - -bootstrapPath = os.path.join(os.path.dirname(sys.argv[0]), 'bootstrap.js') -data = open(bootstrapPath).read() -boot = open(os.path.join(args.dir, 'bootstrap.js'), 'w') -boot.write(data) -boot.close() - -if args.profile: - os.system('mkdir -p {}/extensions'.format(args.profile)) - output = open(args.profile + '/extensions/' + id, 'w') - print >>output, os.path.realpath(args.dir) - output.close() -else: - dir = os.path.realpath(args.dir) - if dir[-1] == os.sep: - dir = dir[:-1] - os.system('cd "{}"; zip ../"{}".xpi -r *'.format(args.dir, os.path.basename(dir)))
--- a/toolkit/components/extensions/Extension.jsm +++ b/toolkit/components/extensions/Extension.jsm @@ -136,16 +136,20 @@ let Management = { this.emitter.on(hook, callback); }, // Ask to run all the callbacks that are registered for a given hook. emit(hook, ...args) { this.lazyInit(); this.emitter.emit(hook, ...args); }, + + off(hook, callback) { + this.emitter.off(hook, callback); + } }; // A MessageBroker that's used to send and receive messages for // extension pages (which run in the chrome process). let globalBroker = new MessageBroker([Services.mm, Services.ppmm]); // An extension page is an execution context for any extension content // that runs in the chrome process. It's used for background pages @@ -524,23 +528,23 @@ Extension.prototype = { this.onShutdown.add(obj); }, forgetOnClose(obj) { this.onShutdown.delete(obj); }, startup() { - GlobalManager.init(this); - return Promise.all([this.readManifest(), this.readLocaleMessages()]).then(([manifest, messages]) => { if (this.hasShutdown) { return; } + GlobalManager.init(this); + this.manifest = manifest; this.localeMessages = messages; Management.emit("startup", this); this.runManifest(manifest); }).catch(e => { dump(`Extension error: ${e} ${e.fileName}:${e.lineNumber}\n`);
rename from browser/components/extensions/bootstrap.js rename to toolkit/mozapps/extensions/internal/WebExtensionBootstrap.js --- a/browser/components/extensions/bootstrap.js +++ b/toolkit/mozapps/extensions/internal/WebExtensionBootstrap.js @@ -3,18 +3,26 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; Components.utils.import("resource://gre/modules/Extension.jsm"); let extension; +function install(data, reason) +{ +} + function startup(data, reason) { extension = new Extension(data); extension.startup(); } function shutdown(data, reason) { extension.shutdown(); } + +function uninstall(data, reason) +{ +}
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -4623,16 +4623,18 @@ this.XPIProvider = { metadata: { addonID: aId } }); logger.error("Attempted to load bootstrap scope from missing directory " + aFile.path); return; } let uri = getURIForResourceInFile(aFile, "bootstrap.js").spec; if (aType == "dictionary") uri = "resource://gre/modules/addons/SpellCheckDictionaryBootstrap.js" + else if (aType == "webextension") + uri = "resource://gre/modules/addons/WebExtensionBootstrap.js" this.bootstrapScopes[aId] = new Cu.Sandbox(principal, { sandboxName: uri, wantGlobalProperties: ["indexedDB"], addonId: aId, metadata: { addonID: aId, URI: uri } }); let loader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
--- a/toolkit/mozapps/extensions/internal/moz.build +++ b/toolkit/mozapps/extensions/internal/moz.build @@ -8,16 +8,17 @@ EXTRA_JS_MODULES.addons += [ 'AddonLogging.jsm', 'AddonRepository.jsm', 'AddonRepository_SQLiteMigrator.jsm', 'AddonUpdateChecker.jsm', 'Content.js', 'GMPProvider.jsm', 'LightweightThemeImageOptimizer.jsm', 'SpellCheckDictionaryBootstrap.js', + 'WebExtensionBootstrap.js', ] # Don't ship unused providers on Android if CONFIG['MOZ_WIDGET_TOOLKIT'] != 'android': EXTRA_JS_MODULES.addons += [ 'PluginProvider.jsm', ]
--- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js @@ -5,47 +5,92 @@ const ID = "webextension1@tests.mozilla.org"; const profileDir = gProfD.clone(); profileDir.append("extensions"); createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); startupManager(); +const { GlobalManager, Management } = Components.utils.import("resource://gre/modules/Extension.jsm", {}); + +function promiseAddonStartup() { + return new Promise(resolve => { + let listener = (extension) => { + Management.off("startup", listener); + resolve(extension); + } + + Management.on("startup", listener); + }); +} + add_task(function*() { - yield promiseInstallAllFiles([do_get_addon("webextension_1")], true); + do_check_eq(GlobalManager.count, 0); + do_check_false(GlobalManager.extensionMap.has(ID)); + + yield Promise.all([ + promiseInstallAllFiles([do_get_addon("webextension_1")], true), + promiseAddonStartup() + ]); + + do_check_eq(GlobalManager.count, 1); + do_check_true(GlobalManager.extensionMap.has(ID)); let addon = yield promiseAddonByID(ID); do_check_neq(addon, null); do_check_eq(addon.version, "1.0"); do_check_eq(addon.name, "Web Extension Name"); do_check_true(addon.isCompatible); do_check_false(addon.appDisabled); do_check_true(addon.isActive); do_check_eq(addon.type, "extension"); do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING); // Should persist through a restart - yield promiseRestartManager(); + yield promiseShutdownManager(); + + do_check_eq(GlobalManager.count, 0); + do_check_false(GlobalManager.extensionMap.has(ID)); + + startupManager(); + yield promiseAddonStartup(); + + do_check_eq(GlobalManager.count, 1); + do_check_true(GlobalManager.extensionMap.has(ID)); addon = yield promiseAddonByID(ID); do_check_neq(addon, null); do_check_eq(addon.version, "1.0"); do_check_eq(addon.name, "Web Extension Name"); do_check_true(addon.isCompatible); do_check_false(addon.appDisabled); do_check_true(addon.isActive); do_check_eq(addon.type, "extension"); do_check_eq(addon.signedState, AddonManager.SIGNEDSTATE_MISSING); let file = getFileForAddon(profileDir, ID); do_check_true(file.exists()); + addon.userDisabled = true; + + do_check_eq(GlobalManager.count, 0); + do_check_false(GlobalManager.extensionMap.has(ID)); + + addon.userDisabled = false; + yield promiseAddonStartup(); + + do_check_eq(GlobalManager.count, 1); + do_check_true(GlobalManager.extensionMap.has(ID)); + addon.uninstall(); + do_check_eq(GlobalManager.count, 0); + do_check_false(GlobalManager.extensionMap.has(ID)); + yield promiseShutdownManager(); }); // Writing the manifest direct to the profile should work add_task(function*() { writeWebManifestForExtension({ name: "Web Extension Name", version: "1.0",