mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-27 20:03:45 +03:00
Craft light version manually
This commit is contained in:
parent
bfdedd10f7
commit
19a305a26d
|
@ -1,33 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
window.utils = {
|
||||
|
||||
areSettingsNotControlledFor(details) {
|
||||
|
||||
return ['controlled_by_other', 'not_controllable']
|
||||
.some( (prefix) => details.levelOfControl.startsWith(prefix) );
|
||||
|
||||
},
|
||||
|
||||
messages: {
|
||||
|
||||
searchSettingsForUrl(niddle) {
|
||||
|
||||
return 'chrome://settings/search#' + (chrome.i18n.getMessage(niddle) || niddle);
|
||||
|
||||
},
|
||||
|
||||
whichExtensionHtml() {
|
||||
|
||||
return chrome.i18n.getMessage('noControl') +
|
||||
` <a href="${ this.searchSettingsForUrl('proxy') }">
|
||||
${ chrome.i18n.getMessage('which') }
|
||||
</a>`;
|
||||
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
window.apis = {};
|
|
@ -0,0 +1,313 @@
|
|||
'use strict';
|
||||
|
||||
console.log('Started.');
|
||||
|
||||
window.state = {
|
||||
lastError: null,
|
||||
ifNotControllable: false,
|
||||
};
|
||||
|
||||
window.whichExtensionHtml = `
|
||||
|
||||
${chrome.i18n.getMessage('noControl')}
|
||||
<a href="chrome://settings/search#${chrome.i18n.getMessage('proxy')}">
|
||||
${chrome.i18n.getMessage('which')}
|
||||
</a>`;
|
||||
|
||||
const resetBadge = function resetBadge() {
|
||||
|
||||
okBadge('M');
|
||||
chrome.browserAction.setTitle({title: ''});
|
||||
|
||||
};
|
||||
|
||||
window.timeouted = (cb) => (...args) => window.setTimeout(() => cb(...args), 0);
|
||||
|
||||
const errorJsonReplacer = function errorJsonReplacer(key, value) {
|
||||
|
||||
// fooWindow.ErrorEvent !== barWindow.ErrorEvent
|
||||
if (!( value && value.constructor
|
||||
&& ['Error', 'Event'].some(
|
||||
(suff) => value.constructor.name.endsWith(suff)
|
||||
)
|
||||
)) {
|
||||
return value;
|
||||
}
|
||||
const alt = {};
|
||||
|
||||
Object.getOwnPropertyNames(value).forEach(function(key) {
|
||||
|
||||
alt[key] = value[key];
|
||||
|
||||
}, value);
|
||||
|
||||
for(const prop in value) {
|
||||
if (/^[A-Z]/.test(prop)) {
|
||||
// MOUSEMOVE, CLICK, KEYUP, NONE, etc.
|
||||
continue;
|
||||
}
|
||||
alt[prop] = value[prop];
|
||||
}
|
||||
|
||||
if (value.constructor.name === 'ErrorEvent') {
|
||||
for(const circularProp of
|
||||
[ // First line are circular props.
|
||||
'target', 'srcElement', 'path', 'currentTarget',
|
||||
'bubbles', 'cancelBubble', 'cancelable', 'composed',
|
||||
'defaultPrevented', 'eventPhase', 'isTrusted', 'returnValue',
|
||||
'timeStamp']) {
|
||||
delete alt[circularProp];
|
||||
}
|
||||
}
|
||||
|
||||
if (value.name) {
|
||||
alt.name = value.name;
|
||||
}
|
||||
|
||||
return alt;
|
||||
|
||||
}
|
||||
|
||||
const extName = chrome.runtime.getManifest().name;
|
||||
|
||||
chrome.notifications.onClicked.addListener( timeouted( (notId) => {
|
||||
|
||||
chrome.notifications.clear(notId);
|
||||
const err = window.state.lastError;
|
||||
err.extName = extName;
|
||||
const type = 'ext-error';
|
||||
const json = JSON.stringify(err, errorJsonReplacer, 0);
|
||||
const url = 'http://rebrand.ly/ac-error/?json=' + encodeURIComponent(json)
|
||||
+ (type ? '&type=' + encodeURIComponent(type) : '')
|
||||
+ '&version=' + chrome.runtime.getManifest().version;
|
||||
chrome.tabs.create(
|
||||
{url: url}
|
||||
);
|
||||
|
||||
}));
|
||||
|
||||
|
||||
const mayNotify = function mayNotify(
|
||||
id, title, errOrMessage,
|
||||
{
|
||||
icon = 'default-128.png',
|
||||
ifSticky = true,
|
||||
} = {}
|
||||
) {
|
||||
|
||||
const message = errOrMessage.message || errOrMessage.toString();
|
||||
chrome.notifications.create(
|
||||
id,
|
||||
{
|
||||
title: title,
|
||||
message: message,
|
||||
contextMessage:
|
||||
extName + ' ' + chrome.runtime.getManifest().version.replace(/\d+\.\d+\./g, ''),
|
||||
requireInteraction: ifSticky,
|
||||
type: 'basic',
|
||||
iconUrl: './icons/' + icon,
|
||||
isClickable: true,
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
window.installListenersOn = function installListenersOn(win, name, cb) {
|
||||
|
||||
win.addEventListener('error', (errEvent) => {
|
||||
|
||||
window.state.lastError = errEvent;
|
||||
console.warn(name + ':GLOBAL ERROR', errEvent);
|
||||
mayNotify('ext-error', 'Ошибка расширения!', errEvent, {icon: 'ext-error-128.png'});
|
||||
|
||||
});
|
||||
|
||||
win.addEventListener('unhandledrejection', (event) => {
|
||||
|
||||
console.warn(name + ': Unhandled rejection. Throwing error.');
|
||||
event.preventDefault();
|
||||
console.log('ev', event);
|
||||
throw event.reason;
|
||||
|
||||
});
|
||||
|
||||
if (cb) {
|
||||
// In most cases getBackgroundPage( (bg) => installListenersOn
|
||||
// Without setTimeout errors are swallowed, bug #357568
|
||||
timeouted(cb)();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
window.installListenersOn(window, 'BG');
|
||||
|
||||
const redBadge = function redBadge(msg) {
|
||||
|
||||
chrome.browserAction.setBadgeBackgroundColor({
|
||||
color: '#db4b2f',
|
||||
});
|
||||
chrome.browserAction.setBadgeText({
|
||||
text: msg,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const defaultColorPromise = new Promise( function (resolve) {
|
||||
|
||||
chrome.browserAction.getBadgeBackgroundColor({}, resolve);
|
||||
|
||||
});
|
||||
|
||||
const okBadge = function okBadge(msg) {
|
||||
|
||||
defaultColorPromise.then( function (defaultColor) {
|
||||
chrome.browserAction.setBadgeBackgroundColor({
|
||||
color: defaultColor,
|
||||
});
|
||||
chrome.browserAction.setBadgeText({
|
||||
text: msg,
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
const mandatory = (err) => {
|
||||
|
||||
throw new TypeError('This arg is required!');
|
||||
|
||||
};
|
||||
|
||||
const throwIfError = (err) => {
|
||||
|
||||
if (err) {
|
||||
throw new Error('Got error in cb!');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
const areSettingsNotControllableFor = function areSettingsNotControllable(details = mandatory()) {
|
||||
|
||||
state.ifNotControllable = ['controlled_by_other', 'not_controllable']
|
||||
.some( (pref) => details.levelOfControl.startsWith(pref) );
|
||||
|
||||
if (state.ifNotControllable) {
|
||||
console.warn('Failed, other extension is in control.');
|
||||
state.ifNotControlled = true;
|
||||
redBadge('xCTRL');
|
||||
chrome.browserAction.setTitle({title: 'Другое расширение контролирует прокси'});
|
||||
} else {
|
||||
console.log('Settings are under our control.');
|
||||
state.ifNotControlled = !details.levelOfControl.startsWith('controlled_by_this');
|
||||
resetBadge();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
chrome.proxy.settings.onChange.addListener( (details) => {
|
||||
|
||||
console.log('CHANGED prx');
|
||||
areSettingsNotControllableFor(details);
|
||||
|
||||
});
|
||||
|
||||
const updateControlState = function updateControlState(cb = mandatory()) {
|
||||
|
||||
chrome.proxy.settings.get({}, timeouted( (details) => {
|
||||
|
||||
areSettingsNotControllableFor(details);
|
||||
cb();
|
||||
|
||||
}));
|
||||
|
||||
};
|
||||
|
||||
const mayUpdatePac = function mayUpdatePac(cb = mandatory()) {
|
||||
|
||||
if (Date.now() < (localStorage.lastPacUpdateStamp || 0) + 12*60*60*1000 ) {
|
||||
console.log('Too early for an update.' );
|
||||
return cb();
|
||||
}
|
||||
|
||||
fetch('https://rebrand.ly/ac-light-pac').then(
|
||||
(res) => {
|
||||
|
||||
const status = res.status;
|
||||
if ( !( status >= 200 && status < 300 || status === 304 ) ) {
|
||||
return cb(new Error('Не удалось скачать скрипт, ошибка ' + status));
|
||||
}
|
||||
return res.text();
|
||||
|
||||
},
|
||||
cb
|
||||
).then( (pacData) => {
|
||||
|
||||
console.log('Updating PAC...');
|
||||
chrome.proxy.settings.set(
|
||||
{
|
||||
value: {
|
||||
mode: 'pac_script',
|
||||
pacScript: {
|
||||
// Use only with extension!
|
||||
data: pacData
|
||||
},
|
||||
},
|
||||
},
|
||||
timeouted(() => {
|
||||
|
||||
const err = chrome.runtime.lastError || chrome.extension.lastError;
|
||||
if(err) {
|
||||
console.log('Updated with error:', err);
|
||||
state.lastError = err;
|
||||
redBadge('ERR');
|
||||
chrome.browserAction.setTitle({title: 'Произошла ошибка'});
|
||||
setTimeout(resetBadge, 10000);
|
||||
return cb(err);
|
||||
}
|
||||
console.log('Updated, no errors.');
|
||||
localStorage.lastPacUpdateStamp = Date.now();
|
||||
updateControlState( () => {
|
||||
|
||||
if(state.ifNotControlled) {
|
||||
cb(new Error(window.whichExtensionHtml));
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})
|
||||
);
|
||||
|
||||
},
|
||||
cb
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
window.switchPac = function switchPac(onOff, cb = mandatory()) {
|
||||
|
||||
if(onOff !== 'off') {
|
||||
localStorage.onOff = 'on';
|
||||
chrome.browserAction.setIcon( {path: './icons/default-128.png'} );
|
||||
return mayUpdatePac(cb);
|
||||
}
|
||||
|
||||
chrome.proxy.settings.clear({}, timeouted(() => {
|
||||
|
||||
localStorage.lastPacUpdateStamp = 0;
|
||||
localStorage.onOff = 'off';
|
||||
chrome.browserAction.setIcon({
|
||||
path: './icons/default-grayscale-128.png',
|
||||
});
|
||||
cb();
|
||||
|
||||
}));
|
||||
|
||||
};
|
||||
|
||||
resetBadge();
|
||||
switchPac( localStorage.onOff, (err) => {
|
||||
|
||||
updateControlState(() => throwIfError(err));
|
||||
|
||||
});
|
|
@ -1,91 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
window.state = {
|
||||
lastError: null,
|
||||
ifNotControlled: false
|
||||
};
|
||||
|
||||
function redBadge(msg) {
|
||||
|
||||
window.chrome.browserAction.setBadgeBackgroundColor({
|
||||
color: '#db4b2f',
|
||||
});
|
||||
chrome.browserAction.setBadgeText({
|
||||
text: msg,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
let defaultColorPromise = new Promise( function (resolve) {
|
||||
|
||||
chrome.browserAction.getBadgeBackgroundColor({}, resolve);
|
||||
|
||||
});
|
||||
|
||||
function okBadge(msg) {
|
||||
|
||||
defaultColorPromise.then( function (defaultColor) {
|
||||
window.chrome.browserAction.setBadgeBackgroundColor({
|
||||
color: defaultColor,
|
||||
});
|
||||
chrome.browserAction.setBadgeText({
|
||||
text: msg,
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function checkControlFor(details) {
|
||||
|
||||
state.ifNotControlled = utils.areSettingsNotControlledFor(details);
|
||||
if (state.ifNotControlled) {
|
||||
console.warn('Failed, other extension is in control.');
|
||||
redBadge('xCTRL');
|
||||
} else {
|
||||
console.log('Successfuly set PAC in proxy settings..');
|
||||
okBadge('ok');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
chrome.proxy.settings.onChange.addListener( checkControlFor );
|
||||
|
||||
chrome.proxy.onProxyError.addListener((details) => {
|
||||
|
||||
console.error(details);
|
||||
//if (window.state.ifNotControlled) {
|
||||
// return;
|
||||
//}
|
||||
});
|
||||
|
||||
chrome.proxy.settings.set(
|
||||
{
|
||||
value: {
|
||||
mode: 'pac_script',
|
||||
pacScript: {
|
||||
/*
|
||||
Don't use in system configs! Because Win does poor caching.
|
||||
Url is encoded to counter abuse.
|
||||
Source: CloudFlare
|
||||
*/
|
||||
//url: 'https://anticensorship-russia.tk/generated-pac-scripts/on-switches-0.17.pac',
|
||||
//url: 'https://antizapret.prostovpn.org/proxy.pac',
|
||||
url: 'http://localhost:8080/on-switches-0.17.pac',
|
||||
mandatory: true
|
||||
//url: '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x73\x68\x69\x70\x2d\x72\x75\x73\x73\x69\x61\x2e\x74\x6b\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x6f\x6e\x2d\x73\x77\x69\x74\x63\x68\x65\x73\x2d\x30\x2e\x31\x37\x2e\x70\x61\x63',
|
||||
},
|
||||
},
|
||||
},
|
||||
function() {
|
||||
|
||||
const err = chrome.runtime.lastError || chrome.extension.lastError;
|
||||
if(err) {
|
||||
alert(333)
|
||||
redBadge('ERR');
|
||||
} else {
|
||||
alert(11);
|
||||
chrome.proxy.settings.get({}, checkControlFor);
|
||||
}
|
||||
|
||||
}
|
||||
);
|
|
@ -2,14 +2,39 @@
|
|||
|
||||
{
|
||||
|
||||
const createMenuLinkEntry = (title, tab2url) => chrome.contextMenus.create({
|
||||
let seqId = 0;
|
||||
|
||||
const createMenuLinkEntry = (title, tab2url) => {
|
||||
|
||||
const id = (++seqId).toString();
|
||||
|
||||
chrome.runtime.onInstalled.addListener(
|
||||
() => chrome.contextMenus.create({
|
||||
id: id,
|
||||
title: title,
|
||||
contexts: ['browser_action'],
|
||||
onclick:
|
||||
(menuInfo, tab) => Promise.resolve( tab2url( tab ) )
|
||||
.then( (url) => chrome.tabs.create({url: url}) ),
|
||||
contexts: ['browser_action']
|
||||
}, timeouted(() => {
|
||||
|
||||
const err = chrome.runtime.lastError;
|
||||
if(err) {
|
||||
console.warn('CTX MENU ERR', err);
|
||||
throw err;
|
||||
}
|
||||
|
||||
}))
|
||||
);
|
||||
|
||||
chrome.contextMenus.onClicked.addListener((info, tab) => {
|
||||
|
||||
if(info.menuItemId === id) {
|
||||
Promise.resolve( tab2url( tab ) )
|
||||
.then( (url) => chrome.tabs.create({url: url}) );
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
createMenuLinkEntry(
|
||||
'Сайт доступен из-за границы? Is up?',
|
||||
(tab) => `data:text/html;charset=utf8,<title>Запрашиваю...</title>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"extName": {
|
||||
"message": "Light Runet Censorship Bypass"
|
||||
"message": "Runet Censorship Bypass MICRO"
|
||||
},
|
||||
"extDesc": {
|
||||
"message": "Circumvent Russian Internet Censorship: https://rebrand.ly/ac-wiki"
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
|
@ -13,8 +13,6 @@
|
|||
|
||||
"permissions": [
|
||||
"proxy",
|
||||
"alarms",
|
||||
"storage",
|
||||
"<all_urls>",
|
||||
"tabs",
|
||||
"contextMenus",
|
||||
|
@ -22,10 +20,10 @@
|
|||
],
|
||||
|
||||
"background": {
|
||||
"persistent": true,
|
||||
"persistent": false,
|
||||
"scripts": [
|
||||
"00-init-apis.js",
|
||||
"12-set-pac-url.js"
|
||||
"00-set-pac.js",
|
||||
"40-context-menus.js"
|
||||
]
|
||||
},
|
||||
"browser_action": {
|
||||
|
|
|
@ -1,43 +1,111 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="display: none">
|
||||
<html style="display: none; will-change: display">
|
||||
<head>
|
||||
<title>Выбор провайдера PAC</title>
|
||||
<style>
|
||||
footer {
|
||||
display: block;
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
.hor-padded {
|
||||
padding-left: 1.4em;
|
||||
padding-right: 1.4em;
|
||||
}
|
||||
header, .control-row {
|
||||
white-space: nowrap;
|
||||
word-break: keep-all;
|
||||
}
|
||||
footer {
|
||||
input[type="radio"], label {
|
||||
cursor: pointer;
|
||||
}
|
||||
.control-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 2em 1em 1em;
|
||||
}
|
||||
header {
|
||||
padding-bottom: 0.4em;
|
||||
}
|
||||
hr {
|
||||
border-width: 1px 0 0 0;
|
||||
margin: 0.6em 0;
|
||||
margin: 0 0 0.6em 0;
|
||||
padding: 0;
|
||||
}
|
||||
.if-not-controlled {
|
||||
.greeting {
|
||||
display: none;
|
||||
color: red;
|
||||
}
|
||||
:root:not(.if-error) .greeting {
|
||||
display: block;
|
||||
}
|
||||
:root:not(.if-not-controlled) .if-not-controlled,
|
||||
:root:not(.if-error) .if-error
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
.ver-padded {
|
||||
padding-top: 1em;
|
||||
padding-bottom: 1em;
|
||||
}
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
.warn {
|
||||
background-color: red;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
|
||||
border-bottom: 1px solid #bfbfbf;
|
||||
}
|
||||
.warn a {
|
||||
color: white;
|
||||
}
|
||||
header, main {
|
||||
border-bottom: 1px solid #bfbfbf;
|
||||
}
|
||||
ul, ol {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
li, li > * {
|
||||
vertical-align: middle;
|
||||
}
|
||||
#pac-switch {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
#pac-switch li {
|
||||
display: inline-block;
|
||||
padding: 1em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
Обход блокировок Рунета облегчённый
|
||||
<section class="if-not-controlled warn hor-padded ver-padded centered" id="which-extension"></section>
|
||||
<header class="hor-padded">
|
||||
<h2>Обход блокировок Рунета МИКРО</h2>
|
||||
</header>
|
||||
<span class="if-not-controlled">
|
||||
<span id="which-extension"></span>
|
||||
<hr style="border-color: red; border-style: solid;"/>
|
||||
</span>
|
||||
<span class="if-error">
|
||||
<span id="last-error"></span>
|
||||
<hr style="border-color: red; border-style: solid;"/>
|
||||
</span>
|
||||
<hr/>
|
||||
<main class="hor-padded ver-padded">
|
||||
<section>
|
||||
<ol id="pac-switch">
|
||||
<li><input type="radio" value="on" id="pac-on" name="pac-switch"/> <label for="pac-on">ON</label></li>
|
||||
<li><input type="radio" value="off" id="pac-off" name="pac-switch"/> <label for="pac-off">OFF</label></li>
|
||||
</ol>
|
||||
</section>
|
||||
</main>
|
||||
<footer>
|
||||
<input type="button" value="Готово" class="close-button"> <a href="../debug/index.html" style="text-decoration: none; margin-left: 1em;">Полная версия расширения</a>
|
||||
<section id="status" class="greeting hor-padded" style="padding-top: 0.5em; padding-bottom: 0">
|
||||
Данная версия предназначена для слабых компьютеров, она не сообщает о разблокировках и не имеет настроек.
|
||||
</section>
|
||||
<section class="if-error centered">
|
||||
<div>Ошибка!</div>
|
||||
<span id="last-error"></span>
|
||||
</section>
|
||||
<div class="control-row">
|
||||
<input type="button" value="Готово" class="close-button"> <a href="../debug/index.html" style="text-decoration: none; margin-left: 1em;">Полная версия расширения</a>
|
||||
</div>
|
||||
</footer>
|
||||
<script src="./index.js"></script>
|
||||
<script src="./keep-links-clickable.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,30 +4,58 @@ chrome.runtime.getBackgroundPage( (backgroundPage) => {
|
|||
|
||||
const state = backgroundPage.state;
|
||||
|
||||
if( state.ifNotControlled ) {
|
||||
document.getElementById('which-extension').innerHTML
|
||||
= backgroundPage.utils.messages.whichExtensionHtml();
|
||||
document.querySelectorAll('.if-not-controlled').forEach( (node) => {
|
||||
|
||||
node.style.display = 'block';
|
||||
|
||||
});
|
||||
if( state.ifNotControllable ) {
|
||||
document.getElementById('which-extension').innerHTML = backgroundPage.whichExtensionHtml;
|
||||
document.documentElement.classList.add('if-not-controlled');
|
||||
}
|
||||
|
||||
if ( state.lastError) {
|
||||
|
||||
document.querySelectorAll('.if-error').forEach( (node) => {
|
||||
const err = ['message', 'stack', 'name'].reduce((acc, prop) => {
|
||||
|
||||
node.style.display = 'block';
|
||||
acc[prop] = state.lastError[prop];
|
||||
return acc;
|
||||
|
||||
}, {});
|
||||
document.getElementById('last-error').innerHTML = JSON.stringify(err);
|
||||
document.documentElement.classList.add('if-error');
|
||||
|
||||
});
|
||||
document.getElementById('last-error').innerHTML = state.lastError;
|
||||
}
|
||||
|
||||
document.documentElement.style.display = '';
|
||||
const setStatusTo = (msg) => {
|
||||
document.getElementById('status').innerHTML = msg;
|
||||
};
|
||||
|
||||
if(localStorage.onOff === 'on') {
|
||||
document.getElementById('pac-on').checked = true;
|
||||
} else {
|
||||
document.getElementById('pac-off').checked = true;
|
||||
}
|
||||
document.getElementById('pac-switch').onclick = function(event) {
|
||||
|
||||
if(event.target.tagName !== 'INPUT') {
|
||||
return true;
|
||||
}
|
||||
setStatusTo('Ждите...');
|
||||
const cb = () => {
|
||||
|
||||
event.target.checked = true;
|
||||
setStatusTo('Готово!');
|
||||
|
||||
};
|
||||
if (event.target.id === 'pac-on') {
|
||||
backgroundPage.switchPac('on', cb);
|
||||
} else {
|
||||
backgroundPage.switchPac('off', cb);
|
||||
}
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
// CLOSE BUTTON
|
||||
|
||||
document.querySelector('.close-button').onclick = () => window.close();
|
||||
|
||||
document.documentElement.style.display = '';
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
/*
|
||||
In popup links are not clickable at all, fix it.
|
||||
On other pages "chrome://" links are not clickable, fix it.
|
||||
Use only if really required because of performance penalty.
|
||||
*/
|
||||
{
|
||||
|
||||
const target = document.documentElement;
|
||||
|
||||
const updateLinks = () => {
|
||||
|
||||
const links = document.querySelectorAll('a:not([href=""])');
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
const ln = links[i];
|
||||
const location = ln.href;
|
||||
ln.onclick = function() {
|
||||
|
||||
chrome.tabs.create({active: !this.dataset.inBg, url: location});
|
||||
return false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
new MutationObserver( updateLinks )
|
||||
.observe(target, {
|
||||
attributes: true,
|
||||
subtree: true,
|
||||
childList: true,
|
||||
characterData: false,
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', updateLinks);
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user