Fix exceptions UI (final), fix block-informer async bugs

This commit is contained in:
Ilya Ig. Petrov 2017-01-30 17:36:31 +00:00
parent 400771eff4
commit c5c1ac559e
4 changed files with 70 additions and 91 deletions

View File

@ -188,7 +188,7 @@
const self = window.apis.ipToHost = { const self = window.apis.ipToHost = {
persistVoid() { persist() {
console.log('Persisting ipToHost...', privates); console.log('Persisting ipToHost...', privates);
const ipToHost = {}; const ipToHost = {};
@ -199,15 +199,16 @@
}, },
resetToDefaultsVoid() { resetToDefaults() {
_state(ip2host, null); _state(ip2host, null);
reinit(); reinit();
}, },
_purgeIpsForVoid(hostStr) { _purgeOldIpsForSync(hostStr) {
console.log('Purging old IPs...');
for(const ip of Object.keys(privates._ipToHostObj)) { for(const ip of Object.keys(privates._ipToHostObj)) {
delete privates._ipToHostObj[ip]; delete privates._ipToHostObj[ip];
} }
@ -218,22 +219,25 @@
getIpsFor(hostStr, (err, ips, ...warns) => { getIpsFor(hostStr, (err, ips, ...warns) => {
console.log('IPS', ips); console.log('IPS', ips, err);
if (!err) { if (!err) {
this._purgeIpsForVoid(hostStr); this._purgeOldIpsForSync(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) {
console.log('IP', ip);
privates._ipToHostObj[ip] = hostObj; privates._ipToHostObj[ip] = hostObj;
console.log(privates._ipToHostObj[ip], privates);
} }
} }
console.log('PP', privates);
return cb(err, null, ...warns); return cb(err, null, ...warns);
}); });
}, },
updateAllAsync(cb = mandatory()) { _updateAllAsync(cb = mandatory()) {
const hostArr = Object.keys(privates._strToHostObj); const hostArr = Object.keys(privates._strToHostObj);
@ -267,6 +271,20 @@
}, },
updateAllAsync(cb = mandatory()) {
this._updateAllAsync((err, ...args) => {
if (!err) {
this.persist();
}
cb(err, ...args);
});
},
_replaceAllAsync(hostArr = mandatory(), cb) { _replaceAllAsync(hostArr = mandatory(), cb) {
if (typeof(hostArr) === 'function') { if (typeof(hostArr) === 'function') {
@ -274,12 +292,12 @@
hostArr = Object.keys(privates._strToHostObj); hostArr = Object.keys(privates._strToHostObj);
} }
this.resetToDefaultsVoid(); this.resetToDefaults();
for(const hostStr of hostArr) { for(const hostStr of hostArr) {
_createHostObj(hostStr); _createHostObj(hostStr);
} }
this.updateAllAsync(cb); this._updateAllAsync(cb);
}, },
@ -296,7 +314,7 @@
this._replaceAllAsync(hostArr, (allErr, ...args) => { this._replaceAllAsync(hostArr, (allErr, ...args) => {
if (!allErr) { if (!allErr) {
this.persistVoid(); this.persist();
} }
cb(allErr, ...args); cb(allErr, ...args);

View File

@ -332,7 +332,7 @@
}, },
resetToDefaultsVoid() { resetToDefaults() {
// Pruge all but exceptions. // Pruge all but exceptions.
const exceptions = kitchenState(modsKey).exceptions; const exceptions = kitchenState(modsKey).exceptions;

View File

@ -351,7 +351,7 @@
<div style="display: flex; justify-content: space-around;"> <div style="display: flex; justify-content: space-around;">
<span>Проксировать</span> <span>Проксировать</span>
<input placeholder="*.example.com" list="exc-list" name="browser" id="exc-editor"/>? <input placeholder="navalny.com" list="exc-list" name="browser" id="exc-editor"/>?
<datalist id="exc-list"></datalist> <datalist id="exc-list"></datalist>
</div> </div>
<ol class="acc-padded horizontal-list" id="exc-radio"> <ol class="acc-padded horizontal-list" id="exc-radio">

View File

@ -244,11 +244,6 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
} }
// EXCEPTIONS PANEL // EXCEPTIONS PANEL
/*
Iterating and modifying select.selectedOptions
at the same time is buggy, iterate this way instead:
[...select.selectedOptions]
*/
{ {
@ -273,14 +268,12 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
}; };
const excPrefix = '*.';
const prefRe = new RegExp('^(\\s*\\*\\.?)?');
const ifProxyHtml = '✔'; const ifProxyHtml = '✔';
const addOption = function addOption(host, ifProxy) { const addOption = function addOption(host, ifProxy) {
const opt = document.createElement('option'); const opt = document.createElement('option');
opt.value = excPrefix + host; opt.value = host;
opt.dataset.host = host; opt.dataset.host = host;
opt.innerHTML = ifProxy ? ifProxyHtml : '✘'; opt.innerHTML = ifProxy ? ifProxyHtml : '✘';
const editorHost = excEditor.value.trim(); const editorHost = excEditor.value.trim();
@ -292,17 +285,6 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
}; };
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 thisYes = document.getElementById('this-yes');
const thisNo = document.getElementById('this-no'); const thisNo = document.getElementById('this-no');
const thisAuto = document.getElementById('this-auto'); const thisAuto = document.getElementById('this-auto');
@ -319,80 +301,55 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
} }
const hideOpt = (opt) => opt.value = '\n';
const unhideOpt = (opt) => opt.value = opt.dataset.host + ' ';
const excList = document.getElementById('exc-list');
excEditor.onkeydown = function(event) { excEditor.onkeydown = function(event) {
console.log('DOWN', event);
moveCursorIfNeeded(); 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') { if(event.key === 'Enter') {
// Hide all non-exact matches. // Hide all.
alert(12); excList.childNodes.forEach( hideOpt );
} }
return true; return true;
}; };
excEditor.oninput = function(event) { excEditor.onclick = excEditor.oninput = function(event) {
console.log('INPUT')
const _host = this.value;
const prefixedHost = this.value.replace(prefRe, excPrefix);
const setInputValue = (newValue) => { const setInputValue = (newValue) => {
if (event && event.type === 'click') {
return;
}
// See bug in my comment to http://stackoverflow.com/a/32394157/521957
// The only shortcoming: first click on empty input may be still ignored.
const nu = this.selectionStart + newValue.length - this.value.length; const nu = this.selectionStart + newValue.length - this.value.length;
this.value = newValue; this.value = newValue;
excEditor.dataset.moveCursorTo = nu; excEditor.dataset.moveCursorTo = nu;
window.setTimeout(moveCursorIfNeeded, 0); window.setTimeout(moveCursorIfNeeded, 0);
} }
setInputValue(prefixedHost); const host = this.value.trim() || ' ';
const _nakedHost = _host.trim().replace(prefRe, '');
setInputValue(host);
thisAuto.checked = true; thisAuto.checked = true;
const toDefault = (opt) => opt.value = excPrefix + opt.dataset.host;; this.classList.remove(noClass, yesClass);
const delim = ' | ';
let exactOpt = false;
const ifLineSelected = _host.includes(delim);
excList.childNodes.forEach( excList.childNodes.forEach(
(opt) => { (opt) => {
const ifExactMatch = opt.dataset.host === _nakedHost || opt.value === _host; const ifExactMatch = opt.dataset.host === host;
if (ifExactMatch) { if (!ifExactMatch) {
exactOpt = opt; return unhideOpt(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 + '$';
} }
} const exactOpt = opt;
);
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;
}
hideOpt(exactOpt);
if(exactOpt.innerHTML === ifProxyHtml) { if(exactOpt.innerHTML === ifProxyHtml) {
thisYes.checked = true; thisYes.checked = true;
this.classList.add(yesClass); this.classList.add(yesClass);
@ -400,7 +357,9 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
thisNo.checked = true; thisNo.checked = true;
this.classList.add(noClass); this.classList.add(noClass);
} }
} }
);
return true; return true;
}; };
@ -422,7 +381,7 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
return true; return true;
} }
const _host = excEditor.value.trim().replace(prefRe, ''); const host = excEditor.value.trim();
const pacMods = pacKitchen.getPacMods(); const pacMods = pacKitchen.getPacMods();
pacMods.exceptions = pacMods.exceptions || {}; pacMods.exceptions = pacMods.exceptions || {};
@ -430,11 +389,11 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
let fixUi = () => {}; let fixUi = () => {};
if (thisAuto.checked) { if (thisAuto.checked) {
delete pacMods.exceptions[_host]; delete pacMods.exceptions[host];
fixUi = () => excEditor.value = ''; fixUi = () => excEditor.value = '';
} else { } else {
// YES or NO. // YES or NO.
if (!validateHost(_host)) { if (!validateHost(host)) {
return false; return false;
} }
if (thisYes.checked && !pacMods.filteredCustomsString) { if (thisYes.checked && !pacMods.filteredCustomsString) {
@ -443,8 +402,8 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
)); ));
return false; return false;
} }
pacMods.exceptions[_host] = thisYes.checked; pacMods.exceptions[host] = thisYes.checked;
fixUi = () => addOption(_host, thisYes.checked); fixUi = () => addOption(host, thisYes.checked);
} }
conduct( conduct(
@ -453,7 +412,9 @@ chrome.runtime.getBackgroundPage( (backgroundPage) =>
'Исключения применены.', 'Исключения применены.',
() => { () => {
getExactOpts(_host).forEach( (opt) => opt.remove() ); excList.childNodes.forEach(
(opt) => opt.dataset.host === host && opt.remove()
);
fixUi(); fixUi();
excEditor.oninput(); excEditor.oninput();
@ -557,8 +518,8 @@ HTTPS 11.22.33.44:8080;">${conf.value || localStorage.getItem(uiRaw) || ''}</tex
if (!ifSure) { if (!ifSure) {
return false; return false;
} }
pacKitchen.resetToDefaultsVoid(); pacKitchen.resetToDefaults();
backgroundPage.apis.ipToHost.resetToDefaultsVoid(); backgroundPage.apis.ipToHost.resetToDefaults();
window.close(); window.close();
}; };