|
Packit |
f0b94e |
"use strict";
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
const {
|
|
Packit |
f0b94e |
utils: Cu,
|
|
Packit |
f0b94e |
classes: Cc,
|
|
Packit |
f0b94e |
interfaces: Ci
|
|
Packit |
f0b94e |
} = Components;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
ChromeUtils.import("resource://gre/modules/PromiseMessage.jsm");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
var ManifestIcons = {
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
async browserFetchIcon(aBrowser, manifest, iconSize) {
|
|
Packit |
f0b94e |
const msgKey = "DOM:WebManifest:fetchIcon";
|
|
Packit |
f0b94e |
const mm = aBrowser.messageManager;
|
|
Packit |
f0b94e |
const {data: {success, result}} =
|
|
Packit |
f0b94e |
await PromiseMessage.send(mm, msgKey, {manifest, iconSize});
|
|
Packit |
f0b94e |
if (!success) {
|
|
Packit |
f0b94e |
throw result;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
return result;
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
async contentFetchIcon(aWindow, manifest, iconSize) {
|
|
Packit |
f0b94e |
return await getIcon(aWindow, toIconArray(manifest.icons), iconSize);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
function parseIconSize(size) {
|
|
Packit |
f0b94e |
if (size === "any" || size === "") {
|
|
Packit |
f0b94e |
// We want icons without size specified to sorted
|
|
Packit |
f0b94e |
// as the largest available icons
|
|
Packit |
f0b94e |
return Number.MAX_SAFE_INTEGER;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// 100x100 will parse as 100
|
|
Packit |
f0b94e |
return parseInt(size, 10);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Create an array of icons sorted by their size
|
|
Packit |
f0b94e |
function toIconArray(icons) {
|
|
Packit |
f0b94e |
const iconBySize = [];
|
|
Packit |
f0b94e |
icons.forEach(icon => {
|
|
Packit |
f0b94e |
const sizes = ("sizes" in icon) ? icon.sizes : "";
|
|
Packit |
f0b94e |
sizes.split(" ").forEach(size => {
|
|
Packit |
f0b94e |
iconBySize.push({src: icon.src, size: parseIconSize(size)});
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
return iconBySize.sort((a, b) => a.size - b.size);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
async function getIcon(aWindow, icons, expectedSize) {
|
|
Packit |
f0b94e |
if (!icons.length) {
|
|
Packit |
f0b94e |
throw new Error("Could not find valid icon");
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
// We start trying the smallest icon that is larger than the requested
|
|
Packit |
f0b94e |
// size and go up to the largest icon if they fail, if all those fail
|
|
Packit |
f0b94e |
// go back down to the smallest
|
|
Packit |
f0b94e |
let index = icons.findIndex(icon => icon.size >= expectedSize);
|
|
Packit |
f0b94e |
if (index === -1) {
|
|
Packit |
f0b94e |
index = icons.length - 1;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return fetchIcon(aWindow, icons[index].src).catch(err => {
|
|
Packit |
f0b94e |
// Remove all icons with the failed source, the same source
|
|
Packit |
f0b94e |
// may have been used for multiple sizes
|
|
Packit |
f0b94e |
icons = icons.filter(x => x.src !== icons[index].src);
|
|
Packit |
f0b94e |
return getIcon(aWindow, icons, expectedSize);
|
|
Packit |
f0b94e |
});
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
async function fetchIcon(aWindow, src) {
|
|
Packit |
f0b94e |
const iconURL = new aWindow.URL(src, aWindow.location);
|
|
Packit |
f0b94e |
const request = new aWindow.Request(iconURL, {mode: "cors"});
|
|
Packit |
f0b94e |
request.overrideContentPolicyType(Ci.nsIContentPolicy.TYPE_IMAGE);
|
|
Packit |
f0b94e |
return aWindow.fetch(request)
|
|
Packit |
f0b94e |
.then(response => response.blob())
|
|
Packit |
f0b94e |
.then(blob => new Promise((resolve, reject) => {
|
|
Packit |
f0b94e |
var reader = new FileReader();
|
|
Packit |
f0b94e |
reader.onloadend = () => resolve(reader.result);
|
|
Packit |
f0b94e |
reader.onerror = reject;
|
|
Packit |
f0b94e |
reader.readAsDataURL(blob);
|
|
Packit |
f0b94e |
}));
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
var EXPORTED_SYMBOLS = ["ManifestIcons"]; // jshint ignore:line
|