Bug 1267402 - Implement chrome.pageAction.onClicked on Android r?kmag
MozReview-Commit-ID: 4c8fRhWCJNc
--- a/mobile/android/components/extensions/ext-pageAction.js
+++ b/mobile/android/components/extensions/ext-pageAction.js
@@ -1,29 +1,43 @@
/* -*- 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");
+
// Import the android PageActions module.
XPCOMUtils.defineLazyModuleGetter(this, "PageActions",
"resource://gre/modules/PageActions.jsm");
+Cu.import("resource://gre/modules/ExtensionUtils.jsm");
+
+var {
+ SingletonEventManager,
+} = ExtensionUtils;
+
// WeakMap[Extension -> PageAction]
var pageActionMap = new WeakMap();
function PageAction(options, extension) {
this.id = null;
let DEFAULT_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAC4klEQVRYhdWXLWzbQBSADQtDAwsHC1tUhUxqfL67lk2tdn+OJg0ODU0rLByqgqINBY6tmlbn7LMTJ5FaFVVBk1G0oUGjG2jT2Y7jxmmcbU/6iJ+f36fz+e5sGP9riCGm9hB37RG+scd4Yo/wsDXCZyIE2xuXsce4bY+wXkAsQtzYmExrfFgvkJkRbkzo1ehoxx5iXcgI/9iYUGt8WH9MqDXEcmNChmEYrRCf2SHWeYgQx3x0tLNRIeKQLTtEFyJEep4NTuhk8BC+yMrwEE3+iozo42d8gK7FAOkMsRiiN8QhW2ttSK5QTfRRV4QoymVeJMvPvDp7gCZigD613MN6yRFA3SWarow9QB9LCfG+NeF9qCtjAKOSQjCqVKhfVsiHEQ+grgx/lRGqUihAc1uL8EFD+KCRO+GrF4J61phcoRoPoEzkYhZYpykh5sMb7kOdIeY+jHKur4QI4Feh4AFX1nVeLxrAvQchGsBz5ls6wa2QdwcvIcE2863bTH79KOvsz/uUYJsp+J0pSzNlDckVqqVGUAF+n6uS7txcOl6wot4JVy70ufDLy4pWLUQVPE81pRI0mGe9oxLMHSeohHvMs/STUNaUK6vDPCvOyxMFDx4achehRDJmHnydnkPww5OFfLxrGIZBFDyYl4LpMzlTQFIP6AQx86w2UeYBccFpJrcKv5L9eGDtUAU6RIELqsB74uynjy/UBRF1gS5BTFxwQT1wTiXoUg9MH7m/3NZRRoi5IJytUbMgzv4Wc832+oQkiKgEehmyMkkpKsFkQV11QsRJL5rJYBLItQgRaUZEmnoZXsomz3vGiWw+I9KMF9SVFOqZEemZekli1jN3U/UOqhHHvC6oWWGElhfSpGdOk6+O9prdwvtLj5BjRsQxdRnot+Zeifpy/2/0stktKTRNLmbk0mwXyl8253fyojj+8rxOHNAhjjm5n0/5OOCGOKBzkrMO0Z75lvSAzKlrF32Z/3z8BqLAn+yMV7VhAAAAAElFTkSuQmCC";
this.options = {
title: options.default_title || extension.name,
icon: DEFAULT_ICON,
id: extension.id,
+ clickCallback: () => {
+ this.emit("click");
+ },
};
+
+ EventEmitter.decorate(this);
}
PageAction.prototype = {
show(tabId) {
// TODO: Only show the PageAction for the tab with the provided tabId.
if (!this.id) {
this.id = PageActions.add(this.options);
}
@@ -49,14 +63,24 @@ extensions.on("shutdown", (type, extensi
pageActionMap.delete(extension);
}
});
/* eslint-enable mozilla/balanced-listeners */
extensions.registerSchemaAPI("pageAction", null, (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) {
pageActionMap.get(extension).show(tabId);
},
},
};
});
--- a/mobile/android/components/extensions/schemas/page_action.json
+++ b/mobile/android/components/extensions/schemas/page_action.json
@@ -207,17 +207,16 @@
]
}
]
}
],
"events": [
{
"name": "onClicked",
- "unsupported": true,
"type": "function",
"description": "Fired when a page action icon is clicked. This event will not fire if the page action has a popup.",
"parameters": [
{
"name": "tab",
"$ref": "tabs.Tab"
}
]
--- a/mobile/android/components/extensions/test/mochitest/.eslintrc
+++ b/mobile/android/components/extensions/test/mochitest/.eslintrc
@@ -1,7 +1,8 @@
{
"extends": "../../../../../../toolkit/components/extensions/test/mochitest/.eslintrc",
"globals": {
"isPageActionShown": true,
+ "clickPageAction": true,
},
}
--- a/mobile/android/components/extensions/test/mochitest/head.js
+++ b/mobile/android/components/extensions/test/mochitest/head.js
@@ -1,11 +1,15 @@
"use strict";
-/* exported isPageActionShown */
+/* exported isPageActionShown clickPageAction */
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/PageActions.jsm");
function isPageActionShown(extensionId) {
return PageActions.isShown(extensionId);
}
+
+function clickPageAction(extensionId) {
+ PageActions.synthesizeClick(extensionId);
+}
--- a/mobile/android/components/extensions/test/mochitest/test_ext_pageAction.html
+++ b/mobile/android/components/extensions/test/mochitest/test_ext_pageAction.html
@@ -18,17 +18,20 @@ function backgroundScript() {
browser.test.assertTrue("show" in browser.pageAction, "API method 'show' exists in browser.pageAction");
// TODO: Use the Tabs API to obtain the tab ids for showing pageActions.
let tabId = 1;
browser.pageAction.show(tabId);
browser.test.sendMessage("page-action-shown");
- browser.test.notifyPass("page-action");
+ browser.pageAction.onClicked.addListener(tab => {
+ // TODO: Make sure we get the correct tab once the tabs API is supported.
+ browser.test.notifyPass("pageAction-clicked");
+ });
}
add_task(function* test_contentscript() {
let extension = ExtensionTestUtils.loadExtension({
background: "(" + backgroundScript.toString() + ")()",
manifest: {
"name": "PageAction Extension",
"page_action": {
@@ -37,17 +40,19 @@ add_task(function* test_contentscript()
},
});
yield extension.startup();
yield extension.awaitMessage("page-action-shown");
is(isPageActionShown(extension.id), true, "The PageAction should be shown");
- yield extension.awaitFinish("page-action");
+ clickPageAction(extension.id);
+
+ yield extension.awaitFinish("pageAction-clicked");
yield extension.unload();
is(isPageActionShown(extension.id), false, "The PageAction should be removed after unload");
});
</script>
</body>
</html>
--- a/mobile/android/modules/PageActions.jsm
+++ b/mobile/android/modules/PageActions.jsm
@@ -26,17 +26,16 @@ function resolveGeckoURI(aURI) {
return registry.convertChromeURL(Services.io.newURI(aURI, null, null)).spec;
} else if (aURI.startsWith("resource://")) {
let handler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
return handler.resolveURI(Services.io.newURI(aURI, null, null));
}
return aURI;
}
-
var PageActions = {
_items: { },
_inited: false,
_maybeInit: function() {
if (!this._inited && Object.keys(this._items).length > 0) {
this._inited = true;
@@ -65,16 +64,23 @@ var PageActions = {
}
}
},
isShown: function(id) {
return !!this._items[id];
},
+ synthesizeClick: function(id) {
+ let item = this._items[id];
+ if (item && item.clickCallback) {
+ item.clickCallback();
+ }
+ },
+
add: function(aOptions) {
let id = aOptions.id || uuidgen.generateUUID().toString()
Messaging.sendRequest({
type: "PageActions:Add",
id: id,
title: aOptions.title,
icon: resolveGeckoURI(aOptions.icon),