mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-24 02:13:43 +03:00
Restyle, scope vars/names out of window
This commit is contained in:
parent
05c6deadf8
commit
1ef480acd1
|
@ -13,518 +13,526 @@
|
||||||
use chrome.runtime.getBackgroundPage(..),
|
use chrome.runtime.getBackgroundPage(..),
|
||||||
extension.getBackgroundPage is deprecated
|
extension.getBackgroundPage is deprecated
|
||||||
*/
|
*/
|
||||||
|
{ // Private namespace starts.
|
||||||
|
|
||||||
window.antiCensorRu = {
|
window.antiCensorRu = {
|
||||||
|
|
||||||
version: chrome.runtime.getManifest().version,
|
version: chrome.runtime.getManifest().version,
|
||||||
|
|
||||||
pacProviders: {
|
pacProviders: {
|
||||||
Антизапрет: {
|
Антизапрет: {
|
||||||
pacUrl: 'https://antizapret.prostovpn.org/proxy.pac',
|
pacUrl: 'https://antizapret.prostovpn.org/proxy.pac',
|
||||||
proxyHosts: ['proxy.antizapret.prostovpn.org'],
|
proxyHosts: ['proxy.antizapret.prostovpn.org'],
|
||||||
proxyIps: {
|
proxyIps: {
|
||||||
'195.123.209.38': 'proxy.antizapret.prostovpn.org',
|
'195.123.209.38': 'proxy.antizapret.prostovpn.org',
|
||||||
'2a02:27ac::10': 'proxy.antizapret.prostovpn.org'
|
'2a02:27ac::10': 'proxy.antizapret.prostovpn.org'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Антиценз: {
|
||||||
|
pacUrl: 'https://config.anticenz.org/proxy.pac',
|
||||||
|
proxyHosts: ['gw2.anticenz.org'],
|
||||||
|
proxyIps: {
|
||||||
|
'5.196.220.114': 'gw2.anticenz.org'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Оба_и_на_свитчах: {
|
||||||
|
//pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0akpCOURNS2VCTmc', // 0.14
|
||||||
|
pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0bzNUR2F4RF8wOU0', // 0.15
|
||||||
|
proxyHosts: ['proxy.antizapret.prostovpn.org', 'gw2.anticenz.org'],
|
||||||
|
proxyIps: {
|
||||||
|
'195.123.209.38': 'proxy.antizapret.prostovpn.org',
|
||||||
|
'2a02:27ac::10': 'proxy.antizapret.prostovpn.org',
|
||||||
|
'5.196.220.114': 'gw2.anticenz.org'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Антиценз: {
|
|
||||||
pacUrl: 'https://config.anticenz.org/proxy.pac',
|
_currentPacProviderKey: 'Оба_и_на_свитчах',
|
||||||
proxyHosts: ['gw2.anticenz.org'],
|
|
||||||
proxyIps: {
|
get currentPacProviderKey() { return this._currentPacProviderKey },
|
||||||
'5.196.220.114': 'gw2.anticenz.org'
|
set currentPacProviderKey(newKey) {
|
||||||
}
|
|
||||||
|
if (newKey && !this.pacProviders[newKey])
|
||||||
|
throw new IllegalArgumentException('No provider for key:' + newKey);
|
||||||
|
this._currentPacProviderKey = newKey;
|
||||||
},
|
},
|
||||||
Оба_и_на_свитчах: {
|
|
||||||
//pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0akpCOURNS2VCTmc', // 0.14
|
|
||||||
pacUrl: 'https://drive.google.com/uc?export=download&id=0B-ZCVSvuNWf0bzNUR2F4RF8wOU0', // 0.15
|
|
||||||
proxyHosts: ['proxy.antizapret.prostovpn.org', 'gw2.anticenz.org'],
|
|
||||||
proxyIps: {
|
|
||||||
'195.123.209.38': 'proxy.antizapret.prostovpn.org',
|
|
||||||
'2a02:27ac::10': 'proxy.antizapret.prostovpn.org',
|
|
||||||
'5.196.220.114': 'gw2.anticenz.org'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_currentPacProviderKey: 'Оба_и_на_свитчах',
|
get pacProvider() { return this.pacProviders[this.currentPacProviderKey] },
|
||||||
|
|
||||||
get currentPacProviderKey() { return this._currentPacProviderKey },
|
/*
|
||||||
set currentPacProviderKey(newKey) {
|
Is it the first time extension installed? Do something, e.g. initiate PAC sync.
|
||||||
|
*/
|
||||||
|
ifFirstInstall: false,
|
||||||
|
lastPacUpdateStamp: 0,
|
||||||
|
|
||||||
if (newKey && !this.pacProviders[newKey])
|
_periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта Антизапрет',
|
||||||
throw new IllegalArgumentException('No provider for key:' + newKey);
|
|
||||||
this._currentPacProviderKey = newKey;
|
|
||||||
},
|
|
||||||
|
|
||||||
get pacProvider() { return this.pacProviders[this.currentPacProviderKey] },
|
pushToStorage(cb) {
|
||||||
|
|
||||||
/*
|
console.log('Pushing to storage...');
|
||||||
Is it the first time extension installed? Do something, e.g. initiate PAC sync.
|
|
||||||
*/
|
|
||||||
ifFirstInstall: false,
|
|
||||||
lastPacUpdateStamp: 0,
|
|
||||||
|
|
||||||
_periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта Антизапрет',
|
// Copy only settable properties (except functions).
|
||||||
|
const onlySettable = {};
|
||||||
pushToStorage(cb) {
|
for(const key of Object.keys(this)) {
|
||||||
|
if (Object.getOwnPropertyDescriptor(this, key).writable && typeof(this[key]) !== 'function') {
|
||||||
console.log('Pushing to storage...');
|
onlySettable[key] = this[key];
|
||||||
|
|
||||||
// Copy only settable properties (except functions).
|
|
||||||
const onlySettable = {};
|
|
||||||
for(const key of Object.keys(this)) {
|
|
||||||
if (Object.getOwnPropertyDescriptor(this, key).writable && typeof(this[key]) !== 'function') {
|
|
||||||
onlySettable[key] = this[key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return chrome.storage.local.clear(
|
|
||||||
() => chrome.storage.local.set(
|
|
||||||
onlySettable,
|
|
||||||
chromified(cb, onlySettable)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
pullFromStorage(cb) {
|
|
||||||
|
|
||||||
chrome.storage.local.get(null, (storage) => {
|
|
||||||
|
|
||||||
const err = checkChromeError();
|
|
||||||
if (!err) {
|
|
||||||
console.log('Pulled from storage:', storage);
|
|
||||||
for(const key of Object.keys(storage)) {
|
|
||||||
this[key] = storage[key];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Synced with storage, any callback?', !!cb);
|
return chrome.storage.local.clear(
|
||||||
return cb && cb(err, storage);
|
() => chrome.storage.local.set(
|
||||||
|
onlySettable,
|
||||||
|
chromified(cb, onlySettable)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
pullFromStorage(cb) {
|
||||||
|
|
||||||
|
chrome.storage.local.get(null, (storage) => {
|
||||||
|
|
||||||
|
const err = checkChromeError();
|
||||||
|
if (!err) {
|
||||||
|
console.log('Pulled from storage:', storage);
|
||||||
|
for(const key of Object.keys(storage)) {
|
||||||
|
this[key] = storage[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Synced with storage, any callback?', !!cb);
|
||||||
|
return cb && cb(err, storage);
|
||||||
|
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
syncWithPacProvider(cb) {
|
||||||
|
|
||||||
|
cb = asyncLogGroup('Syncing with PAC provider...', cb);
|
||||||
|
if (!this.pacProvider) {
|
||||||
|
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
|
||||||
|
}
|
||||||
|
|
||||||
|
const pacSetPromise = new Promise(
|
||||||
|
(resolve, reject) => setPacScriptFromProvider(
|
||||||
|
this.pacProvider,
|
||||||
|
(err, res) => {
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
this.lastPacUpdateStamp = Date.now();
|
||||||
|
this.ifFirstInstall = false;
|
||||||
|
this.setAlarms();
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolve([err, res]);
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const ipsPromise = new Promise(
|
||||||
|
(resolve, reject) => updatePacProxyIps(
|
||||||
|
this.pacProvider,
|
||||||
|
(ipsError) => {
|
||||||
|
|
||||||
|
if (ipsError && ipsError.clarification) {
|
||||||
|
ipsError.clarification.ifNotCritical = true;
|
||||||
|
}
|
||||||
|
return resolve([ipsError]);
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Promise.all([pacSetPromise, ipsPromise]).then(
|
||||||
|
([[pacErr, pacRes], [ipsErr]]) => {
|
||||||
|
|
||||||
|
if (pacErr && ipsErr) {
|
||||||
|
return cb(pacErr, pacRes);
|
||||||
|
}
|
||||||
|
return cb(pacErr || ipsErr);
|
||||||
|
this.pushToStorage(
|
||||||
|
(pushErr) => cb(pacErr || ipsErr || pushErr, pacRes)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_pacUpdatePeriodInMinutes: 4*60,
|
||||||
|
|
||||||
|
setAlarms() {
|
||||||
|
|
||||||
|
let nextUpdateMoment = this.lastPacUpdateStamp + this._pacUpdatePeriodInMinutes*60*1000;
|
||||||
|
const now = Date.now();
|
||||||
|
if (nextUpdateMoment < now) {
|
||||||
|
nextUpdateMoment = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log( 'Next PAC update is scheduled on', new Date(nextUpdateMoment).toLocaleString('ru-RU') );
|
||||||
|
|
||||||
|
chrome.alarms.create(
|
||||||
|
this._periodicUpdateAlarmReason,
|
||||||
|
{
|
||||||
|
when: nextUpdateMoment,
|
||||||
|
periodInMinutes: this._pacUpdatePeriodInMinutes
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return nextUpdateMoment === now; // ifAlarmTriggered. May be changed in the future.
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
installPac(key, cb) {
|
||||||
|
|
||||||
|
console.log('Installing PAC');
|
||||||
|
if(typeof(key) === 'function') {
|
||||||
|
cb = key;
|
||||||
|
key = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(key) {
|
||||||
|
this.currentPacProviderKey = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.syncWithPacProvider(cb);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
clearPac(cb) {
|
||||||
|
|
||||||
|
cb = asyncLogGroup('Cearing alarms and PAC...', cb);
|
||||||
|
chrome.alarms.clearAll(
|
||||||
|
() => chrome.proxy.settings.clear(
|
||||||
|
{},
|
||||||
|
() => {
|
||||||
|
|
||||||
|
const err = checkChromeError();
|
||||||
|
if (err) {
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
this.currentPacProviderKey = undefined;
|
||||||
|
return this.pushToStorage(cb);
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
|
||||||
|
chrome.storage.local.get(null, (oldStorage) => {
|
||||||
|
|
||||||
|
console.log('Init on storage:', oldStorage);
|
||||||
|
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
|
||||||
|
|
||||||
|
if (!antiCensorRu.ifFirstInstall) {
|
||||||
|
// LAUNCH, RELOAD, UPDATE
|
||||||
|
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
|
||||||
|
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
|
||||||
|
console.log( 'Last PAC update was on', new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU') );
|
||||||
|
}
|
||||||
|
|
||||||
|
chrome.alarms.onAlarm.addListener(
|
||||||
|
(alarm) => {
|
||||||
|
|
||||||
|
if (alarm.name === antiCensorRu._periodicUpdateAlarmReason) {
|
||||||
|
console.log('Periodic PAC update triggered:', new Date().toLocaleString('ru-RU'));
|
||||||
|
antiCensorRu.syncWithPacProvider(/* Swallows errors. */);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
console.log('Alarm listener installed. We won\'t miss any PAC update.');
|
||||||
|
|
||||||
|
window.addEventListener('online', () => {
|
||||||
|
|
||||||
|
console.log('We are online, checking periodic updates...');
|
||||||
|
antiCensorRu.setAlarms();
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
|
|
||||||
syncWithPacProvider(cb) {
|
if (antiCensorRu.ifFirstInstall) {
|
||||||
|
// INSTALL
|
||||||
cb = asyncLogGroup('Syncing with PAC provider...', cb);
|
console.log('Installing...');
|
||||||
if (!this.pacProvider) {
|
return chrome.runtime.openOptionsPage();
|
||||||
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const pacSetPromise = new Promise(
|
if (!antiCensorRu.pacProvider) {
|
||||||
(resolve, reject) => setPacScriptFromProvider(
|
return console.log('No PAC provider set. Do nothing.');
|
||||||
this.pacProvider,
|
/*
|
||||||
(err, res) => {
|
In case of UPDATE:
|
||||||
|
1. new providers will still be shown.
|
||||||
if (!err) {
|
2. new version won't be pushed to storage
|
||||||
this.lastPacUpdateStamp = Date.now();
|
*/
|
||||||
this.ifFirstInstall = false;
|
|
||||||
this.setAlarms();
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve([err, res]);
|
|
||||||
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const ipsPromise = new Promise(
|
|
||||||
(resolve, reject) => updatePacProxyIps(
|
|
||||||
this.pacProvider,
|
|
||||||
(ipsError) => {
|
|
||||||
|
|
||||||
if (ipsError && ipsError.clarification) {
|
|
||||||
ipsError.clarification.ifNotCritical = true;
|
|
||||||
}
|
|
||||||
return resolve([ipsError]);
|
|
||||||
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
Promise.all([pacSetPromise, ipsPromise]).then(
|
|
||||||
([[pacErr, pacRes], [ipsErr]]) => {
|
|
||||||
|
|
||||||
if (pacErr && ipsErr) {
|
|
||||||
return cb(pacErr, pacRes);
|
|
||||||
}
|
|
||||||
return cb(pacErr || ipsErr);
|
|
||||||
this.pushToStorage(
|
|
||||||
(pushErr) => cb(pacErr || ipsErr || pushErr, pacRes)
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
_pacUpdatePeriodInMinutes: 4*60,
|
|
||||||
|
|
||||||
setAlarms() {
|
|
||||||
|
|
||||||
let nextUpdateMoment = this.lastPacUpdateStamp + this._pacUpdatePeriodInMinutes*60*1000;
|
|
||||||
const now = Date.now();
|
|
||||||
if (nextUpdateMoment < now)
|
|
||||||
nextUpdateMoment = now;
|
|
||||||
|
|
||||||
console.log( 'Next PAC update is scheduled on', new Date(nextUpdateMoment).toLocaleString('ru-RU') );
|
|
||||||
|
|
||||||
chrome.alarms.create(
|
|
||||||
this._periodicUpdateAlarmReason,
|
|
||||||
{
|
|
||||||
when: nextUpdateMoment,
|
|
||||||
periodInMinutes: this._pacUpdatePeriodInMinutes
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return nextUpdateMoment === now; // ifAlarmTriggered. May be changed in the future.
|
|
||||||
},
|
|
||||||
|
|
||||||
installPac(key, cb) {
|
|
||||||
|
|
||||||
console.log('Installing PAC');
|
|
||||||
if(typeof(key) === 'function') {
|
|
||||||
cb = key;
|
|
||||||
key = undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(key) {
|
/*
|
||||||
this.currentPacProviderKey = key;
|
1. There is no way to check that chrome.runtime.onInstalled wasn't fired except timeout.
|
||||||
|
Otherwise we could put storage migration code only there.
|
||||||
|
2. We have to check storage for migration before using it.
|
||||||
|
Better on each launch then on each pull.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const ifAlarmTriggered = antiCensorRu.setAlarms();
|
||||||
|
|
||||||
|
if (antiCensorRu.version === oldStorage.version) {
|
||||||
|
// LAUNCH, RELOAD, ENABLE
|
||||||
|
antiCensorRu.pacProviders = oldStorage.pacProviders;
|
||||||
|
return console.log('Extension launched, reloaded or enabled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.syncWithPacProvider(cb);
|
// UPDATE & MIGRATION
|
||||||
|
console.log('Extension updated.');
|
||||||
},
|
if (!ifAlarmTriggered) {
|
||||||
|
antiCensorRu.pushToStorage(/* Swallows errors. */);
|
||||||
clearPac(cb) {
|
|
||||||
|
|
||||||
cb = asyncLogGroup('Cearing alarms and PAC...', cb);
|
|
||||||
chrome.alarms.clearAll(
|
|
||||||
() => chrome.proxy.settings.clear(
|
|
||||||
{},
|
|
||||||
() => {
|
|
||||||
|
|
||||||
const err = checkChromeError();
|
|
||||||
if (err) {
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
this.currentPacProviderKey = undefined;
|
|
||||||
return this.pushToStorage(cb);
|
|
||||||
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE
|
|
||||||
chrome.storage.local.get(null, (oldStorage) => {
|
|
||||||
|
|
||||||
console.log('Init on storage:', oldStorage);
|
|
||||||
antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0;
|
|
||||||
|
|
||||||
if (!antiCensorRu.ifFirstInstall) {
|
|
||||||
// LAUNCH, RELOAD, UPDATE
|
|
||||||
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
|
|
||||||
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
|
|
||||||
console.log( 'Last PAC update was on', new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU') );
|
|
||||||
}
|
|
||||||
|
|
||||||
chrome.alarms.onAlarm.addListener(
|
|
||||||
(alarm) => {
|
|
||||||
|
|
||||||
if (alarm.name === antiCensorRu._periodicUpdateAlarmReason) {
|
|
||||||
console.log('Periodic PAC update triggered:', new Date().toLocaleString('ru-RU'));
|
|
||||||
antiCensorRu.syncWithPacProvider(/* Swallows errors. */);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
console.log('Alarm listener installed. We won\'t miss any PAC update.');
|
|
||||||
|
|
||||||
window.addEventListener('online', () => {
|
|
||||||
|
|
||||||
console.log('We are online, checking periodic updates...');
|
|
||||||
antiCensorRu.setAlarms();
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
History of Changes to Storage (Migration Guide)
|
||||||
|
-----------------------------------------------
|
||||||
|
Version 0.0.0.10
|
||||||
|
* Added this.version
|
||||||
|
* PacProvider.proxyIps changed from {ip -> Boolean} to {ip -> hostname}
|
||||||
|
Version 0.0.0.8-9
|
||||||
|
* Changed storage.ifNotInstalled to storage.ifFirstInstall
|
||||||
|
* Added storage.lastPacUpdateStamp
|
||||||
|
**/
|
||||||
});
|
});
|
||||||
|
|
||||||
if (antiCensorRu.ifFirstInstall) {
|
function asyncLogGroup(...args) {
|
||||||
// INSTALL
|
|
||||||
console.log('Installing...');
|
const cb = args.pop() || (() => {});
|
||||||
return chrome.runtime.openOptionsPage();
|
console.group.apply(console, args);
|
||||||
|
return function(...cbArgs) {
|
||||||
|
|
||||||
|
console.groupEnd();
|
||||||
|
console.log('Group finished.');
|
||||||
|
return cb.apply(this, cbArgs);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!antiCensorRu.pacProvider) {
|
function checkChromeError(betterStack) {
|
||||||
return console.log('No PAC provider set. Do nothing.');
|
|
||||||
|
// Chrome API calls your cb in a context different from the point of API method invokation.
|
||||||
|
const err = chrome.runtime.lastError || chrome.extension.lastError || null;
|
||||||
|
if (err) {
|
||||||
|
const args = ['API returned error:', err];
|
||||||
|
if (betterStack) {
|
||||||
|
args.push('\n' + betterStack);
|
||||||
|
}
|
||||||
|
console.warn.apply(console, args);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
function chromified(cb, ...replaceArgs) {
|
||||||
1. There is no way to check that chrome.runtime.onInstalled wasn't fired except timeout.
|
|
||||||
Otherwise we could put storage migration code only there.
|
|
||||||
2. We have to check storage for migration before using it.
|
|
||||||
Better on each launch then on each pull.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const ifAlarmTriggered = antiCensorRu.setAlarms();
|
const stack = (new Error()).stack;
|
||||||
|
// Take error first callback and covert it to chrome api callback.
|
||||||
|
return function(...args) {
|
||||||
|
|
||||||
|
if (replaceArgs.length) {
|
||||||
|
args = replaceArgs;
|
||||||
|
}
|
||||||
|
const err = checkChromeError(stack);
|
||||||
|
return cb && cb.call(this, err, ...args);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
if (antiCensorRu.version === oldStorage.version) {
|
|
||||||
// LAUNCH, RELOAD, ENABLE
|
|
||||||
antiCensorRu.pacProviders = oldStorage.pacProviders;
|
|
||||||
return console.log('Extension launched, reloaded or enabled.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATE & MIGRATION
|
function httpGet(url, cb) {
|
||||||
console.log('Extension updated.');
|
|
||||||
if (!ifAlarmTriggered) {
|
const start = Date.now();
|
||||||
updatePacProxyIps(
|
return fetch(url).then(
|
||||||
antiCensorRu.pacProvider,
|
(res) => {
|
||||||
(ipsError) => ipsError ? console.error('Error updating IPs:', ipsError) : antiCensorRu.pushToStorage(/* Swallows errors. */)
|
|
||||||
|
const textCb =
|
||||||
|
(err) => cb && res.text()
|
||||||
|
.then( (text) => cb(err, text), cb );
|
||||||
|
const status = res.status;
|
||||||
|
if ( !( status >= 200 && status < 300 || status === 304 ) ) {
|
||||||
|
res.clarification = {message: 'Получен ответ с неудачным HTTP-кодом ' + status + '.'};
|
||||||
|
return textCb(res);
|
||||||
|
}
|
||||||
|
console.log('GETed with success:', url, Date.now() - start);
|
||||||
|
return textCb();
|
||||||
|
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
|
||||||
|
err.clarification = {message: 'Что-то не так с сетью, проверьте соединение.'};
|
||||||
|
return cb && cb(err);
|
||||||
|
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
function getOneDnsRecord(args, cb) {
|
||||||
History of Changes to Storage (Migration Guide)
|
|
||||||
-----------------------------------------------
|
|
||||||
Version 0.0.0.10
|
|
||||||
* Added this.version
|
|
||||||
* PacProvider.proxyIps changed from {ip -> Boolean} to {ip -> hostname}
|
|
||||||
Version 0.0.0.8-9
|
|
||||||
* Changed storage.ifNotInstalled to storage.ifFirstInstall
|
|
||||||
* Added storage.lastPacUpdateStamp
|
|
||||||
**/
|
|
||||||
});
|
|
||||||
|
|
||||||
function asyncLogGroup(...args) {
|
// args: { host:..., type: 'AAAA', filter: ['AAAA'] }
|
||||||
|
if (!(args.host && args.type && cb)) {
|
||||||
const cb = args.pop() || (() => {});
|
throw new Error('Wrong args:' + host + ',' + type);
|
||||||
console.group.apply(console, args);
|
|
||||||
return function(...cbArgs) {
|
|
||||||
|
|
||||||
console.groupEnd();
|
|
||||||
console.log('Group finished.');
|
|
||||||
return cb.apply(this, cbArgs);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkChromeError(betterStack) {
|
|
||||||
|
|
||||||
// Chrome API calls your cb in a context different from the point of API method invokation.
|
|
||||||
const err = chrome.runtime.lastError || chrome.extension.lastError || null;
|
|
||||||
if (err) {
|
|
||||||
const args = ['API returned error:', err];
|
|
||||||
if (betterStack) {
|
|
||||||
args.push('\n' + betterStack);
|
|
||||||
}
|
}
|
||||||
console.warn.apply(console, args);
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
|
|
||||||
}
|
const type2str = {
|
||||||
|
// https://en.wikipedia.org/wiki/List_of_DNS_record_types
|
||||||
|
// A, AAAA may be localized (github, e.g.), but you may use ANY
|
||||||
|
1: 'A', // IPv4
|
||||||
|
28: 'AAAA', // IPv6
|
||||||
|
2: 'NS',
|
||||||
|
5: 'CNAME', // Synonyms, returned by server together with A/AAAA.
|
||||||
|
255: 'ANY' // Deprecated on some servers, not recommended
|
||||||
|
};
|
||||||
|
|
||||||
function chromified(cb, ...replaceArgs) {
|
httpGet(
|
||||||
|
'https://dns.google.com/resolve?type=' + args.type + '&name=' + args.host,
|
||||||
const stack = (new Error()).stack;
|
(err, res) => {
|
||||||
// Take error first callback and covert it to chrome api callback.
|
if (res) {
|
||||||
return function(...args) {
|
try {
|
||||||
|
res = JSON.parse(res);
|
||||||
if (replaceArgs.length) {
|
console.log('Json parsed.');
|
||||||
args = replaceArgs;
|
if (err || res.Status) {
|
||||||
}
|
const msg = ['Answer', 'Comment', 'Status']
|
||||||
const err = checkChromeError(stack);
|
.filter( (prop) => res[ prop ] )
|
||||||
return cb && cb.call(this, err, ...args);
|
.map( (prop) => prop + ': ' + JSON.stringify( res[ prop ] ) )
|
||||||
|
.join(', \n');
|
||||||
};
|
err.clarification.message += ' Сервер (json): ' + msg;
|
||||||
|
err.data = err.data || res;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
function httpGet(url, cb) {
|
res = res.Answer || [];
|
||||||
|
for (const record of res) {
|
||||||
const start = Date.now();
|
record.type = type2str[ record.type ];
|
||||||
return fetch(url).then(
|
}
|
||||||
(res) => {
|
if ( args.filter ) {
|
||||||
|
res = res.filter( (record) => args.filter.indexOf( record.type ) > -1 );
|
||||||
const textCb =
|
}
|
||||||
(err) => cb && res.text()
|
}
|
||||||
.then( (text) => cb(err, text), cb );
|
}
|
||||||
const status = res.status;
|
catch(e) {
|
||||||
if ( !( status >= 200 && status < 300 || status === 304 ) ) {
|
err = e || err || {clarification:{message:''}};
|
||||||
res.clarification = {message: 'Получен ответ с неудачным HTTP-кодом ' + status + '.'};
|
err.clarification = err.clarification || { message: '' };
|
||||||
return textCb(res);
|
err.clarification.message += ' Сервер (текст): '+ res;
|
||||||
}
|
err.clarification.message.trim();
|
||||||
console.log('GETed with success:', url, Date.now() - start);
|
|
||||||
return textCb();
|
|
||||||
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
|
|
||||||
err.clarification = {message: 'Что-то не так с сетью, проверьте соединение.'};
|
|
||||||
return cb && cb(err);
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOneDnsRecord(args, cb) {
|
|
||||||
|
|
||||||
// args: { host:..., type: 'AAAA', filter: ['AAAA'] }
|
|
||||||
if (!(args.host && args.type && cb)) {
|
|
||||||
throw new Error('Wrong args:' + host + ',' + type);
|
|
||||||
}
|
|
||||||
|
|
||||||
const type2str = {
|
|
||||||
// https://en.wikipedia.org/wiki/List_of_DNS_record_types
|
|
||||||
// A, AAAA may be localized (github, e.g.), but you may use ANY
|
|
||||||
1: 'A', // IPv4
|
|
||||||
28: 'AAAA', // IPv6
|
|
||||||
2: 'NS',
|
|
||||||
5: 'CNAME', // Synonyms, returned by server together with A/AAAA.
|
|
||||||
255: 'ANY' // Deprecated on some servers, not recommended
|
|
||||||
};
|
|
||||||
|
|
||||||
httpGet(
|
|
||||||
'https://dns.google.com/resolve?type=' + args.type + '&name=' + args.host,
|
|
||||||
(err, res) => {
|
|
||||||
if (res) {
|
|
||||||
try {
|
|
||||||
res = JSON.parse(res);
|
|
||||||
console.log('Json parsed.');
|
|
||||||
if (err || res.Status) {
|
|
||||||
const msg = ['Answer', 'Comment', 'Status']
|
|
||||||
.filter( (prop) => res[ prop ] )
|
|
||||||
.map( (prop) => prop + ': ' + JSON.stringify( res[ prop ] ) )
|
|
||||||
.join(', \n');
|
|
||||||
err.clarification.message += ' Сервер (json): ' + msg;
|
|
||||||
err.data = err.data || res;
|
err.data = err.data || res;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
res = res.Answer || [];
|
|
||||||
for (const record of res) {
|
|
||||||
record.type = type2str[ record.type ];
|
|
||||||
}
|
|
||||||
if ( args.filter ) {
|
|
||||||
res = res.filter( (record) => args.filter.indexOf( record.type ) > -1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(e) {
|
|
||||||
err = e || err || {clarification:{message:''}};
|
|
||||||
err.clarification = err.clarification || { message: '' };
|
|
||||||
err.clarification.message += ' Сервер (текст): '+ res;
|
|
||||||
err.clarification.message.trim();
|
|
||||||
err.data = err.data || res;
|
|
||||||
}
|
}
|
||||||
|
return cb( err, res );
|
||||||
}
|
}
|
||||||
return cb( err, res );
|
);
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
function getDnsRecords(args, cb) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
Example of input:
|
|
||||||
{
|
|
||||||
// Required
|
|
||||||
host: 'proxy.navalny.cia.gov',
|
|
||||||
// Optional
|
|
||||||
types: {
|
|
||||||
string: ['A', 'AAAA'], // <- Default. Makes one request per each type.
|
|
||||||
filter: ['A', 'AAAA'], // <- Default. E.g., you want to get rid of CNAME type from response.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Exmple of answer from google:
|
|
||||||
"Answer":
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"name": "apple.com.", // Always matches name in the Question section
|
|
||||||
"type": 1, // A - Standard DNS RR type
|
|
||||||
"TTL": 3599, // Record's time-to-live in seconds
|
|
||||||
"data": "17.178.96.59" // Data for A - IP address as text
|
|
||||||
},
|
|
||||||
...
|
|
||||||
Exmple of output:
|
|
||||||
The same as google, but types _may be_ canonical strings ('AAAA', 'A')
|
|
||||||
**/
|
|
||||||
|
|
||||||
if ( !args.host.length ) {
|
|
||||||
throw new Error('args.host is required: ' + args.host);
|
|
||||||
}
|
|
||||||
args.types = Object.assign({
|
|
||||||
string: ['A', 'AAAA'],
|
|
||||||
filter: ['A', 'AAAA']
|
|
||||||
}, args.types);
|
|
||||||
|
|
||||||
const promises = args.types.string.map(
|
|
||||||
(type) => new Promise( (resolve, reject) =>
|
|
||||||
getOneDnsRecord({ host: args.host, type: type, filter: args.types.filter }, (err, res) => err ? reject(err) : resolve(res) )
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Promise.all(promises).then( (answers) => cb( null, [].concat.apply([], answers) ), cb );
|
|
||||||
}
|
|
||||||
|
|
||||||
const getIpDnsRecords = (host, cb) => getDnsRecords({ host: host }, cb);
|
|
||||||
|
|
||||||
function updatePacProxyIps(provider, cb) {
|
|
||||||
|
|
||||||
cb = asyncLogGroup('Getting IP for '+ provider.proxyHosts.join(', ') +'...', cb);
|
|
||||||
let failure = {
|
|
||||||
clarification: {message:'Не удалось получить один или несколько IP адресов для прокси-серверов. Иконка для уведомления об обходе блокировок может не отображаться.'},
|
|
||||||
errors: {}
|
|
||||||
};
|
};
|
||||||
let i = 0;
|
|
||||||
provider.proxyHosts.map(
|
|
||||||
(proxyHost) => getIpDnsRecords(
|
|
||||||
proxyHost,
|
|
||||||
(err, records) => {
|
|
||||||
|
|
||||||
if (!err) {
|
function getDnsRecords(args, cb) {
|
||||||
provider.proxyIps = provider.proxyIps || {};
|
|
||||||
records.forEach( (ans) => provider.proxyIps[ ans.data ] = proxyHost );
|
/*
|
||||||
}
|
Example of input:
|
||||||
else {
|
{
|
||||||
failure.errors[proxyHost] = err;
|
// Required
|
||||||
|
host: 'proxy.navalny.cia.gov',
|
||||||
|
// Optional
|
||||||
|
types: {
|
||||||
|
string: ['A', 'AAAA'], // <- Default. Makes one request per each type.
|
||||||
|
filter: ['A', 'AAAA'], // <- Default. E.g., you want to get rid of CNAME type from response.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Exmple of answer from google:
|
||||||
|
"Answer":
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "apple.com.", // Always matches name in the Question section
|
||||||
|
"type": 1, // A - Standard DNS RR type
|
||||||
|
"TTL": 3599, // Record's time-to-live in seconds
|
||||||
|
"data": "17.178.96.59" // Data for A - IP address as text
|
||||||
|
},
|
||||||
|
...
|
||||||
|
Exmple of output:
|
||||||
|
The same as google, but types _may be_ canonical strings ('AAAA', 'A')
|
||||||
|
**/
|
||||||
|
|
||||||
if ( ++i === provider.proxyHosts.length ) {
|
if ( !args.host.length ) {
|
||||||
failure = Object.keys(failure.errors).length ? failure : null;
|
throw new Error('args.host is required: ' + args.host);
|
||||||
return cb(failure, provider.proxyIps);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPacScriptFromProvider(provider, cb) {
|
|
||||||
|
|
||||||
cb = asyncLogGroup('Getting pac script from provider...', provider.pacUrl, cb);
|
|
||||||
|
|
||||||
httpGet(
|
|
||||||
provider.pacUrl,
|
|
||||||
(err, pacData) => {
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
err.clarification = {
|
|
||||||
message: 'Не удалось скачать PAC-скрипт с адреса: ' + provider.pacUrl + '.',
|
|
||||||
prev: err.clarification
|
|
||||||
};
|
|
||||||
return cb(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
mode: 'pac_script',
|
|
||||||
pacScript: {
|
|
||||||
mandatory: false,
|
|
||||||
data: pacData
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log('Setting chrome proxy settings...');
|
|
||||||
chrome.proxy.settings.set( {value: config}, chromified(cb) );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
args.types = Object.assign({
|
||||||
|
string: ['A', 'AAAA'],
|
||||||
|
filter: ['A', 'AAAA']
|
||||||
|
}, args.types);
|
||||||
|
|
||||||
|
const promises = args.types.string.map(
|
||||||
|
(type) => new Promise( (resolve, reject) =>
|
||||||
|
getOneDnsRecord({ host: args.host, type: type, filter: args.types.filter }, (err, res) => err ? reject(err) : resolve(res) )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Promise.all(promises).then( (answers) => cb( null, [].concat.apply([], answers) ), cb );
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIpDnsRecords = (host, cb) => getDnsRecords({ host: host }, cb);
|
||||||
|
|
||||||
|
function updatePacProxyIps(provider, cb) {
|
||||||
|
|
||||||
|
cb = asyncLogGroup('Getting IP for '+ provider.proxyHosts.join(', ') +'...', cb);
|
||||||
|
let failure = {
|
||||||
|
clarification: {message:'Не удалось получить один или несколько IP адресов для прокси-серверов. Иконка для уведомления об обходе блокировок может не отображаться.'},
|
||||||
|
errors: {}
|
||||||
|
};
|
||||||
|
let i = 0;
|
||||||
|
provider.proxyHosts.map(
|
||||||
|
(proxyHost) => getIpDnsRecords(
|
||||||
|
proxyHost,
|
||||||
|
(err, records) => {
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
provider.proxyIps = provider.proxyIps || {};
|
||||||
|
records.forEach( (ans) => provider.proxyIps[ ans.data ] = proxyHost );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
failure.errors[proxyHost] = err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ++i === provider.proxyHosts.length ) {
|
||||||
|
failure = Object.keys(failure.errors).length ? failure : null;
|
||||||
|
return cb(failure, provider.proxyIps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPacScriptFromProvider(provider, cb) {
|
||||||
|
|
||||||
|
cb = asyncLogGroup('Getting pac script from provider...', provider.pacUrl, cb);
|
||||||
|
|
||||||
|
httpGet(
|
||||||
|
provider.pacUrl,
|
||||||
|
(err, pacData) => {
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
err.clarification = {
|
||||||
|
message: 'Не удалось скачать PAC-скрипт с адреса: ' + provider.pacUrl + '.',
|
||||||
|
prev: err.clarification
|
||||||
|
};
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
|
mode: 'pac_script',
|
||||||
|
pacScript: {
|
||||||
|
mandatory: false,
|
||||||
|
data: pacData
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log('Setting chrome proxy settings...');
|
||||||
|
chrome.proxy.settings.set( {value: config}, chromified(cb) );
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('error', (err) => {
|
window.addEventListener('error', (err) => {
|
||||||
|
|
|
@ -18,9 +18,9 @@ window.chrome.browserAction.setBadgeBackgroundColor({
|
||||||
|
|
||||||
window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
|
|
||||||
+function() {
|
{
|
||||||
|
|
||||||
var _tabCallbacks = {};
|
const _tabCallbacks = {};
|
||||||
|
|
||||||
function afterTabUpdated(tabId, cb) {
|
function afterTabUpdated(tabId, cb) {
|
||||||
if (_tabCallbacks[tabId])
|
if (_tabCallbacks[tabId])
|
||||||
|
@ -42,7 +42,7 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.webRequest.onErrorOccurred.addListener(
|
chrome.webRequest.onErrorOccurred.addListener(
|
||||||
requestDetails =>
|
(requestDetails) =>
|
||||||
isInsideTabWithIp(requestDetails) &&
|
isInsideTabWithIp(requestDetails) &&
|
||||||
(
|
(
|
||||||
isProxiedAndInformed(requestDetails) || requestDetails.type === 'main_frame' && ( window.tabWithError2ip[requestDetails.tabId] = requestDetails.ip )
|
isProxiedAndInformed(requestDetails) || requestDetails.type === 'main_frame' && ( window.tabWithError2ip[requestDetails.tabId] = requestDetails.ip )
|
||||||
|
@ -50,9 +50,9 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
{ urls: ['<all_urls>'] }
|
{ urls: ['<all_urls>'] }
|
||||||
);
|
);
|
||||||
|
|
||||||
chrome.tabs.onRemoved.addListener( tabId => { onTabUpdate(tabId); delete window.tabWithError2ip[tabId] } );
|
chrome.tabs.onRemoved.addListener( (tabId) => { onTabUpdate(tabId); delete window.tabWithError2ip[tabId] } );
|
||||||
|
|
||||||
var previousUpdateTitleFinished = Promise.resolve();
|
let previousUpdateTitleFinished = Promise.resolve();
|
||||||
|
|
||||||
function isProxiedAndInformed(requestDetails) {
|
function isProxiedAndInformed(requestDetails) {
|
||||||
|
|
||||||
|
@ -62,12 +62,12 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var ifMainFrame = requestDetails.type === 'main_frame';
|
const ifMainFrame = requestDetails.type === 'main_frame';
|
||||||
|
|
||||||
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
|
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
|
||||||
() => new Promise(
|
() => new Promise(
|
||||||
resolve => {
|
(resolve) => {
|
||||||
var cb = () => updateTitle( requestDetails, resolve );
|
const cb = () => updateTitle( requestDetails, resolve );
|
||||||
return ifMainFrame ? afterTabUpdated(requestDetails.tabId, cb) : cb();
|
return ifMainFrame ? afterTabUpdated(requestDetails.tabId, cb) : cb();
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -79,15 +79,16 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
|
|
||||||
chrome.browserAction.getTitle(
|
chrome.browserAction.getTitle(
|
||||||
{ tabId: requestDetails.tabId },
|
{ tabId: requestDetails.tabId },
|
||||||
title => {
|
(title) => {
|
||||||
var ifTitleSetAlready = /\n/.test(title);
|
|
||||||
var proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
|
|
||||||
|
|
||||||
var hostname = new URL( requestDetails.url ).hostname;
|
const ifTitleSetAlready = /\n/.test(title);
|
||||||
|
const proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
|
||||||
|
|
||||||
var ifShouldUpdateTitle = false;
|
const hostname = new URL( requestDetails.url ).hostname;
|
||||||
var indent = ' ';
|
|
||||||
var proxyTitle = 'Прокси:';
|
let ifShouldUpdateTitle = false;
|
||||||
|
const indent = ' ';
|
||||||
|
const proxyTitle = 'Прокси:';
|
||||||
|
|
||||||
if (!ifTitleSetAlready) {
|
if (!ifTitleSetAlready) {
|
||||||
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
|
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
|
||||||
|
@ -98,7 +99,8 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
text: ifMainFrame ? '1' : '%1'
|
text: ifMainFrame ? '1' : '%1'
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
const hostsProxiesPair = title.split(proxyTitle);
|
const hostsProxiesPair = title.split(proxyTitle);
|
||||||
|
|
||||||
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
|
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
|
||||||
|
@ -110,10 +112,11 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
|
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
|
||||||
ifShouldUpdateTitle = true;
|
ifShouldUpdateTitle = true;
|
||||||
|
|
||||||
var _cb = cb;
|
const _cb = cb;
|
||||||
cb = () => chrome.browserAction.getBadgeText(
|
cb = () => chrome.browserAction.getBadgeText(
|
||||||
{tabId: requestDetails.tabId},
|
{tabId: requestDetails.tabId},
|
||||||
result => {
|
(result) => {
|
||||||
|
|
||||||
chrome.browserAction.setBadgeText(
|
chrome.browserAction.setBadgeText(
|
||||||
{
|
{
|
||||||
tabId: requestDetails.tabId,
|
tabId: requestDetails.tabId,
|
||||||
|
@ -121,27 +124,30 @@ window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return _cb();
|
return _cb();
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ifShouldUpdateTitle)
|
if (ifShouldUpdateTitle) {
|
||||||
chrome.browserAction.setTitle({
|
chrome.browserAction.setTitle({
|
||||||
title: title,
|
title: title,
|
||||||
tabId: requestDetails.tabId
|
tabId: requestDetails.tabId
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return cb();
|
return cb();
|
||||||
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.webRequest.onResponseStarted.addListener(
|
chrome.webRequest.onResponseStarted.addListener(
|
||||||
requestDetails => isInsideTabWithIp(requestDetails) && isProxiedAndInformed(requestDetails),
|
(requestDetails) => isInsideTabWithIp(requestDetails) && isProxiedAndInformed(requestDetails),
|
||||||
{ urls: ['<all_urls>'] }
|
{ urls: ['<all_urls>'] }
|
||||||
);
|
);
|
||||||
|
|
||||||
}();
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
const createMenuLinkEntry = (title, tab2url) => chrome.contextMenus.create({
|
const createMenuLinkEntry = (title, tab2url) => chrome.contextMenus.create({
|
||||||
title: title,
|
title: title,
|
||||||
contexts: ['browser_action'],
|
contexts: ['browser_action'],
|
||||||
onclick: (menuInfo, tab) => Promise.resolve( tab2url( tab ) ).then( url => chrome.tabs.create({url: url}) )
|
onclick: (menuInfo, tab) => Promise.resolve( tab2url( tab ) ).then( (url) => chrome.tabs.create({url: url}) )
|
||||||
});
|
});
|
||||||
|
|
||||||
createMenuLinkEntry( 'Сайт доступен из-за границы? Is up?', (tab) => 'http://isup.me/'+ new URL(tab.url).hostname );
|
createMenuLinkEntry( 'Сайт доступен из-за границы? Is up?', (tab) => 'http://isup.me/'+ new URL(tab.url).hostname );
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
|
|
||||||
"name": "Обход блокировок Рунета",
|
"name": "Обход блокировок Рунета 0.15",
|
||||||
"description": "Аргументы против цензуры: https://git.io/vEkI9",
|
"description": "Аргументы против цензуры: https://git.io/vEkI9",
|
||||||
"version": "0.0.0.15",
|
"version": "0.0.0.15",
|
||||||
"icons": {
|
"icons": {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user