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

View File

@ -68,6 +68,7 @@ window.antiCensorRu = {
_periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта Антизапрет',
pushToStorage(cb) {
console.log('Pushing...');
// Copy only settable properties.
var onlySettable = {};
@ -99,7 +100,7 @@ window.antiCensorRu = {
syncWithPacProvider(cb) {
var cb = asyncLogGroup('Syncing with PAC provider...', cb);
if (!this.pacProvider)
return cb({clarification: 'Сперва выберите PAC-провайдера.'});
return cb({clarification:{message:'Сперва выберите PAC-провайдера.'}});
var pacSetPromise = new Promise(
(resolve, reject) => setPacScriptFromProvider(
@ -140,7 +141,7 @@ window.antiCensorRu = {
var 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(
@ -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) {
@ -191,6 +192,7 @@ chrome.storage.local.get(null, oldStorage => {
// 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(
@ -222,7 +224,7 @@ chrome.storage.local.get(null, oldStorage => {
var ifAlarmTriggered = antiCensorRu.setAlarms();
if (antiCensorRu.version === oldStorage.version) {
// LAUNCH, RELOAD
// LAUNCH, RELOAD, ENABLE
antiCensorRu.pacProviders = oldStorage.pacProviders;
return console.log('Extension launched, reloaded or enabled.');
}
@ -232,7 +234,7 @@ chrome.storage.local.get(null, oldStorage => {
if (!ifAlarmTriggered)
updatePacProxyIps(
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() {
var args = [].slice.apply(arguments);
var cb = args.pop();
@ -267,25 +267,44 @@ function asyncLogGroup() {
}
}
function ifSuccessfulCode(status) {
return status >= 200 && status < 300 || status === 304;
function httpGet(url, cb) {
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) {
var cb = cb || (() => {});
var req = new XMLHttpRequest();
var ifAsync = true;
req.open('GET', url, ifAsync);
req.onload = event => {
if ( !ifSuccessfulCode(req.status) ) {
req.clarification = {message: 'Получен ответ с неудачным HTTP-кодом '+req.status+ '.'};
return cb(req);
function getIpsAndCnames(host, cb) {
httpGet(
'http://www.dns-lg.com/google1/'+ host +'/a',
(err, res) => {
if (res)
try {
res = JSON.parse(res);
if (err)
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) {
@ -296,14 +315,12 @@ function updatePacProxyIps(provider, cb) {
};
var i = 0;
provider.proxyHosts.map(
proxyHost => httpGet(
'http://www.dns-lg.com/google1/'+ proxyHost +'/A',
(err, res) => {
proxyHost => getIpsAndCnames(
proxyHost,
(err, ans) => {
if (!err) {
provider.proxyIps = provider.proxyIps || {};
JSON.parse(res).answer.map(
ans => provider.proxyIps[ ans.rdata ] = proxyHost
)
ans.filter( ans => ans.type === 'A' ).map( ans => provider.proxyIps[ ans.rdata ] = proxyHost );
} else
failure.errors[proxyHost] = err;
@ -324,7 +341,7 @@ function setPacScriptFromProvider(provider, cb) {
(err, res) => {
if (err) {
err.clarification = {
message: 'Не удалось скачать PAC-скрипт с адреса: ' +provider.pacUrl+ '.',
message: 'Не удалось скачать PAC-скрипт с адреса: '+ provider.pacUrl +'.',
prev: err.clarification
};
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,
"name": "Обход блокировок Рунета",
"name": "Обход блокировок Рунета NEW",
"description": "Аргументы против цензуры: https://git.io/vEkI9",
"version": "0.0.0.12",
"version": "0.0.0.14",
"icons": {
"128": "/icons/ribbon128.png"
},
@ -16,12 +16,14 @@
"alarms",
"storage",
"<all_urls>",
"tabs"
"tabs",
"contextMenus"
],
"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": {
"default_title": "Этот сайт благословлён РКН",
"default_popup": "/pages/choose-pac-provider/index.html"
},
"options_ui": {

View File

@ -1,9 +1,6 @@
'use strict';
renderPage();
function renderPage() {
console.log('Rendering started.');
chrome.runtime.getBackgroundPage( backgroundPage => {
function getStatus() {
return document.querySelector('#status');
@ -16,134 +13,127 @@ function renderPage() {
status.innerHTML = msg;
} else
status.classList.add('off');
}
var antiCensorRu = backgroundPage.antiCensorRu;
// 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 + ' назад';
}
var dateElement = document.querySelector('.update-date');
dateElement.innerText = dateForUser;
dateElement.title = new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU');
}
chrome.runtime.getBackgroundPage( backgroundPage => {
setDate();
chrome.storage.onChanged.addListener( changes => changes.lastPacUpdateStamp.newValue && setDate() );
var antiCensorRu = backgroundPage.antiCensorRu;
// CLOSE BUTTON
// SET DATE
document.querySelector('.close-button').onclick = () => window.close();
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 + ' назад';
// RADIOS
var currentRadio = () => {
var id = antiCensorRu.currentPacProviderKey || 'none';
return document.querySelector('#'+id);
}
var checkChosenProvider = () => {
var radio = currentRadio();
radio.checked = true;
}
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');
dateElement.innerText = dateForUser;
dateElement.title = new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU');
}
enableDisableInputs();
setStatusTo('Установка...');
antiCensorRu.installPac(pacKey, err => {
if (err) {
var ifNotCritical = err.clarification && err.clarification.ifNotCritical;
setDate();
chrome.storage.onChanged.addListener( setDate );
// CLOSE BUTTON
document.querySelector('.close-button').onclick = () => window.close();
// RADIOS
var currentRadio = () => {
var id = antiCensorRu.currentPacProviderKey || 'none';
return document.querySelector('#'+id);
}
var checkChosenProvider = () => {
var radio = currentRadio();
radio.checked = true;
}
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 = '\
var message = '';
var clarification = err.clarification;
do {
message = message +' '+ (clarification && clarification.message || err.message || '');
clarification = clarification.prev;
} while( clarification );
message = message.trim();
setStatusTo(
`<span style="color:red">${ifNotCritical ? 'Некритичная ошибка.' : 'Ошибка!'}</span>
<br/>
<span style="font-size: 0.9em; color: darkred">${message}</span>
<a href class="link-button">[Ещё&nbsp;подробнее]</a>`
);
getStatus().querySelector('.link-button').onclick = function() {
var div = document.createElement('div');
div.innerHTML = '\
Более подробную информацию можно узнать из логов фоновой страницы:<br/>\
<a href class="ext">chrome://extensions</a> Это расширение Отладка страниц: фоновая страница Console (DevTools)';
getStatus().replaceChild(div, this);
div.querySelector('.ext').onclick = () => {
chrome.tabs.create({ url: 'chrome://extensions?id='+ chrome.runtime.id });
return false;
}
getStatus().replaceChild(div, this);
div.querySelector('.ext').onclick = () => {
chrome.tabs.create({ url: 'chrome://extensions?id='+ chrome.runtime.id });
return false;
};
} else
setStatusTo('PAC-скрипт установлен.');
enableDisableInputs();
});
}
}
return false;
};
} else
setStatusTo('PAC-скрипт установлен.');
enableDisableInputs();
});
}
}
setStatusTo('');
checkChosenProvider();
if (antiCensorRu.ifFirstInstall)
triggerChosenProvider();
setStatusTo('');
checkChosenProvider();
if (antiCensorRu.ifFirstInstall)
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