mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-24 02:13:43 +03:00
Add exceptions w/o working UI yet
This commit is contained in:
parent
ff5c51af11
commit
2dacd14f57
|
@ -18,7 +18,7 @@
|
||||||
|
|
||||||
const _match = function _match(ipRe, str) {
|
const _match = function _match(ipRe, str) {
|
||||||
|
|
||||||
let m = (str.match(ipRe) || []).filter( (c) => c );
|
const m = (str.match(ipRe) || []).filter( (c) => c );
|
||||||
const port = m.length > 1 ? m.pop() : false;
|
const port = m.length > 1 ? m.pop() : false;
|
||||||
return { ifMatched: m.length, port: port };
|
return { ifMatched: m.length, port: port };
|
||||||
|
|
||||||
|
@ -55,17 +55,19 @@
|
||||||
|
|
||||||
const privates = {};
|
const privates = {};
|
||||||
|
|
||||||
|
const _createHostObj = function _addHostObj(hostStr) {
|
||||||
|
|
||||||
|
return (privates._strToHostObj[hostStr] = { host: hostStr });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
const _getHostObj = function _getHostObj(hostStr) {
|
const _getHostObj = function _getHostObj(hostStr) {
|
||||||
|
|
||||||
let hostObj = privates._strToHostObj[hostStr];
|
return privates._strToHostObj[hostStr] || _createHostObj(hostStr);
|
||||||
if (!hostObj) {
|
|
||||||
hostObj = privates._strToHostObj[hostStr] = { host: hostStr };
|
|
||||||
}
|
|
||||||
return hostObj;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const init = function init() {
|
const reinit = function reinit() {
|
||||||
|
|
||||||
// Defaults.
|
// Defaults.
|
||||||
const _antizapret = {
|
const _antizapret = {
|
||||||
|
@ -100,7 +102,7 @@
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
init();
|
reinit();
|
||||||
|
|
||||||
const getIpsFor = function getIpsFor(host, cb = mandatory()) {
|
const getIpsFor = function getIpsFor(host, cb = mandatory()) {
|
||||||
|
|
||||||
|
@ -200,7 +202,15 @@
|
||||||
resetToDefaultsVoid() {
|
resetToDefaultsVoid() {
|
||||||
|
|
||||||
_state(ip2host, null);
|
_state(ip2host, null);
|
||||||
init();
|
reinit();
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_purgeIpsForVoid(hostStr) {
|
||||||
|
|
||||||
|
for(const ip of Object.keys(privates._ipToHostObj)) {
|
||||||
|
delete privates._ipToHostObj[ip];
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -210,6 +220,7 @@
|
||||||
|
|
||||||
console.log('IPS', ips);
|
console.log('IPS', ips);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
|
this._purgeIpsForVoid(hostStr);
|
||||||
// Object may be shared, string can't.
|
// Object may be shared, string can't.
|
||||||
const hostObj = _getHostObj(hostStr);
|
const hostObj = _getHostObj(hostStr);
|
||||||
for(const ip of ips) {
|
for(const ip of ips) {
|
||||||
|
@ -222,14 +233,9 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_replaceAllAsync(hostArr = mandatory(), cb) {
|
updateAllAsync(cb = mandatory()) {
|
||||||
|
|
||||||
if (typeof(hostArr) === 'function') {
|
const hostArr = Object.keys(privates._strToHostObj);
|
||||||
cb = hostArr;
|
|
||||||
hostArr = Object.keys(privates._strToHostObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resetToDefaultsVoid();
|
|
||||||
|
|
||||||
const promises = hostArr.map(
|
const promises = hostArr.map(
|
||||||
(hostStr) => new Promise( (resolve) => this._addAsync(hostStr, (...args) => resolve(args) ) )
|
(hostStr) => new Promise( (resolve) => this._addAsync(hostStr, (...args) => resolve(args) ) )
|
||||||
|
@ -261,6 +267,22 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_replaceAllAsync(hostArr = mandatory(), cb) {
|
||||||
|
|
||||||
|
if (typeof(hostArr) === 'function') {
|
||||||
|
cb = hostArr;
|
||||||
|
hostArr = Object.keys(privates._strToHostObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.resetToDefaultsVoid();
|
||||||
|
for(const hostStr of hostArr) {
|
||||||
|
_createHostObj(hostStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateAllAsync(cb);
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
replaceAllAsync(addrArr, cb = mandatory()) {
|
replaceAllAsync(addrArr, cb = mandatory()) {
|
||||||
|
|
||||||
console.log('Replacing...');
|
console.log('Replacing...');
|
||||||
|
@ -282,12 +304,6 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAllAsync(cb = mandatory()) {
|
|
||||||
|
|
||||||
this._replaceAllAsync(cb);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
get(ip) {
|
get(ip) {
|
||||||
|
|
||||||
const tmp = privates._ipToHostObj[ip];
|
const tmp = privates._ipToHostObj[ip];
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
const kitchenState = window.utils.createStorage('pac-kitchen-');
|
const kitchenState = window.utils.createStorage('pac-kitchen-');
|
||||||
const ifIncontinence = 'if-incontinence';
|
const ifIncontinence = 'if-incontinence';
|
||||||
|
|
||||||
|
// Don't keep objects in defaults or at least freeze them!
|
||||||
const configs = {
|
const configs = {
|
||||||
|
|
||||||
ifProxyHttpsUrlsOnly: {
|
ifProxyHttpsUrlsOnly: {
|
||||||
|
@ -24,23 +25,35 @@
|
||||||
desc: 'Шифровать соединение до прокси от провайдера. Провайдер всё же сможет видеть адреса (но не содержимое) проксируемых ресурсов из протокола DNS.',
|
desc: 'Шифровать соединение до прокси от провайдера. Провайдер всё же сможет видеть адреса (но не содержимое) проксируемых ресурсов из протокола DNS.',
|
||||||
index: 1,
|
index: 1,
|
||||||
},
|
},
|
||||||
|
ifProhibitDns: {
|
||||||
|
dflt: false,
|
||||||
|
label: 'запретить опредление по IP/DNS',
|
||||||
|
desc: 'Пытается запретить скрипту использовать DNS, без которого определение блокировки по IP работать не будет. Используйте, если вам кажется, что мы проксируем слишком много сайтов.',
|
||||||
|
index: 2,
|
||||||
|
},
|
||||||
ifUsePacScriptProxies: {
|
ifUsePacScriptProxies: {
|
||||||
dflt: true,
|
dflt: true,
|
||||||
label: 'использовать прокси PAC-скрипта',
|
label: 'использовать прокси PAC-скрипта',
|
||||||
desc: 'Использовать прокси от авторов PAC-скрипта.',
|
desc: 'Использовать прокси от авторов PAC-скрипта.',
|
||||||
index: 2,
|
index: 3,
|
||||||
},
|
},
|
||||||
ifUseLocalTor: {
|
ifUseLocalTor: {
|
||||||
dflt: false,
|
dflt: false,
|
||||||
label: 'использовать свой локальный TOR',
|
label: 'использовать СВОЙ локальный TOR',
|
||||||
desc: 'Установите TOR на свой компьютер и используйте его как прокси. <a href="https://rebrand.ly/ac-tor">ВАЖНО</a>',
|
desc: 'Установите <a href="https://ru.wikipedia.org/wiki/Tor">TOR</a> на свой компьютер и используйте его как прокси. <a href="https://rebrand.ly/ac-tor">ВАЖНО</a>',
|
||||||
index: 3,
|
index: 4,
|
||||||
|
},
|
||||||
|
exceptions: {
|
||||||
|
dflt: null,
|
||||||
|
label: 'учитывать исключения',
|
||||||
|
desc: 'Учитывать сайты, добавленные вручную. Только для своих прокси! Без своих прокси работать не будет.',
|
||||||
|
index: 5,
|
||||||
},
|
},
|
||||||
customProxyStringRaw: {
|
customProxyStringRaw: {
|
||||||
dflt: '',
|
dflt: '',
|
||||||
label: 'использовать свои прокси',
|
label: 'использовать СВОИ прокси',
|
||||||
url: 'https://rebrand.ly/ac-own-proxy',
|
url: 'https://rebrand.ly/ac-own-proxy',
|
||||||
index: 4,
|
index: 6,
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -59,21 +72,18 @@
|
||||||
const getCurrentConfigs = function getCurrentConfigs() {
|
const getCurrentConfigs = function getCurrentConfigs() {
|
||||||
|
|
||||||
const mods = kitchenState('mods');
|
const mods = kitchenState('mods');
|
||||||
if (!mods) {
|
return new PacModifiers(mods || {});
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return new PacModifiers(mods);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOrderedConfigsForUser = function getOrderedConfigs() {
|
const getOrderedConfigsForUser = function getOrderedConfigs() {
|
||||||
|
|
||||||
const pacMods = getCurrentConfigs() || {};
|
const pacMods = getCurrentConfigs();
|
||||||
return Object.keys(configs).reduce((arr, key) => {
|
return Object.keys(configs).reduce((arr, key) => {
|
||||||
|
|
||||||
const conf = configs[key]
|
const conf = configs[key]
|
||||||
arr[conf.index] = conf;
|
arr[conf.index] = conf;
|
||||||
conf.value = (key in pacMods) ? pacMods[key] : conf.dflt;
|
conf.value = pacMods[key];
|
||||||
conf.key = key;
|
conf.key = key;
|
||||||
return arr;
|
return arr;
|
||||||
|
|
||||||
|
@ -89,7 +99,8 @@
|
||||||
const ifAllDefaults =
|
const ifAllDefaults =
|
||||||
Object.keys(defaults)
|
Object.keys(defaults)
|
||||||
.every(
|
.every(
|
||||||
(prop) => !(prop in mods) || Boolean(defaults[prop]) === Boolean(mods[prop])
|
(prop) => !(prop in mods)
|
||||||
|
|| Boolean(defaults[prop]) === Boolean(mods[prop])
|
||||||
);
|
);
|
||||||
|
|
||||||
Object.assign(this, defaults, mods);
|
Object.assign(this, defaults, mods);
|
||||||
|
@ -121,13 +132,31 @@
|
||||||
this.filteredCustomsString = '';
|
this.filteredCustomsString = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.exceptions) {
|
||||||
|
this.included = [];
|
||||||
|
this.excluded = [];
|
||||||
|
for(const host of Object.keys(this.exceptions)) {
|
||||||
|
if (this.exceptions[host]) {
|
||||||
|
this.included.push(host)
|
||||||
|
} else {
|
||||||
|
this.excluded.push(host);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.included && !this.filteredCustomsString) {
|
||||||
|
throw new TypeError(
|
||||||
|
'Проксировать свои сайты можно только через свои прокси. Нет ни одного своего прокси, удовлетворяющего вашим требованиям!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
window.apis.pacKitchen = {
|
window.apis.pacKitchen = {
|
||||||
|
|
||||||
getConfigs: getOrderedConfigsForUser,
|
getPacMods: getCurrentConfigs,
|
||||||
|
getOrderedConfigs: getOrderedConfigsForUser,
|
||||||
|
|
||||||
cook(pacData, pacMods = mandatory()) {
|
cook(pacData, pacMods = mandatory()) {
|
||||||
|
|
||||||
|
@ -139,22 +168,42 @@
|
||||||
global.FindProxyForURL = function(url, host) {
|
global.FindProxyForURL = function(url, host) {
|
||||||
${function() {
|
${function() {
|
||||||
|
|
||||||
let res = '';
|
let res = pacMods.ifProhibitDns ? `
|
||||||
|
global.dnsResolve = function(host) { return null; };
|
||||||
|
` : '';
|
||||||
if (pacMods.ifProxyHttpsUrlsOnly) {
|
if (pacMods.ifProxyHttpsUrlsOnly) {
|
||||||
|
|
||||||
res = `
|
res += `
|
||||||
if (!url.startsWith("https")) {
|
if (!url.startsWith("https")) {
|
||||||
return "DIRECT";
|
return "DIRECT";
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
if(
|
}
|
||||||
!pacMods.ifUseSecureProxiesOnly &&
|
|
||||||
!pacMods.filteredCustomsString &&
|
if (pacMods.included && pacMods.included.length) {
|
||||||
pacMods.ifUsePacScriptProxies
|
res += `
|
||||||
) {
|
if ( ${JSON.stringify(pacMods.included)}.some( (included) => host.endsWith(included) ) ) {
|
||||||
return res + `
|
return "${pacMods.filteredCustomsString}; DIRECT";
|
||||||
return originalFindProxyForURL(url, host);`;
|
}
|
||||||
}
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pacMods.excluded && pacMods.excluded.length) {
|
||||||
|
res += `
|
||||||
|
if ( ${JSON.stringify(pacMods.excluded)}.some( (excluded) => host.endsWith(excluded) ) ) {
|
||||||
|
return "DIRECT";
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(
|
||||||
|
!pacMods.ifUseSecureProxiesOnly &&
|
||||||
|
!pacMods.filteredCustomsString &&
|
||||||
|
pacMods.ifUsePacScriptProxies
|
||||||
|
) {
|
||||||
|
return res + `
|
||||||
|
return originalFindProxyForURL(url, host);
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res + `
|
return res + `
|
||||||
|
@ -296,9 +345,7 @@
|
||||||
return originalSet(details, cb);
|
return originalSet(details, cb);
|
||||||
}
|
}
|
||||||
const pacMods = getCurrentConfigs();
|
const pacMods = getCurrentConfigs();
|
||||||
if (pacMods) {
|
pac.data = pacKitchen.cook( pac.data, pacMods );
|
||||||
pac.data = pacKitchen.cook( pac.data, pacMods );
|
|
||||||
}
|
|
||||||
originalSet({ value: details.value }, (/* No args. */) => {
|
originalSet({ value: details.value }, (/* No args. */) => {
|
||||||
|
|
||||||
kitchenState(ifIncontinence, null);
|
kitchenState(ifIncontinence, null);
|
||||||
|
|
|
@ -125,11 +125,11 @@
|
||||||
|
|
||||||
let previousUpdateTitleFinished = Promise.resolve();
|
let previousUpdateTitleFinished = Promise.resolve();
|
||||||
|
|
||||||
const isProxiedAndInformed = function isProxiedAndInformed(requestDetails) {
|
const tryProxyAndInform = function tryProxyAndInform(requestDetails) {
|
||||||
|
|
||||||
const host = window.apis.ipToHost.get( requestDetails.ip );
|
const host = window.apis.ipToHost.get( requestDetails.ip );
|
||||||
if (!host) {
|
if (!host) {
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ifMainFrame = requestDetails.type === 'main_frame';
|
const ifMainFrame = requestDetails.type === 'main_frame';
|
||||||
|
@ -144,27 +144,27 @@
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isInsideTabWithIp = function isInsideTabWithIp(requestDetails) {
|
const isInsideTabWithIp = function isInsideTabWithIp(requestDetails) {
|
||||||
|
|
||||||
return requestDetails.tabId !== -1 && requestDetails.ip;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
chrome.webRequest.onResponseStarted.addListener(
|
const onRequest = function onRequest(requestDetails) {
|
||||||
(requestDetails) => isInsideTabWithIp(requestDetails)
|
|
||||||
&& isProxiedAndInformed(requestDetails),
|
|
||||||
{urls: ['<all_urls>']}
|
|
||||||
);
|
|
||||||
|
|
||||||
chrome.webRequest.onErrorOccurred.addListener(
|
const ifInsideTabWithIp = requestDetails.tabId !== -1 && requestDetails.ip;
|
||||||
(requestDetails) =>
|
if (ifInsideTabWithIp) {
|
||||||
isInsideTabWithIp(requestDetails)
|
tryProxyAndInform(requestDetails);
|
||||||
&& isProxiedAndInformed(requestDetails),
|
}
|
||||||
{urls: ['<all_urls>']}
|
|
||||||
);
|
};
|
||||||
|
|
||||||
|
for(const eventName of ['onResponseStarted', 'onErrorOccurred']) {
|
||||||
|
chrome.webRequest[eventName].addListener(
|
||||||
|
onRequest,
|
||||||
|
{urls: ['<all_urls>']}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,23 +6,25 @@
|
||||||
:root {
|
:root {
|
||||||
--ribbon-color: #4169e1; /* #1a6cc8 */
|
--ribbon-color: #4169e1; /* #1a6cc8 */
|
||||||
}
|
}
|
||||||
div, section {
|
body {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.main-padded {
|
||||||
|
margin: 0 17px;
|
||||||
|
}
|
||||||
|
div, section, header {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
header {
|
|
||||||
margin: 0 0 0.4em;
|
.valign-parent {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
section header {
|
section header h4 {
|
||||||
display: block;
|
margin: 0 0 0 0.7em;
|
||||||
border-bottom: 1px solid #558abb;
|
|
||||||
border-left: 5px solid #1048ac;
|
|
||||||
margin: 0;
|
|
||||||
position: relative;
|
|
||||||
height: 2em;
|
|
||||||
background-color: DodgerBlue;
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
|
@ -46,6 +48,14 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
border-width: 1px 0 0 0;
|
||||||
|
margin: 0 0 0.6em 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* COMMON */
|
||||||
|
|
||||||
.link-button, .link-button:visited {
|
.link-button, .link-button:visited {
|
||||||
color: #0000EE;
|
color: #0000EE;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -54,27 +64,30 @@
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checked-radio-panel {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
input:checked ~ .checked-radio-panel {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
hr {
|
|
||||||
border-width: 1px 0 0 0;
|
|
||||||
margin: 0.6em 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
#none:checked + label {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
.if-not-controlled {
|
.if-not-controlled {
|
||||||
display: none;
|
display: none;
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
li.info-row {
|
|
||||||
|
/* PAC PROVIDER */
|
||||||
|
|
||||||
|
.update-button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
input:checked ~ .update-button {
|
||||||
|
visibility: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
#none:checked + label {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* INFO SIGNS */
|
||||||
|
|
||||||
|
.info-row {
|
||||||
display: table;
|
display: table;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.info-sign {
|
.info-sign {
|
||||||
|
@ -84,11 +97,15 @@
|
||||||
margin-left: 0.1em;
|
margin-left: 0.1em;
|
||||||
}
|
}
|
||||||
.info-url {
|
.info-url {
|
||||||
float: right;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
line-height: initial;
|
|
||||||
vertical-align: bottom !important;
|
float: right;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
line-height: normal !important;
|
||||||
|
vertical-align: top !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Source: https://jsfiddle.net/greypants/zgCb7/ */
|
/* Source: https://jsfiddle.net/greypants/zgCb7/ */
|
||||||
.desc {
|
.desc {
|
||||||
display: table-cell;
|
display: table-cell;
|
||||||
|
@ -137,16 +154,76 @@
|
||||||
left: 75%;
|
left: 75%;
|
||||||
width: calc(25% + 0.6em);
|
width: calc(25% + 0.6em);
|
||||||
}
|
}
|
||||||
#custom-proxy-string-raw ~ textarea {
|
|
||||||
|
/* PAC MODS & EXCEPTIONS */
|
||||||
|
|
||||||
|
#mods-custom-proxy-string-raw ~ textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 7em;
|
height: 7em;
|
||||||
margin-top: 0.3em;
|
margin-top: 0.3em;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
#custom-proxy-string-raw:not(:checked) ~ textarea {
|
#mods-custom-proxy-string-raw:not(:checked) ~ textarea {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#this-yes:disabled + label {
|
||||||
|
color: grey;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EXCEPTIONS */
|
||||||
|
|
||||||
|
#right-flexed-editor {
|
||||||
|
flex-grow: 99;
|
||||||
|
|
||||||
|
max-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#right-flexed-editor > * {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#except-editor {
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-bottom: 0;
|
||||||
|
max-height: 1.6em !important;
|
||||||
|
min-height: 1.6em !important;
|
||||||
|
|
||||||
|
flex-grow: 99;
|
||||||
|
}
|
||||||
|
#bottom-flexed-editor {
|
||||||
|
flex-grow: 99;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
select#exceptions-select {
|
||||||
|
color: black;
|
||||||
|
background: transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
text-shadow: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#exc-flex-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#exc-flex-container > * {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CONTROL RAW = BUTTON + LINK */
|
||||||
|
|
||||||
.control-row {
|
.control-row {
|
||||||
display: table;
|
display: table;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -160,107 +237,194 @@
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
select#exceptions-select {
|
.main-nav {
|
||||||
color: black;
|
display: flex;
|
||||||
background: transparent;
|
flex-direction: column;
|
||||||
border-radius: 0;
|
counter-reset: line;
|
||||||
box-shadow: none;
|
|
||||||
text-shadow: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
#flex-right {
|
|
||||||
flex-grow: 99;
|
|
||||||
}
|
|
||||||
#flex-right > * {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#except-editor {
|
|
||||||
border-radius: 0 !important;
|
|
||||||
border-bottom: 0;
|
|
||||||
height: 1.6em !important;
|
|
||||||
min-height: 1.6em !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#flex-container {
|
/* ACCORDION */
|
||||||
position: relative;
|
|
||||||
padding: 0;
|
.accordion-radio {
|
||||||
margin: 0;
|
display: none;
|
||||||
display: flex;
|
|
||||||
}
|
}
|
||||||
#flex-container > * {
|
.accordion-title {
|
||||||
flex-grow: 1;
|
position: relative;
|
||||||
|
height: 1.8em;
|
||||||
|
border-bottom: 1px solid #558abb;
|
||||||
|
}
|
||||||
|
.accordion-title label:before {
|
||||||
|
content: counter(line) '.';
|
||||||
|
counter-increment: line;
|
||||||
|
padding-left: 0.2em;
|
||||||
|
}
|
||||||
|
.accordion-title label {
|
||||||
|
background-color: transparent;
|
||||||
|
color: black;
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
.accordion-radio:checked + section {
|
||||||
|
order: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#status {
|
||||||
|
padding: 0 0.3em 1em;
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
order: 2;
|
||||||
|
/*border-left: 5px solid DodgerBlue;*/
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-radio:checked + section .accordion-title {
|
||||||
|
margin-top: 0.3em; /* Short gap. */
|
||||||
|
}
|
||||||
|
.accordion-radio:checked + section .accordion-title label,
|
||||||
|
.accordion-title:hover label
|
||||||
|
{
|
||||||
|
background-color: DodgerBlue;
|
||||||
|
color: white;
|
||||||
|
padding-left: 0;
|
||||||
|
border-left: 5px solid #1048ac;
|
||||||
|
}
|
||||||
|
.accordion-title label {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
.accordion-radio:not(:checked) + section .accordion-content {
|
||||||
|
/* Hide, but preclude width resizes. */
|
||||||
|
height: 0px !important;
|
||||||
|
line-height: 0px !important;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
display: block;
|
||||||
|
visibility: hidden;
|
||||||
|
transform:scaleY(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-radio:not(:checked) + section .accordion-content * {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-radio + section .accordion-content .acc-padded {
|
||||||
|
margin: 0.6em 0 1em 0.5em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<span class="if-not-controlled">
|
|
||||||
<span id="which-extension"></span>
|
<section class="if-not-controlled">
|
||||||
|
<div id="which-extension" class="main-padded" style="margin-bottom: 1em"></div>
|
||||||
<hr style="border-color: red; border-style: solid;"/>
|
<hr style="border-color: red; border-style: solid;"/>
|
||||||
</span>
|
|
||||||
<section>
|
|
||||||
<header>PAC-скрипт</header>
|
|
||||||
<ul id="list-of-providers">
|
|
||||||
<li><input type="radio" name="pacProvider" id="none" checked> <label for="none">Отключить</label></li>
|
|
||||||
</ul>
|
|
||||||
<div style="white-space: nowrap">
|
|
||||||
Обновлялись: <span class="update-date">...</span>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
<section id="status" style="will-change: contents">Загрузка...</section>
|
|
||||||
|
<nav class="main-padded main-nav">
|
||||||
|
|
||||||
|
<input type="radio" name="accordion" id="acc-pac-provider" class="accordion-radio" checked/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<header class='accordion-title'>
|
||||||
|
<label for="acc-pac-provider" class="valign-parent"><h4>PAC-скрипт</h4></label>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="accordion-content">
|
||||||
|
<div class="acc-padded">
|
||||||
|
<ul id="list-of-providers">
|
||||||
|
<li><input type="radio" name="pacProvider" id="none" checked> <label for="none">Отключить</label></li>
|
||||||
|
</ul>
|
||||||
|
<div style="white-space: nowrap">
|
||||||
|
Обновлялись: <span class="update-date">...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<input type="radio" name="accordion" id="acc-exceptions" class="accordion-radio"/>
|
||||||
|
|
||||||
|
<section id="exceptions">
|
||||||
|
|
||||||
|
<header class='accordion-title'>
|
||||||
|
<label for="acc-exceptions" class="valign-parent"><h4>Проксировать этот сайт?</h4></label>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="accordion-content">
|
||||||
|
<div class="acc-padded" id="exc-flex-container">
|
||||||
|
<ul style="padding-right: 1em">
|
||||||
|
<li><input id="this-auto" type="radio" checked name="if-proxy-this-site"/> <label for="this-auto">🔄︎ авто</label></li>
|
||||||
|
<li><input id="this-yes" type="radio" name="if-proxy-this-site"/> <label for="this-yes">✔ да</label></li>
|
||||||
|
<li><input id="this-no" type="radio" name="if-proxy-this-site"/> <label for="this-no">✘ нет</label></li>
|
||||||
|
<li><a href>Весь список</a></li>
|
||||||
|
</ul>
|
||||||
|
<div id="right-flexed-editor">
|
||||||
|
<input type="text" value="google.com" id="except-editor"/>
|
||||||
|
<div id="bottom-flexed-editor">
|
||||||
|
|
||||||
|
<select multiple id="exceptions-select"></select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<input type="radio" name="accordion" id="acc-pac-mods" class="accordion-radio"/>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<header class='accordion-title'>
|
||||||
|
<label for="acc-pac-mods" class="valign-parent"><h4>Модификаторы PAC-скрипта</h4></label>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="accordion-content">
|
||||||
|
<div class="acc-padded">
|
||||||
|
<ul id="pac-mods">
|
||||||
|
<li class="control-row">
|
||||||
|
<input type="button" value="Применить" id="apply-mods" disabled/>
|
||||||
|
<a href id="reset-mods" class="link-button">К изначальным!</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<input type="radio" name="accordion" id="acc-notifications" class="accordion-radio"/>
|
||||||
|
|
||||||
|
<section id="configs-panel">
|
||||||
|
|
||||||
|
<header class='accordion-title'>
|
||||||
|
<label for="acc-notifications" class="valign-parent"><h4>Уведомления</h4></label>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="accordion-content">
|
||||||
|
<div class="acc-padded">
|
||||||
|
<ul id="list-of-handlers"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</nav>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<div id="exceptions">
|
|
||||||
<header>Проксировать этот сайт?</header>
|
<div class="main-padded">
|
||||||
<div id="flex-container">
|
|
||||||
<ul style="padding-right: 1em">
|
<div id="status" style="will-change: contents">Загрузка...</div>
|
||||||
<li><input id="this-auto" type="radio" checked name="if-proxy-this-site"/> <label for="this-auto">🔄︎ авто</label></li>
|
|
||||||
<li><input id="this-yes" type="radio" name="if-proxy-this-site"/> <label for="this-yes">✔ да</label></li>
|
|
||||||
<li><input id="this-no" type="radio" name="if-proxy-this-site"/> <label for="this-no">✘ нет</label></li>
|
|
||||||
<li><a href>Весь список</a></li>
|
|
||||||
</ul>
|
|
||||||
<div id="flex-right">
|
|
||||||
<input type="text" value="google.com" id="except-editor"/>
|
|
||||||
<select multiple id="exceptions-select">
|
|
||||||
<option class="sel">google.com</option>
|
|
||||||
<option class="sel">yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
<option>yandex.ru</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr/>
|
|
||||||
<ul id="pac-mods">
|
|
||||||
<li class="control-row">
|
|
||||||
<input type="button" value="Применить" id="apply-mods" disabled/>
|
|
||||||
<a href id="reset-mods" class="link-button">К изначальным!</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<hr/>
|
|
||||||
<div id="configs-panel">
|
|
||||||
<header>Я ❤️ уведомления:</header>
|
|
||||||
<ul id="list-of-handlers"></ul>
|
|
||||||
</div>
|
|
||||||
<footer class="control-row">
|
<footer class="control-row">
|
||||||
<input type="button" value="Готово" class="close-button">
|
<input type="button" value="Готово" class="close-button">
|
||||||
<a href="../troubleshoot/index.html" class="link-button">
|
<a href="../troubleshoot/index.html" class="link-button">
|
||||||
Проблемы?
|
Проблемы?
|
||||||
</a>
|
</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="./index.js"></script>
|
<script src="./index.js"></script>
|
||||||
<script src="../lib/keep-links-clickable.js"></script>
|
<script src="../lib/keep-links-clickable.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -173,7 +173,7 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
li.innerHTML = `
|
li.innerHTML = `
|
||||||
<input type="radio" name="pacProvider" id="${providerKey}">
|
<input type="radio" name="pacProvider" id="${providerKey}">
|
||||||
<label for="${providerKey}"> ${provider.label}</label>
|
<label for="${providerKey}"> ${provider.label}</label>
|
||||||
<a href class="link-button checked-radio-panel"
|
<a href class="link-button update-button"
|
||||||
id="update-${providerKey}">[обновить]</a> ` +
|
id="update-${providerKey}">[обновить]</a> ` +
|
||||||
infoSign(provider.desc);
|
infoSign(provider.desc);
|
||||||
li.querySelector('.link-button').onclick =
|
li.querySelector('.link-button').onclick =
|
||||||
|
@ -224,39 +224,74 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
|
|
||||||
// EXCEPTIONS PANEL
|
// EXCEPTIONS PANEL
|
||||||
|
|
||||||
chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
|
|
||||||
|
|
||||||
/*
|
|
||||||
console.log(tab);
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.text =
|
|
||||||
opt.selected = true;
|
|
||||||
opt.style.backgroundColor = 'green !important';
|
|
||||||
opt.style.background = 'green !important';
|
|
||||||
|
|
||||||
const sl = document.getElementById('exceptions-select');
|
|
||||||
sl.insertBefore( opt, sl.firstChild );
|
|
||||||
*/
|
|
||||||
|
|
||||||
document.getElementById('except-editor').value = new URL(tab.url).hostname;
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// PAC MODS PANEL
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const pacKitchen = backgroundPage.apis.pacKitchen;
|
const pacKitchen = backgroundPage.apis.pacKitchen;
|
||||||
|
|
||||||
|
chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
|
||||||
|
|
||||||
|
document.getElementById('except-editor').value = new URL(tab.url).hostname;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
const pacMods = pacKitchen.getPacMods();
|
||||||
|
const exc = pacMods.exceptions || {};
|
||||||
|
|
||||||
|
const addOption = function addOption(host) {
|
||||||
|
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.text = host;
|
||||||
|
document.getElementById('exceptions-select').add(opt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const host of Object.keys(exc).sort()) {
|
||||||
|
addOption(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('this-yes').onclick = function() {
|
||||||
|
|
||||||
|
const pacMods = pacKitchen.getPacMods();
|
||||||
|
if (!pacMods.filteredCustomsString) {
|
||||||
|
showErrors( new TypeError(
|
||||||
|
'Проксировать СВОИ сайты можно только при наличии СВОИХ прокси (см.«Модификаторы»).'
|
||||||
|
));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const host = document.getElementById('except-editor').value;
|
||||||
|
const ValidHostnameRegex = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||||
|
if(!ValidHostnameRegex.test(host)) {
|
||||||
|
showErrors(new TypeError('Должно быть только доменное имя, без протокола и пути. Попробуйте ещё раз.'));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pacMods.exceptions = pacMods.exceptions || {};
|
||||||
|
pacMods.exceptions[host] = true;
|
||||||
|
pacKitchen.keepCookedNowAsync(
|
||||||
|
pacMods,
|
||||||
|
(err) => err
|
||||||
|
? showErrors(err)
|
||||||
|
: addOption(host)
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// PAC MODS PANEL
|
||||||
|
|
||||||
const modPanel = document.getElementById('pac-mods');
|
const modPanel = document.getElementById('pac-mods');
|
||||||
const _firstChild = modPanel.firstChild;
|
const _firstChild = modPanel.firstChild;
|
||||||
const keyToLi = {};
|
const keyToLi = {};
|
||||||
const customProxyStringKey = 'customProxyStringRaw';
|
const customProxyStringKey = 'customProxyStringRaw';
|
||||||
const uiRaw = 'ui-proxy-string-raw';
|
const uiRaw = 'ui-proxy-string-raw';
|
||||||
pacKitchen.getConfigs().forEach( (conf) => {
|
|
||||||
|
for(const conf of pacKitchen.getOrderedConfigs()) {
|
||||||
|
|
||||||
const key = conf.key;
|
const key = conf.key;
|
||||||
const iddy = conf.key.replace(/([A-Z])/g, (_, p) => '-' + p.toLowerCase());
|
const iddy = 'mods-' + conf.key.replace(/([A-Z])/g, (_, p) => '-' + p.toLowerCase());
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
li.className = 'info-row';
|
li.className = 'info-row';
|
||||||
keyToLi[key] = li;
|
keyToLi[key] = li;
|
||||||
|
@ -283,7 +318,7 @@ HTTPS 11.22.33.44:8080;">${conf.value || localStorage.getItem(uiRaw) || ''}</tex
|
||||||
|
|
||||||
modPanel.insertBefore( li, _firstChild );
|
modPanel.insertBefore( li, _firstChild );
|
||||||
|
|
||||||
});
|
};
|
||||||
document.getElementById('apply-mods').onclick = () => {
|
document.getElementById('apply-mods').onclick = () => {
|
||||||
|
|
||||||
const configs = Object.keys(keyToLi).reduce( (configs, key) => {
|
const configs = Object.keys(keyToLi).reduce( (configs, key) => {
|
||||||
|
@ -298,7 +333,7 @@ HTTPS 11.22.33.44:8080;">${conf.value || localStorage.getItem(uiRaw) || ''}</tex
|
||||||
|
|
||||||
}, {});
|
}, {});
|
||||||
const taVal = keyToLi[customProxyStringKey].querySelector('textarea').value;
|
const taVal = keyToLi[customProxyStringKey].querySelector('textarea').value;
|
||||||
if (configs[customProxyStringKey]) {
|
if (configs[customProxyStringKey] !== false) {
|
||||||
const ifValid = taVal
|
const ifValid = taVal
|
||||||
.replace(/#.*$/mg)
|
.replace(/#.*$/mg)
|
||||||
.split(/\s*[;\n\r]+\s*/g)
|
.split(/\s*[;\n\r]+\s*/g)
|
||||||
|
@ -329,7 +364,7 @@ HTTPS 11.22.33.44:8080;">${conf.value || localStorage.getItem(uiRaw) || ''}</tex
|
||||||
|
|
||||||
const ifSure = backgroundPage.confirm('Сбросить все модификации PAC-скрипта?');
|
const ifSure = backgroundPage.confirm('Сбросить все модификации PAC-скрипта?');
|
||||||
if (!ifSure) {
|
if (!ifSure) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
pacKitchen.resetToDefaultsVoid();
|
pacKitchen.resetToDefaultsVoid();
|
||||||
backgroundPage.apis.ipToHost.resetToDefaultsVoid();
|
backgroundPage.apis.ipToHost.resetToDefaultsVoid();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user