Added context menus

This commit is contained in:
Ilya Ig. Petrov 2016-03-24 21:11:36 +05:00
parent b8c1b325e4
commit 3d9ec1fd3d
19 changed files with 417 additions and 280 deletions

View File

@ -19,7 +19,7 @@
Если пункт уже выбран, нажмите кнопку "[обновить]". Если пункт уже выбран, нажмите кнопку "[обновить]".
2. Если появилось сообщение об ошибке, с которой вы не можете справиться, то [сообщите о проблеме](#Как-сообщить-о-проблеме). 2. Если появилось сообщение об ошибке, с которой вы не можете справиться, то [сообщите о проблеме](#Как-сообщить-о-проблеме).
3. Если ошибок нет, пишет "PAC-скрипт установлен", но https://archive.org всё равно не открывается, то нужно разбираться: 3. Если ошибок нет, пишет "PAC-скрипт установлен", но https://archive.org всё равно не открывается, то нужно разбираться:
* Зайдите в настройки chrome://settings, убедитесь, что параметр прокси контролируется этим расширением, а не другим. * Зайдите в настройки chrome://settings/search#proxy и убедитесь, что параметр прокси контролируется этим расширением, а не другим.
* Проверьте доступность прокси АнтиЗапрет и АнтиЦенз: `ping proxy.antizapret.prostovpn.org`, `ping gw2.anticenz.org` * Проверьте доступность прокси АнтиЗапрет и АнтиЦенз: `ping proxy.antizapret.prostovpn.org`, `ping gw2.anticenz.org`
* Посмотрите логи фоновой страницы в chrome://extensions, если умеете. * Посмотрите логи фоновой страницы в chrome://extensions, если умеете.
4. Если ничего не помогло, то [сообщите о проблеме](#Как-сообщить-о-проблеме). 4. Если ничего не помогло, то [сообщите о проблеме](#Как-сообщить-о-проблеме).

View File

@ -68,6 +68,7 @@ window.antiCensorRu = {
_periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта Антизапрет', _periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта Антизапрет',
pushToStorage(cb) { pushToStorage(cb) {
console.log('Pushing...');
// Copy only settable properties. // Copy only settable properties.
var onlySettable = {}; var onlySettable = {};
@ -99,7 +100,7 @@ window.antiCensorRu = {
syncWithPacProvider(cb) { syncWithPacProvider(cb) {
var cb = asyncLogGroup('Syncing with PAC provider...', cb); var cb = asyncLogGroup('Syncing with PAC provider...', cb);
if (!this.pacProvider) if (!this.pacProvider)
return cb({clarification: 'Сперва выберите PAC-провайдера.'}); return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
var pacSetPromise = new Promise( var pacSetPromise = new Promise(
(resolve, reject) => setPacScriptFromProvider( (resolve, reject) => setPacScriptFromProvider(
@ -151,7 +152,7 @@ window.antiCensorRu = {
} }
); );
return nextUpdateMoment === now; // ifAlarmTriggered. Return value may be changed. return nextUpdateMoment === now; // ifAlarmTriggered. May be changed.
}, },
installPac(key, cb) { installPac(key, cb) {
@ -191,6 +192,7 @@ chrome.storage.local.get(null, oldStorage => {
// LAUNCH, RELOAD, UPDATE // LAUNCH, RELOAD, UPDATE
antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey; antiCensorRu._currentPacProviderKey = oldStorage._currentPacProviderKey;
antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp; antiCensorRu.lastPacUpdateStamp = oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp;
console.log( 'Last PAC update was on', new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU') );
} }
chrome.alarms.onAlarm.addListener( chrome.alarms.onAlarm.addListener(
@ -222,7 +224,7 @@ chrome.storage.local.get(null, oldStorage => {
var ifAlarmTriggered = antiCensorRu.setAlarms(); var ifAlarmTriggered = antiCensorRu.setAlarms();
if (antiCensorRu.version === oldStorage.version) { if (antiCensorRu.version === oldStorage.version) {
// LAUNCH, RELOAD // LAUNCH, RELOAD, ENABLE
antiCensorRu.pacProviders = oldStorage.pacProviders; antiCensorRu.pacProviders = oldStorage.pacProviders;
return console.log('Extension launched, reloaded or enabled.'); return console.log('Extension launched, reloaded or enabled.');
} }
@ -232,7 +234,7 @@ chrome.storage.local.get(null, oldStorage => {
if (!ifAlarmTriggered) if (!ifAlarmTriggered)
updatePacProxyIps( updatePacProxyIps(
antiCensorRu.pacProvider, antiCensorRu.pacProvider,
ipsError => ipsError ? console.log('Error updating IPs:', ipsError) : antiCensorRu.pushToStorage() ipsError => ipsError ? console.error('Error updating IPs:', ipsError) : antiCensorRu.pushToStorage()
); );
/* /*
@ -253,8 +255,6 @@ chrome.storage.local.get(null, oldStorage => {
**/ **/
}); });
// PRIVATE
function asyncLogGroup() { function asyncLogGroup() {
var args = [].slice.apply(arguments); var args = [].slice.apply(arguments);
var cb = args.pop(); var cb = args.pop();
@ -267,25 +267,44 @@ function asyncLogGroup() {
} }
} }
function ifSuccessfulCode(status) { function httpGet(url, cb) {
return status >= 200 && status < 300 || status === 304; return fetch(url).then(
res => {
var textCb = err => cb && res.text().then( text => cb(err, text), cb );
var status = res.status;
if ( !( status >= 200 && status < 300 || status === 304 ) ) {
res.clarification = {message: 'Получен ответ с неудачным HTTP-кодом '+status+'.'};
return textCb(res);
}
console.log('GETed with success.');
return textCb();
},
err => {
err.clarification = {message: 'Что-то не так с сетью, проверьте соединение.'};
return cb && cb(err);
}
);
} }
function httpGet(url, cb) { function getIpsAndCnames(host, cb) {
var cb = cb || (() => {}); httpGet(
var req = new XMLHttpRequest(); 'http://www.dns-lg.com/google1/'+ host +'/a',
var ifAsync = true; (err, res) => {
req.open('GET', url, ifAsync); if (res)
req.onload = event => { try {
if ( !ifSuccessfulCode(req.status) ) { res = JSON.parse(res);
req.clarification = {message: 'Получен ответ с неудачным HTTP-кодом '+req.status+ '.'}; if (err)
return cb(req); err.clarification.message += ' Сервер: '+ res.message;
else
res = res.answer;
} catch(e) {
err = err || {clarification:{message:''}};
err.clarification.message += ' Сервер: '+ res;
err.clarification.message.trim();
}
return cb( err, res );
} }
console.log('GETed with success.'); );
return cb(null, req.responseText)
};
req.onerror = event => { event.clarification = {message: 'Что-то не так с сетью, проверьте соединение.'}; return cb(event); };
req.send();
} }
function updatePacProxyIps(provider, cb) { function updatePacProxyIps(provider, cb) {
@ -296,14 +315,12 @@ function updatePacProxyIps(provider, cb) {
}; };
var i = 0; var i = 0;
provider.proxyHosts.map( provider.proxyHosts.map(
proxyHost => httpGet( proxyHost => getIpsAndCnames(
'http://www.dns-lg.com/google1/'+ proxyHost +'/A', proxyHost,
(err, res) => { (err, ans) => {
if (!err) { if (!err) {
provider.proxyIps = provider.proxyIps || {}; provider.proxyIps = provider.proxyIps || {};
JSON.parse(res).answer.map( ans.filter( ans => ans.type === 'A' ).map( ans => provider.proxyIps[ ans.rdata ] = proxyHost );
ans => provider.proxyIps[ ans.rdata ] = proxyHost
)
} else } else
failure.errors[proxyHost] = err; failure.errors[proxyHost] = err;
@ -324,7 +341,7 @@ function setPacScriptFromProvider(provider, cb) {
(err, res) => { (err, res) => {
if (err) { if (err) {
err.clarification = { err.clarification = {
message: 'Не удалось скачать PAC-скрипт с адреса: ' +provider.pacUrl+ '.', message: 'Не удалось скачать PAC-скрипт с адреса: '+ provider.pacUrl +'.',
prev: err.clarification prev: err.clarification
}; };
return cb(err); return cb(err);

View File

@ -0,0 +1,147 @@
'use strict';
// Shows user browserAction icon if any part of the current site is being blocked and proxied.
/*
In what moment the title of the previous icon is cleared?
By my observations it usually takes place near tabs.onUpdate of tab status to "loading".
So if you set a title earlier it may be cleared by browser.
It pertains not only to page refesh but to newly opened pages too.
Also on loosing title see:
https://github.com/ilyaigpetrov/repository-for-chrome-bugs/blob/master/browserAction-title-lost-after-setting/background.js
Crazy parallel Chrome.
**/
window.tabWithError2ip = {}; // For errors only: Error? -> Check this IP!
function getHostname(url) {
var a = document.createElement('a');
a.href = url;
return a.hostname;
}
+function() {
var _tabCallbacks = {};
function afterTabUpdated(tabId, cb) {
if (_tabCallbacks[tabId])
_tabCallbacks[tabId].push(cb);
else _tabCallbacks[tabId] = [cb];
}
function onTabUpdate(tabId) {
if (_tabCallbacks[tabId]) {
_tabCallbacks[tabId].map( f => f() );
delete _tabCallbacks[tabId];
}
}
chrome.tabs.onUpdated.addListener( onTabUpdate );
function isInsideTabWithIp(requestDetails) {
return requestDetails.tabId !== -1 && requestDetails.ip
}
chrome.webRequest.onErrorOccurred.addListener(
requestDetails =>
isInsideTabWithIp(requestDetails) &&
(
isProxiedAndInformed(requestDetails) || requestDetails.type === 'main_frame' && ( window.tabWithError2ip[requestDetails.tabId] = requestDetails.ip )
),
{ urls: ['<all_urls>'] }
);
chrome.tabs.onRemoved.addListener( tabId => { onTabUpdate(tabId); delete window.tabWithError2ip[tabId] } );
var previousUpdateTitleFinished = Promise.resolve();
function isProxiedAndInformed(requestDetails) {
if (
!( window.antiCensorRu.pacProvider && window.antiCensorRu.pacProvider.proxyIps && window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ] )
) return false;
var ifMainFrame = requestDetails.type === 'main_frame';
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
() => new Promise(
resolve => {
var cb = () => updateTitle( requestDetails, resolve );
return ifMainFrame ? afterTabUpdated(requestDetails.tabId, cb) : cb();
}
)
);
return true;
function updateTitle(requestDetails, cb) {
chrome.browserAction.getTitle(
{ tabId: requestDetails.tabId },
title => {
var ifTitleSetAlready = /\n/.test(title);
var proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
var hostname = getHostname( requestDetails.url );
var ifShouldUpdateTitle = false;
var indent = ' ';
var proxyTitle = 'Прокси:';
if (!ifTitleSetAlready) {
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
ifShouldUpdateTitle = true;
chrome.browserAction.setBadgeText({
tabId: requestDetails.tabId,
text: ifMainFrame ? '1' : '%1'
});
} else {
var hostsProxiesPair = title.split(proxyTitle);
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
title = title.replace(hostsProxiesPair[1], hostsProxiesPair[1] +'\n'+ indent + proxyHost);
ifShouldUpdateTitle = true;
}
if (hostsProxiesPair[0].indexOf(hostname) === -1) {
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
ifShouldUpdateTitle = true;
var _cb = cb;
cb = () => chrome.browserAction.getBadgeText(
{tabId: requestDetails.tabId},
result => {
chrome.browserAction.setBadgeText(
{
tabId: requestDetails.tabId,
text: ( isNaN( result.charAt(0) ) && result.charAt(0) || '' ) + (hostsProxiesPair[0].split('\n').length - 1)
}
);
return _cb();
}
);
}
}
if (ifShouldUpdateTitle)
chrome.browserAction.setTitle({
title: title,
tabId: requestDetails.tabId
});
return cb();
}
);
}
}
chrome.webRequest.onResponseStarted.addListener(
requestDetails => isInsideTabWithIp(requestDetails) && isProxiedAndInformed(requestDetails),
{ urls: ['<all_urls>'] }
);
}();

View File

@ -0,0 +1,37 @@
'use strict';
+function() {
var createMenuLinkEntry = (title, tab2url) => chrome.contextMenus.create({
title: title,
contexts: ['browser_action'],
onclick: (menuInfo, tab) => Promise.resolve( tab2url( tab ) ).then( url => chrome.tabs.create({url: url}) )
});
createMenuLinkEntry( 'Сайт доступен из-за границы? ISUP.ME', tab => 'http://isup.me/'+ getHostname(tab.url) );
createMenuLinkEntry( 'Сайт доступен из-за границы?', tab =>
`data:text/html;charset=utf8,<title>Запрашиваю...</title>
<form method="POST" action="https://www.host-tracker.com/ru/InstantCheck/Create">
<input name="InstantCheckUrl" value="${getHostname(tab.url)}" type="hidden">
</form>
<script>document.forms[0].submit()</script>`
);
window.reestrUrl = 'http://reestr.rublacklist.net/search/?q=';
createMenuLinkEntry('IP этого сайта в реестре блокировок?', tab => {
var hostname = getHostname( tab.url );
var ip = window.tabWithError2ip[tab.id];
if ( /^[.\d]+$/.test(hostname) || /^[:\dA-Fa-f]+$/.test(hostname) )
ip = hostname;
return ip
? reestrUrl + ip
: chrome.extension.getURL('./pages/is-ip-blocked/index.html') +'?'+ hostname
});
createMenuLinkEntry( 'Домен этого сайта в реестре блокировок?', tab => reestrUrl + getHostname(tab.url) );
createMenuLinkEntry( 'Поиск этой страницы в архиве archive.org', tab => 'http://web.archive.org/web/*/'+ tab.url );
createMenuLinkEntry( 'Разблокировать страницу по-другому', tab => chrome.extension.getURL('./pages/other-unblocks/index.html') +'?'+ tab.url );
}();

View File

@ -1,124 +0,0 @@
'use strict';
// Shows user browserAction icon if any part of the current site is being blocked and proxied.
/*
In what moment the title of the previous icon is cleared?
By my observations it usually takes place near tabs.onUpdate of tab status to "loading".
So if you set a title earlier it may be cleared by browser.
It pertains not only to page refesh but to newly opened pages too.
Also on loosing title see:
https://github.com/ilyaigpetrov/repository-for-chrome-bugs/blob/master/browserAction-title-lost-after-setting/background.js
Crazy parallel Chrome.
**/
window._tabCallbacks = {};
function afterTabUpdated(tabId, cb) {
if (window._tabCallbacks[tabId])
window._tabCallbacks[tabId].push(cb);
else window._tabCallbacks[tabId] = [cb];
}
function onTabUpdate(tabId) {
if (window._tabCallbacks[tabId]) {
window._tabCallbacks[tabId].map( f => f() );
delete window._tabCallbacks[tabId];
}
}
chrome.tabs.onUpdated.addListener( onTabUpdate );
chrome.tabs.onRemoved.addListener( onTabUpdate );
var previousUpdateTitleFinished = Promise.resolve();
function blockInform(requestDetails) {
if (
requestDetails.tabId === -1 || // Not inside tab.
!window.antiCensorRu.pacProvider || !window.antiCensorRu.pacProvider.proxyIps || !window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ]
) return;
previousUpdateTitleFinished = previousUpdateTitleFinished.then(
() => new Promise(
resolve => {
var cb = () => updateTitle( requestDetails, resolve );
return requestDetails.type === 'main_frame' ? afterTabUpdated(requestDetails.tabId, cb) : cb();
}
)
);
function updateTitle(requestDetails, cb) {
chrome.browserAction.getTitle(
{ tabId: requestDetails.tabId },
title => {
var ifTitleSetAlready = /\n/.test(title);
var proxyHost = window.antiCensorRu.pacProvider.proxyIps[ requestDetails.ip ];
var a = document.createElement('a');
a.href = requestDetails.url;
var hostname = a.hostname;
var ifShouldUpdateTitle = false;
var indent = ' ';
var proxyTitle = 'Прокси:';
if (!ifTitleSetAlready) {
title = 'Разблокированы:\n'+ indent + hostname +'\n'+ proxyTitle +'\n'+ indent + proxyHost;
ifShouldUpdateTitle = true;
chrome.browserAction.setBadgeText({
tabId: requestDetails.tabId,
text: requestDetails.type === 'main_frame' ? '1' : '%1'
});
} else {
var hostsProxiesPair = title.split(proxyTitle);
if (hostsProxiesPair[1].indexOf(proxyHost) === -1) {
title = title.replace(hostsProxiesPair[1], hostsProxiesPair[1] +'\n'+ indent + proxyHost);
ifShouldUpdateTitle = true;
}
if (hostsProxiesPair[0].indexOf(hostname) === -1) {
title = title.replace(proxyTitle, indent + hostname +'\n'+ proxyTitle);
ifShouldUpdateTitle = true;
var _cb = cb;
cb = () => chrome.browserAction.getBadgeText(
{tabId: requestDetails.tabId},
result => {
chrome.browserAction.setBadgeText(
{
tabId: requestDetails.tabId,
text: ( isNaN( result.charAt(0) ) && result.charAt(0) || '' ) + (hostsProxiesPair[0].split('\n').length - 1)
}
);
return _cb();
}
);
}
}
if (ifShouldUpdateTitle)
chrome.browserAction.setTitle({
title: title,
tabId: requestDetails.tabId
});
return cb();
}
);
}
}
chrome.webRequest.onResponseStarted.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);
chrome.webRequest.onErrorOccurred.addListener(
blockInform,
{ urls: ['<all_urls>'] }
);

View File

@ -1,9 +1,9 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Обход блокировок Рунета", "name": "Обход блокировок Рунета NEW",
"description": "Аргументы против цензуры: https://git.io/vEkI9", "description": "Аргументы против цензуры: https://git.io/vEkI9",
"version": "0.0.0.12", "version": "0.0.0.14",
"icons": { "icons": {
"128": "/icons/ribbon128.png" "128": "/icons/ribbon128.png"
}, },
@ -16,12 +16,14 @@
"alarms", "alarms",
"storage", "storage",
"<all_urls>", "<all_urls>",
"tabs" "tabs",
"contextMenus"
], ],
"background": { "background": {
"scripts": ["sync-pac-script-with-pac-provider.js", "block-informer.js"] "scripts": ["1-sync-pac-script-with-pac-provider.js", "2-block-informer.js", "3-context-menus.js"]
}, },
"browser_action": { "browser_action": {
"default_title": "Этот сайт благословлён РКН",
"default_popup": "/pages/choose-pac-provider/index.html" "default_popup": "/pages/choose-pac-provider/index.html"
}, },
"options_ui": { "options_ui": {

View File

@ -1,9 +1,6 @@
'use strict'; 'use strict';
renderPage(); chrome.runtime.getBackgroundPage( backgroundPage => {
function renderPage() {
console.log('Rendering started.');
function getStatus() { function getStatus() {
return document.querySelector('#status'); return document.querySelector('#status');
@ -18,132 +15,125 @@ function renderPage() {
status.classList.add('off'); status.classList.add('off');
} }
chrome.runtime.getBackgroundPage( backgroundPage => { var antiCensorRu = backgroundPage.antiCensorRu;
var antiCensorRu = backgroundPage.antiCensorRu; // SET DATE
// SET DATE function setDate() {
var dateForUser = 'никогда';
if( antiCensorRu.lastPacUpdateStamp ) {
var diff = Date.now() - antiCensorRu.lastPacUpdateStamp;
var units = ' мс';
var gauges = [
[1000, ' с'],
[60, ' мин'],
[60, ' ч'],
[24, ' дн'],
[7, ' недель'],
[4, ' месяцев'],
[12, ' г']
];
for(var g of gauges) {
var diffy = Math.floor(diff / g[0]);
if (!diffy)
break;
diff = diffy;
var units = g[1];
}
dateForUser = diff + units + ' назад';
}
function setDate() { var dateElement = document.querySelector('.update-date');
var dateForUser = 'никогда'; dateElement.innerText = dateForUser;
if( antiCensorRu.lastPacUpdateStamp ) { dateElement.title = new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU');
var diff = Date.now() - antiCensorRu.lastPacUpdateStamp; }
var units = ' мс';
var gauges = [ setDate();
[1000, ' с'], chrome.storage.onChanged.addListener( changes => changes.lastPacUpdateStamp.newValue && setDate() );
[60, ' мин'],
[60, ' ч'], // CLOSE BUTTON
[24, ' дн'],
[7, ' недель'], document.querySelector('.close-button').onclick = () => window.close();
[4, ' месяцев'],
[12, ' г'] // RADIOS
];
for(var g of gauges) { var currentRadio = () => {
var diffy = Math.floor(diff / g[0]); var id = antiCensorRu.currentPacProviderKey || 'none';
if (!diffy) return document.querySelector('#'+id);
break; }
diff = diffy; var checkChosenProvider = () => {
var units = g[1]; var radio = currentRadio();
} radio.checked = true;
dateForUser = diff + units + ' назад'; }
var triggerChosenProvider = () => {
var event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
currentRadio().dispatchEvent(event);
}
var ul = document.querySelector('#list-of-providers');
var _firstChild = ul.firstChild;
for( var providerKey of Object.keys(antiCensorRu.pacProviders) ) {
var li = document.createElement('li');
li.innerHTML = '<input type="radio" name="pacProvider" id="'+providerKey+'"> <label for="'+providerKey+'">'+providerKey+'</label> <a href class="link-button checked-radio-panel">[обновить]</a>';
li.querySelector('.link-button').onclick = () => {triggerChosenProvider(); return false;};
ul.insertBefore( li, _firstChild );
}
var radios = [].slice.apply( document.querySelectorAll('[name=pacProvider]') );
for(var radio of radios) {
radio.onchange = function(event) {
var pacKey = event.target.id;
if (pacKey === 'none')
return antiCensorRu.clearPac();
function enableDisableInputs() {
var inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++)
inputs[i].disabled = !inputs[i].disabled;
} }
var dateElement = document.querySelector('.update-date'); enableDisableInputs();
dateElement.innerText = dateForUser; setStatusTo('Установка...');
dateElement.title = new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU'); antiCensorRu.installPac(pacKey, err => {
} if (err) {
var ifNotCritical = err.clarification && err.clarification.ifNotCritical;
setDate(); var message = '';
chrome.storage.onChanged.addListener( setDate ); var clarification = err.clarification;
do {
// CLOSE BUTTON message = message +' '+ (clarification && clarification.message || err.message || '');
clarification = clarification.prev;
document.querySelector('.close-button').onclick = () => window.close(); } while( clarification );
message = message.trim();
// RADIOS setStatusTo(
`<span style="color:red">${ifNotCritical ? 'Некритичная ошибка.' : 'Ошибка!'}</span>
var currentRadio = () => { <br/>
var id = antiCensorRu.currentPacProviderKey || 'none'; <span style="font-size: 0.9em; color: darkred">${message}</span>
return document.querySelector('#'+id); <a href class="link-button">[Ещё&nbsp;подробнее]</a>`
} );
var checkChosenProvider = () => { getStatus().querySelector('.link-button').onclick = function() {
var radio = currentRadio(); var div = document.createElement('div');
radio.checked = true; div.innerHTML = '\
}
var triggerChosenProvider = () => {
var event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
currentRadio().dispatchEvent(event);
}
var ul = document.querySelector('#list-of-providers');
var _firstChild = ul.firstChild;
for( var providerKey of Object.keys(antiCensorRu.pacProviders) ) {
var li = document.createElement('li');
li.innerHTML = '<input type="radio" name="pacProvider" id="'+providerKey+'"> <label for="'+providerKey+'">'+providerKey+'</label> <a href class="link-button checked-radio-panel">[обновить]</a>';
li.querySelector('.link-button').onclick = () => {triggerChosenProvider(); return false;};
ul.insertBefore( li, _firstChild );
}
var radios = [].slice.apply( document.querySelectorAll('[name=pacProvider]') );
for(var radio of radios) {
radio.onchange = function(event) {
var pacKey = event.target.id;
if (pacKey === 'none')
return antiCensorRu.clearPac();
function enableDisableInputs() {
var inputs = document.querySelectorAll('input');
console.log(inputs.length);
for (var i = 0; i < inputs.length; i++)
inputs[i].disabled = !inputs[i].disabled;
}
enableDisableInputs();
setStatusTo('Установка...');
antiCensorRu.installPac(pacKey, err => {
if (err) {
var ifNotCritical = err.clarification && err.clarification.ifNotCritical;
var message = '';
var clarification = err.clarification;
do {
message = message +' '+ (clarification && clarification.message || err.message || '');
clarification = clarification.prev;
} while( clarification && clarification.prev );
message = message.trim();
message = '<span style="font-size: 0.9em; color: darkred">'+ message +'</span>';
var label = ifNotCritical ? 'Некритичная ошибка.' : 'Ошибка!';
label = '<span style="color:red">'+ label +'</span>';
setStatusTo(
label +'<br/>'+ message +' <a href class="link-button">[Ещё подробнее]</a>'
);
var btn = getStatus().querySelector('.link-button');
btn.onclick = function() {
var div = document.createElement('div');
div.innerHTML = '\
Более подробную информацию можно узнать из логов фоновой страницы:<br/>\ Более подробную информацию можно узнать из логов фоновой страницы:<br/>\
<a href class="ext">chrome://extensions</a> Это расширение Отладка страниц: фоновая страница Console (DevTools)'; <a href class="ext">chrome://extensions</a> Это расширение Отладка страниц: фоновая страница Console (DevTools)';
getStatus().replaceChild(div, this); getStatus().replaceChild(div, this);
div.querySelector('.ext').onclick = () => { div.querySelector('.ext').onclick = () => {
chrome.tabs.create({ url: 'chrome://extensions?id='+ chrome.runtime.id }); chrome.tabs.create({ url: 'chrome://extensions?id='+ chrome.runtime.id });
return false;
}
return false; return false;
}; }
} else return false;
setStatusTo('PAC-скрипт установлен.'); };
enableDisableInputs(); } else
}); setStatusTo('PAC-скрипт установлен.');
} enableDisableInputs();
});
} }
}
setStatusTo(''); setStatusTo('');
checkChosenProvider(); checkChosenProvider();
if (antiCensorRu.ifFirstInstall) if (antiCensorRu.ifFirstInstall)
triggerChosenProvider(); triggerChosenProvider();
}); });
}

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Ищу IP...</title>
<script src="./index.js"></script>
</head>
</html>

View File

@ -0,0 +1,26 @@
'use strict';
chrome.runtime.getBackgroundPage( backgroundPage => {
var hostname = window.location.search.substring(1);
backgroundPage.getIpsAndCnames( hostname, (err, records) =>
err
? document.write(
`<title>IP уже нет</title>
Не могу получить IP для домена "${hostname}". Домена уже нет?<br/>
Ошибка:<br/>
${err.clarification && err.clarification.message || err.message}`
)
: records.length === 1 && records[0].type === 'A'
? window.location.replace( backgroundPage.reestrUrl + records[0].rdata )
: document.write(
'<title>Выбор IP</title>'
+ '<h4>У домена несколько IP / синонимов:</h4>'
+ records
.sort( (a,b) => a.rdata.localeCompare(b.rdata) )
.map( ans => ans.rdata.link( ans.type === 'A' ? backgroundPage.reestrUrl + ans.rdata : window.location.pathname +'?'+ ans.rdata ) )
.join('<br/>')
)
)
})

View File

@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<title>По-другому</title>
<style></style>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>

View File

@ -0,0 +1,25 @@
'use strict';
var url = decodeURIComponent(window.location.search.substring(1));
document.body.innerHTML = `
<input type="text" value="${url}" autofocus style="width: 100%; border: 0; outline: none; font-size: 2em"/>
<button>Копировать</button>
<h3>Веб-прокси</h3>
<a href="https://www.vpnbook.com/webproxy">vpnbook [COPY]</a><br/>
<a href="https://webproxy.com/browse.php?u=${url}">webproxy.com</a><br/>
<a href="http://buka.link/browse.php?u=${url.replace(/\?.+/,'')}">buka.link [AVAST]</a><br/>
<a href="https://hide.me/en/proxy">hide.me [COPY]</a><br/>
<a href="https://www.hidemyass.com/proxy">Hide my ass [COPY]</a><br/>
<a href="https://www.google.com/search?q=webproxy">Другие</a>
<h3>Из кеша поисковиков</h3>
<a href="https://webcache.googleusercontent.com/search?q=cache:${url}">Google</a></br>
<a href="http://viewcached.com/${url}">viewcached.com</a></br>
<a href="http://cachedview.com">cachedview.com [COPY]</a>
<h3>Из архивов Интернета</h3>
<a href="http://web.archive.org/web/*/${url}">web.archive.org</a><br/>
<a href="http://archive.is/${url}">archive.is</a><br/>
<a href="http://timetravel.mementoweb.org">Momento Time Travel [COPY]</a>
`;
var _ = document.querySelector('input');
_.onfocus = function() { this.select() };
document.querySelector('button').onclick = () => {_.focus(); document.execCommand('copy')};

0
pac-generator/dump.csv Normal file → Executable file
View File

Can't render this file because it is too large.

View File

0
pac-performance-analyses/benchmark/Program.cs Normal file → Executable file
View File

0
pac-performance-analyses/benchmark/project.json Normal file → Executable file
View File

0
pac-performance-analyses/chart/README.md Normal file → Executable file
View File

0
pac-performance-analyses/chart/src/data.tsv Normal file → Executable file
View File

0
pac-performance-analyses/chart/src/index.html Normal file → Executable file
View File