How to get the site's favicon and the main color on it?

Hello. I developing an add-on that works with the history of the browser.
But I ran into a problem: I have a domain of an arbitrary site. Next to it, I want to display the favicon of this site, and fill up the whole section with the favicon color. How can i do this? Does the browser have an API to get the site’s favicon? Does the browser have an API to determine the main color in the image?

Well, there isn’t really such a thing as a sties favicon. Every page can set it’s own and even change it while it is open. It is only customary that all / most pages on a site use the same one. The favicon on the homepage of a site is probably what you want.

Tab.faviconUrl gives you the current favicon URL of the top page in a tab. Other than that, you could fetch the homepages HTML and look for the meta tags that set the favicon. The fallback URL is /favicon.ico. There is also a Google-service to get favicons for URLs.

Assuming that the “main color in the image” is the color of which there are the most pixels of exactly that color in the image, the code below should work (havn’t tested it though):

const canvas = document.createElement('canvas'), ctx = canvas.getContext('2d');
const image = new Image;
image.onload = () => {
	const width = canvas.width = image.width;
	const height = canvas.height = image.height;
	ctx.drawImage(
		image,
		0, 0, width, height,
		0, 0, width, height
	);
	const { data, } = ctx.getImageData(0, 0, width, height);
	const colors = new Map;

	for (let i = 0, l = data.length; i < l; i += 4) {
		const color = (data[i] << 16) + data[i+1] << 8) + data[i+2]; // ignore alpha
		colors.set(color, (colors.get(color) || 0) + 1);
	}
	const max = Math.max(...colors.keys());
	for (const [ color, count, ] of colors) {
		if (count === max) { return [
			color >> 16,
			(color >> 8) & 0xff,
			color & 0xff,
		]; }
	}
};
image.src = faviconUrl;

I tried to use a similar approach with canvas, but I get the error “SecurityError: The operation is insecure.”

If adding the <all_urls> host permission doesn’t help, try

image.src =  URL.createObjectURL(await (await fetch(faviconUrl)).blob());