diff options
Diffstat (limited to 'js/hosts-files.js')
-rw-r--r-- | js/hosts-files.js | 340 |
1 files changed, 171 insertions, 169 deletions
diff --git a/js/hosts-files.js b/js/hosts-files.js index b2f19f6..92a7efc 100644 --- a/js/hosts-files.js +++ b/js/hosts-files.js @@ -2,7 +2,7 @@ ηMatrix - a browser extension to black/white list requests. Copyright (C) 2014-2019 Raymond Hill - Copyright (C) 2019-2020 Alessio Vanni + Copyright (C) 2019-2022 Alessio Vanni This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see {http://www.gnu.org/licenses/}. - Home: https://libregit.spks.xyz/heckyel/ematrix + Home: https://gitlab.com/vannilla/ematrix uMatrix Home: https://github.com/gorhill/uMatrix */ @@ -30,104 +30,104 @@ let reValidExternalList = /[a-z-]+:\/\/\S*\/\S+/; vAPI.messaging.addListener(function (msg) { - switch (msg.what) { - case 'assetUpdated': + switch (msg.what) { + case 'assetUpdated': updateAssetStatus(msg); break; - case 'assetsUpdated': + case 'assetsUpdated': document.body.classList.remove('updating'); break; - case 'loadHostsFilesCompleted': + case 'loadHostsFilesCompleted': renderHostsFiles(); break; - default: + default: break; - } + } }); let renderNumber = function (value) { - return value.toLocaleString(); + return value.toLocaleString(); }; let renderHostsFiles = function (soft) { - let listEntryTemplate = uDom('#templates .listEntry'); + let listEntryTemplate = uDom('#templates .listEntry'); let listStatsTemplate = vAPI.i18n('hostsFilesPerFileStats'); let renderETTS = vAPI.i18n.renderElapsedTimeToString; let reExternalHostFile = /^https?:/; - // Assemble a pretty list name if possible - let listNameFromListKey = function (listKey) { + // Assemble a pretty list name if possible + let listNameFromListKey = function (listKey) { let list = - listDetails.current[listKey] || listDetails.available[listKey]; + listDetails.current[listKey] || listDetails.available[listKey]; let listTitle = list ? list.title : ''; if (listTitle === '') { - return listKey; - } + return listKey; + } return listTitle; - }; + }; - let liFromListEntry = function (listKey, li) { + let liFromListEntry = function (listKey, li) { let entry = listDetails.available[listKey]; - let elem; + let elem; if (!li) { - li = listEntryTemplate.clone().nodeAt(0); + li = listEntryTemplate.clone().nodeAt(0); } if (li.getAttribute('data-listkey') !== listKey) { - li.setAttribute('data-listkey', listKey); + li.setAttribute('data-listkey', listKey); - elem = li.querySelector('input[type="checkbox"]'); - elem.checked = (entry.off !== true); - elem = li.querySelector('a:nth-of-type(1)'); - elem.setAttribute('href', - 'asset-viewer.html?url=' + encodeURI(listKey)); - elem.setAttribute('type', 'text/html'); - elem.textContent = listNameFromListKey(listKey); + elem = li.querySelector('input[type="checkbox"]'); + elem.checked = (entry.off !== true); + elem = li.querySelector('a:nth-of-type(1)'); + elem.setAttribute('href', + 'asset-viewer.html?url=' + encodeURI(listKey)); + elem.setAttribute('type', 'text/html'); + elem.textContent = listNameFromListKey(listKey); - li.classList.remove('toRemove'); + li.classList.remove('toRemove'); - if (entry.supportName) { + if (entry.supportName) { li.classList.add('support'); elem = li.querySelector('a.support'); elem.setAttribute('href', entry.supportURL); elem.setAttribute('title', entry.supportName); - } else { + } else { li.classList.remove('support'); - } + } - if (entry.external) { + if (entry.external) { li.classList.add('external'); - } else { + } else { li.classList.remove('external'); - } + } - if (entry.instructionURL) { + if (entry.instructionURL) { li.classList.add('mustread'); elem = li.querySelector('a.mustread'); elem.setAttribute('href', entry.instructionURL); - } else { + } else { li.classList.remove('mustread'); - } + } } // https://github.com/gorhill/uBlock/issues/1429 if (!soft) { - elem = li.querySelector('input[type="checkbox"]'); - elem.checked = entry.off !== true; + elem = li.querySelector('input[type="checkbox"]'); + elem.checked = entry.off !== true; } elem = li.querySelector('span.counts'); let text = ''; if (!isNaN(+entry.entryUsedCount) && !isNaN(+entry.entryCount)) { - text = listStatsTemplate + text = listStatsTemplate .replace('{{used}}', - renderNumber(entry.off ? 0 : entry.entryUsedCount)) + renderNumber(entry.off ? 0 : entry.entryUsedCount)) .replace('{{total}}', - renderNumber(entry.entryCount)); + renderNumber(entry.entryCount)); } elem.textContent = text; @@ -137,26 +137,26 @@ let remoteURL = asset.remoteURL; li.classList.toggle('unsecure', - typeof remoteURL === 'string' - && remoteURL.lastIndexOf('http:', 0) === 0); + typeof remoteURL === 'string' + && remoteURL.lastIndexOf('http:', 0) === 0); li.classList.toggle('failed', asset.error !== undefined); li.classList.toggle('obsolete', asset.obsolete === true); li.classList.toggle('cached', - asset.cached === true && asset.writeTime > 0); + asset.cached === true && asset.writeTime > 0); if (asset.cached) { - li.querySelector('.status.cache') - .setAttribute('title', - lastUpdateTemplateString - .replace('{{ago}}', - renderETTS(asset.writeTime))); + li.querySelector('.status.cache') + .setAttribute('title', + lastUpdateTemplateString + .replace('{{ago}}', + renderETTS(asset.writeTime))); } li.classList.remove('discard'); return li; - }; + }; - let onListsReceived = function (details) { + let onListsReceived = function (details) { // Before all, set context vars listDetails = details; @@ -165,225 +165,227 @@ uDom('#lists .listEntry').addClass('discard'); let availableLists = details.available; - let listKeys = Object.keys(details.available); + let listKeys = Object.keys(details.available); // Sort works this way: // - Send /^https?:/ items at the end (custom hosts file URL) listKeys.sort(function (a, b) { - let ta = availableLists[a].title || a; + let ta = availableLists[a].title || a; let tb = availableLists[b].title || b; + let ca = reExternalHostFile.test(ta); + let cb = reExternalHostFile.test(tb); - if (reExternalHostFile.test(ta) === reExternalHostFile.test(tb)) { + if (ca === cb) { return ta.localeCompare(tb); - } + } - return reExternalHostFile.test(tb) ? -1 : 1; + return (cb) ? -1 : 1; }); let ulList = document.querySelector('#lists'); for (let i=0; i<listKeys.length; ++i) { - let liEntry = liFromListEntry(listKeys[i], ulList.children[i]); - if (liEntry.parentElement === null) { + let liEntry = liFromListEntry(listKeys[i], ulList.children[i]); + if (liEntry.parentElement === null) { ulList.appendChild(liEntry); - } + } } uDom('#lists .listEntry.discard').remove(); uDom('#listsOfBlockedHostsPrompt') - .text(vAPI.i18n('hostsFilesStats') - .replace('{{blockedHostnameCount}}', - renderNumber(details.blockedHostnameCount))); + .text(vAPI.i18n('hostsFilesStats') + .replace('{{blockedHostnameCount}}', + renderNumber(details.blockedHostnameCount))); uDom('#autoUpdate').prop('checked', - listDetails.autoUpdate === true); + listDetails.autoUpdate === true); if (!soft) { - hostsFilesSettingsHash = hashFromCurrentFromSettings(); + hostsFilesSettingsHash = hashFromCurrentFromSettings(); } renderWidgets(); - }; + }; - vAPI.messaging.send('hosts-files.js', { - what: 'getLists' - }, onListsReceived); + vAPI.messaging.send('hosts-files.js', { + what: 'getLists' + }, onListsReceived); }; let renderWidgets = function () { - let sel1 = - 'body:not(.updating) #lists .listEntry.obsolete ' - + '> input[type="checkbox"]:checked'; - let sel2 = '#lists .listEntry.cached'; - - uDom('#buttonUpdate') - .toggleClass('disabled', document.querySelector(sel1) === null); - uDom('#buttonPurgeAll') - .toggleClass('disabled', document.querySelector(sel2) === null); - uDom('#buttonApply') - .toggleClass('disabled', - hostsFilesSettingsHash === - hashFromCurrentFromSettings()); + let sel1 = + 'body:not(.updating) #lists .listEntry.obsolete ' + + '> input[type="checkbox"]:checked'; + let sel2 = '#lists .listEntry.cached'; + + uDom('#buttonUpdate') + .toggleClass('disabled', document.querySelector(sel1) === null); + uDom('#buttonPurgeAll') + .toggleClass('disabled', document.querySelector(sel2) === null); + uDom('#buttonApply') + .toggleClass('disabled', + hostsFilesSettingsHash === + hashFromCurrentFromSettings()); }; let updateAssetStatus = function (details) { - let li = document - .querySelector('#lists .listEntry[data-listkey="'+details.key+'"]'); - if (li === null) { - return; - } - - li.classList.toggle('failed', !!details.failed); - li.classList.toggle('obsolete', !details.cached); - li.classList.toggle('cached', !!details.cached); - - if (details.cached) { - let str = vAPI.i18n.renderElapsedTimeToString(Date.now()); + let li = document + .querySelector('#lists .listEntry[data-listkey="'+details.key+'"]'); + if (li === null) { + return; + } + + li.classList.toggle('failed', !!details.failed); + li.classList.toggle('obsolete', !details.cached); + li.classList.toggle('cached', !!details.cached); + + if (details.cached) { + let str = vAPI.i18n.renderElapsedTimeToString(Date.now()); li.querySelector('.status.cache') - .setAttribute('title', - lastUpdateTemplateString.replace('{{ago}}', str)); - } + .setAttribute('title', + lastUpdateTemplateString.replace('{{ago}}', str)); + } - renderWidgets(); + renderWidgets(); }; /** - Compute a hash from all the settings affecting how filter lists are loaded - in memory. + Compute a hash from all the settings affecting how filter lists are loaded + in memory. **/ let hashFromCurrentFromSettings = function () { - let hash = []; + let hash = []; let listHash = []; - let sel = '#lists .listEntry[data-listkey]:not(.toRemove)'; - let ext = 'externalHostsFiles'; + let sel = '#lists .listEntry[data-listkey]:not(.toRemove)'; + let ext = 'externalHostsFiles'; let listEntries = document.querySelectorAll(sel); for (let i=listEntries.length-1; i>=0; --i) { let li = listEntries[i]; if (li.querySelector('input[type="checkbox"]:checked') !== null) { - listHash.push(li.getAttribute('data-listkey')); + listHash.push(li.getAttribute('data-listkey')); } - } + } - hash.push(listHash.sort().join(), - reValidExternalList.test(document.getElementById(ext).value), - document.querySelector('#lists .listEntry.toRemove') !== null); + hash.push(listHash.sort().join(), + reValidExternalList.test(document.getElementById(ext).value), + document.querySelector('#lists .listEntry.toRemove') !== null); - return hash.join(); + return hash.join(); }; let onHostsFilesSettingsChanged = function () { - renderWidgets(); + renderWidgets(); }; let onRemoveExternalHostsFile = function (ev) { - let liEntry = uDom(this).ancestors('[data-listkey]'); + let liEntry = uDom(this).ancestors('[data-listkey]'); let listKey = liEntry.attr('data-listkey'); - if (listKey) { + if (listKey) { liEntry.toggleClass('toRemove'); renderWidgets(); - } + } - ev.preventDefault(); + ev.preventDefault(); }; let onPurgeClicked = function () { - let button = uDom(this); + let button = uDom(this); let liEntry = button.ancestors('[data-listkey]'); let listKey = liEntry.attr('data-listkey'); - if (!listKey) { - return; - } + if (!listKey) { + return; + } - vAPI.messaging.send('hosts-files.js', { - what: 'purgeCache', - assetKey: listKey - }); + vAPI.messaging.send('hosts-files.js', { + what: 'purgeCache', + assetKey: listKey + }); - liEntry.addClass('obsolete'); - liEntry.removeClass('cached'); + liEntry.addClass('obsolete'); + liEntry.removeClass('cached'); - if (liEntry.descendants('input').first().prop('checked')) { + if (liEntry.descendants('input').first().prop('checked')) { renderWidgets(); - } + } }; let selectHostsFiles = function (callback) { - // Hosts files to select - let toSelect = []; - let sel = '#lists .listEntry[data-listkey]:not(.toRemove)'; - let sel2 = '#lists .listEntry.toRemove[data-listkey]'; + // Hosts files to select + let toSelect = []; + let sel = '#lists .listEntry[data-listkey]:not(.toRemove)'; + let sel2 = '#lists .listEntry.toRemove[data-listkey]'; let liEntries = document.querySelectorAll(sel); for (let i=liEntries.length-1; i>=0; --i) { let li = liEntries[i]; if (li.querySelector('input[type="checkbox"]:checked') !== null) { - toSelect.push(li.getAttribute('data-listkey')); + toSelect.push(li.getAttribute('data-listkey')); } - } + } - // External hosts files to remove - let toRemove = []; - liEntries = document.querySelectorAll(sel2); + // External hosts files to remove + let toRemove = []; + liEntries = document.querySelectorAll(sel2); - for (let i=liEntries.length-1; i>=0; --i) { + for (let i=liEntries.length-1; i>=0; --i) { toRemove.push(liEntries[i].getAttribute('data-listkey')); - } + } - // External hosts files to import - let externalListsElem = document.getElementById('externalHostsFiles'); + // External hosts files to import + let externalListsElem = document.getElementById('externalHostsFiles'); let toImport = externalListsElem.value.trim(); - externalListsElem.value = ''; + externalListsElem.value = ''; - vAPI.messaging.send('hosts-files.js', { - what: 'selectHostsFiles', - toSelect: toSelect, - toImport: toImport, - toRemove: toRemove + vAPI.messaging.send('hosts-files.js', { + what: 'selectHostsFiles', + toSelect: toSelect, + toImport: toImport, + toRemove: toRemove }, callback); - hostsFilesSettingsHash = hashFromCurrentFromSettings(); + hostsFilesSettingsHash = hashFromCurrentFromSettings(); }; let buttonApplyHandler = function () { - uDom('#buttonApply').removeClass('enabled'); - selectHostsFiles(function () { + uDom('#buttonApply').removeClass('enabled'); + selectHostsFiles(function () { vAPI.messaging.send('hosts-files.js', { - what: 'reloadHostsFiles' - }); - }); + what: 'reloadHostsFiles' + }); + }); - renderWidgets(); + renderWidgets(); }; let buttonUpdateHandler = function () { - uDom('#buttonUpdate').removeClass('enabled'); - selectHostsFiles(function () { + uDom('#buttonUpdate').removeClass('enabled'); + selectHostsFiles(function () { document.body.classList.add('updating'); vAPI.messaging.send('hosts-files.js', { - what: 'forceUpdateAssets' - }); + what: 'forceUpdateAssets' + }); renderWidgets(); - }); - renderWidgets(); + }); + renderWidgets(); }; let buttonPurgeAllHandler = function () { - uDom('#buttonPurgeAll').removeClass('enabled'); - vAPI.messaging.send('hosts-files.js', { - what: 'purgeAllCaches' - }, function () { - renderHostsFiles(true); + uDom('#buttonPurgeAll').removeClass('enabled'); + vAPI.messaging.send('hosts-files.js', { + what: 'purgeAllCaches' + }, function () { + renderHostsFiles(true); }); }; let autoUpdateCheckboxChanged = function () { - vAPI.messaging.send('hosts-files.js', { - what: 'userSettings', - name: 'autoUpdate', - value: this.checked + vAPI.messaging.send('hosts-files.js', { + what: 'userSettings', + name: 'autoUpdate', + value: this.checked }); }; @@ -392,9 +394,9 @@ uDom('#buttonUpdate').on('click', buttonUpdateHandler); uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler); uDom('#lists').on('change', '.listEntry > input', - onHostsFilesSettingsChanged); + onHostsFilesSettingsChanged); uDom('#lists').on('click', '.listEntry > a.remove', - onRemoveExternalHostsFile); + onRemoveExternalHostsFile); uDom('#lists').on('click', 'span.cache', onPurgeClicked); uDom('#externalHostsFiles').on('input', onHostsFilesSettingsChanged); |