remember and skip bad favicons
This commit is contained in:
parent
5ff664f9b9
commit
38ac974d8a
|
@ -32,6 +32,13 @@ Object.assign(newUI, {
|
||||||
$.rootCL.toggle('newUI', newUI.enabled);
|
$.rootCL.toggle('newUI', newUI.enabled);
|
||||||
$.rootCL.toggle('oldUI', !newUI.enabled);
|
$.rootCL.toggle('oldUI', !newUI.enabled);
|
||||||
},
|
},
|
||||||
|
hasFavs: () => newUI.enabled && newUI.favicons,
|
||||||
|
badFavsKey: 'badFavs',
|
||||||
|
async readBadFavs() {
|
||||||
|
const key = newUI.badFavsKey;
|
||||||
|
const val = await API.prefsDb.get(key);
|
||||||
|
return (newUI[key] = Array.isArray(val) ? val : []);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
// ...read the actual values
|
// ...read the actual values
|
||||||
for (const id of newUI.ids) {
|
for (const id of newUI.ids) {
|
||||||
|
@ -44,7 +51,7 @@ newUI.renderClass();
|
||||||
const [styles, ids] = await Promise.all([
|
const [styles, ids] = await Promise.all([
|
||||||
API.styles.getAll(),
|
API.styles.getAll(),
|
||||||
query && API.styles.searchDB({query, mode: router.getSearch('searchMode')}),
|
query && API.styles.searchDB({query, mode: router.getSearch('searchMode')}),
|
||||||
// needed to avoid flicker due to an extra frame and layout shift
|
newUI.hasFavs() && newUI.readBadFavs(),
|
||||||
prefs.ready,
|
prefs.ready,
|
||||||
]);
|
]);
|
||||||
installed.on('click', Events.entryClicked);
|
installed.on('click', Events.entryClicked);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* global $$ $ $create animateElement scrollElementIntoView */// dom.js
|
/* global $$ $ $create animateElement scrollElementIntoView */// dom.js
|
||||||
/* global API */// msg.js
|
/* global API */// msg.js
|
||||||
/* global URLS debounce isEmptyObj sessionStore */// toolbox.js
|
/* global URLS debounce getOwnTab isEmptyObj sessionStore stringAsRegExp */// toolbox.js
|
||||||
/* global filterAndAppend */// filters.js
|
/* global filterAndAppend */// filters.js
|
||||||
/* global installed newUI */// manage.js
|
/* global installed newUI */// manage.js
|
||||||
/* global prefs */
|
/* global prefs */
|
||||||
|
@ -45,6 +45,7 @@ const AGES = [
|
||||||
})();
|
})();
|
||||||
|
|
||||||
let elementParts;
|
let elementParts;
|
||||||
|
let badFavs;
|
||||||
|
|
||||||
function $entry(styleOrId, root = installed) {
|
function $entry(styleOrId, root = installed) {
|
||||||
return $(`#${ENTRY_ID_PREFIX_RAW}${styleOrId.id || styleOrId}`, root);
|
return $(`#${ENTRY_ID_PREFIX_RAW}${styleOrId.id || styleOrId}`, root);
|
||||||
|
@ -214,20 +215,41 @@ function createTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
||||||
entry._numTargets = numTargets;
|
entry._numTargets = numTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFaviconSrc(container = installed) {
|
async function getFaviconSrc(container = installed) {
|
||||||
if (!newUI.enabled || !newUI.favicons) return;
|
if (!newUI.hasFavs()) return;
|
||||||
|
if (!badFavs) {
|
||||||
|
// API creates a new function each time so we save it for `debounce` which is keyed on function object
|
||||||
|
const {put} = API.prefsDb;
|
||||||
|
const key = newUI.badFavsKey;
|
||||||
|
const rxHost = new RegExp(`^${stringAsRegExp(URLS.favicon('\n'), '', true).replace('\n', '(.*)')}$`);
|
||||||
|
badFavs = newUI[key] || await newUI.readBadFavs();
|
||||||
|
const fn = e => {
|
||||||
|
const host = e.statusCode !== 200 && e.url.match(rxHost)[1];
|
||||||
|
if (host && !badFavs.includes(e)) {
|
||||||
|
badFavs.push(host);
|
||||||
|
debounce(put, 250, badFavs, key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const filter = {
|
||||||
|
urls: [URLS.favicon('*')], // we assume there's no redirect
|
||||||
|
types: ['image'],
|
||||||
|
tabId: (await getOwnTab()).id,
|
||||||
|
};
|
||||||
|
chrome.webRequest.onCompleted.addListener(fn, filter); // works in Chrome
|
||||||
|
chrome.webRequest.onErrorOccurred.addListener(fn, filter); // works in FF
|
||||||
|
}
|
||||||
const regexpRemoveNegativeLookAhead = /(\?!([^)]+\))|\(\?![\w(]+[^)]+[\w|)]+)/g;
|
const regexpRemoveNegativeLookAhead = /(\?!([^)]+\))|\(\?![\w(]+[^)]+[\w|)]+)/g;
|
||||||
// replace extra characters & all but the first group entry "(abc|def|ghi)xyz" => abcxyz
|
// replace extra characters & all but the first group entry "(abc|def|ghi)xyz" => abcxyz
|
||||||
const regexpReplaceExtraCharacters = /[\\(]|((\|\w+)+\))/g;
|
const regexpReplaceExtraCharacters = /[\\(]|((\|\w+)+\))/g;
|
||||||
const regexpMatchRegExp = /[\w-]+[.(]+(com|org|co|net|im|io|edu|gov|biz|info|de|cn|uk|nl|eu|ru)\b/g;
|
const regexpMatchRegExp = /[\w-]+[.(]+(com|org|co|net|im|io|edu|gov|biz|info|de|cn|uk|nl|eu|ru)\b/g;
|
||||||
const regexpMatchDomain = /^.*?:\/\/([^/]+)/;
|
const regexpMatchDomain = /^.*?:\/\/\W*([-.\w]+)/;
|
||||||
for (const target of $$('.target', container)) {
|
for (const target of $$('.target', container)) {
|
||||||
const type = target.dataset.type;
|
const type = target.dataset.type;
|
||||||
const targetValue = target.textContent;
|
const targetValue = target.textContent;
|
||||||
if (!targetValue) continue;
|
if (!targetValue) continue;
|
||||||
let favicon = '';
|
let favicon = '';
|
||||||
if (type === 'domains') {
|
if (type === 'domains') {
|
||||||
favicon = URLS.favicon(targetValue);
|
favicon = targetValue;
|
||||||
} else if (targetValue.includes('chrome-extension:') || targetValue.includes('moz-extension:')) {
|
} else if (targetValue.includes('chrome-extension:') || targetValue.includes('moz-extension:')) {
|
||||||
favicon = OWN_ICON;
|
favicon = OWN_ICON;
|
||||||
} else if (type === 'regexps') {
|
} else if (type === 'regexps') {
|
||||||
|
@ -235,12 +257,17 @@ function getFaviconSrc(container = installed) {
|
||||||
.replace(regexpRemoveNegativeLookAhead, '')
|
.replace(regexpRemoveNegativeLookAhead, '')
|
||||||
.replace(regexpReplaceExtraCharacters, '')
|
.replace(regexpReplaceExtraCharacters, '')
|
||||||
.match(regexpMatchRegExp);
|
.match(regexpMatchRegExp);
|
||||||
favicon = favicon ? URLS.favicon(favicon.shift()) : '';
|
favicon = favicon ? favicon.shift() : '';
|
||||||
} else {
|
} else if (/^(f|ht)tps?:/.test(targetValue)) {
|
||||||
favicon = targetValue.includes('://') && targetValue.match(regexpMatchDomain);
|
favicon = targetValue.match(regexpMatchDomain);
|
||||||
favicon = favicon ? URLS.favicon(favicon[1]) : '';
|
favicon = favicon ? favicon[1].replace(/\W+$/, '') : '';
|
||||||
|
}
|
||||||
|
if (!favicon || badFavs && badFavs.includes(favicon)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (favicon !== OWN_ICON) {
|
||||||
|
favicon = URLS.favicon(favicon);
|
||||||
}
|
}
|
||||||
if (!favicon) continue;
|
|
||||||
const img = $(':scope > img:first-child', target) ||
|
const img = $(':scope > img:first-child', target) ||
|
||||||
target.insertAdjacentElement('afterbegin', $create('img', {loading: 'lazy'}));
|
target.insertAdjacentElement('afterbegin', $create('img', {loading: 'lazy'}));
|
||||||
if ((img.dataset.src || img.src) !== favicon) {
|
if ((img.dataset.src || img.src) !== favicon) {
|
||||||
|
@ -376,7 +403,7 @@ function switchUI({styleOnly} = {}) {
|
||||||
Object.assign(newUI, current);
|
Object.assign(newUI, current);
|
||||||
newUI.renderClass();
|
newUI.renderClass();
|
||||||
|
|
||||||
installed.classList.toggle('has-favicons', newUI.enabled && newUI.favicons);
|
installed.classList.toggle('has-favicons', newUI.hasFavs());
|
||||||
installed.classList.toggle('favicons-grayed', newUI.enabled && newUI.faviconsGray);
|
installed.classList.toggle('favicons-grayed', newUI.enabled && newUI.faviconsGray);
|
||||||
if (installed.style.getPropertyValue('--num-targets') !== `${newUI.targets}`) {
|
if (installed.style.getPropertyValue('--num-targets') !== `${newUI.targets}`) {
|
||||||
installed.style.setProperty('--num-targets', newUI.targets);
|
installed.style.setProperty('--num-targets', newUI.targets);
|
||||||
|
@ -386,7 +413,7 @@ function switchUI({styleOnly} = {}) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconsEnabled = newUI.enabled && newUI.favicons;
|
const iconsEnabled = newUI.hasFavs();
|
||||||
let iconsMissing = iconsEnabled && !$('.applies-to img');
|
let iconsMissing = iconsEnabled && !$('.applies-to img');
|
||||||
if (changed.enabled || (iconsMissing && !elementParts)) {
|
if (changed.enabled || (iconsMissing && !elementParts)) {
|
||||||
installed.textContent = '';
|
installed.textContent = '';
|
||||||
|
|
Loading…
Reference in New Issue
Block a user