1
0
mirror of https://github.com/roytam1/UXP.git synced 2026-06-17 22:09:07 +00:00
Files
UXP/mobile/android/components/extensions/ext-pageAction.js
T

170 lines
4.9 KiB
JavaScript

/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
XPCOMUtils.defineLazyModuleGetter(this, "EventEmitter",
"resource://devtools/shared/event-emitter.js");
XPCOMUtils.defineLazyModuleGetter(this, "Services",
"resource://gre/modules/Services.jsm");
// Import the android PageActions module.
XPCOMUtils.defineLazyModuleGetter(this, "PageActions",
"resource://gre/modules/PageActions.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
var {
IconDetails,
SingletonEventManager,
} = ExtensionUtils;
// WeakMap[Extension -> PageAction]
var pageActionMap = new WeakMap();
function PageAction(options, extension) {
this.id = null;
this.extension = extension;
this.icons = IconDetails.normalize({path: options.default_icon}, extension);
this.popupUrl = options.default_popup;
this.options = {
title: options.default_title || extension.name,
id: `{${extension.uuid}}`,
clickCallback: () => {
if (this.popupUrl) {
let win = Services.wm.getMostRecentWindow("navigator:browser");
win.BrowserApp.addTab(this.popupUrl, {
selected: true,
parentId: win.BrowserApp.selectedTab.id,
});
} else {
this.emit("click");
}
},
};
this.shouldShow = false;
EventEmitter.decorate(this);
}
PageAction.prototype = {
show(tabId, context) {
if (this.id) {
return Promise.resolve();
}
if (this.options.icon) {
this.id = PageActions.add(this.options);
return Promise.resolve();
}
this.shouldShow = true;
// TODO(robwu): Remove dependency on contentWindow from this file. It should
// be put in a separate file called ext-c-pageAction.js.
// Note: Fennec is not going to be multi-process for the foreseaable future,
// so this layering violation has no immediate impact. However, it is should
// be done at some point.
let {contentWindow} = context.xulBrowser;
// TODO(robwu): Why is this contentWindow.devicePixelRatio, while
// convertImageURLToDataURL uses browserWindow.devicePixelRatio?
let {icon} = IconDetails.getPreferredIcon(this.icons, this.extension,
18 * contentWindow.devicePixelRatio);
let browserWindow = Services.wm.getMostRecentWindow("navigator:browser");
return IconDetails.convertImageURLToDataURL(icon, contentWindow, browserWindow).then(dataURI => {
if (this.shouldShow) {
this.options.icon = dataURI;
this.id = PageActions.add(this.options);
}
}).catch(() => {
return Promise.reject({
message: "Failed to load PageAction icon",
});
});
},
hide(tabId) {
this.shouldShow = false;
if (this.id) {
PageActions.remove(this.id);
this.id = null;
}
},
setPopup(tab, url) {
// TODO: Only set the popup for the specified tab once we have Tabs API support.
this.popupUrl = url;
},
getPopup(tab) {
// TODO: Only return the popup for the specified tab once we have Tabs API support.
return this.popupUrl;
},
shutdown() {
this.hide();
},
};
/* eslint-disable mozilla/balanced-listeners */
extensions.on("manifest_page_action", (type, directive, extension, manifest) => {
let pageAction = new PageAction(manifest.page_action, extension);
pageActionMap.set(extension, pageAction);
});
extensions.on("shutdown", (type, extension) => {
if (pageActionMap.has(extension)) {
pageActionMap.get(extension).shutdown();
pageActionMap.delete(extension);
}
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("pageAction", "addon_parent", context => {
let {extension} = context;
return {
pageAction: {
onClicked: new SingletonEventManager(context, "pageAction.onClicked", fire => {
let listener = (event) => {
fire();
};
pageActionMap.get(extension).on("click", listener);
return () => {
pageActionMap.get(extension).off("click", listener);
};
}).api(),
show(tabId) {
return pageActionMap.get(extension)
.show(tabId, context)
.then(() => {});
},
hide(tabId) {
pageActionMap.get(extension).hide(tabId);
return Promise.resolve();
},
setPopup(details) {
// TODO: Use the Tabs API to get the tab from details.tabId.
let tab = null;
let url = details.popup && context.uri.resolve(details.popup);
pageActionMap.get(extension).setPopup(tab, url);
},
getPopup(details) {
// TODO: Use the Tabs API to get the tab from details.tabId.
let tab = null;
let popup = pageActionMap.get(extension).getPopup(tab);
return Promise.resolve(popup);
},
},
};
});