--- a/browser/components/extensions/ext-browser.js
+++ b/browser/components/extensions/ext-browser.js
@@ -69,170 +69,8 @@ global.openOptionsPage = (extension) =>
});
return Promise.resolve();
}
let viewId = `addons://detail/${encodeURIComponent(extension.id)}/preferences`;
return window.BrowserOpenAddonsMgr(viewId);
};
-
-extensions.registerModules({
- bookmarks: {
- url: "chrome://browser/content/ext-bookmarks.js",
- schema: "chrome://browser/content/schemas/bookmarks.json",
- scopes: ["addon_parent"],
- paths: [
- ["bookmarks"],
- ],
- },
- browserAction: {
- url: "chrome://browser/content/ext-browserAction.js",
- schema: "chrome://browser/content/schemas/browser_action.json",
- scopes: ["addon_parent"],
- manifest: ["browser_action"],
- paths: [
- ["browserAction"],
- ],
- },
- browsingData: {
- url: "chrome://browser/content/ext-browsingData.js",
- schema: "chrome://browser/content/schemas/browsing_data.json",
- scopes: ["addon_parent"],
- paths: [
- ["browsingData"],
- ],
- },
- chrome_settings_overrides: {
- url: "chrome://browser/content/ext-chrome-settings-overrides.js",
- scopes: [],
- schema: "chrome://browser/content/schemas/chrome_settings_overrides.json",
- manifest: ["chrome_settings_overrides"],
- },
- commands: {
- url: "chrome://browser/content/ext-commands.js",
- schema: "chrome://browser/content/schemas/commands.json",
- scopes: ["addon_parent"],
- manifest: ["commands"],
- paths: [
- ["commands"],
- ],
- },
- devtools: {
- url: "chrome://browser/content/ext-devtools.js",
- schema: "chrome://browser/content/schemas/devtools.json",
- scopes: ["devtools_parent"],
- manifest: ["devtools_page"],
- paths: [
- ["devtools"],
- ],
- },
- devtools_inspectedWindow: {
- url: "chrome://browser/content/ext-devtools-inspectedWindow.js",
- schema: "chrome://browser/content/schemas/devtools_inspected_window.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "inspectedWindow"],
- ],
- },
- devtools_network: {
- url: "chrome://browser/content/ext-devtools-network.js",
- schema: "chrome://browser/content/schemas/devtools_network.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "network"],
- ],
- },
- devtools_panels: {
- url: "chrome://browser/content/ext-devtools-panels.js",
- schema: "chrome://browser/content/schemas/devtools_panels.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "panels"],
- ],
- },
- history: {
- url: "chrome://browser/content/ext-history.js",
- schema: "chrome://browser/content/schemas/history.json",
- scopes: ["addon_parent"],
- paths: [
- ["history"],
- ],
- },
- // This module supports the "menus" and "contextMenus" namespaces,
- // and because of permissions, the module name must differ from both.
- menusInternal: {
- url: "chrome://browser/content/ext-menus.js",
- schema: "chrome://browser/content/schemas/menus.json",
- scopes: ["addon_parent"],
- paths: [
- ["menusInternal"],
- ],
- },
- omnibox: {
- url: "chrome://browser/content/ext-omnibox.js",
- schema: "chrome://browser/content/schemas/omnibox.json",
- scopes: ["addon_parent"],
- manifest: ["omnibox"],
- paths: [
- ["omnibox"],
- ],
- },
- pageAction: {
- url: "chrome://browser/content/ext-pageAction.js",
- schema: "chrome://browser/content/schemas/page_action.json",
- scopes: ["addon_parent"],
- manifest: ["page_action"],
- paths: [
- ["pageAction"],
- ],
- },
- geckoProfiler: {
- url: "chrome://browser/content/ext-geckoProfiler.js",
- schema: "chrome://browser/content/schemas/geckoProfiler.json",
- scopes: ["addon_parent"],
- paths: [
- ["geckoProfiler"],
- ],
- },
- sessions: {
- url: "chrome://browser/content/ext-sessions.js",
- schema: "chrome://browser/content/schemas/sessions.json",
- scopes: ["addon_parent"],
- paths: [
- ["sessions"],
- ],
- },
- sidebarAction: {
- url: "chrome://browser/content/ext-sidebarAction.js",
- schema: "chrome://browser/content/schemas/sidebar_action.json",
- scopes: ["addon_parent"],
- manifest: ["sidebar_action"],
- paths: [
- ["sidebarAction"],
- ],
- },
- tabs: {
- url: "chrome://browser/content/ext-tabs.js",
- schema: "chrome://browser/content/schemas/tabs.json",
- scopes: ["addon_parent"],
- paths: [
- ["tabs"],
- ],
- },
- urlOverrides: {
- url: "chrome://browser/content/ext-url-overrides.js",
- schema: "chrome://browser/content/schemas/url_overrides.json",
- scopes: ["addon_parent"],
- manifest: ["chrome_url_overrides"],
- paths: [
- ["urlOverrides"],
- ],
- },
- windows: {
- url: "chrome://browser/content/ext-windows.js",
- schema: "chrome://browser/content/schemas/windows.json",
- scopes: ["addon_parent"],
- paths: [
- ["windows"],
- ],
- },
-});
copy from browser/components/extensions/ext-browser.js
copy to browser/components/extensions/ext-browser.json
--- a/browser/components/extensions/ext-browser.js
+++ b/browser/components/extensions/ext-browser.json
@@ -1,238 +1,159 @@
-"use strict";
-
-// The ext-* files are imported into the same scopes.
-/* import-globals-from ext-utils.js */
-
-global.EventEmitter = ExtensionUtils.EventEmitter;
-
-// This function is pretty tightly tied to Extension.jsm.
-// Its job is to fill in the |tab| property of the sender.
-const getSender = (extension, target, sender) => {
- let tabId;
- if ("tabId" in sender) {
- // The message came from a privileged extension page running in a tab. In
- // that case, it should include a tabId property (which is filled in by the
- // page-open listener below).
- tabId = sender.tabId;
- delete sender.tabId;
- } else if (target instanceof Ci.nsIDOMXULElement) {
- tabId = tabTracker.getBrowserData(target).tabId;
- }
-
- if (tabId) {
- let tab = extension.tabManager.get(tabId, null);
- if (tab) {
- sender.tab = tab.convert();
- }
- }
-};
-
-// Used by Extension.jsm
-global.tabGetSender = getSender;
-
-/* eslint-disable mozilla/balanced-listeners */
-extensions.on("uninstall", (msg, extension) => {
- if (extension.uninstallURL) {
- let browser = windowTracker.topWindow.gBrowser;
- browser.addTab(extension.uninstallURL, {relatedToCurrent: true});
- }
-});
-
-extensions.on("page-shutdown", (type, context) => {
- if (context.viewType == "tab") {
- if (context.extension.id !== context.xulBrowser.contentPrincipal.addonId) {
- // Only close extension tabs.
- // This check prevents about:addons from closing when it contains a
- // WebExtension as an embedded inline options page.
- return;
- }
- let {gBrowser} = context.xulBrowser.ownerGlobal;
- if (gBrowser) {
- let nativeTab = gBrowser.getTabForBrowser(context.xulBrowser);
- if (nativeTab) {
- gBrowser.removeTab(nativeTab);
- }
- }
- }
-});
-/* eslint-enable mozilla/balanced-listeners */
-
-global.openOptionsPage = (extension) => {
- let window = windowTracker.topWindow;
- if (!window) {
- return Promise.reject({message: "No browser window available"});
- }
-
- if (extension.manifest.options_ui.open_in_tab) {
- window.switchToTabHavingURI(extension.manifest.options_ui.page, true, {
- triggeringPrincipal: extension.principal,
- });
- return Promise.resolve();
- }
-
- let viewId = `addons://detail/${encodeURIComponent(extension.id)}/preferences`;
-
- return window.BrowserOpenAddonsMgr(viewId);
-};
-
-extensions.registerModules({
- bookmarks: {
- url: "chrome://browser/content/ext-bookmarks.js",
- schema: "chrome://browser/content/schemas/bookmarks.json",
- scopes: ["addon_parent"],
- paths: [
- ["bookmarks"],
- ],
+{
+ "bookmarks": {
+ "url": "chrome://browser/content/ext-bookmarks.js",
+ "schema": "chrome://browser/content/schemas/bookmarks.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["bookmarks"]
+ ]
+ },
+ "browserAction": {
+ "url": "chrome://browser/content/ext-browserAction.js",
+ "schema": "chrome://browser/content/schemas/browser_action.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["browser_action"],
+ "paths": [
+ ["browserAction"]
+ ]
+ },
+ "browsingData": {
+ "url": "chrome://browser/content/ext-browsingData.js",
+ "schema": "chrome://browser/content/schemas/browsing_data.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["browsingData"]
+ ]
+ },
+ "chrome_settings_overrides": {
+ "url": "chrome://browser/content/ext-chrome-settings-overrides.js",
+ "scopes": [],
+ "schema": "chrome://browser/content/schemas/chrome_settings_overrides.json",
+ "manifest": ["chrome_settings_overrides"]
},
- browserAction: {
- url: "chrome://browser/content/ext-browserAction.js",
- schema: "chrome://browser/content/schemas/browser_action.json",
- scopes: ["addon_parent"],
- manifest: ["browser_action"],
- paths: [
- ["browserAction"],
- ],
+ "commands": {
+ "url": "chrome://browser/content/ext-commands.js",
+ "schema": "chrome://browser/content/schemas/commands.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["commands"],
+ "paths": [
+ ["commands"]
+ ]
+ },
+ "devtools": {
+ "url": "chrome://browser/content/ext-devtools.js",
+ "schema": "chrome://browser/content/schemas/devtools.json",
+ "scopes": ["devtools_parent"],
+ "manifest": ["devtools_page"],
+ "paths": [
+ ["devtools"]
+ ]
},
- browsingData: {
- url: "chrome://browser/content/ext-browsingData.js",
- schema: "chrome://browser/content/schemas/browsing_data.json",
- scopes: ["addon_parent"],
- paths: [
- ["browsingData"],
- ],
+ "devtools_inspectedWindow": {
+ "url": "chrome://browser/content/ext-devtools-inspectedWindow.js",
+ "schema": "chrome://browser/content/schemas/devtools_inspected_window.json",
+ "scopes": ["devtools_parent"],
+ "paths": [
+ ["devtools", "inspectedWindow"]
+ ]
},
- chrome_settings_overrides: {
- url: "chrome://browser/content/ext-chrome-settings-overrides.js",
- scopes: [],
- schema: "chrome://browser/content/schemas/chrome_settings_overrides.json",
- manifest: ["chrome_settings_overrides"],
+ "devtools_network": {
+ "url": "chrome://browser/content/ext-devtools-network.js",
+ "schema": "chrome://browser/content/schemas/devtools_network.json",
+ "scopes": ["devtools_parent"],
+ "paths": [
+ ["devtools", "network"]
+ ]
},
- commands: {
- url: "chrome://browser/content/ext-commands.js",
- schema: "chrome://browser/content/schemas/commands.json",
- scopes: ["addon_parent"],
- manifest: ["commands"],
- paths: [
- ["commands"],
- ],
+ "devtools_panels": {
+ "url": "chrome://browser/content/ext-devtools-panels.js",
+ "schema": "chrome://browser/content/schemas/devtools_panels.json",
+ "scopes": ["devtools_parent"],
+ "paths": [
+ ["devtools", "panels"]
+ ]
},
- devtools: {
- url: "chrome://browser/content/ext-devtools.js",
- schema: "chrome://browser/content/schemas/devtools.json",
- scopes: ["devtools_parent"],
- manifest: ["devtools_page"],
- paths: [
- ["devtools"],
- ],
+ "history": {
+ "url": "chrome://browser/content/ext-history.js",
+ "schema": "chrome://browser/content/schemas/history.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["history"]
+ ]
},
- devtools_inspectedWindow: {
- url: "chrome://browser/content/ext-devtools-inspectedWindow.js",
- schema: "chrome://browser/content/schemas/devtools_inspected_window.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "inspectedWindow"],
- ],
- },
- devtools_network: {
- url: "chrome://browser/content/ext-devtools-network.js",
- schema: "chrome://browser/content/schemas/devtools_network.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "network"],
- ],
+ "menusInternal": {
+ "url": "chrome://browser/content/ext-menus.js",
+ "schema": "chrome://browser/content/schemas/menus.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["menusInternal"]
+ ]
},
- devtools_panels: {
- url: "chrome://browser/content/ext-devtools-panels.js",
- schema: "chrome://browser/content/schemas/devtools_panels.json",
- scopes: ["devtools_parent"],
- paths: [
- ["devtools", "panels"],
- ],
- },
- history: {
- url: "chrome://browser/content/ext-history.js",
- schema: "chrome://browser/content/schemas/history.json",
- scopes: ["addon_parent"],
- paths: [
- ["history"],
- ],
+ "omnibox": {
+ "url": "chrome://browser/content/ext-omnibox.js",
+ "schema": "chrome://browser/content/schemas/omnibox.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["omnibox"],
+ "paths": [
+ ["omnibox"]
+ ]
},
- // This module supports the "menus" and "contextMenus" namespaces,
- // and because of permissions, the module name must differ from both.
- menusInternal: {
- url: "chrome://browser/content/ext-menus.js",
- schema: "chrome://browser/content/schemas/menus.json",
- scopes: ["addon_parent"],
- paths: [
- ["menusInternal"],
- ],
+ "pageAction": {
+ "url": "chrome://browser/content/ext-pageAction.js",
+ "schema": "chrome://browser/content/schemas/page_action.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["page_action"],
+ "paths": [
+ ["pageAction"]
+ ]
},
- omnibox: {
- url: "chrome://browser/content/ext-omnibox.js",
- schema: "chrome://browser/content/schemas/omnibox.json",
- scopes: ["addon_parent"],
- manifest: ["omnibox"],
- paths: [
- ["omnibox"],
- ],
+ "geckoProfiler": {
+ "url": "chrome://browser/content/ext-geckoProfiler.js",
+ "schema": "chrome://browser/content/schemas/geckoProfiler.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["geckoProfiler"]
+ ]
},
- pageAction: {
- url: "chrome://browser/content/ext-pageAction.js",
- schema: "chrome://browser/content/schemas/page_action.json",
- scopes: ["addon_parent"],
- manifest: ["page_action"],
- paths: [
- ["pageAction"],
- ],
+ "sessions": {
+ "url": "chrome://browser/content/ext-sessions.js",
+ "schema": "chrome://browser/content/schemas/sessions.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["sessions"]
+ ]
},
- geckoProfiler: {
- url: "chrome://browser/content/ext-geckoProfiler.js",
- schema: "chrome://browser/content/schemas/geckoProfiler.json",
- scopes: ["addon_parent"],
- paths: [
- ["geckoProfiler"],
- ],
- },
- sessions: {
- url: "chrome://browser/content/ext-sessions.js",
- schema: "chrome://browser/content/schemas/sessions.json",
- scopes: ["addon_parent"],
- paths: [
- ["sessions"],
- ],
+ "sidebarAction": {
+ "url": "chrome://browser/content/ext-sidebarAction.js",
+ "schema": "chrome://browser/content/schemas/sidebar_action.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["sidebar_action"],
+ "paths": [
+ ["sidebarAction"]
+ ]
},
- sidebarAction: {
- url: "chrome://browser/content/ext-sidebarAction.js",
- schema: "chrome://browser/content/schemas/sidebar_action.json",
- scopes: ["addon_parent"],
- manifest: ["sidebar_action"],
- paths: [
- ["sidebarAction"],
- ],
- },
- tabs: {
- url: "chrome://browser/content/ext-tabs.js",
- schema: "chrome://browser/content/schemas/tabs.json",
- scopes: ["addon_parent"],
- paths: [
- ["tabs"],
- ],
+ "tabs": {
+ "url": "chrome://browser/content/ext-tabs.js",
+ "schema": "chrome://browser/content/schemas/tabs.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["tabs"]
+ ]
},
- urlOverrides: {
- url: "chrome://browser/content/ext-url-overrides.js",
- schema: "chrome://browser/content/schemas/url_overrides.json",
- scopes: ["addon_parent"],
- manifest: ["chrome_url_overrides"],
- paths: [
- ["urlOverrides"],
- ],
+ "urlOverrides": {
+ "url": "chrome://browser/content/ext-url-overrides.js",
+ "schema": "chrome://browser/content/schemas/url_overrides.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["chrome_url_overrides"],
+ "paths": [
+ ["urlOverrides"]
+ ]
},
- windows: {
- url: "chrome://browser/content/ext-windows.js",
- schema: "chrome://browser/content/schemas/windows.json",
- scopes: ["addon_parent"],
- paths: [
- ["windows"],
- ],
- },
-});
+ "windows": {
+ "url": "chrome://browser/content/ext-windows.js",
+ "schema": "chrome://browser/content/schemas/windows.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["windows"]
+ ]
+ }
+}
--- a/browser/components/extensions/extensions-browser.manifest
+++ b/browser/components/extensions/extensions-browser.manifest
@@ -1,6 +1,8 @@
+category webextension-modules browser chrome://browser/content/ext-browser.json
+
category webextension-scripts browser chrome://browser/content/ext-browser.js
category webextension-scripts utils chrome://browser/content/ext-utils.js
category webextension-scripts-devtools browser chrome://browser/content/ext-c-browser.js
category webextension-scripts-addon browser chrome://browser/content/ext-c-browser.js
category webextension-schemas menus_internal chrome://browser/content/schemas/menus_internal.json
--- a/browser/components/extensions/jar.mn
+++ b/browser/components/extensions/jar.mn
@@ -9,16 +9,17 @@ browser.jar:
content/browser/extension-mac-panel.css
#endif
#ifdef XP_WIN
content/browser/extension-win-panel.css
#endif
content/browser/extension.svg
content/browser/ext-bookmarks.js
content/browser/ext-browser.js
+ content/browser/ext-browser.json
content/browser/ext-browserAction.js
content/browser/ext-browsingData.js
content/browser/ext-chrome-settings-overrides.js
content/browser/ext-commands.js
content/browser/ext-devtools.js
content/browser/ext-devtools-inspectedWindow.js
content/browser/ext-devtools-network.js
content/browser/ext-devtools-panels.js
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -10,16 +10,18 @@
*/
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
/* exported ExtensionCommon */
this.EXPORTED_SYMBOLS = ["ExtensionCommon"];
+Cu.importGlobalProperties(["fetch"]);
+
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "MessageChannel",
"resource://gre/modules/MessageChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Preferences",
"resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
@@ -613,16 +615,36 @@ function deepCopy(dest, source) {
}
deepCopy(dest[prop], source[prop]);
} else {
Object.defineProperty(dest, prop, desc);
}
}
}
+function getChild(map, key) {
+ let child = map.children.get(key);
+ if (!child) {
+ child = {
+ modules: new Set(),
+ children: new Map(),
+ };
+
+ map.children.set(key, child);
+ }
+ return child;
+}
+
+function getPath(map, path) {
+ for (let key of path) {
+ map = getChild(map, key);
+ }
+ return map;
+}
+
/**
* Manages loading and accessing a set of APIs for a specific extension
* context.
*
* @param {BaseContext} context
* The context to manage APIs for.
* @param {SchemaAPIManager} apiManager
* The API manager holding the APIs to manage.
@@ -707,17 +729,17 @@ class CanOfAPIs {
let obj = this.root;
let modules = this.apiManager.modulePaths;
for (let key of path.split(".")) {
if (!obj) {
return;
}
- modules = modules.get(key);
+ modules = getChild(modules, key);
for (let name of modules.modules) {
if (!this.apis.has(name)) {
this.loadAPI(name);
}
}
obj = obj[key];
@@ -743,17 +765,17 @@ class CanOfAPIs {
let obj = this.root;
let modules = this.apiManager.modulePaths;
for (let key of path.split(".")) {
if (!obj) {
return;
}
- modules = modules.get(key);
+ modules = getChild(modules, key);
for (let name of modules.modules) {
if (!this.apis.has(name)) {
await this.asyncLoadAPI(name);
}
}
if (typeof obj[key] === "function") {
@@ -763,28 +785,16 @@ class CanOfAPIs {
}
}
this.apiPaths.set(path, obj);
return obj;
}
}
-class DeepMap extends DefaultMap {
- constructor() {
- super(() => new DeepMap());
-
- this.modules = new Set();
- }
-
- getPath(path) {
- return path.reduce((map, key) => map.get(key), this);
- }
-}
-
/**
* @class APIModule
* @abstract
*
* @property {string} url
* The URL of the script which contains the module's
* implementation. This script must define a global property
* matching the modules name, which must be a class constructor
@@ -827,27 +837,64 @@ class SchemaAPIManager extends EventEmit
* "proxy" - A proxy script process.
*/
constructor(processType) {
super();
this.processType = processType;
this.global = this._createExtGlobal();
this.modules = new Map();
- this.modulePaths = new DeepMap();
+ this.modulePaths = {children: new Map(), modules: new Set()};
this.manifestKeys = new Map();
this.eventModules = new DefaultMap(() => new Set());
+ this._modulesJSONLoaded = false;
+
this.schemaURLs = new Set();
this.apis = new DefaultWeakMap(() => new Map());
this._scriptScopes = [];
}
+ async loadModuleJSON(urls) {
+ function fetchJSON(url) {
+ return fetch(url).then(resp => resp.json());
+ }
+
+ for (let json of await Promise.all(urls.map(fetchJSON))) {
+ this.registerModules(json);
+ }
+
+ this._modulesJSONLoaded = true;
+
+ return new StructuredCloneHolder({
+ modules: this.modules,
+ modulePaths: this.modulePaths,
+ manifestKeys: this.manifestKeys,
+ eventModules: this.eventModules,
+ schemaURLs: this.schemaURLs,
+ });
+ }
+
+ initModuleData(moduleData) {
+ if (!this._modulesJSONLoaded) {
+ let data = moduleData.deserialize({});
+
+ this.modules = data.modules;
+ this.modulePaths = data.modulePaths;
+ this.manifestKeys = data.manifestKeys;
+ this.eventModules = new DefaultMap(() => new Set(),
+ data.eventModules);
+ this.schemaURLs = data.schemaURLs;
+ }
+
+ this._modulesJSONLoaded = true;
+ }
+
/**
* Registers a set of ExtensionAPI modules to be lazily loaded and
* managed by this manager.
*
* @param {object} obj
* An object containing property for eacy API module to be
* registered. Each value should be an object implementing the
* APIModule interface.
@@ -873,17 +920,17 @@ class SchemaAPIManager extends EventEmit
if (this.manifestKeys.has(key)) {
throw new Error(`Manifest key '${key}' already registered by '${this.manifestKeys.get(key)}'`);
}
this.manifestKeys.set(key, name);
}
for (let path of details.paths || []) {
- this.modulePaths.getPath(path).modules.add(name);
+ getPath(this.modulePaths, path).modules.add(name);
}
}
}
/**
* Emits an `onManifestEntry` event for the top-level manifest entry
* on all relevant {@link ExtensionAPI} instances for the given
* extension.
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -59,26 +59,28 @@ var {
defineLazyGetter,
promiseDocumentLoaded,
promiseEvent,
promiseFileContents,
promiseObserved,
} = ExtensionUtils;
const BASE_SCHEMA = "chrome://extensions/content/schemas/manifest.json";
+const CATEGORY_EXTENSION_MODULES = "webextension-modules";
const CATEGORY_EXTENSION_SCHEMAS = "webextension-schemas";
const CATEGORY_EXTENSION_SCRIPTS = "webextension-scripts";
let schemaURLs = new Set();
schemaURLs.add("chrome://extensions/content/schemas/experiments.json");
let GlobalManager;
let ParentAPIManager;
let ProxyMessenger;
+let StartupCache;
// This object loads the ext-*.js scripts that define the extension API.
let apiManager = new class extends SchemaAPIManager {
constructor() {
super("main");
this.initialized = null;
this.on("startup", (event, extension) => { // eslint-disable-line mozilla/balanced-listeners
@@ -88,28 +90,41 @@ let apiManager = new class extends Schem
api.onStartup(extension.startupReason);
}));
}
return Promise.all(promises);
});
}
+ getModuleJSONURLs() {
+ return Array.from(XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_MODULES),
+ ([name, url]) => url);
+ }
+
// Loads all the ext-*.js scripts currently registered.
lazyInit() {
if (this.initialized) {
return this.initialized;
}
- let scripts = [];
+ let modulesPromise = StartupCache.other.get(
+ ["parentModules"],
+ () => this.loadModuleJSON(this.getModuleJSONURLs()));
+
+ let scriptURLs = [];
for (let [/* name */, value] of XPCOMUtils.enumerateCategoryEntries(CATEGORY_EXTENSION_SCRIPTS)) {
- scripts.push(value);
+ scriptURLs.push(value);
}
- let promise = Promise.all(scripts.map(url => ChromeUtils.compileScript(url))).then(scripts => {
+ let promise = (async () => {
+ let scripts = await Promise.all(scriptURLs.map(url => ChromeUtils.compileScript(url)));
+
+ this.initModuleData(await modulesPromise);
+
for (let script of scripts) {
script.executeInGlobal(this.global);
}
// Load order matters here. The base manifest defines types which are
// extended by other schemas, so needs to be loaded first.
return Schemas.load(BASE_SCHEMA).then(() => {
let promises = [];
@@ -119,17 +134,17 @@ let apiManager = new class extends Schem
for (let url of this.schemaURLs) {
promises.push(Schemas.load(url));
}
for (let url of schemaURLs) {
promises.push(Schemas.load(url));
}
return Promise.all(promises);
});
- });
+ })();
/* eslint-disable mozilla/balanced-listeners */
Services.mm.addMessageListener("Extension:GetTabAndWindowId", this);
/* eslint-enable mozilla/balanced-listeners */
this.initialized = promise;
return this.initialized;
}
@@ -1356,20 +1371,20 @@ let IconDetails = {
// These URLs should already be properly escaped, but make doubly sure CSS
// string escape characters are escaped here, since they could lead to a
// sandbox break.
escapeUrl(url) {
return url.replace(/[\\\s"]/g, encodeURIComponent);
},
};
-let StartupCache = {
+StartupCache = {
DB_NAME: "ExtensionStartupCache",
- STORE_NAMES: Object.freeze(["general", "locales", "manifests", "permissions", "schemas"]),
+ STORE_NAMES: Object.freeze(["general", "locales", "manifests", "other", "permissions", "schemas"]),
get file() {
return FileUtils.getFile("ProfLD", ["startupCache", "webext.sc.lz4"]);
},
get saver() {
if (!this._saver) {
this._saver = new DeferredSave(this.file.path,
--- a/toolkit/components/extensions/ext-toolkit.js
+++ b/toolkit/components/extensions/ext-toolkit.js
@@ -73,195 +73,16 @@ global.getContainerForCookieStoreId = fu
};
global.isValidCookieStoreId = function(storeId) {
return isDefaultCookieStoreId(storeId) ||
isPrivateCookieStoreId(storeId) ||
isContainerCookieStoreId(storeId);
};
-extensions.registerModules({
- manifest: {
- schema: "chrome://extensions/content/schemas/extension_types.json",
- scopes: [],
- },
- alarms: {
- url: "chrome://extensions/content/ext-alarms.js",
- schema: "chrome://extensions/content/schemas/alarms.json",
- scopes: ["addon_parent"],
- paths: [
- ["alarms"],
- ],
- },
- backgroundPage: {
- url: "chrome://extensions/content/ext-backgroundPage.js",
- scopes: ["addon_parent"],
- manifest: ["background"],
- },
- browserSettings: {
- url: "chrome://extensions/content/ext-browserSettings.js",
- schema: "chrome://extensions/content/schemas/browser_settings.json",
- scopes: ["addon_parent"],
- paths: [
- ["browserSettings"],
- ],
- },
- contextualIdentities: {
- url: "chrome://extensions/content/ext-contextualIdentities.js",
- schema: "chrome://extensions/content/schemas/contextual_identities.json",
- scopes: ["addon_parent"],
- paths: [
- ["contextualIdentities"],
- ],
- },
- cookies: {
- url: "chrome://extensions/content/ext-cookies.js",
- schema: "chrome://extensions/content/schemas/cookies.json",
- scopes: ["addon_parent"],
- paths: [
- ["cookies"],
- ],
- },
- downloads: {
- url: "chrome://extensions/content/ext-downloads.js",
- schema: "chrome://extensions/content/schemas/downloads.json",
- scopes: ["addon_parent"],
- paths: [
- ["downloads"],
- ],
- },
- extension: {
- url: "chrome://extensions/content/ext-extension.js",
- schema: "chrome://extensions/content/schemas/extension.json",
- scopes: ["addon_parent"],
- paths: [
- ["extension"],
- ],
- },
- geolocation: {
- url: "chrome://extensions/content/ext-geolocation.js",
- events: ["startup"],
- },
- i18n: {
- url: "chrome://extensions/content/ext-i18n.js",
- schema: "chrome://extensions/content/schemas/i18n.json",
- scopes: ["addon_parent", "content_child", "devtools_child"],
- paths: [
- ["i18n"],
- ],
- },
- idle: {
- url: "chrome://extensions/content/ext-idle.js",
- schema: "chrome://extensions/content/schemas/idle.json",
- scopes: ["addon_parent"],
- paths: [
- ["idle"],
- ],
- },
- management: {
- url: "chrome://extensions/content/ext-management.js",
- schema: "chrome://extensions/content/schemas/management.json",
- scopes: ["addon_parent"],
- paths: [
- ["management"],
- ],
- },
- notifications: {
- url: "chrome://extensions/content/ext-notifications.js",
- schema: "chrome://extensions/content/schemas/notifications.json",
- scopes: ["addon_parent"],
- paths: [
- ["notifications"],
- ],
- },
- permissions: {
- url: "chrome://extensions/content/ext-permissions.js",
- schema: "chrome://extensions/content/schemas/permissions.json",
- scopes: ["addon_parent"],
- paths: [
- ["permissions"],
- ],
- },
- privacy: {
- url: "chrome://extensions/content/ext-privacy.js",
- schema: "chrome://extensions/content/schemas/privacy.json",
- scopes: ["addon_parent"],
- paths: [
- ["privacy"],
- ],
- },
- protocolHandlers: {
- url: "chrome://extensions/content/ext-protocolHandlers.js",
- schema: "chrome://extensions/content/schemas/extension_protocol_handlers.json",
- scopes: ["addon_parent"],
- manifest: ["protocol_handlers"],
- },
- proxy: {
- url: "chrome://extensions/content/ext-proxy.js",
- schema: "chrome://extensions/content/schemas/proxy.json",
- scopes: ["addon_parent"],
- paths: [
- ["proxy"],
- ],
- },
- runtime: {
- url: "chrome://extensions/content/ext-runtime.js",
- schema: "chrome://extensions/content/schemas/runtime.json",
- scopes: ["addon_parent", "content_parent", "devtools_parent"],
- paths: [
- ["runtime"],
- ],
- },
- storage: {
- url: "chrome://extensions/content/ext-storage.js",
- schema: "chrome://extensions/content/schemas/storage.json",
- scopes: ["addon_parent", "content_parent", "devtools_parent"],
- paths: [
- ["storage"],
- ],
- },
- test: {
- schema: "chrome://extensions/content/schemas/test.json",
- scopes: [],
- },
- theme: {
- url: "chrome://extensions/content/ext-theme.js",
- schema: "chrome://extensions/content/schemas/theme.json",
- scopes: ["addon_parent"],
- manifest: ["theme"],
- paths: [
- ["theme"],
- ],
- },
- topSites: {
- url: "chrome://extensions/content/ext-topSites.js",
- schema: "chrome://extensions/content/schemas/top_sites.json",
- scopes: ["addon_parent"],
- paths: [
- ["topSites"],
- ],
- },
- webNavigation: {
- url: "chrome://extensions/content/ext-webNavigation.js",
- schema: "chrome://extensions/content/schemas/web_navigation.json",
- scopes: ["addon_parent"],
- paths: [
- ["webNavigation"],
- ],
- },
- webRequest: {
- url: "chrome://extensions/content/ext-webRequest.js",
- schema: "chrome://extensions/content/schemas/web_request.json",
- scopes: ["addon_parent"],
- paths: [
- ["webRequest"],
- ],
- },
-});
-
if (AppConstants.MOZ_BUILD_APP === "browser") {
extensions.registerModules({
identity: {
schema: "chrome://extensions/content/schemas/identity.json",
scopes: ["addon_parent"],
},
});
}
copy from toolkit/components/extensions/ext-toolkit.js
copy to toolkit/components/extensions/ext-toolkit.json
--- a/toolkit/components/extensions/ext-toolkit.js
+++ b/toolkit/components/extensions/ext-toolkit.json
@@ -1,267 +1,178 @@
-"use strict";
-
-// These are defined on "global" which is used for the same scopes as the other
-// ext-*.js files.
-/* exported getCookieStoreIdForTab, getCookieStoreIdForContainer,
- getContainerForCookieStoreId,
- isValidCookieStoreId, isContainerCookieStoreId,
- EventManager, InputEventManager */
-/* global getCookieStoreIdForTab:false, getCookieStoreIdForContainer:false,
- getContainerForCookieStoreId: false,
- isValidCookieStoreId:false, isContainerCookieStoreId:false,
- isDefaultCookieStoreId: false, isPrivateCookieStoreId:false,
- EventManager: false, InputEventManager: false */
-
-XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
- "resource://gre/modules/ContextualIdentityService.jsm");
-
-Cu.import("resource://gre/modules/ExtensionCommon.jsm");
-
-global.EventManager = ExtensionCommon.EventManager;
-global.InputEventManager = class extends EventManager {
- constructor(...args) {
- super(...args);
- this.inputHandling = true;
- }
-};
-
-/* globals DEFAULT_STORE, PRIVATE_STORE, CONTAINER_STORE */
-
-global.DEFAULT_STORE = "firefox-default";
-global.PRIVATE_STORE = "firefox-private";
-global.CONTAINER_STORE = "firefox-container-";
-
-global.getCookieStoreIdForTab = function(data, tab) {
- if (data.incognito) {
- return PRIVATE_STORE;
- }
-
- if (tab.userContextId) {
- return getCookieStoreIdForContainer(tab.userContextId);
- }
-
- return DEFAULT_STORE;
-};
-
-global.isPrivateCookieStoreId = function(storeId) {
- return storeId == PRIVATE_STORE;
-};
-
-global.isDefaultCookieStoreId = function(storeId) {
- return storeId == DEFAULT_STORE;
-};
-
-global.isContainerCookieStoreId = function(storeId) {
- return storeId !== null && storeId.startsWith(CONTAINER_STORE);
-};
-
-global.getCookieStoreIdForContainer = function(containerId) {
- return CONTAINER_STORE + containerId;
-};
-
-global.getContainerForCookieStoreId = function(storeId) {
- if (!isContainerCookieStoreId(storeId)) {
- return null;
- }
-
- let containerId = storeId.substring(CONTAINER_STORE.length);
- if (ContextualIdentityService.getPublicIdentityFromId(containerId)) {
- return parseInt(containerId, 10);
- }
-
- return null;
-};
-
-global.isValidCookieStoreId = function(storeId) {
- return isDefaultCookieStoreId(storeId) ||
- isPrivateCookieStoreId(storeId) ||
- isContainerCookieStoreId(storeId);
-};
-
-extensions.registerModules({
- manifest: {
- schema: "chrome://extensions/content/schemas/extension_types.json",
- scopes: [],
+{
+ "manifest": {
+ "schema": "chrome://extensions/content/schemas/extension_types.json",
+ "scopes": []
+ },
+ "alarms": {
+ "url": "chrome://extensions/content/ext-alarms.js",
+ "schema": "chrome://extensions/content/schemas/alarms.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["alarms"]
+ ]
+ },
+ "backgroundPage": {
+ "url": "chrome://extensions/content/ext-backgroundPage.js",
+ "scopes": ["addon_parent"],
+ "manifest": ["background"]
+ },
+ "browserSettings": {
+ "url": "chrome://extensions/content/ext-browserSettings.js",
+ "schema": "chrome://extensions/content/schemas/browser_settings.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["browserSettings"]
+ ]
+ },
+ "contextualIdentities": {
+ "url": "chrome://extensions/content/ext-contextualIdentities.js",
+ "schema": "chrome://extensions/content/schemas/contextual_identities.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["contextualIdentities"]
+ ]
+ },
+ "cookies": {
+ "url": "chrome://extensions/content/ext-cookies.js",
+ "schema": "chrome://extensions/content/schemas/cookies.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["cookies"]
+ ]
},
- alarms: {
- url: "chrome://extensions/content/ext-alarms.js",
- schema: "chrome://extensions/content/schemas/alarms.json",
- scopes: ["addon_parent"],
- paths: [
- ["alarms"],
- ],
+ "downloads": {
+ "url": "chrome://extensions/content/ext-downloads.js",
+ "schema": "chrome://extensions/content/schemas/downloads.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["downloads"]
+ ]
},
- backgroundPage: {
- url: "chrome://extensions/content/ext-backgroundPage.js",
- scopes: ["addon_parent"],
- manifest: ["background"],
+ "extension": {
+ "url": "chrome://extensions/content/ext-extension.js",
+ "schema": "chrome://extensions/content/schemas/extension.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["extension"]
+ ]
},
- browserSettings: {
- url: "chrome://extensions/content/ext-browserSettings.js",
- schema: "chrome://extensions/content/schemas/browser_settings.json",
- scopes: ["addon_parent"],
- paths: [
- ["browserSettings"],
- ],
+ "geolocation": {
+ "url": "chrome://extensions/content/ext-geolocation.js",
+ "events": ["startup"]
},
- contextualIdentities: {
- url: "chrome://extensions/content/ext-contextualIdentities.js",
- schema: "chrome://extensions/content/schemas/contextual_identities.json",
- scopes: ["addon_parent"],
- paths: [
- ["contextualIdentities"],
- ],
+ "i18n": {
+ "url": "chrome://extensions/content/ext-i18n.js",
+ "schema": "chrome://extensions/content/schemas/i18n.json",
+ "scopes": ["addon_parent", "content_child", "devtools_child"],
+ "paths": [
+ ["i18n"]
+ ]
},
- cookies: {
- url: "chrome://extensions/content/ext-cookies.js",
- schema: "chrome://extensions/content/schemas/cookies.json",
- scopes: ["addon_parent"],
- paths: [
- ["cookies"],
- ],
+ "idle": {
+ "url": "chrome://extensions/content/ext-idle.js",
+ "schema": "chrome://extensions/content/schemas/idle.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["idle"]
+ ]
},
- downloads: {
- url: "chrome://extensions/content/ext-downloads.js",
- schema: "chrome://extensions/content/schemas/downloads.json",
- scopes: ["addon_parent"],
- paths: [
- ["downloads"],
- ],
+ "management": {
+ "url": "chrome://extensions/content/ext-management.js",
+ "schema": "chrome://extensions/content/schemas/management.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["management"]
+ ]
},
- extension: {
- url: "chrome://extensions/content/ext-extension.js",
- schema: "chrome://extensions/content/schemas/extension.json",
- scopes: ["addon_parent"],
- paths: [
- ["extension"],
- ],
- },
- geolocation: {
- url: "chrome://extensions/content/ext-geolocation.js",
- events: ["startup"],
+ "notifications": {
+ "url": "chrome://extensions/content/ext-notifications.js",
+ "schema": "chrome://extensions/content/schemas/notifications.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["notifications"]
+ ]
},
- i18n: {
- url: "chrome://extensions/content/ext-i18n.js",
- schema: "chrome://extensions/content/schemas/i18n.json",
- scopes: ["addon_parent", "content_child", "devtools_child"],
- paths: [
- ["i18n"],
- ],
- },
- idle: {
- url: "chrome://extensions/content/ext-idle.js",
- schema: "chrome://extensions/content/schemas/idle.json",
- scopes: ["addon_parent"],
- paths: [
- ["idle"],
- ],
+ "permissions": {
+ "url": "chrome://extensions/content/ext-permissions.js",
+ "schema": "chrome://extensions/content/schemas/permissions.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["permissions"]
+ ]
},
- management: {
- url: "chrome://extensions/content/ext-management.js",
- schema: "chrome://extensions/content/schemas/management.json",
- scopes: ["addon_parent"],
- paths: [
- ["management"],
- ],
+ "privacy": {
+ "url": "chrome://extensions/content/ext-privacy.js",
+ "schema": "chrome://extensions/content/schemas/privacy.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["privacy"]
+ ]
},
- notifications: {
- url: "chrome://extensions/content/ext-notifications.js",
- schema: "chrome://extensions/content/schemas/notifications.json",
- scopes: ["addon_parent"],
- paths: [
- ["notifications"],
- ],
+ "protocolHandlers": {
+ "url": "chrome://extensions/content/ext-protocolHandlers.js",
+ "schema": "chrome://extensions/content/schemas/extension_protocol_handlers.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["protocol_handlers"]
},
- permissions: {
- url: "chrome://extensions/content/ext-permissions.js",
- schema: "chrome://extensions/content/schemas/permissions.json",
- scopes: ["addon_parent"],
- paths: [
- ["permissions"],
- ],
+ "proxy": {
+ "url": "chrome://extensions/content/ext-proxy.js",
+ "schema": "chrome://extensions/content/schemas/proxy.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["proxy"]
+ ]
},
- privacy: {
- url: "chrome://extensions/content/ext-privacy.js",
- schema: "chrome://extensions/content/schemas/privacy.json",
- scopes: ["addon_parent"],
- paths: [
- ["privacy"],
- ],
- },
- protocolHandlers: {
- url: "chrome://extensions/content/ext-protocolHandlers.js",
- schema: "chrome://extensions/content/schemas/extension_protocol_handlers.json",
- scopes: ["addon_parent"],
- manifest: ["protocol_handlers"],
+ "runtime": {
+ "url": "chrome://extensions/content/ext-runtime.js",
+ "schema": "chrome://extensions/content/schemas/runtime.json",
+ "scopes": ["addon_parent", "content_parent", "devtools_parent"],
+ "paths": [
+ ["runtime"]
+ ]
},
- proxy: {
- url: "chrome://extensions/content/ext-proxy.js",
- schema: "chrome://extensions/content/schemas/proxy.json",
- scopes: ["addon_parent"],
- paths: [
- ["proxy"],
- ],
+ "storage": {
+ "url": "chrome://extensions/content/ext-storage.js",
+ "schema": "chrome://extensions/content/schemas/storage.json",
+ "scopes": ["addon_parent", "content_parent", "devtools_parent"],
+ "paths": [
+ ["storage"]
+ ]
},
- runtime: {
- url: "chrome://extensions/content/ext-runtime.js",
- schema: "chrome://extensions/content/schemas/runtime.json",
- scopes: ["addon_parent", "content_parent", "devtools_parent"],
- paths: [
- ["runtime"],
- ],
+ "test": {
+ "schema": "chrome://extensions/content/schemas/test.json",
+ "scopes": []
},
- storage: {
- url: "chrome://extensions/content/ext-storage.js",
- schema: "chrome://extensions/content/schemas/storage.json",
- scopes: ["addon_parent", "content_parent", "devtools_parent"],
- paths: [
- ["storage"],
- ],
- },
- test: {
- schema: "chrome://extensions/content/schemas/test.json",
- scopes: [],
+ "theme": {
+ "url": "chrome://extensions/content/ext-theme.js",
+ "schema": "chrome://extensions/content/schemas/theme.json",
+ "scopes": ["addon_parent"],
+ "manifest": ["theme"],
+ "paths": [
+ ["theme"]
+ ]
},
- theme: {
- url: "chrome://extensions/content/ext-theme.js",
- schema: "chrome://extensions/content/schemas/theme.json",
- scopes: ["addon_parent"],
- manifest: ["theme"],
- paths: [
- ["theme"],
- ],
- },
- topSites: {
- url: "chrome://extensions/content/ext-topSites.js",
- schema: "chrome://extensions/content/schemas/top_sites.json",
- scopes: ["addon_parent"],
- paths: [
- ["topSites"],
- ],
+ "topSites": {
+ "url": "chrome://extensions/content/ext-topSites.js",
+ "schema": "chrome://extensions/content/schemas/top_sites.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["topSites"]
+ ]
},
- webNavigation: {
- url: "chrome://extensions/content/ext-webNavigation.js",
- schema: "chrome://extensions/content/schemas/web_navigation.json",
- scopes: ["addon_parent"],
- paths: [
- ["webNavigation"],
- ],
+ "webNavigation": {
+ "url": "chrome://extensions/content/ext-webNavigation.js",
+ "schema": "chrome://extensions/content/schemas/web_navigation.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["webNavigation"]
+ ]
},
- webRequest: {
- url: "chrome://extensions/content/ext-webRequest.js",
- schema: "chrome://extensions/content/schemas/web_request.json",
- scopes: ["addon_parent"],
- paths: [
- ["webRequest"],
- ],
- },
-});
-
-if (AppConstants.MOZ_BUILD_APP === "browser") {
- extensions.registerModules({
- identity: {
- schema: "chrome://extensions/content/schemas/identity.json",
- scopes: ["addon_parent"],
- },
- });
+ "webRequest": {
+ "url": "chrome://extensions/content/ext-webRequest.js",
+ "schema": "chrome://extensions/content/schemas/web_request.json",
+ "scopes": ["addon_parent"],
+ "paths": [
+ ["webRequest"]
+ ]
+ }
}
--- a/toolkit/components/extensions/extensions-toolkit.manifest
+++ b/toolkit/components/extensions/extensions-toolkit.manifest
@@ -1,9 +1,11 @@
# scripts
+category webextension-modules toolkit chrome://extensions/content/ext-toolkit.json
+
category webextension-scripts tabs-base chrome://extensions/content/ext-tabs-base.js
category webextension-scripts toolkit chrome://extensions/content/ext-toolkit.js
category webextension-scripts-content toolkit chrome://extensions/content/ext-c-toolkit.js
category webextension-scripts-devtools toolkit chrome://extensions/content/ext-c-toolkit.js
category webextension-scripts-addon toolkit chrome://extensions/content/ext-c-toolkit.js
category webextension-schemas events chrome://extensions/content/schemas/events.json
category webextension-schemas native_host_manifest chrome://extensions/content/schemas/native_host_manifest.json
--- a/toolkit/components/extensions/jar.mn
+++ b/toolkit/components/extensions/jar.mn
@@ -22,16 +22,17 @@ toolkit.jar:
content/extensions/ext-privacy.js
content/extensions/ext-protocolHandlers.js
content/extensions/ext-proxy.js
content/extensions/ext-runtime.js
content/extensions/ext-storage.js
content/extensions/ext-tabs-base.js
content/extensions/ext-theme.js
content/extensions/ext-toolkit.js
+ content/extensions/ext-toolkit.json
content/extensions/ext-topSites.js
content/extensions/ext-webRequest.js
content/extensions/ext-webNavigation.js
# Below is a separate group using the naming convention ext-c-*.js that run
# in the child process.
content/extensions/ext-c-backgroundPage.js
content/extensions/ext-c-extension.js
#ifndef ANDROID