Не получается сделать отключение расширения
Я нашёл исходный код расширения для того чтобы можно было посещать сайты которые расположены в доменных зонах .bit, .lib, .emc, .coin, .bazar. Я делаю возможность отключения расширения при нажатии на checkbox.
Исходный код на GitHub.
Пробовал: добавил чекбок для отключения, на него добавил слушателя, на событие click, в лямбде написал код для сохрания состояния в localStorage.
Интерфейс расширения:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="ui.js"></script>
</head>
<body>
<input type="checkbox" id="state" />
<label for="state">Работает</label>
</body>
</html>
Код для сохраниния состояния:
document.addEventListener('DOMContentLoaded', () => {
var stateCheckBox = document.getElementById('state');
var state = localStorage.getItem('State');
stateCheckBox.checked = state === null || state === 'on';
stateCheckBox.addEventListener('click') e => {
localStorage.setItem('State', e.target.checked ? 'on' : 'off');
});
});
Код расширения (здесь я сделал функцию IsActive, и добавил в обработчиках слушателей проверку состояния из localStorage):
/*
Chrome Quirks
=============
Unlike Firefox, in Chrome:
* If proxy settings are changed from within onBeforeRequest - they will be effective
for this request (which has triggered onBeforeRequest).
* onBeforeRequest doesn't support promises thus async functions (e.g. async XHR)
cannot be used. But sync XHR causes deprecation warning in the console.
* Returning {cancel: true} keeps the canelled URL in the tab, with the text:
"Request blocked by extension".
Because of the first point, others do not matter since they were used to workaround
Firefox' limitations. Chrome's addon's code almost makes sense - with an exception of
setting complete PAC script on every resolution.
Other highlights:
* If a tab's loading was cancelled or has failed due to an addon, Chrome will
periodically refresh that tab; this can't be told apart from user doing so manually.
* Chrome doesn't let addons handle URLs entered without scheme, i.e. "foo.lib"
won't be handled (Google search will open instead) - "http(s)://foo.lib" has to
be typed explicitly ("foo.lib/" will also work, as it was discovered).
* Using https:// is useless because there is no way to obtain a valid certificate
for unofficial TLDs; Chrome will block this request with proxy security error
message (and no way to bypass/add exception as in Firefox).
*/
// id => timestamp (ms).
var notificationTimes = {};
// One throttled notification per this many seconds.
var notificationTimespan = 30;
function showThrottledNotification(id, title, msg) {
var last = notificationTimes[id];
if (!last || last < Date.now() - notificationTimespan * 1000) {
notificationTimes[id] = Date.now();
return showNotification(title, msg);
}
}
function showNotification(title, msg) {
return chrome.notifications.create({
type: 'basic',
iconUrl: 'icon-64.png',
title: title,
message: msg || '',
});
}
var pac = {
_scriptStub: function () {
var cache = CACHE_HERE;
function FindProxyForURL(url, host) {
// Verbatim copy of Firefox' pac.js' FindProxyForURL().
var res = 'DIRECT';
var ips = cache[host];
if (ips) {
var pos = url.indexOf(host);
var port;
if (pos != -1) {
port = (url.substr(pos + host.length).match(/^:(\d+)/) || [])[1];
}
var https = url.match(/^https:/i);
var directive = https ? 'HTTPS ' : 'PROXY ';
port = ':' + (port || (https ? 443 : 80));
res = directive + ips.join(port + '; ' + directive) + port;
}
return res;
}
},
buildObject: function () {
var obj = {};
cache.each(function (domain) {
var ips = cache.ips(domain);
if (ips.length) { obj[domain] = ips; }
});
return JSON.stringify(obj);
},
onIpChange: function (domain, ips, existed) {
if (!ips.length) {
// Non-existent domains are handled (cancelled) by onBeforeRequest.
// They don't reach PAC.
return;
}
var script = pac._scriptStub.toString()
.replace(/^.*|.*$/g, '') // wrapping 'function () { ... }'.
.replace('CACHE_HERE', pac.buildObject());
//console.log(script);
var config = {
mode: 'pac_script',
pacScript: {
data: script,
},
};
chrome.proxy.settings.set({value: config}, function () {
console.log('BDNS: set new PAC script, length = ' + script.length); //-
});
},
// No need to update PAC on domains missing (deleted) from cache since they
// will be reprocessed by onBeforeRequest before PAC is queried.
onDomainDelete: function (domain) { },
}
cache.onIpChange = pac.onIpChange;
cache.onDomainDelete = pac.onDomainDelete;
function IsActive() {
var state = localStorage.getItem('State');
return state === null || state === 'on';
}
chrome.webRequest.onBeforeRequest.addListener(function(details) {
// Проверка состояния
if (IsActive()) {
var url = parseURL(details.url);
if (url) {
var ips = cache.ips(url.domain);
if (ips) {
console.log('BDNS: #' + details.requestId + ' (' + url.domain + '): already resolved to ' + ips + '; cache size = ' + cache.length); //-
// No need to update visited domains' times like in Firefox because
// even if newly resolved IPs change from the ones user used to visit the
// resource, this won't impair his experience (POST will be properly sent
// to a new working IP, etc.).
if (!ips.length) {
showThrottledNotification(url.domain, 'Non-existent .' + url.tld + ' domain: ' + url.domain);
return {
cancel: true
};
}
} else {
console.log('BDNS: #' + details.requestId + ' (' + url.domain + '): resolving, full URL: ' + url.url); //-
var res = {
cancel: true
};
resolveViaAPI(url.domain, false, function(ips) {
// On error or {cancel}, Chrome fires 1-2 more same requests which cause
// repeated notifications.
if (!ips) {
showThrottledNotification(url.domain, 'Resolution of .' + url.tld + ' is temporary unavailable');
rotateApiHost();
} else if (!ips.length) {
cache.set(url.domain, []);
showThrottledNotification(url.domain, 'Non-existent .' + url.tld + ' domain: ' + url.domain);
} else {
cache.set(url.domain, ips);
res = null;
}
});
console.log('BDNS: #' + details.requestId + ' (' + url.domain + '): resolution finished, returning ' + res); //-
return res;
}
}
}
}, allURLs, ["blocking"]);
chrome.webRequest.onErrorOccurred.addListener(function(details) {
// Проверка состояния
if (IsActive()) {
var req = details.requestId;
var url = parseURL(details.url);
console.log('BDNS: #' + req + ' (' + url.domain + '): ' + details.error); //-
switch (details.error) {
// Proxy error. Fired once, only if all IPs from the list of domain's IPs are down.
case 'net::ERR_PROXY_CONNECTION_FAILED':
if (cache.has(url.domain)) {
showThrottledNotification(url.domain, url.domain + ' is down');
}
break;
}
}
}, allURLs);
chrome.alarms.create({periodInMinutes: 1});
chrome.alarms.onAlarm.addListener(function () {
var count = cache.prune();
console.log('BDNS: deleted ' + count + ' expired entries; cache size = ' + cache.length); //-
});
var tabSupport = {};
var activeTab;
chrome.tabs.onActivated.addListener(function (info) {
activeTab = info.tabId;
console.info('BDNS: tab #' + activeTab + ' now active'); //-
var supported = tabSupport[activeTab];
chrome.browserAction[!supported ? 'enable' : 'disable']();
});
chrome.tabs.onUpdated.addListener(function(id, changeInfo) {
// Проверка состояния
if (IsActive()) {
var url = parseURL(changeInfo.url || '');
if (url) {
var supported = isSupportedTLD(url.tld);
console.info('BDNS: tab #' + id + ' updated to ' + (supported ? '' : 'un') + 'supported TLD, domain: ' + url.domain); //-
if (supported) {
tabSupport[id] = supported;
}
if (activeTab == id) {
// Passing tabId doesn't seem to stick in Chrome like it does in Firefox;
// button's state is not restored when switching tabs.
chrome.browserAction[!supported ? 'enable' : 'disable']();
}
}
}
});
chrome.browserAction.onClicked.addListener(function () {
chrome.tabs.create({
url: "https://blockchain-dns.info"
});
});
У меня получилось, но если сайт уже был посещён то после выключения на него можно зайти, и только после перезапуска браузера, оно перестаёт работать.
Как можно это исправить?