I am working on a cross-browser extension and use the "tabs API" (https://developer.chrome.com/docs/extensions/reference/tabs/) to store relevant information about each tab.
One of these fields is the tab's favIconUrl.
In Chrome & Microsoft Edge, this field is given as a URL string and is usually relatively short (a few bytes).
However in Firefox, this is given as a data:image/x-icon;base64
string and is VERY long (a couple of KB).
The problem is that I use storage.sync
and this resource is sparse per item stored - so what takes up nothing in Chrome/Edge, is barely enough in Firefox for a single tab.
Chrome & Microsoft Edge:
https://static.xx.fbcdn.net/rsrc.php/yo/r/iRmz9lCMBD2.ico
Firefox:
data:image/x-icon;base64,AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAs2hCtbJnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L///////////+yZ0L/smdC/7JnQv+yZ0L/s2hCtbJnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv///////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L///////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv///////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/////////////////////////////////8WMcP+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv/////////////////////////////////RpI3/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv///////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L///////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//ny7v//////z6GK/7NoQ/+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv/ixbf/////////////////2bOh/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/t3BO/+LGuP/59PH///7+/9evm/+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/s2hCtbJnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/s2hCtQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAsmlCSbNnQuOyZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L//////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/s2dC47JpQkmzZ0LjsmdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/s2dC47JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L//////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L//////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L//////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv/////////////////////////////////////////////////////////////////SpZD/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/////////////////////////////////////////////////////////////////969rf+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/////////////////////////////////////////////////////////////////6tXK/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv/////////////////////////////////////////////////////////////////27Oj/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L//////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv//////////////////////s2lF/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC//fv6//////////////////Kl33/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/69fN//////////////////nz8P/Iknj/tWxI/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv/bt6X///////////////////////////////////////////+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7ZvTP/37ur//////////////////////////////////////7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/8aNcf/48e3/////////////////////////////////smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7ZvTP/atqT/7dzT//n08f///////v38//fv6/+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7NpRP+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/s2dC47JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7NnQuOyaUJJs2dC47JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+yZ0L/smdC/7JnQv+zZ0LjsmlCSQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Any ideas how I can shorten this Base64 string?
Ideally, I would need some decoder that decodes base64 but keeps regular URL strings unchanged.
I ended up converting it to a blob url by modifying this answer to my needs: https://stackoverflow.com/a/16245768/4298115
function convertToShortURL(input_str, sliceSize = 512) {
if (input_str && input_str.includes("base64")) {
input_str = input_str.split(",")[1]; // get the base64 part
const byteCharacters = atob(input_str);
const byteArrays = [];
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
const slice = byteCharacters.slice(offset, offset + sliceSize);
const byteNumbers = new Array(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
}
const blob = new Blob(byteArrays);
return URL.createObjectURL(blob);
} else {
return input_str;
}
}
This function takes in an input string that you would get from tab.favIconUrl
using the "Tabs API" and if it is a base64 string, will return a short blob url - which you can then use the same way as a url string. Otherwise, if the input is already a url string or undefined (not base64), the function simply returns it as is.
Based on:
function getFavIconURL(url) {
var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];
return "http://www.google.com/s2/favicons?domain=" + domain;
}
This function simply returns the favicon url without returning a blob file.
Simple and elegant in my opinion. Cheers!