Refactor err handlers, unixify newlines, restructure files

This commit is contained in:
Ilya Ig. Petrov 2016-12-01 07:01:20 -08:00
parent 257495168c
commit 6750872ea5
11 changed files with 357 additions and 206 deletions

View File

@ -1,3 +1,7 @@
# Dev
Linting JS: `npm run lint`
# О расширении
Обход интернет-цензуры в России пока что не является преступлением.

View File

@ -1,56 +0,0 @@
'use strict';
{
const extName = chrome.runtime.getManifest().name;
const notify = (
id,
title,
message,
icon = 'default-128.png',
context = extName
) => chrome.notifications.create(
id,
{
title: title,
message: message,
contextMessage: context,
requireInteraction: true,
type: 'basic',
iconUrl: './icons/' + icon,
}
);
window.addEventListener('error', (err) => {
console.warn('Global error');
notify('Unhandled error', 'Unhandled error', JSON.stringify(err),
'ext-error-128.png');
});
window.addEventListener('unhandledrejection', (event) => {
console.warn('Unhandled rejection. Throwing error.');
event.preventDefault();
throw event.reason;
});
chrome.proxy.onProxyError.addListener((details) => {
console.warn('PAC ERROR:', details);
notify('pac-error', ' PAC !', JSON.stringify(details),
'pac-error-128.png' );
});
chrome.proxy.settings.onChange.addListener((details) => {
console.log('Proxy settings changed.', details);
// const ifOther = details.levelOfControl.startsWith('controlled_by_other');
notify('Proxy change', 'Proxy changed', JSON.stringify(details),
'no-control-128.png');
});
}

View File

@ -0,0 +1,14 @@
'use strict';
window.utils = {
areSettingsNotControlledFor(details) {
return ['controlled_by_other', 'not_controllable']
.some( (prefix) => details.levelOfControl.startsWith(prefix) );
},
};
window.apis = {};

View File

@ -0,0 +1,148 @@
'use strict';
{ // Private namespace
const handlersState = function(key, value) {
console.log(key, value, '!');
key = 'handlers-' + key;
if (value === null) {
return localStorage.removeItem(key);
}
if (value === undefined) {
const item = localStorage.getItem(key);
return item && JSON.parse(item);
}
if (value instanceof Date) {
throw new TypeError('Converting Date format to JSON is not supported.');
}
localStorage.setItem(key, JSON.stringify(value));
};
const ifPrefix = 'if-on-';
window.apis.errorHandlers = {
getEventsMap() {
return new Map([
['pac-error', 'ошибки PAC скриптов'],
['ext-error', 'ошибки расширения'],
['no-control', 'утеря контроля над настройками'],
]);
},
switch(onOffStr, eventName) {
if (!['on', 'off'].includes(onOffStr)) {
throw new TypeError('First argument bust be "on" or "off".');
}
for(
const name of (eventName ? [eventName] : this.getEventsMap().keys() )
) {
handlersState( ifPrefix + name, onOffStr === 'on' ? 'on' : null );
}
},
isOn(eventName) {
return handlersState( ifPrefix + eventName);
},
ifNotControlled: null,
isNotControlled(details) {
this.ifNotControlled = window.utils.areSettingsNotControlledFor( details );
if (this.ifNotControlled) {
chrome.browserAction.disable();
} else {
chrome.browserAction.enable();
}
return this.ifNotControlled;
},
};
}
// INIT
chrome.proxy.settings.get(
{},
(details) => window.apis.errorHandlers.isNotControlled(details)
);
{
const extName = chrome.runtime.getManifest().name;
const mayNotify = function(
id, title, message,
icon = 'default-128.png',
context = extName
) {
if ( !window.apis.errorHandlers.isOn(id) ) {
return;
}
chrome.notifications.create(
id,
{
title: title,
message: message,
contextMessage: context,
requireInteraction: true,
type: 'basic',
iconUrl: './icons/' + icon,
isClickable: true,
}
);
};
window.addEventListener('error', (err) => {
console.warn('GLOBAL ERROR', err);
mayNotify('ext-error', 'Unhandled error', JSON.stringify(err),
'ext-error-128.png');
});
window.addEventListener('unhandledrejection', (event) => {
console.warn('Unhandled rejection. Throwing error.');
event.preventDefault();
throw event.reason;
});
chrome.proxy.onProxyError.addListener((details) => {
if (window.apis.errorHandlers.ifNoControl) {
return;
}
console.warn('PAC ERROR', details);
mayNotify('pac-error', ' PAC !', JSON.stringify(details),
'pac-error-128.png' );
});
chrome.proxy.settings.onChange.addListener((details) => {
console.log('Proxy settings changed.', details);
const noCon = 'no-control';
if ( window.apis.errorHandlers.isNotControlled(details) ) {
mayNotify(noCon, 'Proxy changed', JSON.stringify(details),
'no-control-128.png');
} else {
chrome.notifications.clear( noCon );
}
});
}

View File

