From 262a1a044f706d8937ba430911359d7c306329e4 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Wed, 2 Dec 2020 09:09:28 -0500 Subject: [PATCH] Improve auto-complete of hostname values in "My filters" Related issue: - https://github.com/uBlockOrigin/uBlock-issues/issues/1134 Related commit: - https://github.com/gorhill/uBlock/commit/daf464b3c30e9c0c5f5991ba1bde8f9dca1d7078 --- src/js/1p-filters.js | 45 +++++++++++++++++------ src/js/codemirror/ubo-static-filtering.js | 45 ++++++++++++++--------- src/js/messaging.js | 18 +++++---- 3 files changed, 72 insertions(+), 36 deletions(-) diff --git a/src/js/1p-filters.js b/src/js/1p-filters.js index 7d70b85ad..647d48cdf 100644 --- a/src/js/1p-filters.js +++ b/src/js/1p-filters.js @@ -49,22 +49,43 @@ const cmEditor = new CodeMirror(document.getElementById('userFilters'), { uBlockDashboard.patchCodeMirrorEditor(cmEditor); -vAPI.messaging.send('dashboard', { - what: 'getAutoCompleteDetails' -}).then(response => { - if ( response instanceof Object === false ) { return; } - const mode = cmEditor.getMode(); - // TODO: listen to changes in currently opened set of tabs? - if ( mode.setHints instanceof Function ) { - mode.setHints(response); - } - mode.parser.expertMode = response.expertMode !== false; -}); - let cachedUserFilters = ''; /******************************************************************************/ +// Add auto-complete ability to the editor. + +{ + let hintUpdateToken = 0; + + const responseHandler = function(response) { + if ( response instanceof Object === false ) { return; } + if ( response.hintUpdateToken !== undefined ) { + const firstVisit = hintUpdateToken === 0; + const mode = cmEditor.getMode(); + if ( mode.setHints instanceof Function ) { + mode.setHints(response, firstVisit); + } + if ( firstVisit ) { + mode.parser.expertMode = response.expertMode !== false; + } + hintUpdateToken = response.hintUpdateToken; + } + vAPI.setTimeout(getHints, 2503); + }; + + const getHints = function() { + vAPI.messaging.send('dashboard', { + what: 'getAutoCompleteDetails', + hintUpdateToken + }).then(responseHandler); + }; + + getHints(); +} + +/******************************************************************************/ + const getEditorText = function() { const text = cmEditor.getValue().replace(/\s+$/, ''); return text === '' ? text : text + '\n'; diff --git a/src/js/codemirror/ubo-static-filtering.js b/src/js/codemirror/ubo-static-filtering.js index cc55c7548..78a8710c5 100644 --- a/src/js/codemirror/ubo-static-filtering.js +++ b/src/js/codemirror/ubo-static-filtering.js @@ -361,26 +361,37 @@ CodeMirror.defineMode('ubo-static-filtering', function() { style = style.trim(); return style !== '' ? style : null; }, - setHints: function(details) { - for ( const [ name, desc ] of details.redirectResources ) { - const displayText = desc.aliasOf !== '' - ? `${name} (${desc.aliasOf})` - : ''; - if ( desc.canRedirect ) { - redirectNames.set(name, displayText); - } - if ( desc.canInject && name.endsWith('.js') ) { - scriptletNames.set(name.slice(0, -3), displayText); + setHints: function(details, firstVisit = false) { + if ( Array.isArray(details.redirectResources) ) { + for ( const [ name, desc ] of details.redirectResources ) { + const displayText = desc.aliasOf !== '' + ? `${name} (${desc.aliasOf})` + : ''; + if ( desc.canRedirect ) { + redirectNames.set(name, displayText); + } + if ( desc.canInject && name.endsWith('.js') ) { + scriptletNames.set(name.slice(0, -3), displayText); + } } } - details.preparseDirectiveTokens.forEach(([ a, b ]) => { - preparseDirectiveTokens.set(a, b); - }); - preparseDirectiveHints.push(...details.preparseDirectiveHints); - for ( const hint of details.originHints ) { - originHints.push(hint); + if ( Array.isArray(details.preparseDirectiveTokens)) { + details.preparseDirectiveTokens.forEach(([ a, b ]) => { + preparseDirectiveTokens.set(a, b); + }); + } + if ( Array.isArray(details.preparseDirectiveHints)) { + preparseDirectiveHints.push(...details.preparseDirectiveHints); + } + if ( Array.isArray(details.originHints) ) { + originHints.length = 0; + for ( const hint of details.originHints ) { + originHints.push(hint); + } + } + if ( firstVisit ) { + initHints(); } - initHints(); }, get parser() { return parser; diff --git a/src/js/messaging.js b/src/js/messaging.js index 5af3d539f..478f2c215 100644 --- a/src/js/messaging.js +++ b/src/js/messaging.js @@ -1201,13 +1201,17 @@ const onMessage = function(request, sender, callback) { break; case 'getAutoCompleteDetails': - response = { - redirectResources: µb.redirectEngine.getResourceDetails(), - preparseDirectiveTokens: µb.preparseDirectives.getTokens(), - preparseDirectiveHints: µb.preparseDirectives.getHints(), - originHints: getOriginHints(), - expertMode: µb.hiddenSettings.filterAuthorMode, - }; + response = {}; + if ( request.hintUpdateToken === 0 ) { + response.redirectResources = µb.redirectEngine.getResourceDetails(); + response.preparseDirectiveTokens = µb.preparseDirectives.getTokens(); + response.preparseDirectiveHints = µb.preparseDirectives.getHints(); + response.expertMode = µb.hiddenSettings.filterAuthorMode; + } + if ( request.hintUpdateToken !== µb.pageStoresToken ) { + response.originHints = getOriginHints(); + response.hintUpdateToken = µb.pageStoresToken; + } break; case 'getRules':