mirror of
https://github.com/anticensority/runet-censorship-bypass.git
synced 2024-11-10 19:46:34 +03:00
Change UI of exceptions to datalist
This commit is contained in:
parent
d022220303
commit
400771eff4
3
extensions/chromium/readings.txt
Normal file
3
extensions/chromium/readings.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
https://chromereleases.googleblog.com/search/label/Stable%20updates
|
||||||
|
https://www.chromestatus.com
|
||||||
|
https://www.youtube.com/user/ChromeDevelopers/videos
|
|
@ -41,6 +41,9 @@
|
||||||
padding-left: 1.4em;
|
padding-left: 1.4em;
|
||||||
padding-right: 1.4em;
|
padding-right: 1.4em;
|
||||||
}
|
}
|
||||||
|
.horizontal-list li {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
/* NOT CONTROLLED */
|
/* NOT CONTROLLED */
|
||||||
|
|
||||||
|
@ -67,7 +70,7 @@
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.acc-padded {
|
.acc-padded {
|
||||||
padding: 0.6em 0 1em 0.5em;
|
padding: 0.6em 0.5em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* HIDE */
|
/* HIDE */
|
||||||
|
@ -96,10 +99,7 @@
|
||||||
}
|
}
|
||||||
.nav-labels {
|
.nav-labels {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
--blue-bg: DodgerBlue;
|
--blue-bg: dodgerblue;
|
||||||
}
|
|
||||||
.nav-labels li {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
.nav-labels li label {
|
.nav-labels li label {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -259,49 +259,27 @@
|
||||||
|
|
||||||
/* TAB_3 EXCEPTIONS */
|
/* TAB_3 EXCEPTIONS */
|
||||||
|
|
||||||
#right-flexed-editor {
|
#exc-editor {
|
||||||
flex-grow: 99;
|
|
||||||
max-height: 100%;
|
|
||||||
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
#right-flexed-editor > * {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
#except-editor {
|
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
border: none;
|
border: none !important;
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--ribbon-color) !important;
|
||||||
|
// I don't understand this three, but they have effect.
|
||||||
max-height: 1.6em !important;
|
max-height: 1.6em !important;
|
||||||
min-height: 1.6em !important;
|
min-height: 1.6em !important;
|
||||||
|
height: 1em !important;
|
||||||
flex-grow: 99;
|
|
||||||
width: 100% !important;
|
|
||||||
}
|
}
|
||||||
#bottom-flexed-editor {
|
#exc-radio {
|
||||||
flex-grow: 99;
|
display: flex;
|
||||||
position: relative;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
[name="if-proxy-this-site"]:checked + label {
|
||||||
select#exceptions-select {
|
font-weight: bold;
|
||||||
color: black;
|
}
|
||||||
background: transparent;
|
#exc-editor.if-yes {
|
||||||
border-radius: 0;
|
background-color: lightgreen;
|
||||||
box-shadow: none;
|
}
|
||||||
text-shadow: none;
|
#exc-editor.if-no {
|
||||||
padding: 0;
|
background-color: pink;
|
||||||
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
border: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
option.if-proxied {
|
option.if-proxied {
|
||||||
|
@ -311,21 +289,6 @@
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
#exc-flex-container {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
/* Fixes multi-select bug
|
|
||||||
when its border is rendered below
|
|
||||||
its scrollbar. */
|
|
||||||
--border-color: var(--default-grey);
|
|
||||||
}
|
|
||||||
#exc-flex-container > * {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* CONTROL RAW = BUTTON + LINK */
|
/* CONTROL RAW = BUTTON + LINK */
|
||||||
|
|
||||||
.control-row {
|
.control-row {
|
||||||
|
@ -357,7 +320,7 @@
|
||||||
<input type="radio" name="accordion" class="off" id="acc-mods"/>
|
<input type="radio" name="accordion" class="off" id="acc-mods"/>
|
||||||
<input type="radio" name="accordion" class="off" id="acc-ntf"/>
|
<input type="radio" name="accordion" class="off" id="acc-ntf"/>
|
||||||
|
|
||||||
<section class="nav-labels hidden-for-options-page">
|
<section class="nav-labels horizontal-list hidden-for-options-page">
|
||||||
<ul>
|
<ul>
|
||||||
<li><label for="acc-pac" class="nav-label">PAC-скрипт</label></li>
|
<li><label for="acc-pac" class="nav-label">PAC-скрипт</label></li>
|
||||||
<li><label for="acc-mods" class="nav-label">Модификаторы</label></li>
|
<li><label for="acc-mods" class="nav-label">Модификаторы</label></li>
|
||||||
|
@ -384,22 +347,18 @@
|
||||||
|
|
||||||
<section data-for="acc-exc" class="hideable">
|
<section data-for="acc-exc" class="hideable">
|
||||||
|
|
||||||
<header>Проксировать этот сайт?</header>
|
|
||||||
<div class="acc-padded" id="exc-flex-container">
|
|
||||||
<ul style="padding-right: 1em" id="exc-radio">
|
|
||||||
<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" placeholder="example.com" id="except-editor"/>
|
|
||||||
<div id="bottom-flexed-editor">
|
|
||||||
<select multiple id="exceptions-select"></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
<div style="display: flex; justify-content: space-around;">
|
||||||
|
<span>Проксировать</span>
|
||||||
|
<input placeholder="*.example.com" list="exc-list" name="browser" id="exc-editor"/>?
|
||||||
|
<datalist id="exc-list"></datalist>
|
||||||
|
</div>
|
||||||
|
<ol class="acc-padded horizontal-list" id="exc-radio">
|
||||||
|
<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>
|
||||||
|
</ol>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section data-for="acc-mods" class="hideable">
|
<section data-for="acc-mods" class="hideable">
|
||||||
|
|
|
@ -256,79 +256,12 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
const excEditor = document.getElementById('except-editor');
|
const excEditor = document.getElementById('exc-editor');
|
||||||
|
|
||||||
if (currentTab && !currentTab.url.startsWith('chrome')) {
|
if (currentTab && !currentTab.url.startsWith('chrome')) {
|
||||||
excEditor.value = new URL(currentTab.url).hostname;
|
excEditor.value = new URL(currentTab.url).hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
const excSelect = document.getElementById('exceptions-select');
|
|
||||||
|
|
||||||
excEditor.onkeyup = function() {
|
|
||||||
|
|
||||||
this.value = this.value.trim();
|
|
||||||
for(const opt of excSelect.options) {
|
|
||||||
let commonChars = 0;
|
|
||||||
for( const i in this.value ) {
|
|
||||||
if (this.value.charAt(i) !== opt.value.charAt(i)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
++commonChars;
|
|
||||||
}
|
|
||||||
opt.style.order = commonChars;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const thisYes = document.getElementById('this-yes');
|
|
||||||
const thisNo = document.getElementById('this-no');
|
|
||||||
const ifProxiedClass = 'if-proxied';
|
|
||||||
|
|
||||||
excSelect.onclick = function(event) {
|
|
||||||
|
|
||||||
// Only one item may be selecte at a time.
|
|
||||||
// Spread op is used to fight weird bug with iterator.
|
|
||||||
for(const sopt of [...this.selectedOptions]) {
|
|
||||||
sopt.selected = false;
|
|
||||||
}
|
|
||||||
const opt = event.target;
|
|
||||||
opt.selected = true;
|
|
||||||
if (opt.classList.contains(ifProxiedClass)) {
|
|
||||||
thisYes.checked = true;
|
|
||||||
} else {
|
|
||||||
thisNo.checked = true;
|
|
||||||
}
|
|
||||||
excEditor.value = opt.value.trim();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
const addOption = function addOption(host, ifProxy) {
|
|
||||||
|
|
||||||
const opt = document.createElement('option');
|
|
||||||
opt.text = host;
|
|
||||||
if(ifProxy) {
|
|
||||||
opt.classList.add(ifProxiedClass);
|
|
||||||
};
|
|
||||||
const editorHost = excEditor.value.trim();
|
|
||||||
if (host === editorHost) {
|
|
||||||
excSelect.insertBefore( opt, excSelect.firstChild );
|
|
||||||
opt.click();
|
|
||||||
} else {
|
|
||||||
excSelect.add(opt);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // Populate select box.
|
|
||||||
|
|
||||||
const pacMods = pacKitchen.getPacMods();
|
|
||||||
for(const host of Object.keys(pacMods.exceptions || {}).sort()) {
|
|
||||||
addOption(host, pacMods.exceptions[host]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const validateHost = function validateHost(host) {
|
const validateHost = function validateHost(host) {
|
||||||
|
|
||||||
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])$/;
|
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])$/;
|
||||||
|
@ -340,30 +273,165 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const excPrefix = '*.';
|
||||||
|
const prefRe = new RegExp('^(\\s*\\*\\.?)?');
|
||||||
|
const ifProxyHtml = '✔';
|
||||||
|
|
||||||
|
const addOption = function addOption(host, ifProxy) {
|
||||||
|
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = excPrefix + host;
|
||||||
|
opt.dataset.host = host;
|
||||||
|
opt.innerHTML = ifProxy ? ifProxyHtml : '✘';
|
||||||
|
const editorHost = excEditor.value.trim();
|
||||||
|
if (host === editorHost) {
|
||||||
|
excList.insertBefore( opt, excList.firstChild );
|
||||||
|
} else {
|
||||||
|
excList.appendChild(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const excList = document.getElementById('exc-list');
|
||||||
|
const getExactOpts = (_host) => {
|
||||||
|
|
||||||
|
const _nakedHost = _host.replace(prefRe, '');
|
||||||
|
return [].filter.call(
|
||||||
|
excList.childNodes,
|
||||||
|
(opt) => opt.dataset.host === _nakedHost
|
||||||
|
);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const thisYes = document.getElementById('this-yes');
|
||||||
|
const thisNo = document.getElementById('this-no');
|
||||||
|
const thisAuto = document.getElementById('this-auto');
|
||||||
|
const yesClass = 'if-yes';
|
||||||
|
const noClass = 'if-no';
|
||||||
|
|
||||||
|
function moveCursorIfNeeded() {
|
||||||
|
|
||||||
|
const nu = excEditor.dataset.moveCursorTo;
|
||||||
|
if(nu !== undefined) {
|
||||||
|
excEditor.setSelectionRange(nu, nu);
|
||||||
|
delete excEditor.dataset.moveCursorTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
excEditor.onkeydown = function(event) {
|
||||||
|
|
||||||
|
console.log('DOWN', event);
|
||||||
|
moveCursorIfNeeded();
|
||||||
|
const start = this.selectionStart;
|
||||||
|
const end = this.selectionEnd;
|
||||||
|
if (start < 2 && event.key.length === 1) {
|
||||||
|
this.setSelectionRange(2, end < 2 ? 2 : end);
|
||||||
|
}
|
||||||
|
if(event.key === 'Enter') {
|
||||||
|
// Hide all non-exact matches.
|
||||||
|
alert(12);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
excEditor.oninput = function(event) {
|
||||||
|
|
||||||
|
console.log('INPUT')
|
||||||
|
const _host = this.value;
|
||||||
|
const prefixedHost = this.value.replace(prefRe, excPrefix);
|
||||||
|
const setInputValue = (newValue) => {
|
||||||
|
|
||||||
|
const nu = this.selectionStart + newValue.length - this.value.length;
|
||||||
|
this.value = newValue;
|
||||||
|
excEditor.dataset.moveCursorTo = nu;
|
||||||
|
window.setTimeout(moveCursorIfNeeded, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
setInputValue(prefixedHost);
|
||||||
|
const _nakedHost = _host.trim().replace(prefRe, '');
|
||||||
|
|
||||||
|
thisAuto.checked = true;
|
||||||
|
|
||||||
|
const toDefault = (opt) => opt.value = excPrefix + opt.dataset.host;;
|
||||||
|
|
||||||
|
const delim = ' | ';
|
||||||
|
let exactOpt = false;
|
||||||
|
const ifLineSelected = _host.includes(delim);
|
||||||
|
excList.childNodes.forEach(
|
||||||
|
(opt) => {
|
||||||
|
|
||||||
|
const ifExactMatch = opt.dataset.host === _nakedHost || opt.value === _host;
|
||||||
|
if (ifExactMatch) {
|
||||||
|
exactOpt = opt;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
toDefault(opt);
|
||||||
|
const ifCommonPrefix = opt.dataset.host.startsWith(_nakedHost);
|
||||||
|
if (ifCommonPrefix) {
|
||||||
|
opt.value = prefixedHost + delim + '^' + opt.dataset.host;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const ifCommonSuffix = opt.dataset.host.endsWith(_nakedHost);
|
||||||
|
if (ifCommonSuffix) {
|
||||||
|
opt.value = this.value + delim + opt.dataset.host + '$';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.classList.remove(noClass, yesClass);
|
||||||
|
if (exactOpt) {
|
||||||
|
console.log('EXACT', exactOpt);
|
||||||
|
//excList.childNodes.forEach( (opt) => opt.value = false );
|
||||||
|
setInputValue(toDefault(exactOpt));
|
||||||
|
if (ifLineSelected) {
|
||||||
|
// Hide all.
|
||||||
|
excList.childNodes.forEach( (opt) => opt.value = false );
|
||||||
|
} else {
|
||||||
|
// Hide exact.
|
||||||
|
exactOpt.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exactOpt.innerHTML === ifProxyHtml) {
|
||||||
|
thisYes.checked = true;
|
||||||
|
this.classList.add(yesClass);
|
||||||
|
} else {
|
||||||
|
thisNo.checked = true;
|
||||||
|
this.classList.add(noClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
{ // Populate selector.
|
||||||
|
|
||||||
|
const pacMods = pacKitchen.getPacMods();
|
||||||
|
for(const host of Object.keys(pacMods.exceptions || {}).sort()) {
|
||||||
|
addOption(host, pacMods.exceptions[host]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
excEditor.oninput();
|
||||||
|
|
||||||
document.getElementById('exc-radio').onclick = function(event) {
|
document.getElementById('exc-radio').onclick = function(event) {
|
||||||
|
|
||||||
if( !['LABEL', 'INPUT'].includes( event.target.tagName ) ) {
|
/* ON CLICK */
|
||||||
|
if(event.target.tagName !== 'INPUT') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _host = excEditor.value.trim();
|
const _host = excEditor.value.trim().replace(prefRe, '');
|
||||||
|
|
||||||
const pacMods = pacKitchen.getPacMods();
|
const pacMods = pacKitchen.getPacMods();
|
||||||
pacMods.exceptions = pacMods.exceptions || {};
|
pacMods.exceptions = pacMods.exceptions || {};
|
||||||
|
|
||||||
let fixSelectBox;
|
let fixUi = () => {};
|
||||||
|
|
||||||
if (document.getElementById('this-auto').checked) {
|
if (thisAuto.checked) {
|
||||||
delete pacMods.exceptions[_host];
|
delete pacMods.exceptions[_host];
|
||||||
fixSelectBox = () => {
|
fixUi = () => excEditor.value = '';
|
||||||
|
|
||||||
for(const sopt of [...excSelect.selectedOptions]) {
|
|
||||||
const shost = sopt.value.trim();
|
|
||||||
delete pacMods.exceptions[shost];
|
|
||||||
sopt.remove();
|
|
||||||
}
|
|
||||||
excEditor.value = '';
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// YES or NO.
|
// YES or NO.
|
||||||
if (!validateHost(_host)) {
|
if (!validateHost(_host)) {
|
||||||
|
@ -376,33 +444,20 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pacMods.exceptions[_host] = thisYes.checked;
|
pacMods.exceptions[_host] = thisYes.checked;
|
||||||
|
fixUi = () => addOption(_host, thisYes.checked);
|
||||||
if (excSelect.selectedIndex === -1) {
|
|
||||||
// Add new.
|
|
||||||
fixSelectBox = () => addOption(_host, thisYes.checked);
|
|
||||||
} else {
|
|
||||||
// Edit selected.
|
|
||||||
fixSelectBox = () => {
|
|
||||||
|
|
||||||
for(const sopt of [...excSelect.selectedOptions]) {
|
|
||||||
sopt.value = _host;
|
|
||||||
if (thisYes.checked) {
|
|
||||||
sopt.classList.add(ifProxiedClass);
|
|
||||||
} else {
|
|
||||||
sopt.classList.remove(ifProxiedClass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
conduct(
|
conduct(
|
||||||
'Применяем исключения...',
|
'Применяем исключения...',
|
||||||
(cb) => pacKitchen.keepCookedNowAsync(pacMods, cb),
|
(cb) => pacKitchen.keepCookedNowAsync(pacMods, cb),
|
||||||
'Исключения применены.',
|
'Исключения применены.',
|
||||||
fixSelectBox
|
() => {
|
||||||
|
|
||||||
|
getExactOpts(_host).forEach( (opt) => opt.remove() );
|
||||||
|
fixUi();
|
||||||
|
excEditor.oninput();
|
||||||
|
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -550,6 +605,7 @@ HTTPS 11.22.33.44:8080;">${conf.value || localStorage.getItem(uiRaw) || ''}</tex
|
||||||
document.querySelector('#update-' + id).click();
|
document.querySelector('#update-' + id).click();
|
||||||
}
|
}
|
||||||
document.documentElement.style.display = '';
|
document.documentElement.style.display = '';
|
||||||
|
|
||||||
console.log(Date.now() - START);
|
console.log(Date.now() - START);
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user