@ -9,39 +9,17 @@
*/
/*
In background scripts use window.antiCensorRu public variables.
In pages window.antiCensorRu is not accessible,
In background scripts use window.apis.antiCensorRu public variables.
In pages window.apis.antiCensorRu is not accessible,
use chrome.runtime.getBackgroundPage(..),
extension.getBackgroundPage is deprecated
*/
{ // Private namespace starts.
window.antiCensorRu = {
window.apis.antiCensorRu = {
version: chrome.runtime.getManifest().version,
fixErrorsContext() {
/* `setTimeout` changes context of execution from other window
(e.g. popup) to background window, so we may catch errors
in bg error handlers.
More: https://bugs.chromium.org/p/chromium/issues/detail?id=357568
*/
for(const prop of Object.keys(this)) {
if ( typeof(this[prop]) === 'function' ) {
const method = this[prop];
this[prop] = function(...args) {
setTimeout(method.bind(this, ...args), 0);
};
}
}
},
throw() {
throw new Error('Artificial error');
},
pacProviders: {
Антизапрет: {
pacUrl: 'https://antizapret.prostovpn.org/proxy.pac',
@ -293,6 +271,7 @@
}
)
);
},
};
@ -307,8 +286,7 @@
E.g. install window may fail to open or be closed by user accidentally.
In such case extension _should_ try to work on default parameters.
*/
const antiCensorRu = window.antiCensorRu;
antiCensorRu.fixErrorsContext();
const antiCensorRu = window.apis.antiCensorRu;
chrome.alarms.onAlarm.addListener(
(alarm) => {
@ -393,6 +371,7 @@
* Changed storage.ifNotInstalled to storage.ifFirstInstall
* Added storage.lastPacUpdateStamp
**/
});
function asyncLogGroup(...args) {
@ -406,6 +385,7 @@
cb(...cbArgs);
};
}
function checkChromeError(betterStack) {
@ -458,8 +438,7 @@
}
chrome.proxy.settings.get({}, (details) => {
const ifThis = details.levelOfControl.startsWith('controlled_by_this');
if (!ifThis) {
if ( window.utils.areSettingsNotControlledFor( details ) ) {
console.warn('Failed, other extension is in control.');
return cb({clarification: {message: 'Настройки прокси контролирует другое расширение. <a href="chrome://settings/search#proxy">Какое?</a>'}});
}
@ -500,6 +479,7 @@
}
);
}
function getIpsFor(host, cb) {
@ -600,6 +580,7 @@
}
)
);
}
function setPacScriptFromProvider(provider, cb) {
@ -625,6 +606,7 @@
}
);
}
}

View File

@ -0,0 +1,23 @@
'use strict';
/* `setTimeout` changes context of execution from other window
(e.g. popup) to background window, so we may catch errors
in bg error handlers.
More: https://bugs.chromium.org/p/chromium/issues/detail?id=357568
*/
// Fix error context of methods of all APIs.
for(const api of Object.keys(window.apis)) {
for(const prop of Object.keys(api)) {
if ( typeof(api[prop]) !== 'function' ) {
continue;
}
const method = api[prop];
api[prop] = function(...args) {
setTimeout(method.bind(this, ...args), 0);
};
}
}

View File

@ -14,6 +14,8 @@
Crazy parallel Chrome.
**/
const antiCensorRu = window.apis.antiCensorRu;
window.chrome.browserAction.setBadgeBackgroundColor({
color: '#db4b2f',
});
@ -66,7 +68,7 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
(title) => {
const ifTitleSetAlready = /\n/.test(title);
const proxyHost = window.antiCensorRu.getPacProvider()
const proxyHost = antiCensorRu.getPacProvider()
.proxyIps[requestDetails.ip];
const hostname = new URL( requestDetails.url ).hostname;
@ -141,7 +143,7 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
function isProxiedAndInformed(requestDetails) {
if ( !(requestDetails.ip
&& window.antiCensorRu.isProxied( requestDetails.ip )) ) {
&& antiCensorRu.isProxied( requestDetails.ip )) ) {
return false;
}

View File

@ -21,7 +21,7 @@
"notifications"
],
"background": {
"scripts": ["0-error-handlers.js", "1-sync-pac-script-with-pac-provider.js", "2-block-informer.js", "3-context-menus.js"]
"scripts": ["00-init-apis.js", "11-api-error-handlers.js", "12-api-sync-pac-script-with-pac-provider.js", "20-api-fixes.js", "30-block-informer.js", "40-context-menus.js"]
},
"browser_action": {
"default_title": "Этот сайт благословлён",

View File

@ -3,6 +3,9 @@
<head>
<title>Выбор провайдера PAC</title>
<style>
label {
user-select: none;
}
ul {
list-style-type: none;
padding: 0;
@ -39,6 +42,12 @@
footer {
margin: 2em 1em 1em;
}
hr {
border-width: 1px 0 0 0;
}
#configs-panel > header {
margin: 0.6em 0 0.4em;
}
</style>
</head>
<body>
@ -49,6 +58,12 @@
Обновлялись: <span class="update-date">...</span>
</div>
<div id="status">Загрузка...</div>
<hr/>
<div id="configs-panel">
<header>Я ❤️ уведомления:</header>
<ul id="list-of-handlers">
</ul>
</div>
<footer>
<input type="button" value="Готово" class="close-button">&nbsp;<a href="../debug/index.html" style="text-decoration: none; margin-left: 1em;">Отладка</a>
</footer>

View File

@ -16,7 +16,7 @@ chrome.runtime.getBackgroundPage( (backgroundPage) => {
};
const antiCensorRu = backgroundPage.antiCensorRu;
const antiCensorRu = backgroundPage.apis.antiCensorRu;
// SET DATE
@ -182,6 +182,25 @@ chrome://extensions</a>
};
}
const conpanel = document.getElementById('list-of-handlers');
backgroundPage.apis.errorHandlers.getEventsMap().forEach( (value, name) => {
const li = document.createElement('li');
li.innerHTML = `
<input type="checkbox" id="if-on-${name}"/>
<label for="if-on-${name}">${value}</label>`;
const box = li.querySelector('input');
box.checked = backgroundPage.apis.errorHandlers.isOn(name);
box.onclick = function() {
const id = this.id.replace('if-on-', '');
backgroundPage.apis.errorHandlers.switch(this.checked ? 'on' : 'off', id);
};
conpanel.appendChild(li);
});
setStatusTo('');
if (antiCensorRu.ifFirstInstall) {
const id = antiCensorRu.currentPacProviderKey || 'none';