diff --git a/src/css/epicker-ui.css b/src/css/epicker-ui.css index efe685f76..68f33ad1b 100644 --- a/src/css/epicker-ui.css +++ b/src/css/epicker-ui.css @@ -116,7 +116,7 @@ html#ublock0-epicker, justify-content: space-evenly; } #resultsetModifiers.hide > * { - display: none; + visibility: hidden; } .resultsetModifier { border: 0; diff --git a/src/js/epicker-ui.js b/src/js/epicker-ui.js index 7ab87c35f..abb9d86ed 100644 --- a/src/js/epicker-ui.js +++ b/src/js/epicker-ui.js @@ -230,13 +230,24 @@ const candidateFromFilterChoice = function(filterChoice) { paths.unshift('body > '); } - computedCandidate = `##${paths.join('')}`; + if ( paths.length === 0 ) { return ''; } - $id('resultsetModifiers').classList.remove('hide'); renderRange('resultsetDepth', slot, true); renderRange('resultsetSpecificity'); - return computedCandidate; + vAPI.MessagingConnection.sendTo(epickerConnectionId, { + what: 'optimizeCandidate', + paths, + }); +}; + +/******************************************************************************/ + +const onCandidateOptimized = function(details) { + $id('resultsetModifiers').classList.remove('hide'); + computedCandidate = details.filter; + taCandidate.value = computedCandidate; + onCandidateChanged(); }; /******************************************************************************/ @@ -437,10 +448,12 @@ const onDepthChanged = function() { const input = $stor('#resultsetDepth input'); const max = parseInt(input.max, 10); const value = parseInt(input.value, 10); - taCandidate.value = candidateFromFilterChoice({ + const text = candidateFromFilterChoice({ filters: cosmeticFilterCandidates, slot: max - value, }); + if ( text === undefined ) { return; } + taCandidate.value = text; onCandidateChanged(); }; @@ -448,10 +461,12 @@ const onDepthChanged = function() { const onSpecificityChanged = function() { if ( taCandidate.value !== computedCandidate ) { return; } - taCandidate.value = candidateFromFilterChoice({ + const text = candidateFromFilterChoice({ filters: cosmeticFilterCandidates, slot: computedCandidateSlot, }); + if ( text === undefined ) { return; } + taCandidate.value = text; onCandidateChanged(); }; @@ -470,7 +485,9 @@ const onCandidateClicked = function(ev) { li = li.previousElementSibling; choice.slot += 1; } - taCandidate.value = candidateFromFilterChoice(choice); + const text = candidateFromFilterChoice(choice); + if ( text === undefined ) { return; } + taCandidate.value = text; onCandidateChanged(); }; @@ -692,7 +709,9 @@ const showDialog = function(details) { slot: filter.slot, }; - taCandidate.value = candidateFromFilterChoice(filterChoice); + const text = candidateFromFilterChoice(filterChoice); + if ( text === undefined ) { return; } + taCandidate.value = text; onCandidateChanged(); }; @@ -751,6 +770,9 @@ const quitPicker = function() { const onPickerMessage = function(msg) { switch ( msg.what ) { + case 'candidateOptimized': + onCandidateOptimized(msg); + break; case 'showDialog': showDialog(msg); break; diff --git a/src/js/scriptlets/epicker.js b/src/js/scriptlets/epicker.js index 943e5b7b0..311c226f3 100644 --- a/src/js/scriptlets/epicker.js +++ b/src/js/scriptlets/epicker.js @@ -820,6 +820,26 @@ const filterToDOMInterface = (( ) => { /******************************************************************************/ +const onOptmizeCandidate = function(details) { + const { paths } = details; + let count = Number.MAX_SAFE_INTEGER; + let selector = ''; + for ( let i = 0, n = paths.length; i < n; i++ ) { + const s = paths.slice(n - i - 1).join(''); + const elems = document.querySelectorAll(s); + if ( elems.length < count ) { + selector = s; + count = elems.length; + } + } + vAPI.MessagingConnection.sendTo(epickerConnectionId, { + what: 'candidateOptimized', + filter: `##${selector}`, + }); +}; + +/******************************************************************************/ + const showDialog = function(options) { vAPI.MessagingConnection.sendTo(epickerConnectionId, { what: 'showDialog', @@ -1044,6 +1064,9 @@ const onDialogMessage = function(msg) { highlightElements([], true); } break; + case 'optimizeCandidate': + onOptmizeCandidate(msg); + break; case 'dialogCreate': filterToDOMInterface.queryAll(msg); filterToDOMInterface.preview(true, true);