bbpro
Version:
BrowserBox - remote browser isolation tool
120 lines (104 loc) • 2.96 kB
JavaScript
/* eslint-disable no-inner-declarations */
{
const Sent = new Set();
let faviconDataUrl;
let received = false;
let running = false;
const targetId = self.targetId;
install();
function install() {
if ( window !== top ) return;
self.getFaviconElement = getFaviconElement;
self.reportFaviconReceived = reportFaviconReceived;
self.addEventListener('DOMContentLoaded', getFaviconElement);
s({installed:true, targetId});
}
function reportFaviconReceived() {
received = true;
}
async function getFaviconElement(load) {
s({functionCall: "getFaviconElement", targetId});
if ( received || running ) return;
running = true;
s({running: "getFaviconElement", targetId});
try {
const iconURLs = Array.from(
document.querySelectorAll(
'link[rel~="icon"], link[rel~="shortcut"]'
)
).map(el => el.href);
let url;
{
const urlCopy = new URL(location);
urlCopy.pathname = "/favicon.ico";
urlCopy.search = '';
urlCopy.hash = '';
url = urlCopy + '';
}
iconURLs.push(url);
let hasIcon = false;
for( const iconURL of iconURLs ) {
try {
hasIcon = await getIcon(iconURL);
} catch(e) {
s({getIconWithoutCredentialsError: e+''});
}
if ( ! hasIcon ) {
try {
await getIcon(iconURL, {withCredentials: true});
} catch(e) {
s({getIconWithCredentialsError: e+''});
}
}
}
} catch(e) {
s({e: e+''});
running = false;
}
}
function s(o) {
if ( received || Sent.has(o.faviconDataUrl) ) return;
if ( o.faviconDataUrl ) {
Sent.add(o.faviconDataUrl);
}
console.log(JSON.stringify({favicon:o}));
}
async function getIcon(iconURL, {withCredentials = false} = {}) {
if ( received ) return;
let hasIcon = false;
let resolve;
const pr = new Promise(res => resolve = res);
const image = new Image();
if ( withCredentials ) {
image.crossOrigin = 'use-credentials';
} else {
image.crossOrigin = 'anonymous';
}
image.onload = () => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
try {
faviconDataUrl = canvas.toDataURL();
s({faviconDataUrl,targetId});
hasIcon = true;
} catch (e) {
s({imageToDataURLError: e+'', faviconURL:image.src, targetId});
} finally {
running = false;
resolve(hasIcon);
}
};
image.onerror = err => {
s({imageLoadError: { imageURL: image.src }});
s({faviconURL: image.src, targetId});
running = false;
resolve(false);
};
image.src = iconURL;
return pr;
}
}
/* eslint-enable no-inner-declarations */