--- a/browser/components/extensions/ext-browserAction.js
+++ b/browser/components/extensions/ext-browserAction.js
@@ -13,17 +13,17 @@ XPCOMUtils.defineLazyServiceGetter(this,
"@mozilla.org/inspector/dom-utils;1",
"inIDOMUtils");
Cu.import("resource://devtools/shared/event-emitter.js");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/Task.jsm");
var {
- EventManager,
+ SingletonEventManager,
IconDetails,
} = ExtensionUtils;
const POPUP_PRELOAD_TIMEOUT_MS = 200;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
function isAncestorOrSelf(target, node) {
@@ -441,20 +441,20 @@ extensions.on("shutdown", (type, extensi
}
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("browserAction", "addon_parent", context => {
let {extension} = context;
return {
browserAction: {
- onClicked: new EventManager(context, "browserAction.onClicked", fire => {
+ onClicked: new SingletonEventManager(context, "browserAction.onClicked", fire => {
let listener = () => {
let tab = TabManager.activeTab;
- fire(TabManager.convert(extension, tab));
+ fire.async(TabManager.convert(extension, tab));
};
BrowserAction.for(extension).on("click", listener);
return () => {
BrowserAction.for(extension).off("click", listener);
};
}).api(),
enable: function(tabId) {
--- a/browser/components/extensions/ext-commands.js
+++ b/browser/components/extensions/ext-commands.js
@@ -1,17 +1,17 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
Cu.import("resource://devtools/shared/event-emitter.js");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
+ SingletonEventManager,
PlatformInfo,
} = ExtensionUtils;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
// WeakMap[Extension -> CommandList]
var commandsMap = new WeakMap();
@@ -240,19 +240,19 @@ extensions.registerSchemaAPI("commands",
return Promise.resolve(Array.from(commands, ([name, command]) => {
return ({
name,
description: command.description,
shortcut: command.shortcut,
});
}));
},
- onCommand: new EventManager(context, "commands.onCommand", fire => {
+ onCommand: new SingletonEventManager(context, "commands.onCommand", fire => {
let listener = (eventName, commandName) => {
- fire(commandName);
+ fire.async(commandName);
};
commandsMap.get(extension).on("command", listener);
return () => {
commandsMap.get(extension).off("command", listener);
};
}).api(),
},
};
--- a/browser/components/extensions/ext-contextMenus.js
+++ b/browser/components/extensions/ext-contextMenus.js
@@ -3,19 +3,19 @@
"use strict";
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/MatchPattern.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var {
- EventManager,
ExtensionError,
IconDetails,
+ SingletonEventManager,
} = ExtensionUtils;
const ACTION_MENU_TOP_LEVEL_LIMIT = 6;
// Map[Extension -> Map[ID -> MenuItem]]
// Note: we want to enumerate all the menu items so
// this cannot be a weak map.
var gContextMenuMap = new Map();
@@ -620,19 +620,19 @@ extensions.registerSchemaAPI("contextMen
removeAll: function() {
let root = gRootItems.get(extension);
if (root) {
root.remove();
}
},
- onClicked: new EventManager(context, "contextMenus.onClicked", fire => {
+ onClicked: new SingletonEventManager(context, "contextMenus.onClicked", fire => {
let listener = (event, info, tab) => {
- fire(info, tab);
+ fire.async(info, tab);
};
extension.on("webext-contextmenu-menuitem-click", listener);
return () => {
extension.off("webext-contextmenu-menuitem-click", listener);
};
}).api(),
},
--- a/browser/components/extensions/ext-pageAction.js
+++ b/browser/components/extensions/ext-pageAction.js
@@ -1,16 +1,16 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
Cu.import("resource://gre/modules/Task.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
+ SingletonEventManager,
IconDetails,
} = ExtensionUtils;
// WeakMap[Extension -> PageAction]
var pageActionMap = new WeakMap();
// Handles URL bar icons, including the |page_action| manifest entry
// and associated API.
@@ -239,19 +239,19 @@ PageAction.for = extension => {
};
global.pageActionFor = PageAction.for;
extensions.registerSchemaAPI("pageAction", "addon_parent", context => {
let {extension} = context;
return {
pageAction: {
- onClicked: new EventManager(context, "pageAction.onClicked", fire => {
+ onClicked: new SingletonEventManager(context, "pageAction.onClicked", fire => {
let listener = (evt, tab) => {
- fire(TabManager.convert(extension, tab));
+ fire.async(TabManager.convert(extension, tab));
};
let pageAction = PageAction.for(extension);
pageAction.on("click", listener);
return () => {
pageAction.off("click", listener);
};
}).api(),
--- a/browser/components/extensions/ext-tabs.js
+++ b/browser/components/extensions/ext-tabs.js
@@ -13,17 +13,17 @@ XPCOMUtils.defineLazyModuleGetter(this,
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
+ SingletonEventManager,
ignoreEvent,
} = ExtensionUtils;
// This function is pretty tightly tied to Extension.jsm.
// Its job is to fill in the |tab| property of the sender.
function getSender(extension, target, sender) {
let tabId;
if ("tabId" in sender) {
@@ -278,22 +278,22 @@ extensions.on("startup", () => {
extensions.registerSchemaAPI("tabs", "addon_parent", context => {
let {extension} = context;
let self = {
tabs: {
onActivated: new WindowEventManager(context, "tabs.onActivated", "TabSelect", (fire, event) => {
let tab = event.originalTarget;
let tabId = TabManager.getId(tab);
let windowId = WindowManager.getId(tab.ownerGlobal);
- fire({tabId, windowId});
+ fire.async({tabId, windowId});
}).api(),
- onCreated: new EventManager(context, "tabs.onCreated", fire => {
+ onCreated: new SingletonEventManager(context, "tabs.onCreated", fire => {
let listener = (eventName, event) => {
- fire(TabManager.convert(extension, event.tab));
+ fire.async(TabManager.convert(extension, event.tab));
};
tabListener.on("tab-created", listener);
return () => {
tabListener.off("tab-created", listener);
};
}).api(),
@@ -302,55 +302,55 @@ extensions.registerSchemaAPI("tabs", "ad
* essentially acts an alias for self.tabs.onActivated but returns
* the tabId in an array to match the API.
* @see https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/Tabs/onHighlighted
*/
onHighlighted: new WindowEventManager(context, "tabs.onHighlighted", "TabSelect", (fire, event) => {
let tab = event.originalTarget;
let tabIds = [TabManager.getId(tab)];
let windowId = WindowManager.getId(tab.ownerGlobal);
- fire({tabIds, windowId});
+ fire.async({tabIds, windowId});
}).api(),
- onAttached: new EventManager(context, "tabs.onAttached", fire => {
+ onAttached: new SingletonEventManager(context, "tabs.onAttached", fire => {
let listener = (eventName, event) => {
- fire(event.tabId, {newWindowId: event.newWindowId, newPosition: event.newPosition});
+ fire.async(event.tabId, {newWindowId: event.newWindowId, newPosition: event.newPosition});
};
tabListener.on("tab-attached", listener);
return () => {
tabListener.off("tab-attached", listener);
};
}).api(),
- onDetached: new EventManager(context, "tabs.onDetached", fire => {
+ onDetached: new SingletonEventManager(context, "tabs.onDetached", fire => {
let listener = (eventName, event) => {
- fire(event.tabId, {oldWindowId: event.oldWindowId, oldPosition: event.oldPosition});
+ fire.async(event.tabId, {oldWindowId: event.oldWindowId, oldPosition: event.oldPosition});
};
tabListener.on("tab-detached", listener);
return () => {
tabListener.off("tab-detached", listener);
};
}).api(),
- onRemoved: new EventManager(context, "tabs.onRemoved", fire => {
+ onRemoved: new SingletonEventManager(context, "tabs.onRemoved", fire => {
let listener = (eventName, event) => {
- fire(event.tabId, {windowId: event.windowId, isWindowClosing: event.isWindowClosing});
+ fire.async(event.tabId, {windowId: event.windowId, isWindowClosing: event.isWindowClosing});
};
tabListener.on("tab-removed", listener);
return () => {
tabListener.off("tab-removed", listener);
};
}).api(),
onReplaced: ignoreEvent(context, "tabs.onReplaced"),
- onMoved: new EventManager(context, "tabs.onMoved", fire => {
+ onMoved: new SingletonEventManager(context, "tabs.onMoved", fire => {
// There are certain circumstances where we need to ignore a move event.
//
// Namely, the first time the tab is moved after it's created, we need
// to report the final position as the initial position in the tab's
// onAttached or onCreated event. This is because most tabs are inserted
// in a temporary location and then moved after the TabOpen event fires,
// which generates a TabOpen event followed by a TabMove event, which
// does not match the contract of our API.
@@ -368,32 +368,32 @@ extensions.registerSchemaAPI("tabs", "ad
let moveListener = event => {
let tab = event.originalTarget;
if (ignoreNextMove.has(tab)) {
ignoreNextMove.delete(tab);
return;
}
- fire(TabManager.getId(tab), {
+ fire.async(TabManager.getId(tab), {
windowId: WindowManager.getId(tab.ownerGlobal),
fromIndex: event.detail,
toIndex: tab._tPos,
});
};
AllWindowEvents.addListener("TabMove", moveListener);
AllWindowEvents.addListener("TabOpen", openListener);
return () => {
AllWindowEvents.removeListener("TabMove", moveListener);
AllWindowEvents.removeListener("TabOpen", openListener);
};
}).api(),
- onUpdated: new EventManager(context, "tabs.onUpdated", fire => {
+ onUpdated: new SingletonEventManager(context, "tabs.onUpdated", fire => {
const restricted = ["url", "favIconUrl", "title"];
function sanitize(extension, changeInfo) {
let result = {};
let nonempty = false;
for (let prop in changeInfo) {
if (extension.hasPermission("tabs") || !restricted.includes(prop)) {
nonempty = true;
@@ -405,17 +405,17 @@ extensions.registerSchemaAPI("tabs", "ad
let fireForBrowser = (browser, changed) => {
let [needed, changeInfo] = sanitize(extension, changed);
if (needed) {
let gBrowser = browser.ownerGlobal.gBrowser;
let tabElem = gBrowser.getTabForBrowser(browser);
let tab = TabManager.convert(extension, tabElem);
- fire(tab.id, changeInfo, tab);
+ fire.async(tab.id, changeInfo, tab);
}
};
let listener = event => {
let needed = [];
if (event.type == "TabAttrModified") {
let changed = event.detail.changed;
if (changed.includes("image")) {
@@ -442,17 +442,17 @@ extensions.registerSchemaAPI("tabs", "ad
if (needed.length) {
let tab = TabManager.convert(extension, event.originalTarget);
let changeInfo = {};
for (let prop of needed) {
changeInfo[prop] = tab[prop];
}
- fire(tab.id, changeInfo, tab);
+ fire.async(tab.id, changeInfo, tab);
}
};
let progressListener = {
onStateChange(browser, webProgress, request, stateFlags, statusCode) {
if (!webProgress.isTopLevel) {
return;
}
@@ -1020,17 +1020,17 @@ extensions.registerSchemaAPI("tabs", "ad
let currentSettings = this._getZoomSettings(tab.id);
if (!Object.keys(settings).every(key => settings[key] === currentSettings[key])) {
return Promise.reject(`Unsupported zoom settings: ${JSON.stringify(settings)}`);
}
return Promise.resolve();
},
- onZoomChange: new EventManager(context, "tabs.onZoomChange", fire => {
+ onZoomChange: new SingletonEventManager(context, "tabs.onZoomChange", fire => {
let getZoomLevel = browser => {
let {ZoomManager} = browser.ownerGlobal;
return ZoomManager.getZoomForBrowser(browser);
};
// Stores the last known zoom level for each tab's browser.
// WeakMap[<browser> -> number]
@@ -1070,17 +1070,17 @@ extensions.registerSchemaAPI("tabs", "ad
let oldZoomFactor = zoomLevels.get(browser);
let newZoomFactor = getZoomLevel(browser);
if (oldZoomFactor != newZoomFactor) {
zoomLevels.set(browser, newZoomFactor);
let tabId = TabManager.getId(tab);
- fire({
+ fire.async({
tabId,
oldZoomFactor,
newZoomFactor,
zoomSettings: self.tabs._getZoomSettings(tabId),
});
}
};
--- a/browser/components/extensions/ext-utils.js
+++ b/browser/components/extensions/ext-utils.js
@@ -23,18 +23,18 @@ Cu.import("resource://gre/modules/Extens
Cu.import("resource://gre/modules/AppConstants.jsm");
const POPUP_LOAD_TIMEOUT_MS = 200;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var {
DefaultWeakMap,
- EventManager,
promiseEvent,
+ SingletonEventManager,
} = ExtensionUtils;
// This file provides some useful code for the |tabs| and |windows|
// modules. All of the code is installed on |global|, which is a scope
// shared among the different ext-*.js scripts.
global.makeWidgetId = id => {
id = id.toLowerCase();
@@ -1276,21 +1276,21 @@ global.AllWindowEvents = {
this.addWindowListener(window, eventType, listener);
}
}
},
};
AllWindowEvents.openListener = AllWindowEvents.openListener.bind(AllWindowEvents);
-// Subclass of EventManager where we just need to call
+// Subclass of SingletonEventManager where we just need to call
// add/removeEventListener on each XUL window.
-global.WindowEventManager = function(context, name, event, listener) {
- EventManager.call(this, context, name, fire => {
- let listener2 = (...args) => listener(fire, ...args);
- AllWindowEvents.addListener(event, listener2);
- return () => {
- AllWindowEvents.removeListener(event, listener2);
- };
- });
+global.WindowEventManager = class extends SingletonEventManager {
+ constructor(context, name, event, listener) {
+ super(context, name, fire => {
+ let listener2 = (...args) => listener(fire, ...args);
+ AllWindowEvents.addListener(event, listener2);
+ return () => {
+ AllWindowEvents.removeListener(event, listener2);
+ };
+ });
+ }
};
-
-WindowEventManager.prototype = Object.create(EventManager.prototype);
--- a/browser/components/extensions/ext-windows.js
+++ b/browser/components/extensions/ext-windows.js
@@ -7,50 +7,50 @@ XPCOMUtils.defineLazyServiceGetter(this,
"nsIAboutNewTabService");
XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
"resource://gre/modules/AppConstants.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
+ SingletonEventManager,
promiseObserved,
} = ExtensionUtils;
function onXULFrameLoaderCreated({target}) {
target.messageManager.sendAsyncMessage("AllowScriptsToClose", {});
}
extensions.registerSchemaAPI("windows", "addon_parent", context => {
let {extension} = context;
return {
windows: {
onCreated:
new WindowEventManager(context, "windows.onCreated", "domwindowopened", (fire, window) => {
- fire(WindowManager.convert(extension, window));
+ fire.async(WindowManager.convert(extension, window));
}).api(),
onRemoved:
new WindowEventManager(context, "windows.onRemoved", "domwindowclosed", (fire, window) => {
- fire(WindowManager.getId(window));
+ fire.async(WindowManager.getId(window));
}).api(),
- onFocusChanged: new EventManager(context, "windows.onFocusChanged", fire => {
+ onFocusChanged: new SingletonEventManager(context, "windows.onFocusChanged", fire => {
// Keep track of the last windowId used to fire an onFocusChanged event
let lastOnFocusChangedWindowId;
let listener = event => {
// Wait a tick to avoid firing a superfluous WINDOW_ID_NONE
// event when switching focus between two Firefox windows.
Promise.resolve().then(() => {
let window = Services.focus.activeWindow;
let windowId = window ? WindowManager.getId(window) : WindowManager.WINDOW_ID_NONE;
if (windowId !== lastOnFocusChangedWindowId) {
- fire(windowId);
+ fire.async(windowId);
lastOnFocusChangedWindowId = windowId;
}
});
};
AllWindowEvents.addListener("focus", listener);
AllWindowEvents.addListener("blur", listener);
return () => {
AllWindowEvents.removeListener("focus", listener);
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -36,17 +36,16 @@ XPCOMUtils.defineLazyModuleGetter(this,
const CATEGORY_EXTENSION_SCRIPTS_ADDON = "webextension-scripts-addon";
const CATEGORY_EXTENSION_SCRIPTS_DEVTOOLS = "webextension-scripts-devtools";
Cu.import("resource://gre/modules/ExtensionCommon.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
const {
DefaultMap,
- EventManager,
SingletonEventManager,
SpreadArgs,
defineLazyGetter,
getInnerWindowID,
getMessageManager,
getUniqueId,
injectAPI,
promiseEvent,
@@ -114,27 +113,27 @@ class Port {
disconnect: () => {
this.disconnect();
},
postMessage: json => {
this.postMessage(json);
},
- onDisconnect: new EventManager(this.context, "Port.onDisconnect", fire => {
+ onDisconnect: new SingletonEventManager(this.context, "Port.onDisconnect", fire => {
return this.registerOnDisconnect(error => {
portError = error && this.context.normalizeError(error);
- fire.withoutClone(portObj);
+ fire.asyncWithoutClone(portObj);
});
}).api(),
- onMessage: new EventManager(this.context, "Port.onMessage", fire => {
+ onMessage: new SingletonEventManager(this.context, "Port.onMessage", fire => {
return this.registerOnMessage(msg => {
msg = Cu.cloneInto(msg, this.context.cloneScope);
- fire.withoutClone(msg, portObj);
+ fire.asyncWithoutClone(msg, portObj);
});
}).api(),
get error() {
return portError;
},
};
--- a/toolkit/components/extensions/ext-alarms.js
+++ b/toolkit/components/extensions/ext-alarms.js
@@ -1,15 +1,15 @@
"use strict";
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
+ SingletonEventManager,
} = ExtensionUtils;
// WeakMap[Extension -> Map[name -> Alarm]]
var alarmsMap = new WeakMap();
// WeakMap[Extension -> Set[callback]]
var alarmCallbacksMap = new WeakMap();
@@ -135,19 +135,19 @@ extensions.registerSchemaAPI("alarms", "
let cleared = false;
for (let alarm of alarmsMap.get(extension).values()) {
alarm.clear();
cleared = true;
}
return Promise.resolve(cleared);
},
- onAlarm: new EventManager(context, "alarms.onAlarm", fire => {
+ onAlarm: new SingletonEventManager(context, "alarms.onAlarm", fire => {
let callback = alarm => {
- fire(alarm.data);
+ fire.sync(alarm.data);
};
alarmCallbacksMap.get(extension).add(callback);
return () => {
alarmCallbacksMap.get(extension).delete(callback);
};
}).api(),
},
--- a/toolkit/components/extensions/ext-cookies.js
+++ b/toolkit/components/extensions/ext-cookies.js
@@ -4,17 +4,17 @@ const {interfaces: Ci, utils: Cu} = Comp
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
"resource://gre/modules/ContextualIdentityService.jsm");
var {
- EventManager,
+ SingletonEventManager,
} = ExtensionUtils;
var DEFAULT_STORE = "firefox-default";
var PRIVATE_STORE = "firefox-private";
var CONTAINER_STORE = "firefox-container-";
global.getCookieStoreIdForTab = function(data, tab) {
if (data.incognito) {
@@ -433,23 +433,23 @@ extensions.registerSchemaAPI("cookies",
let result = [];
for (let key in data) {
result.push({id: key, tabIds: data[key], incognito: key == PRIVATE_STORE});
}
return Promise.resolve(result);
},
- onChanged: new EventManager(context, "cookies.onChanged", fire => {
+ onChanged: new SingletonEventManager(context, "cookies.onChanged", fire => {
let observer = (subject, topic, data) => {
let notify = (removed, cookie, cause) => {
cookie.QueryInterface(Ci.nsICookie2);
if (extension.whiteListedHosts.matchesCookie(cookie)) {
- fire({removed, cookie: convert({cookie, isPrivate: topic == "private-cookie-changed"}), cause});
+ fire.async({removed, cookie: convert({cookie, isPrivate: topic == "private-cookie-changed"}), cause});
}
};
// We do our best effort here to map the incompatible states.
switch (data) {
case "deleted":
notify(true, subject, "explicit");
break;
--- a/toolkit/components/extensions/ext-notifications.js
+++ b/toolkit/components/extensions/ext-notifications.js
@@ -3,17 +3,17 @@
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter",
"resource://devtools/shared/event-emitter.js");
var {
- EventManager,
+ SingletonEventManager,
ignoreEvent,
} = ExtensionUtils;
// WeakMap[Extension -> Map[id -> Notification]]
var notificationsMap = new WeakMap();
// Manages a notification popup (notifications API) created by the extension.
function Notification(extension, id, options) {
@@ -126,31 +126,31 @@ extensions.registerSchemaAPI("notificati
getAll: function() {
let result = {};
notificationsMap.get(extension).forEach((value, key) => {
result[key] = value.options;
});
return Promise.resolve(result);
},
- onClosed: new EventManager(context, "notifications.onClosed", fire => {
+ onClosed: new SingletonEventManager(context, "notifications.onClosed", fire => {
let listener = (event, notificationId) => {
// FIXME: Support the byUser argument.
- fire(notificationId, true);
+ fire.async(notificationId, true);
};
notificationsMap.get(extension).on("closed", listener);
return () => {
notificationsMap.get(extension).off("closed", listener);
};
}).api(),
- onClicked: new EventManager(context, "notifications.onClicked", fire => {
+ onClicked: new SingletonEventManager(context, "notifications.onClicked", fire => {
let listener = (event, notificationId) => {
- fire(notificationId, true);
+ fire.async(notificationId, true);
};
notificationsMap.get(extension).on("clicked", listener);
return () => {
notificationsMap.get(extension).off("clicked", listener);
};
}).api(),
--- a/toolkit/components/extensions/ext-storage.js
+++ b/toolkit/components/extensions/ext-storage.js
@@ -6,18 +6,18 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://gre/modules/ExtensionStorage.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "ExtensionStorageSync",
"resource://gre/modules/ExtensionStorageSync.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "AddonManagerPrivate",
"resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
- EventManager,
ExtensionError,
+ SingletonEventManager,
} = ExtensionUtils;
function enforceNoTemporaryAddon(extensionId) {
const EXCEPTION_MESSAGE =
"The storage API will not work with a temporary addon ID. " +
"Please add an explicit addon ID to your manifest. " +
"For more information see https://bugzil.la/1323228.";
if (AddonManagerPrivate.isTemporaryInstallID(extensionId)) {
@@ -58,22 +58,22 @@ function storageApiFactory(context) {
return ExtensionStorageSync.remove(extension, keys, context);
},
clear: function() {
enforceNoTemporaryAddon(extension.id);
return ExtensionStorageSync.clear(extension, context);
},
},
- onChanged: new EventManager(context, "storage.onChanged", fire => {
+ onChanged: new SingletonEventManager(context, "storage.onChanged", fire => {
let listenerLocal = changes => {
- fire(changes, "local");
+ fire.async(changes, "local");
};
let listenerSync = changes => {
- fire(changes, "sync");
+ fire.async(changes, "sync");
};
ExtensionStorage.addOnChangedListener(extension.id, listenerLocal);
ExtensionStorageSync.addOnChangedListener(extension, listenerSync, context);
return () => {
ExtensionStorage.removeOnChangedListener(extension.id, listenerLocal);
ExtensionStorageSync.removeOnChangedListener(extension, listenerSync);
};