diff options
Diffstat (limited to 'application/basilisk/components/extensions/ext-c-contextMenus.js')
-rw-r--r-- | application/basilisk/components/extensions/ext-c-contextMenus.js | 158 |
1 files changed, 0 insertions, 158 deletions
diff --git a/application/basilisk/components/extensions/ext-c-contextMenus.js b/application/basilisk/components/extensions/ext-c-contextMenus.js deleted file mode 100644 index 9fde90808..000000000 --- a/application/basilisk/components/extensions/ext-c-contextMenus.js +++ /dev/null @@ -1,158 +0,0 @@ -/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set sts=2 sw=2 et tw=80: */ -"use strict"; - -// If id is not specified for an item we use an integer. -// This ID need only be unique within a single addon. Since all addon code that -// can use this API runs in the same process, this local variable suffices. -var gNextMenuItemID = 0; - -// Map[Extension -> Map[string or id, ContextMenusClickPropHandler]] -var gPropHandlers = new Map(); - -// The contextMenus API supports an "onclick" attribute in the create/update -// methods to register a callback. This class manages these onclick properties. -class ContextMenusClickPropHandler { - constructor(context) { - this.context = context; - // Map[string or integer -> callback] - this.onclickMap = new Map(); - this.dispatchEvent = this.dispatchEvent.bind(this); - } - - // A listener on contextMenus.onClicked that forwards the event to the only - // listener, if any. - dispatchEvent(info, tab) { - let onclick = this.onclickMap.get(info.menuItemId); - if (onclick) { - // No need for runSafe or anything because we are already being run inside - // an event handler -- the event is just being forwarded to the actual - // handler. - onclick(info, tab); - } - } - - // Sets the `onclick` handler for the given menu item. - // The `onclick` function MUST be owned by `this.context`. - setListener(id, onclick) { - if (this.onclickMap.size === 0) { - this.context.childManager.getParentEvent("contextMenus.onClicked").addListener(this.dispatchEvent); - this.context.callOnClose(this); - } - this.onclickMap.set(id, onclick); - - let propHandlerMap = gPropHandlers.get(this.context.extension); - if (!propHandlerMap) { - propHandlerMap = new Map(); - } else { - // If the current callback was created in a different context, remove it - // from the other context. - let propHandler = propHandlerMap.get(id); - if (propHandler && propHandler !== this) { - propHandler.unsetListener(id); - } - } - propHandlerMap.set(id, this); - gPropHandlers.set(this.context.extension, propHandlerMap); - } - - // Deletes the `onclick` handler for the given menu item. - // The `onclick` function MUST be owned by `this.context`. - unsetListener(id) { - if (!this.onclickMap.delete(id)) { - return; - } - if (this.onclickMap.size === 0) { - this.context.childManager.getParentEvent("contextMenus.onClicked").removeListener(this.dispatchEvent); - this.context.forgetOnClose(this); - } - let propHandlerMap = gPropHandlers.get(this.context.extension); - propHandlerMap.delete(id); - if (propHandlerMap.size === 0) { - gPropHandlers.delete(this.context.extension); - } - } - - // Deletes the `onclick` handler for the given menu item, if any, regardless - // of the context where it was created. - unsetListenerFromAnyContext(id) { - let propHandlerMap = gPropHandlers.get(this.context.extension); - let propHandler = propHandlerMap && propHandlerMap.get(id); - if (propHandler) { - propHandler.unsetListener(id); - } - } - - // Remove all `onclick` handlers of the extension. - deleteAllListenersFromExtension() { - let propHandlerMap = gPropHandlers.get(this.context.extension); - if (propHandlerMap) { - for (let [id, propHandler] of propHandlerMap) { - propHandler.unsetListener(id); - } - } - } - - // Removes all `onclick` handlers from this context. - close() { - for (let id of this.onclickMap.keys()) { - this.unsetListener(id); - } - } -} - -extensions.registerSchemaAPI("contextMenus", "addon_child", context => { - let onClickedProp = new ContextMenusClickPropHandler(context); - - return { - contextMenus: { - create(createProperties, callback) { - if (createProperties.id === null) { - createProperties.id = ++gNextMenuItemID; - } - let {onclick} = createProperties; - delete createProperties.onclick; - context.childManager.callParentAsyncFunction("contextMenus.createInternal", [ - createProperties, - ]).then(() => { - if (onclick) { - onClickedProp.setListener(createProperties.id, onclick); - } - if (callback) { - callback(); - } - }); - return createProperties.id; - }, - - update(id, updateProperties) { - let {onclick} = updateProperties; - delete updateProperties.onclick; - return context.childManager.callParentAsyncFunction("contextMenus.update", [ - id, - updateProperties, - ]).then(() => { - if (onclick) { - onClickedProp.setListener(id, onclick); - } else if (onclick === null) { - onClickedProp.unsetListenerFromAnyContext(id); - } - // else onclick is not set so it should not be changed. - }); - }, - - remove(id) { - onClickedProp.unsetListenerFromAnyContext(id); - return context.childManager.callParentAsyncFunction("contextMenus.remove", [ - id, - ]); - }, - - removeAll() { - onClickedProp.deleteAllListenersFromExtension(); - - return context.childManager.callParentAsyncFunction("contextMenus.removeAll", []); - }, - }, - }; -}); |