From ba26eb1d32ed29864a3ed1250e0bbde98d8c9370 Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Fri, 19 May 2017 21:05:55 -0700 Subject: [PATCH 01/10] 0.0.0.34 --- .../chromium/runet-censorship-bypass/src/templates-data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/templates-data.js b/extensions/chromium/runet-censorship-bypass/src/templates-data.js index 78f75ec..7e0ab0a 100644 --- a/extensions/chromium/runet-censorship-bypass/src/templates-data.js +++ b/extensions/chromium/runet-censorship-bypass/src/templates-data.js @@ -1,7 +1,7 @@ 'use strict'; const commonContext = { - version: '0.33', + version: '0.34', }; exports.contexts = {}; From 37f0a51487ec248dfaaa80cdf4796841d6fefb1b Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Fri, 19 May 2017 21:25:43 -0700 Subject: [PATCH 02/10] Fix exc export page (again2) --- .../src/extension-common/pages/exceptions/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/exceptions/index.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/exceptions/index.js index a20eb9d..1b514f2 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/exceptions/index.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/exceptions/index.js @@ -20,12 +20,12 @@ chrome.runtime.getBackgroundPage( (backgroundPage) => # ПРОКСИРОВАТЬ: -${mods.included.join('\n')} +${(mods.included || []).join('\n')} =============================== # НЕ ПРОКСИРОВАТЬ: -${mods.excluded.join('\n')}`; +${(mods.excluded || []).join('\n')}`; status.innerText = 'Успешно загружено!'; From 11df7f6641882ad1d644c512878e9d98e20492d2 Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Fri, 19 May 2017 21:31:30 -0700 Subject: [PATCH 03/10] Improve icon grayscaled by chrome (again) --- .../icons/default-grayscale-128.png | Bin 5348 -> 7717 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/icons/default-grayscale-128.png b/extensions/chromium/runet-censorship-bypass/src/extension-common/icons/default-grayscale-128.png index 277056bd4aa386da1428e91f14ddb38fa97b16cd..eeadc198cbc1e6b05565974497864fea28931c4a 100644 GIT binary patch literal 7717 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

j=D$9HqhL7SE8P*-ZKiO3l9Be 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 Date: Sat, 17 Jun 2017 20:09:02 +0500 Subject: [PATCH 04/10] Remove mini from default build, restyle --- extensions/chromium/runet-censorship-bypass/gulpfile.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/gulpfile.js b/extensions/chromium/runet-censorship-bypass/gulpfile.js index 0f2ea15..94a2c00 100644 --- a/extensions/chromium/runet-censorship-bypass/gulpfile.js +++ b/extensions/chromium/runet-censorship-bypass/gulpfile.js @@ -17,12 +17,12 @@ const templatePlugin = (context) => through.obj(function(file, encoding, cb) { file.path = file.path.replace(new RegExp(`${tjson}$`), '.json'); if (file.isStream()) { - return cb(new PluginError(PluginName, 'Streams not supported!')); + return cb(new PluginError(PluginName, 'Streams are not supported!')); } else if (file.isBuffer()) { const {keys, values} = Object.keys(context).reduce( (acc, key) => { - const value = context[key]; + const value = context[key]; acc.keys.push(key); acc.values.push(value); return acc; @@ -103,4 +103,5 @@ gulp.task('_cp-full', ['_cp-common'], function(cb) { }); -gulp.task('build', ['_cp-mini', '_cp-full']); +gulp.task('build:prod', ['_cp-mini', '_cp-full']); +gulp.task('build', ['_cp-full']); From 040d598d67fe3f74dd2566c648541a801f7326f6 Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Sat, 17 Jun 2017 20:13:19 +0500 Subject: [PATCH 05/10] Remove extra spaces --- .../extension-common/pages/options/src/components/App.js | 2 +- .../pages/options/src/components/ExcEditor.js | 4 ++-- .../extension-common/pages/options/src/components/InfoLi.js | 2 +- .../extension-common/pages/options/src/components/Main.js | 2 +- .../pages/options/src/components/ModList.js | 2 +- .../pages/options/src/components/PacChooser.js | 2 +- .../pages/options/src/components/ProxyEditor.js | 6 +++--- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js index 4bfd555..be46259 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js @@ -206,7 +206,7 @@ export default function getApp(theState) { }; let messageHtml = err ? errToHtmlMessage(err) : ''; - + const warningHtml = warns .filter((w) => w) .map( diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ExcEditor.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ExcEditor.js index 378e92b..4bf2dbe 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ExcEditor.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ExcEditor.js @@ -65,7 +65,7 @@ export default function getExcEditor(theState) { return class ExcEditor extends Component { modsToOpts(pacMods) { - + return Object.keys(pacMods.exceptions || {}).sort().map( (excHost) => [excHost, pacMods.exceptions[excHost]] ); @@ -100,7 +100,7 @@ export default function getExcEditor(theState) { }, {}), }); - + } isHostValid(host) { diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/InfoLi.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/InfoLi.js index 131ff77..d1f1c53 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/InfoLi.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/InfoLi.js @@ -41,7 +41,7 @@ export default function getInfoLi() { .desc { text-align: right; color: var(--ribbon-color); - cursor: help; + cursor: help; padding-left: 0.3em; } .tooltip { diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js index 8ae6249..46b3fbc 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js @@ -96,7 +96,7 @@ export default function getMain(theState) { return acc; }, {}); - + this.setState({ catToOrderedMods: newCats, ifModsChangesStashed: true, diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js index d43c1c1..169eb43 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js @@ -7,7 +7,7 @@ export default function getModList(theState) { const InfoLi = getInfoLi(theState); - return class ModList extends Component { + return class ModList extends Component { constructor(props) { diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/PacChooser.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/PacChooser.js index c5b45b3..894c146 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/PacChooser.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/PacChooser.js @@ -88,7 +88,7 @@ export default function getPacChooser(theState) { radioClickHandler(event) { - const checkChosenProvider = () => + const checkChosenProvider = () => this.setState({ chosenPacName: this.getCurrentProviderId() }); const pacKey = event.target.id; diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js index bbca265..31a3eab 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js @@ -246,7 +246,7 @@ export default function getProxyEditor(theState) { proxyStrings.splice(index - 1, 2, proxyStrings[index], proxyStrings[index-1]); that.props.setProxyStringRaw( joinBySemi(proxyStrings) ); - + } handleSubmit(that, event) { @@ -528,7 +528,7 @@ PROXY foobar.com:8080; # Not HTTP!`.trim()} }; this.handleSwitch = () => this.setState({ifExportsMode: !this.state.ifExportsMode}); waitingTillMount.push(newValue); // Wait till mount or eat bugs. - + } componentDidMount() { @@ -570,7 +570,7 @@ PROXY foobar.com:8080; # Not HTTP!`.trim()} }, }, originalProps); - + return this.state.ifExportsMode ? createElement(ExportsEditor, props) : createElement(TabledEditor, props); From 092c999c59f7c08bfc1abccbbf66d64c93262d9e Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Sat, 17 Jun 2017 20:20:25 +0500 Subject: [PATCH 06/10] Fix type, restyle --- .../pages/options/src/components/ProxyEditor.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js index 31a3eab..ddec6e3 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js @@ -103,7 +103,7 @@ export default function getProxyEditor(theState) { right: 0; } table.editor .add { - font-weight: 900; + font-weight: 900; } table.editor .export { /*padding-right: 2px;*/ @@ -160,7 +160,7 @@ export default function getProxyEditor(theState) { }; const splitBySemi = (proxyString) => proxyString.replace(/#.*$/mg, '').trim().split(/\s*;\s*/g).filter((s) => s); const joinBySemi = (strs) => strs.join(';\n') + ';'; - const normilizeProxyString = (str) => joinBySemi(splitBySemi(str)); + const normalizeProxyString = (str) => joinBySemi(splitBySemi(str)); const PROXY_TYPE_LABEL_PAIRS = [['PROXY', 'PROXY/HTTP'],['HTTPS'],['SOCKS4'],['SOCKS5'],['SOCKS']]; @@ -437,7 +437,7 @@ export default function getProxyEditor(theState) { handleTextareaChange(that, event) { that.setState({ - stashedExports: normilizeProxyString(event.target.value), + stashedExports: normalizeProxyString(event.target.value), }); } From 2c3c36c6431c527b1ee86c124d1d6b220e2b6a8f Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Sat, 17 Jun 2017 20:42:23 +0500 Subject: [PATCH 07/10] Status is never empty --- .../src/extension-common/pages/options/src/components/App.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js index be46259..a6cfdda 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js @@ -36,7 +36,7 @@ export default function getApp(theState) { this.setState( { - status: msg, + status: msg || 'Хорошего настроения Вам!', }, cb ); @@ -156,7 +156,7 @@ export default function getApp(theState) { })(); if (!ifNewsWasSet) { - this.setStatusTo('Хорошего настроения Вам!'); + this.setStatusTo(); } } From 3e170fc7f49602be396063a4dc4dca87818fed63 Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Sat, 17 Jun 2017 20:43:08 +0500 Subject: [PATCH 08/10] Validate on change, not on switch --- .../options/src/components/ProxyEditor.js | 38 +++++++++++-------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js index ddec6e3..f932ce8 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ProxyEditor.js @@ -366,11 +366,15 @@ export default function getProxyEditor(theState) { super(props); this.state = getInitState(); + this.resetState = linkEvent(this, this.resetState); } resetState(that, event) { + if (that.state.ifHasErrors) { + that.props.funs.setStatusTo(''); // Clear errors + } that.setState(getInitState()); event.preventDefault(); @@ -417,28 +421,32 @@ export default function getProxyEditor(theState) { handleModeSwitch(that, event) { - if (that.state.stashedExports !== false) { - const errors = that.getErrorsInStashedExports(); - if (errors) { - that.setState({ifHasErrors: true}); - that.props.funs.showErrors(...errors); - return; - } - that.props.setProxyStringRaw(that.state.stashedExports); + console.log('SWITCH!'); + if (that.state.ifHasErrors) { + return; } - that.setState({ - stashedExports: false, - ifHasErrors: false, - }); that.props.onSwitch(); } handleTextareaChange(that, event) { + console.log('CHANGE!'); that.setState({ stashedExports: normalizeProxyString(event.target.value), }); + const errors = that.getErrorsInStashedExports(); + if (errors) { + that.setState({ifHasErrors: true}); + that.props.funs.showErrors(...errors); + return; + } + // No errors. + that.props.setProxyStringRaw(that.state.stashedExports); + that.setState({ + stashedExports: false, + ifHasErrors: false, + }); } @@ -451,8 +459,6 @@ export default function getProxyEditor(theState) { render(props) { - const reset = linkEvent(this, this.resetState); - return (

@@ -463,8 +469,8 @@ export default function getProxyEditor(theState) { this.state.stashedExports === false ? 'Комментарии вырезаются!' : (this.state.ifHasErrors - ? (Сбросьте изменения или поправьте) - : (Сбросить изменения) + ? (Сбросьте изменения или поправьте) + : (Сбросить изменения) ) } From c16ce17f018ae8cc30c6e70365322c17c1a0dd70 Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Sat, 17 Jun 2017 22:36:48 +0500 Subject: [PATCH 09/10] Make apply button work for ExportsMode of ProxyEditor --- .../pages/options/src/components/Main.js | 36 +++++++++++++++---- .../pages/options/src/components/ModList.js | 7 ++-- .../options/src/components/ProxyEditor.js | 36 ++++++++++++------- 3 files changed, 58 insertions(+), 21 deletions(-) diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js index 46b3fbc..ca68cdf 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/Main.js @@ -38,7 +38,8 @@ export default function getMain(theState) { super(props); this.state = { - ifModsChangesStashed: false, + ifModsChangesAreStashed: false, + ifModsChangesAreValid: true, catToOrderedMods: { 'general': props.apis.pacKitchen.getOrderedConfigs('general'), 'ownProxies': props.apis.pacKitchen.getOrderedConfigs('ownProxies'), @@ -58,24 +59,46 @@ export default function getMain(theState) { handleModApply(that) { + if (!that.state.ifModsChangesAreValid) { + // Error message must be already set by a config validator. + return; + } const modsMutated = that.props.apis.pacKitchen.getPacMods(); const newMods = that.getAllMods().reduce((_, conf) => { modsMutated[conf.key] = conf.value; return modsMutated; - }, modsMutated/*< Needed for index 0*/); + }, modsMutated/* Needed for index 0*/); that.props.funs.conduct( 'Применяем настройки...', (cb) => that.props.apis.pacKitchen.keepCookedNowAsync(newMods, cb), 'Настройки применены.', - () => that.setState({ifModsChangesStashed: false}) + () => that.setState({ + ifModsChangesAreStashed: false, + ifModsChangesAreValid: true, + }) ); } - handleModChange({targetConf, targetIndex, newValue}) { + handleModChange({ifValid, targetConf, targetIndex, newValue}) { + if (ifValid === undefined) { + // User input some data, but not validated yet. + this.setState({ + // Make apply button clickable when user only starts writing. + ifModsChangesAreStashed: true, + }); + return; + } + if (ifValid === false) { + this.setState({ + ifModsChangesAreValid: false, + ifModsChangesAreStashed: true, + }) + return; + } const oldCats = this.state.catToOrderedMods; const newCats = Object.keys(this.state.catToOrderedMods).reduce((acc, cat) => { @@ -99,7 +122,8 @@ export default function getMain(theState) { this.setState({ catToOrderedMods: newCats, - ifModsChangesStashed: true, + ifModsChangesAreStashed: true, + ifModsChangesAreValid: true, }); } @@ -108,7 +132,7 @@ export default function getMain(theState) { const applyModsEl = createElement(ApplyMods, Object.assign({}, props, { - ifInputsDisabled: !this.state.ifModsChangesStashed || props.ifInputsDisabled, + ifInputsDisabled: !this.state.ifModsChangesAreStashed || props.ifInputsDisabled, onClick: linkEvent(this, this.handleModApply), } )); diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js index 169eb43..3c3dab8 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/ModList.js @@ -26,17 +26,18 @@ export default function getModList(theState) { ) }); if (ifChecked === false || !confMeta.ifChild) { - this.handleNewValue(confMeta, ifChecked); + this.handleNewValue(true, confMeta, ifChecked); } } - handleNewValue({ conf, index }, newValue) { + handleNewValue(ifValid, { conf, index }, newValue) { this.props.onConfChanged({ targetConf: conf, targetIndex: index, newValue: newValue, + ifValid, }); } @@ -54,7 +55,7 @@ export default function getModList(theState) { const child = ifMayHaveChild && this.state.checks[index] && createElement( props.childrenOfMod[conf.key], - Object.assign({}, props, {conf, onNewValue: (newValue) => this.handleNewValue(confMeta, newValue)}) + Object.assign({}, props, {conf, onNewValue: (ifValid, newValue) => this.handleNewValue(ifValid, confMeta, newValue)}) ); return ( this.setState({ifExportsMode: !this.state.ifExportsMode}); waitingTillMount.push(newValue); // Wait till mount or eat bugs. @@ -552,12 +555,12 @@ PROXY foobar.com:8080; # Not HTTP!`.trim()} } - mayEmitNewValue(oldValue, newValue) { + mayEmitNewValue(oldValue, newValue, ifValidityChanged) { if ( // Reject: 1) both `false` OR 2) both `===`. - ( Boolean(oldValue) || Boolean(newValue) ) && oldValue !== newValue + ifValidityChanged || ( Boolean(oldValue) || Boolean(newValue) ) && oldValue !== newValue ) { - this.props.onNewValue(newValue); + this.props.onNewValue(this.state.ifValid, newValue); } } @@ -567,12 +570,21 @@ PROXY foobar.com:8080; # Not HTTP!`.trim()} const props = Object.assign({ proxyStringRaw: this.state.proxyStringRaw, onSwitch: this.handleSwitch, - setProxyStringRaw: (newValue) => { + setProxyStringRaw: (ifValid, newValue) => { + + const ifValidityChanged = this.state.ifValid !== ifValid; + if (!ifValid) { + if (ifValidityChanged || ifValid === undefined) { + this.props.onNewValue(ifValid); + this.setState({ ifValid }); + } + return; + } const oldValue = this.state.proxyStringRaw; localStorage.setItem(UI_RAW, newValue); - this.setState({proxyStringRaw: newValue}); - this.mayEmitNewValue(oldValue, newValue); + this.setState({proxyStringRaw: newValue, ifValid}); + this.mayEmitNewValue(oldValue, newValue, ifValidityChanged); }, }, originalProps); From ead7f6b2eaa7b059e486eb73ba37cee512e3abaa Mon Sep 17 00:00:00 2001 From: "Ilya Ig. Petrov" Date: Thu, 13 Jul 2017 23:47:52 +0500 Subject: [PATCH 10/10] Add beta target --- ...7-sync-pac-script-with-pac-provider-api.js | 0 .../runet-censorship-bypass/gulpfile.js | 32 +- .../runet-censorship-bypass/package.json | 4 +- ...c-pac-script-with-pac-provider-api.tmpl.js | 581 ++++++++++++++++++ .../pages/lib/chrome-style/index.css | 4 +- .../pages/options/src/components/App.js | 3 +- .../src/templates-data.js | 25 + 7 files changed, 637 insertions(+), 12 deletions(-) rename extensions/chromium/runet-censorship-bypass/{src/extension-common => }/37-sync-pac-script-with-pac-provider-api.js (100%) create mode 100644 extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.tmpl.js diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.js b/extensions/chromium/runet-censorship-bypass/37-sync-pac-script-with-pac-provider-api.js similarity index 100% rename from extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.js rename to extensions/chromium/runet-censorship-bypass/37-sync-pac-script-with-pac-provider-api.js diff --git a/extensions/chromium/runet-censorship-bypass/gulpfile.js b/extensions/chromium/runet-censorship-bypass/gulpfile.js index 94a2c00..034dfcd 100644 --- a/extensions/chromium/runet-censorship-bypass/gulpfile.js +++ b/extensions/chromium/runet-censorship-bypass/gulpfile.js @@ -10,11 +10,11 @@ const PluginName = 'Template literals'; const templatePlugin = (context) => through.obj(function(file, encoding, cb) { - const tjson = '.tmpl.json'; - if (file.path.endsWith(tjson)) { + const suffixes = ['.tmpl.json', 'tmpl.js']; + if ( suffixes.some( (suff) => file.path.endsWith(suff) ) ) { const originalPath = file.path; - file.path = file.path.replace(new RegExp(`${tjson}$`), '.json'); + file.path = file.path.replace(new RegExp(`tmpl.([^.]+)$`), '$1'); if (file.isStream()) { return cb(new PluginError(PluginName, 'Streams are not supported!')); @@ -60,6 +60,7 @@ const commonWoTests = ['./src/extension-common/**/*', ...excluded]; const miniDst = './build/extension-mini'; const fullDst = './build/extension-full'; +const betaDst = './build/extension-beta'; gulp.task('_cp-common', ['clean'], function(cb) { @@ -71,23 +72,28 @@ gulp.task('_cp-common', ['clean'], function(cb) { }; gulp.src(commonWoTests) - .pipe(changed(miniDst)) + //.pipe(changed(miniDst)) .pipe(templatePlugin(contexts.mini)) .pipe(gulp.dest(miniDst)) .on('end', intheend); gulp.src(commonWoTests) - .pipe(changed(fullDst)) + //.pipe(changed(fullDst)) .pipe(templatePlugin(contexts.full)) .pipe(gulp.dest(fullDst)) .on('end', intheend); + gulp.src(commonWoTests) + //.pipe(changed(fullDst)) + .pipe(templatePlugin(contexts.beta)) + .pipe(gulp.dest(betaDst)) + .on('end', intheend); }); gulp.task('_cp-mini', ['_cp-common'], function(cb) { gulp.src(['./src/extension-mini/**/*', ...excluded]) - .pipe(changed(miniDst)) + //.pipe(changed(miniDst)) .pipe(templatePlugin(contexts.mini)) .pipe(gulp.dest(miniDst)) .on('end', cb); @@ -96,12 +102,22 @@ gulp.task('_cp-mini', ['_cp-common'], function(cb) { gulp.task('_cp-full', ['_cp-common'], function(cb) { gulp.src(['./src/extension-full/**/*', ...excluded]) - .pipe(changed(fullDst)) + //.pipe(changed(fullDst)) .pipe(templatePlugin(contexts.full)) .pipe(gulp.dest(fullDst)) .on('end', cb); }); -gulp.task('build:prod', ['_cp-mini', '_cp-full']); +gulp.task('_cp-beta', ['_cp-common'], function(cb) { + + gulp.src(['./src/extension-full/**/*', ...excluded]) + //.pipe(changed(fullDst)) + .pipe(templatePlugin(contexts.beta)) + .pipe(gulp.dest(betaDst)) + .on('end', cb); + +}); + +gulp.task('build:all', ['_cp-mini', '_cp-full', '_cp-beta']); gulp.task('build', ['_cp-full']); diff --git a/extensions/chromium/runet-censorship-bypass/package.json b/extensions/chromium/runet-censorship-bypass/package.json index 5fdf7a3..88854d6 100644 --- a/extensions/chromium/runet-censorship-bypass/package.json +++ b/extensions/chromium/runet-censorship-bypass/package.json @@ -7,7 +7,9 @@ "lint": "eslint ./src/**/*.js --ignore-pattern vendor", "gulp": "gulp", "test": "mocha --recursive ./src/**/test/*", - "start": "cd ./src/extension-common/pages/options/ && npm run build && cd - && npm run gulp" + "subpages": "cd ./src/extension-common/pages/options/ && npm run build && cd -", + "start": "npm run subpages && npm run gulp", + "beta": "npm run subpages && npm run gulp build:all" }, "author": "Ilya Ig. Petrov", "license": "GPLv3", diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.tmpl.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.tmpl.js new file mode 100644 index 0000000..e2184dc --- /dev/null +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/37-sync-pac-script-with-pac-provider-api.tmpl.js @@ -0,0 +1,581 @@ +'use strict'; + +/* + Task 1. Gets IPs for proxies of antizapret/anticenz via dns over https. + These IPs are used in block-informer to inform user when proxy is ON. + Task 2. Downloads PAC proxy script from antizapret/anticenz/ + my Google Drive and sets it in Chromium settings. + Task 3. Schedules tasks 1 & 2 for every 4 hours. +*/ + +/* + In background scripts use window.apis.antiCensorRu public variables. + In pages window.apis.antiCensorRu is not accessible, + use chrome.runtime.getBackgroundPage(..), + extension.getBackgroundPage is deprecated + + If you want to catch errors, then call api from setTimeout! + See errorHandlers api for more. + +*/ + +{ // Private namespace starts. + + const mandatory = window.utils.mandatory; + const throwIfError = window.utils.throwIfError; + const chromified = window.utils.chromified; + const timeouted = window.utils.timeouted; + + const clarifyThen = window.apis.errorsLib.clarifyThen; + const Warning = window.apis.errorsLib.Warning; + + const httpLib = window.apis.httpLib; + const handlers = window.apis.errorHandlers; + + const asyncLogGroup = function asyncLogGroup(...args) { + + const cb = args.pop(); + if(!(cb && typeof(cb) === 'function')) { + throw new TypeError('cb must be a function, but got: ' + cb); + } + console.group(...args); + return function(...cbArgs) { + + console.groupEnd(); + console.log('Group finished.'); + cb(...cbArgs); + + }; + + }; + + const setPacAsync = function setPacAsync( + pacData = mandatory(), cb = throwIfError + ) { + + const config = { + mode: 'pac_script', + pacScript: { + mandatory: false, + data: pacData, + }, + }; + console.log('Setting chrome proxy settings...'); + chrome.proxy.settings.set( {value: config}, chromified((err) => { + + if (err) { + return cb(err); + } + handlers.updateControlState( () => { + + if ( !handlers.ifControlled ) { + + console.warn('Failed, other extension is in control.'); + return cb( + new Error( window.utils.messages.whichExtensionHtml() ) + ); + + } + console.log('Successfuly set PAC in proxy settings..'); + cb(); + + }); + + })); + + }; + + const updatePacProxyIps = function updatePacProxyIps( + cb = throwIfError + ) { + + cb = asyncLogGroup( + 'Getting IPs for PAC hosts...', + cb + ); + window.utils.fireRequest('ip-to-host-update-all', cb); + + }; + + const setPacScriptFromProviderAsync = function setPacScriptFromProviderAsync( + provider, lastModifiedStr = mandatory(), cb = throwIfError + ) { + + const pacUrl = provider.pacUrls[0]; + cb = asyncLogGroup( + 'Getting PAC script from provider...', pacUrl, + cb + ); + + httpLib.ifModifiedSince(pacUrl, lastModifiedStr, (err, newLastModifiedStr) => { + + if (!newLastModifiedStr) { + const res = {lastModified: lastModifiedStr}; + const ifWasEverModified = lastModifiedStr !== new Date(0).toUTCString(); + if (ifWasEverModified) { + return cb( + null, res, + new Warning( + 'Ваш PAC-скрипт не нуждается в обновлении. Его дата: ' + + lastModifiedStr + ) + ); + } + } + + // Employ all urls, the latter are fallbacks for the former. + const pacDataPromise = provider.pacUrls.reduce( + (promise, url) => promise.catch( + () => new Promise( + (resolve, reject) => httpLib.get( + url, + (newErr, pacData) => newErr ? reject(newErr) : resolve(pacData) + ) + ) + ), + Promise.reject() + ); + + pacDataPromise.then( + + (pacData) => { + + setPacAsync( + pacData, + (err, res) => cb( + err, + Object.assign(res || {}, {lastModified: newLastModifiedStr}) + ) + ); + + }, + + clarifyThen( + 'Не удалось скачать PAC-скрипт с адресов: [ ' + + provider.pacUrls.join(' , ') + ' ].', + cb + ) + + ); + + }); + + }; + + window.apis.antiCensorRu = { + + version: chrome.runtime.getManifest().version, + + pacProviders: { + Антизапрет: { + label: 'Антизапрет', + desc: \`Альтернативный PAC-скрипт от стороннего разработчика. + Работает быстрее, но охватывает меньше сайтов. + Блокировка определяется по доменному имени, +
Страница проекта.\`, + order: 0, + pacUrls: ['https://antizapret.prostovpn.org/proxy.pac'], + }, + Антицензорити: { + label: 'Антицензорити', + desc: \`Основной PAC-скрипт от автора расширения. + Работает медленней, но охватывает больше сайтов. + Блокировка определятся по доменному имени или IP адресу.
+ Страница проекта.\`, + order: 1, + + /* + Don't use in system configs! Because Windows does poor caching. + Some urls are encoded to counter abuse. + Version: 0.17 + */ + pacUrls: ${JSON.stringify(anticensorityPacUrls, null, 2)}, + /*[ + // First official, shortened: + 'https://rebrand.ly/ac-chrome-anticensority-pac', + // Second official, Cloud Flare with caching: + 'https://anticensority.tk/generated-pac-scripts/anticensority.pac', + // GitHub.io (anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63', + // GitHub repo (anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x72\x61\x77\x2e\x67\x69\x74\x68\x75\x62\x75\x73\x65\x72\x63\x6f\x6e\x74\x65\x6e\x74\x2e\x63\x6f\x6d\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x6d\x61\x73\x74\x65\x72\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63', + // Old, deprecated: + 'https://anticensorship-russia.tk/generated-pac-scripts/anticensority.pac', + // Google Drive (0.17, anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x64\x72\x69\x76\x65\x2e\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x6f\x6d\x2f\x75\x63\x3f\x65\x78\x70\x6f\x72\x74\x3d\x64\x6f\x77\x6e\x6c\x6f\x61\x64\x26\x69\x64\x3d\x30\x42\x32\x6d\x68\x42\x67\x46\x6e\x66\x34\x70\x45\x4c\x56\x6c\x47\x4e\x54\x42\x45\x4d\x58\x4e\x6d\x52\x58\x63', + ],*/ + }, + onlyOwnSites: { + label: 'Только свои сайты и свои прокси', + desc: 'Проксируются только добавленные вручную сайты через СВОИ вручную добавленные прокси или через локальный Tor.', + order: 99, + pacUrls: [ + 'data:application/x-ns-proxy-autoconfig,' + escape('function FindProxyForURL(){ return "DIRECT"; }'), + ] + } + }, + + getSortedEntriesForProviders() { + + return Object.entries(this.pacProviders).sort((entryA, entryB) => entryA[1].order - entryB[1].order).map(([key, prov]) => Object.assign({key: key}, prov)); + + }, + + _currentPacProviderKey: 'Антизапрет', + + /* Is it the first time extension installed? + Do something, e.g. initiate PAC sync. + */ + ifFirstInstall: false, + lastPacUpdateStamp: 0, + + setTitle() { + + const upDate = new Date(this.lastPacUpdateStamp).toLocaleString('ru-RU') + .replace(/:\\d+$/, '').replace(/\\.\\d{4}/, ''); + chrome.browserAction.setTitle({ + title: \`Обновлялись \${upDate} | Версия \${window.apis.version.build}\`, + }); + + }, + + _currentPacProviderLastModified: 0, // Not initialized. + + getLastModifiedForKey(key = mandatory()) { + + if (this._currentPacProviderKey === key) { + return new Date(this._currentPacProviderLastModified).toUTCString(); + } + return new Date(0).toUTCString(); + + }, + + setLastModified(newValue = mandatory()) { + + this._currentPacProviderLastModified = newValue; + + }, + + mustBeKey(key = mandatory()) { + + if ( !(key === null || this.pacProviders[key]) ) { + throw new TypeError('No provider for key:' + key); + } + + }, + + getCurrentPacProviderKey() { + + return this._currentPacProviderKey; + + }, + + setCurrentPacProviderKey( + newKey = mandatory(), + lastModified = new Date().toUTCString() + ) { + + this.mustBeKey(newKey); + this._currentPacProviderKey = newKey; + this._currentPacProviderLastModified = lastModified; + + }, + + getPacProvider(key) { + + if(key) { + this.mustBeKey(key); + } else { + key = this.getCurrentPacProviderKey(); + } + return this.pacProviders[key]; + + }, + + _periodicUpdateAlarmReason: 'Периодичное обновление PAC-скрипта', + + pushToStorageAsync(cb = throwIfError) { + + console.log('Pushing to storage...'); + + // 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]; + } + } + + chrome.storage.local.clear( + () => chrome.storage.local.set( + onlySettable, + chromified(cb) + ) + ); + + }, + + syncWithPacProviderAsync( + key = this.currentPacProvierKey, cb = throwIfError) { + + if( typeof(key) === 'function' ) { + cb = key; + key = this.getCurrentPacProviderKey(); + } + cb = asyncLogGroup('Syncing with PAC provider ' + key + '...', cb); + + if (key === null) { + // No pac provider set. + return clarifyThen('Сперва выберите PAC-провайдера.', cb); + } + + const pacProvider = this.getPacProvider(key); + + const pacSetPromise = new Promise( + (resolve, reject) => setPacScriptFromProviderAsync( + pacProvider, + this.getLastModifiedForKey(key), + (err, res, ...warns) => { + + if (!err) { + this.setCurrentPacProviderKey(key, res.lastModified); + this.lastPacUpdateStamp = Date.now(); + this.ifFirstInstall = false; + this.setAlarms(); + this.setTitle(); + } + + resolve([err, null, ...warns]); + + } + ) + ); + + const ipsErrorPromise = new Promise( + (resolve, reject) => updatePacProxyIps( + resolve + ) + ); + + Promise.all([pacSetPromise, ipsErrorPromise]).then( + ([[pacErr, pacRes, ...pacWarns], ipsErr]) => { + + if (pacErr && ipsErr) { + return cb(pacErr, pacRes); + } + const warns = pacWarns; + if (ipsErr) { + warns.push(ipsErr); + } + this.pushToStorageAsync( + (pushErr) => cb(pacErr || pushErr, null, ...warns) + ); + + }, + cb + ); + + }, + + _pacUpdatePeriodInMinutes: 12*60, + get pacUpdatePeriodInMinutes() { + + return this._pacUpdatePeriodInMinutes; + + }, + + 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, + } + ); + + // ifAlarmTriggered. May be changed in the future. + return nextUpdateMoment === now; + + }, + + installPacAsync(key, cb = throwIfError) { + + console.log('Installing PAC...'); + if (!key) { + throw new Error('Key must be defined.'); + } + if (this.currentProviderKey !== key) { + return this.syncWithPacProviderAsync(key, cb); + } + console.log(key + ' already installed.'); + cb(); + + }, + + clearPacAsync(cb = throwIfError) { + + cb = asyncLogGroup('Cearing alarms and PAC...', cb); + chrome.alarms.clearAll( + () => chrome.proxy.settings.clear( + {}, + chromified((err) => { + + if (err) { + return cb(err); + } + this.setCurrentPacProviderKey(null); + this.pushToStorageAsync( + () => handlers.updateControlState(cb) + ); + + }) + ) + ); + + }, + + }; + + // ON EACH LAUNCH, STARTUP, RELOAD, UPDATE, ENABLE + chrome.storage.local.get(null, chromified( async (err, oldStorage) => { + + if (err) { + throw err; + } + + /* + Event handlers that ALWAYS work (even if installation is not done + or failed). + E.g. install window may fail to open or be closed by user accidentally. + In such case extension _should_ try to work on default parameters. + */ + const antiCensorRu = window.apis.antiCensorRu; + + chrome.alarms.onAlarm.addListener( + timeouted( (alarm) => { + + if (alarm.name === antiCensorRu._periodicUpdateAlarmReason) { + console.log( + 'Periodic PAC update triggered:', + new Date().toLocaleString('ru-RU') + ); + antiCensorRu.syncWithPacProviderAsync(() => {/* swallow */}); + } + + }) + ); + 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(); + + }); + + console.log('Keep cooked...'); + await new Promise((resolve) => window.apis.pacKitchen.keepCookedNowAsync(resolve)); + + console.log('Storage on init:', oldStorage); + antiCensorRu.ifFirstInstall = Object.keys(oldStorage).length === 0; + + if (antiCensorRu.ifFirstInstall) { + // INSTALL + console.log('Installing...'); + handlers.switch('on', 'ext-error'); + return chrome.runtime.openOptionsPage(); + } + + // LAUNCH, RELOAD, UPDATE + // Use old or migrate to default. + antiCensorRu._currentPacProviderKey = + oldStorage._currentPacProviderKey || null; + antiCensorRu.lastPacUpdateStamp = + oldStorage.lastPacUpdateStamp || antiCensorRu.lastPacUpdateStamp; + antiCensorRu._currentPacProviderLastModified = + oldStorage._currentPacProviderLastModified + || antiCensorRu._currentPacProviderLastModified; + console.log( + 'Last PAC update was on', + new Date(antiCensorRu.lastPacUpdateStamp).toLocaleString('ru-RU') + ); + + + /* + 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. + */ + + await new Promise((resolve) => { + + const ifUpdating = antiCensorRu.version !== oldStorage.version; + if (!ifUpdating) { + + // LAUNCH, RELOAD, ENABLE + antiCensorRu.pacProviders = oldStorage.pacProviders; + console.log('Extension launched, reloaded or enabled.'); + return resolve(); + + } + + // UPDATE & MIGRATION + console.log('Updating from ', oldStorage.version, 'to', antiCensorRu.version); + const key = antiCensorRu._currentPacProviderKey; + if (key !== null) { + const ifVeryOld = !Object.keys(antiCensorRu.pacProviders).includes(key); + if (ifVeryOld) { + antiCensorRu._currentPacProviderKey = 'Антизапрет'; + } + } + + antiCensorRu.pushToStorageAsync(() => { + + console.log('Extension updated.'); + resolve(); + + }); + + }); + + if (antiCensorRu.getPacProvider()) { + antiCensorRu.setAlarms(); + } + antiCensorRu.setTitle(); + + /* + History of Changes to Storage (Migration Guide) + ----------------------------------------------- + Version 0.0.0.17: + * Remove "Антиценз". + * Rename "Оба_и_на_свитчах" to "Антицензорити" + * Add provider.label and provider.desc. + Version 0.0.0.10: + * Add this.version. + * Change PacProvider.proxyIps from {ip -> Boolean} to {ip -> hostname}. + Version 0.0.0.8-9: + * Change storage.ifNotInstalled to storage.ifFirstInstall. + * Add storage.lastPacUpdateStamp. + **/ + + })); + +} diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/lib/chrome-style/index.css b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/lib/chrome-style/index.css index a3cc382..497fdd0 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/lib/chrome-style/index.css +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/lib/chrome-style/index.css @@ -168,10 +168,10 @@ textarea { min-height: 2em; padding: 3px; outline: none; - +/** /* For better alignment between adjacent buttons and inputs. */ padding-bottom: 4px; - +/**/ } input[type='search'] { diff --git a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js index a6cfdda..32aeeb9 100644 --- a/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js +++ b/extensions/chromium/runet-censorship-bypass/src/extension-common/pages/options/src/components/App.js @@ -79,7 +79,8 @@ export default function getApp(theState) { headers: new Headers(headers), }; - const ghUrl = `https://api.github.com/repos/anticensority/chromium-extension/issues/10/comments${query}`; + //const ghUrl = `https://api.github.com/repos/anticensority/chromium-extension/issues/10/comments${query}`; + const ghUrl = `https://api.github.com/repos/anticensority/for-testing/issues/1/comments${query}`; const [error, comments, etag] = await fetch( ghUrl, diff --git a/extensions/chromium/runet-censorship-bypass/src/templates-data.js b/extensions/chromium/runet-censorship-bypass/src/templates-data.js index 36022f5..eac4931 100644 --- a/extensions/chromium/runet-censorship-bypass/src/templates-data.js +++ b/extensions/chromium/runet-censorship-bypass/src/templates-data.js @@ -2,6 +2,20 @@ const commonContext = { version: '1.3', + anticensorityPacUrls: [ + // First official, shortened: + 'https://rebrand.ly/ac-chrome-anticensority-pac', + // Second official, Cloud Flare with caching: + 'https://anticensority.tk/generated-pac-scripts/anticensority.pac', + // GitHub.io (anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x67\x69\x74\x68\x75\x62\x2e\x69\x6f\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63', + // GitHub repo (anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x72\x61\x77\x2e\x67\x69\x74\x68\x75\x62\x75\x73\x65\x72\x63\x6f\x6e\x74\x65\x6e\x74\x2e\x63\x6f\x6d\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2f\x67\x65\x6e\x65\x72\x61\x74\x65\x64\x2d\x70\x61\x63\x2d\x73\x63\x72\x69\x70\x74\x73\x2f\x6d\x61\x73\x74\x65\x72\x2f\x61\x6e\x74\x69\x63\x65\x6e\x73\x6f\x72\x69\x74\x79\x2e\x70\x61\x63', + // Old, deprecated: + 'https://anticensorship-russia.tk/generated-pac-scripts/anticensority.pac', + // Google Drive (0.17, anticensority): + '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x64\x72\x69\x76\x65\x2e\x67\x6f\x6f\x67\x6c\x65\x2e\x63\x6f\x6d\x2f\x75\x63\x3f\x65\x78\x70\x6f\x72\x74\x3d\x64\x6f\x77\x6e\x6c\x6f\x61\x64\x26\x69\x64\x3d\x30\x42\x32\x6d\x68\x42\x67\x46\x6e\x66\x34\x70\x45\x4c\x56\x6c\x47\x4e\x54\x42\x45\x4d\x58\x4e\x6d\x52\x58\x63', + ] }; exports.contexts = {}; @@ -26,3 +40,14 @@ exports.contexts.mini = Object.assign({}, commonContext, { scripts_8x: '', }); +exports.contexts.beta = Object.assign({}, commonContext, { + anticensorityPacUrls: ['https://rebrand.ly/ac-beta-pac'], + version: '1.5', + versionSuffix: '', + nameSuffixEn: ' FOR TESTING', + nameSuffixRu: ' ДЛЯ ТЕСТОВ', + extra_permissions: ', "webRequest", "webNavigation"', + persistent: '', + scripts_2x: ', "20-ip-to-host-api.js"', + scripts_8x: ', "80-error-menu.js", "83-last-errors.js", "85-block-informer.js"', +});