mirror of https://github.com/gorhill/uBlock.git
Cache element picker's optimized candidates for reuse
Optimized candidates computed for each depth are now cached for reuse. This reduces the amount of work done when moving the depth slider.
This commit is contained in:
parent
5de0ce9757
commit
ee059540f7
|
@ -32,10 +32,6 @@ html#ublock0-epicker,
|
||||||
#ublock0-epicker #toolbar {
|
#ublock0-epicker #toolbar {
|
||||||
cursor: grab;
|
cursor: grab;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
#ublock0-epicker aside.moving #toolbar {
|
|
||||||
cursor: grabbing;
|
|
||||||
}
|
}
|
||||||
#ublock0-epicker ul {
|
#ublock0-epicker ul {
|
||||||
margin: 0.25em 0 0 0;
|
margin: 0.25em 0 0 0;
|
||||||
|
@ -67,6 +63,13 @@ html#ublock0-epicker,
|
||||||
background-color: var(--button-preferred-surface);
|
background-color: var(--button-preferred-surface);
|
||||||
color: var(--button-preferred-ink);
|
color: var(--button-preferred-ink);
|
||||||
}
|
}
|
||||||
|
#ublock0-epicker #move {
|
||||||
|
cursor: grab;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
#ublock0-epicker aside.moving #move {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
#ublock0-epicker section {
|
#ublock0-epicker section {
|
||||||
border: 0;
|
border: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -117,12 +120,14 @@ html#ublock0-epicker,
|
||||||
}
|
}
|
||||||
.resultsetModifier > span {
|
.resultsetModifier > span {
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
border-bottom: 2px solid white;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
.resultsetModifier > span > span {
|
||||||
|
margin: 2px 0;
|
||||||
|
}
|
||||||
.resultsetModifier > span > span:nth-of-type(1) {
|
.resultsetModifier > span > span:nth-of-type(1) {
|
||||||
background-color: var(--checkbox-checked-ink);
|
background-color: var(--checkbox-checked-ink);
|
||||||
border-inline-end: 1px solid #aaa;
|
border-inline-end: 1px solid #aaa;
|
||||||
|
|
|
@ -63,7 +63,7 @@ let netFilterCandidates = [];
|
||||||
let cosmeticFilterCandidates = [];
|
let cosmeticFilterCandidates = [];
|
||||||
let computedCandidateSlot = 0;
|
let computedCandidateSlot = 0;
|
||||||
let computedCandidate = '';
|
let computedCandidate = '';
|
||||||
let computedSpecificityCandidates = [];
|
const computedSpecificityCandidates = new Map();
|
||||||
let needBody = false;
|
let needBody = false;
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
@ -201,6 +201,16 @@ const candidateFromFilterChoice = function(filterChoice) {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const cosmeticCandidatesFromFilterChoice = function(filterChoice) {
|
const cosmeticCandidatesFromFilterChoice = function(filterChoice) {
|
||||||
|
let { slot, filters } = filterChoice;
|
||||||
|
|
||||||
|
renderRange('resultsetDepth', slot, true);
|
||||||
|
renderRange('resultsetSpecificity');
|
||||||
|
|
||||||
|
if ( computedSpecificityCandidates.has(slot) ) {
|
||||||
|
onCandidatesOptimized({ slot });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const specificities = [
|
const specificities = [
|
||||||
0b0000, // remove hierarchy; remove id, nth-of-type, attribute values
|
0b0000, // remove hierarchy; remove id, nth-of-type, attribute values
|
||||||
0b0010, // remove hierarchy; remove id, nth-of-type
|
0b0010, // remove hierarchy; remove id, nth-of-type
|
||||||
|
@ -214,7 +224,6 @@ const cosmeticCandidatesFromFilterChoice = function(filterChoice) {
|
||||||
|
|
||||||
const candidates = [];
|
const candidates = [];
|
||||||
|
|
||||||
let { slot, filters } = filterChoice;
|
|
||||||
let filter = filters[slot];
|
let filter = filters[slot];
|
||||||
|
|
||||||
for ( const specificity of specificities ) {
|
for ( const specificity of specificities ) {
|
||||||
|
@ -288,12 +297,10 @@ const cosmeticCandidatesFromFilterChoice = function(filterChoice) {
|
||||||
candidates.push(paths);
|
candidates.push(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRange('resultsetDepth', slot, true);
|
|
||||||
renderRange('resultsetSpecificity');
|
|
||||||
|
|
||||||
vAPI.MessagingConnection.sendTo(epickerConnectionId, {
|
vAPI.MessagingConnection.sendTo(epickerConnectionId, {
|
||||||
what: 'optimizeCandidates',
|
what: 'optimizeCandidates',
|
||||||
candidates,
|
candidates,
|
||||||
|
slot,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,8 +309,11 @@ const cosmeticCandidatesFromFilterChoice = function(filterChoice) {
|
||||||
const onCandidatesOptimized = function(details) {
|
const onCandidatesOptimized = function(details) {
|
||||||
$id('resultsetModifiers').classList.remove('hide');
|
$id('resultsetModifiers').classList.remove('hide');
|
||||||
const i = parseInt($stor('#resultsetSpecificity input').value, 10);
|
const i = parseInt($stor('#resultsetSpecificity input').value, 10);
|
||||||
computedSpecificityCandidates = details.candidates;
|
if ( Array.isArray(details.candidates) ) {
|
||||||
computedCandidate = computedSpecificityCandidates[i];
|
computedSpecificityCandidates.set(details.slot, details.candidates);
|
||||||
|
}
|
||||||
|
const candidates = computedSpecificityCandidates.get(details.slot);
|
||||||
|
computedCandidate = candidates[i];
|
||||||
cmEditor.setValue(computedCandidate);
|
cmEditor.setValue(computedCandidate);
|
||||||
cmEditor.clearHistory();
|
cmEditor.clearHistory();
|
||||||
onCandidateChanged();
|
onCandidateChanged();
|
||||||
|
@ -521,8 +531,11 @@ const onDepthChanged = function() {
|
||||||
const onSpecificityChanged = function() {
|
const onSpecificityChanged = function() {
|
||||||
renderRange('resultsetSpecificity');
|
renderRange('resultsetSpecificity');
|
||||||
if ( rawFilterFromTextarea() !== computedCandidate ) { return; }
|
if ( rawFilterFromTextarea() !== computedCandidate ) { return; }
|
||||||
|
const depthInput = $stor('#resultsetDepth input');
|
||||||
|
const slot = parseInt(depthInput.max, 10) - parseInt(depthInput.value, 10);
|
||||||
const i = parseInt($stor('#resultsetSpecificity input').value, 10);
|
const i = parseInt($stor('#resultsetSpecificity input').value, 10);
|
||||||
computedCandidate = computedSpecificityCandidates[i];
|
const candidates = computedSpecificityCandidates.get(slot);
|
||||||
|
computedCandidate = candidates[i];
|
||||||
cmEditor.setValue(computedCandidate);
|
cmEditor.setValue(computedCandidate);
|
||||||
cmEditor.clearHistory();
|
cmEditor.clearHistory();
|
||||||
onCandidateChanged();
|
onCandidateChanged();
|
||||||
|
@ -614,7 +627,7 @@ const onStartMoving = (( ) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return function(ev) {
|
return function(ev) {
|
||||||
const target = dialog.querySelector('#toolbar');
|
const target = dialog.querySelector('#move');
|
||||||
if ( ev.target !== target ) { return; }
|
if ( ev.target !== target ) { return; }
|
||||||
if ( dialog.classList.contains('moving') ) { return; }
|
if ( dialog.classList.contains('moving') ) { return; }
|
||||||
isTouch = ev.type.startsWith('touch');
|
isTouch = ev.type.startsWith('touch');
|
||||||
|
@ -735,6 +748,7 @@ const showDialog = function(details) {
|
||||||
|
|
||||||
populateCandidates(netFilters, '#netFilters');
|
populateCandidates(netFilters, '#netFilters');
|
||||||
populateCandidates(cosmeticFilters, '#cosmeticFilters');
|
populateCandidates(cosmeticFilters, '#cosmeticFilters');
|
||||||
|
computedSpecificityCandidates.clear();
|
||||||
|
|
||||||
const depthInput = $stor('#resultsetDepth input');
|
const depthInput = $stor('#resultsetDepth input');
|
||||||
depthInput.max = cosmeticFilters.length - 1;
|
depthInput.max = cosmeticFilters.length - 1;
|
||||||
|
@ -805,8 +819,8 @@ const startPicker = function() {
|
||||||
$id('create').addEventListener('click', onCreateClicked);
|
$id('create').addEventListener('click', onCreateClicked);
|
||||||
$id('pick').addEventListener('click', onPickClicked);
|
$id('pick').addEventListener('click', onPickClicked);
|
||||||
$id('quit').addEventListener('click', onQuitClicked);
|
$id('quit').addEventListener('click', onQuitClicked);
|
||||||
$id('toolbar').addEventListener('mousedown', onStartMoving);
|
$id('move').addEventListener('mousedown', onStartMoving);
|
||||||
$id('toolbar').addEventListener('touchstart', onStartMoving);
|
$id('move').addEventListener('touchstart', onStartMoving);
|
||||||
$id('candidateFilters').addEventListener('click', onCandidateClicked);
|
$id('candidateFilters').addEventListener('click', onCandidateClicked);
|
||||||
$stor('#resultsetDepth input').addEventListener('input', onDepthChanged);
|
$stor('#resultsetDepth input').addEventListener('input', onDepthChanged);
|
||||||
$stor('#resultsetSpecificity input').addEventListener('input', onSpecificityChanged);
|
$stor('#resultsetSpecificity input').addEventListener('input', onSpecificityChanged);
|
||||||
|
|
|
@ -847,6 +847,7 @@ const onOptmizeCandidates = function(details) {
|
||||||
vAPI.MessagingConnection.sendTo(epickerConnectionId, {
|
vAPI.MessagingConnection.sendTo(epickerConnectionId, {
|
||||||
what: 'candidatesOptimized',
|
what: 'candidatesOptimized',
|
||||||
candidates: results.map(a => a.selector),
|
candidates: results.map(a => a.selector),
|
||||||
|
slot: details.slot,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
<div>
|
<div>
|
||||||
<button id="preview" type="button" data-i18n="pickerPreview"></button>
|
<button id="preview" type="button" data-i18n="pickerPreview"></button>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="move"></div>
|
||||||
<div>
|
<div>
|
||||||
<button id="create" type="button" disabled data-i18n="pickerCreate"></button>
|
<button id="create" type="button" disabled data-i18n="pickerCreate"></button>
|
||||||
<button id="pick" type="button" data-i18n="pickerPick"></button>
|
<button id="pick" type="button" data-i18n="pickerPick"></button>
|
||||||
|
|
Loading…
Reference in New Issue