Backed out changeset 1008f5b88e6b (bug 1270742) for failing browser_ext_browserAction_context.js. r=backout

This commit is contained in:
Sebastian Hengst
2016-06-24 13:00:31 +02:00
parent c4bf93aeee
commit 1be0f90cda
10 changed files with 151 additions and 217 deletions

View File

@@ -8,21 +8,138 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils",
"resource://gre/modules/PrivateBrowsingUtils.jsm");
Cu.import("resource://gre/modules/ExtensionUtils.jsm");
Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/AppConstants.jsm");
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const INTEGER = /^[1-9]\d*$/;
// Minimum time between two resizes.
const RESIZE_TIMEOUT = 100;
var {
EventManager,
instanceOf,
} = 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.
// Manages icon details for toolbar buttons in the |pageAction| and
// |browserAction| APIs.
global.IconDetails = {
// Normalizes the various acceptable input formats into an object
// with icon size as key and icon URL as value.
//
// If a context is specified (function is called from an extension):
// Throws an error if an invalid icon size was provided or the
// extension is not allowed to load the specified resources.
//
// If no context is specified, instead of throwing an error, this
// function simply logs a warning message.
normalize(details, extension, context = null) {
let result = {};
try {
if (details.imageData) {
let imageData = details.imageData;
// The global might actually be from Schema.jsm, which
// normalizes most of our arguments. In that case it won't have
// an ImageData property. But Schema.jsm doesn't normalize
// actual ImageData objects, so they will come from a global
// with the right property.
if (instanceOf(imageData, "ImageData")) {
imageData = {"19": imageData};
}
for (let size of Object.keys(imageData)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
result[size] = this.convertImageDataToPNG(imageData[size], context);
}
}
if (details.path) {
let path = details.path;
if (typeof path != "object") {
path = {"19": path};
}
let baseURI = context ? context.uri : extension.baseURI;
for (let size of Object.keys(path)) {
if (!INTEGER.test(size)) {
throw new Error(`Invalid icon size ${size}, must be an integer`);
}
let url = baseURI.resolve(path[size]);
// The Chrome documentation specifies these parameters as
// relative paths. We currently accept absolute URLs as well,
// which means we need to check that the extension is allowed
// to load them. This will throw an error if it's not allowed.
Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(
extension.principal, url,
Services.scriptSecurityManager.DISALLOW_SCRIPT);
result[size] = url;
}
}
} catch (e) {
// Function is called from extension code, delegate error.
if (context) {
throw e;
}
// If there's no context, it's because we're handling this
// as a manifest directive. Log a warning rather than
// raising an error.
extension.manifestError(`Invalid icon data: ${e}`);
}
return result;
},
// Returns the appropriate icon URL for the given icons object and the
// screen resolution of the given window.
getURL(icons, window, extension, size = 16) {
const DEFAULT = "chrome://browser/content/extension.svg";
size *= window.devicePixelRatio;
let bestSize = null;
if (icons[size]) {
bestSize = size;
} else if (icons[2 * size]) {
bestSize = 2 * size;
} else {
let sizes = Object.keys(icons)
.map(key => parseInt(key, 10))
.sort((a, b) => a - b);
bestSize = sizes.find(candidate => candidate > size) || sizes.pop();
}
if (bestSize) {
return {size: bestSize, icon: icons[bestSize]};
}
return {size, icon: DEFAULT};
},
convertImageDataToPNG(imageData, context) {
let document = context.contentWindow.document;
let canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
canvas.width = imageData.width;
canvas.height = imageData.height;
canvas.getContext("2d").putImageData(imageData, 0, 0);
return canvas.toDataURL("image/png");
},
};
global.makeWidgetId = id => {
id = id.toLowerCase();
// FIXME: This allows for collisions.