Bug 1202483 - [webext] Support ImageData for browser.browserAction.setIcon (r=gabor)

This commit is contained in:
Bill McCloskey 2015-09-07 09:59:21 -07:00
parent f006b3e3fe
commit 42aee3f8d4
8 changed files with 91 additions and 28 deletions

View File

@ -14,6 +14,11 @@ var {
// WeakMap[Extension -> BrowserAction]
var browserActionMap = new WeakMap();
// WeakMap[Extension -> docshell]
// This map is a cache of the windowless browser that's used to render ImageData
// for the browser_action icon.
let imageRendererMap = new WeakMap();
function browserActionOf(extension)
{
return browserActionMap.get(extension);
@ -283,8 +288,37 @@ extensions.on("shutdown", (type, extension) => {
browserActionMap.get(extension).shutdown();
browserActionMap.delete(extension);
}
imageRendererMap.delete(extension);
});
function convertImageDataToPNG(extension, imageData)
{
let webNav = imageRendererMap.get(extension);
if (!webNav) {
webNav = Services.appShell.createWindowlessBrowser(false);
let principal = Services.scriptSecurityManager.createCodebasePrincipal(extension.baseURI,
{addonId: extension.id});
let interfaceRequestor = webNav.QueryInterface(Ci.nsIInterfaceRequestor);
let docShell = interfaceRequestor.getInterface(Ci.nsIDocShell);
GlobalManager.injectInDocShell(docShell, extension, null);
docShell.createAboutBlankContentViewer(principal);
}
let document = webNav.document;
let canvas = document.createElement("canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
canvas.getContext("2d").putImageData(imageData, 0, 0);
let url = canvas.toDataURL("image/png");
canvas.remove();
return url;
}
extensions.registerAPI((extension, context) => {
return {
browserAction: {
@ -313,10 +347,11 @@ extensions.registerAPI((extension, context) => {
setIcon: function(details, callback) {
let tab = details.tabId ? TabManager.getTab(details.tabId) : null;
if (details.imageData) {
// FIXME: Support the imageData attribute.
return;
let url = convertImageDataToPNG(extension, details.imageData);
browserActionOf(extension).setProperty(tab, "icon", url);
} else {
browserActionOf(extension).setProperty(tab, "icon", details.path);
}
browserActionOf(extension).setProperty(tab, "icon", details.path);
},
setBadgeText: function(details) {

View File

@ -1,9 +1,12 @@
[DEFAULT]
skip-if = os == 'android' || buildapp == 'b2g' || os == 'mac'
support-files =
head.js
[browser_ext_simple.js]
[browser_ext_currentWindow.js]
[browser_ext_browserAction_simple.js]
[browser_ext_browserAction_icon.js]
[browser_ext_getViews.js]
[browser_ext_tabs_executeScript.js]
[browser_ext_tabs_query.js]

View File

@ -0,0 +1,40 @@
add_task(function* () {
let extension = ExtensionTestUtils.loadExtension({
manifest: {
"browser_action": {},
"background": {
"page": "background.html",
}
},
files: {
"background.html": `<canvas id="canvas" width="2" height="2">
<script src="background.js"></script>`,
"background.js": function() {
var canvas = document.getElementById("canvas");
var canvasContext = canvas.getContext("2d");
canvasContext.clearRect(0, 0, canvas.width, canvas.height);
canvasContext.fillStyle = "green";
canvasContext.fillRect(0, 0, 1, 1);
var url = canvas.toDataURL("image/png");
var imageData = canvasContext.getImageData(0, 0, canvas.width, canvas.height);
browser.browserAction.setIcon({imageData});
browser.test.sendMessage("imageURL", url);
}
},
});
let [_, url] = yield Promise.all([extension.startup(), extension.awaitMessage("imageURL")]);
let widgetId = makeWidgetId(extension.id) + "-browser-action";
let node = CustomizableUI.getWidget(widgetId).forWindow(window).node;
let image = node.getAttribute("image");
is(image, url, "image is correct");
yield extension.unload();
});

View File

@ -1,11 +1,3 @@
let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
function makeWidgetId(id)
{
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}
add_task(function* () {
let extension = ExtensionTestUtils.loadExtension({
manifest: {

View File

@ -1,11 +1,3 @@
let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
function makeWidgetId(id)
{
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}
function* focusWindow(win)
{
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);

View File

@ -1,11 +1,3 @@
let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", {});
function makeWidgetId(id)
{
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}
function genericChecker()
{
var kind = "background";

View File

@ -0,0 +1,7 @@
let {CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm");
function makeWidgetId(id)
{
id = id.toLowerCase();
return id.replace(/[^a-z0-9_-]/g, "_");
}

View File

@ -278,7 +278,9 @@ var GlobalManager = {
if (this.docShells.has(docShell)) {
let {extension, context} = this.docShells.get(docShell);
inject(extension, context);
if (context) {
inject(extension, context);
}
return;
}