mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
Add support to auto-complete values of domain lists
The auto-complete feature in the _"My filters"_ pane will use hostname/domain from the set of opened tabs to assist in entering values for `domain=` option. This also works for the implict `domain=` option ṗrepending static extended filters.
This commit is contained in:
parent
8d3c4916b0
commit
daf464b3c3
3 changed files with 75 additions and 19 deletions
|
@ -54,6 +54,7 @@ vAPI.messaging.send('dashboard', {
|
|||
}).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);
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ const redirectNames = new Map();
|
|||
const scriptletNames = new Map();
|
||||
const preparseDirectiveTokens = new Map();
|
||||
const preparseDirectiveHints = [];
|
||||
const originHints = [];
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -362,6 +363,9 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
preparseDirectiveTokens.set(a, b);
|
||||
});
|
||||
preparseDirectiveHints.push(...details.preparseDirectiveHints);
|
||||
for ( const hint of details.originHints ) {
|
||||
originHints.push(hint);
|
||||
}
|
||||
initHints();
|
||||
},
|
||||
get parser() {
|
||||
|
@ -418,7 +422,23 @@ const initHints = function() {
|
|||
};
|
||||
};
|
||||
|
||||
const getNetOptionHints = function(cursor, isNegated, seedLeft, seedRight) {
|
||||
const getOriginHints = function(cursor, line) {
|
||||
const beg = cursor.ch;
|
||||
const matchLeft = /[^,|=~]*$/.exec(line.slice(0, beg));
|
||||
const matchRight = /^[^#,|]*/.exec(line.slice(beg));
|
||||
if ( matchLeft === null || matchRight === null ) { return; }
|
||||
const hints = [];
|
||||
for ( const text of originHints ) {
|
||||
hints.push(text);
|
||||
}
|
||||
return pickBestHints(cursor, matchLeft[0], matchRight[0], hints);
|
||||
};
|
||||
|
||||
const getNetOptionHints = function(cursor, seedLeft, seedRight) {
|
||||
const isNegated = seedLeft.startsWith('~');
|
||||
if ( isNegated ) {
|
||||
seedLeft = seedLeft.slice(1);
|
||||
}
|
||||
const assignPos = seedRight.indexOf('=');
|
||||
if ( assignPos !== -1 ) { seedRight = seedRight.slice(0, assignPos); }
|
||||
const isException = parser.isException();
|
||||
|
@ -448,26 +468,32 @@ const initHints = function() {
|
|||
|
||||
const getNetHints = function(cursor, line) {
|
||||
const beg = cursor.ch;
|
||||
if ( beg < parser.optionsSpan ) { return; }
|
||||
if ( parser.optionsSpan.len === 0 ) {
|
||||
if ( /[^\w\x80-\xF4#,.-]/.test(line) === false ) {
|
||||
return getOriginHints(cursor, line);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ( beg < parser.slices[parser.optionsSpan.i+1] ) { return; }
|
||||
const lineBefore = line.slice(0, beg);
|
||||
const lineAfter = line.slice(beg);
|
||||
let matchLeft = /~?([^$,~]*)$/.exec(lineBefore);
|
||||
let matchRight = /^([^,]*)/.exec(lineAfter);
|
||||
let matchLeft = /[^$,]*$/.exec(lineBefore);
|
||||
let matchRight = /^[^,]*/.exec(lineAfter);
|
||||
if ( matchLeft === null || matchRight === null ) { return; }
|
||||
let pos = matchLeft[1].indexOf('=');
|
||||
if ( pos === -1 ) {
|
||||
return getNetOptionHints(
|
||||
const assignPos = matchLeft[0].indexOf('=');
|
||||
if ( assignPos === -1 ) {
|
||||
return getNetOptionHints(cursor, matchLeft[0], matchRight[0]);
|
||||
}
|
||||
if ( /^redirect(-rule)?=/.test(matchLeft[0]) ) {
|
||||
return getNetRedirectHints(
|
||||
cursor,
|
||||
matchLeft[0].startsWith('~'),
|
||||
matchLeft[1],
|
||||
matchRight[1]
|
||||
matchLeft[0].slice(assignPos + 1),
|
||||
matchRight[0]
|
||||
);
|
||||
}
|
||||
return getNetRedirectHints(
|
||||
cursor,
|
||||
matchLeft[1].slice(pos + 1),
|
||||
matchRight[1]
|
||||
);
|
||||
if ( matchLeft[0].startsWith('domain=') ) {
|
||||
return getOriginHints(cursor, line);
|
||||
}
|
||||
};
|
||||
|
||||
const getExtSelectorHints = function(cursor, line) {
|
||||
|
@ -527,10 +553,15 @@ const initHints = function() {
|
|||
const line = cm.getLine(cursor.line);
|
||||
parser.analyze(line);
|
||||
if ( parser.category === parser.CATStaticExtFilter ) {
|
||||
if ( parser.hasFlavor(parser.BITFlavorExtScriptlet) ) {
|
||||
return getExtScriptletHints(cursor, line);
|
||||
let hints;
|
||||
if ( cursor.ch <= parser.slices[parser.optionsAnchorSpan.i+1] ) {
|
||||
hints = getOriginHints(cursor, line);
|
||||
} else {
|
||||
hints = parser.hasFlavor(parser.BITFlavorExtScriptlet)
|
||||
? getExtScriptletHints(cursor, line)
|
||||
: getExtSelectorHints(cursor, line);
|
||||
}
|
||||
return getExtSelectorHints(cursor, line);
|
||||
return hints;
|
||||
}
|
||||
if ( parser.category === parser.CATStaticNetFilter ) {
|
||||
return getNetHints(cursor, line);
|
||||
|
@ -538,6 +569,9 @@ const initHints = function() {
|
|||
if ( parser.category === parser.CATComment ) {
|
||||
return getCommentHints(cursor, line);
|
||||
}
|
||||
if ( parser.category === parser.CATNone ) {
|
||||
return getOriginHints(cursor, line);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -1000,7 +1000,7 @@ const resetUserData = async function() {
|
|||
vAPI.app.restart();
|
||||
};
|
||||
|
||||
// 3rd-party filters
|
||||
// Filter lists
|
||||
const prepListEntries = function(entries) {
|
||||
const µburi = µb.URI;
|
||||
for ( const k in entries ) {
|
||||
|
@ -1041,6 +1041,26 @@ const getLists = async function(callback) {
|
|||
callback(r);
|
||||
};
|
||||
|
||||
// My filters
|
||||
|
||||
// TODO: also return origin of embedded frames?
|
||||
const getOriginHints = function() {
|
||||
const punycode = self.punycode;
|
||||
const out = [];
|
||||
for ( const tabId of µb.pageStores.keys() ) {
|
||||
if ( tabId === -1 ) { continue; }
|
||||
const tabContext = µb.tabContextManager.lookup(tabId);
|
||||
if ( tabContext === null ) { continue; }
|
||||
let { rootDomain, rootHostname } = tabContext;
|
||||
if ( rootDomain.endsWith('-scheme') ) { continue; }
|
||||
const isPunycode = rootHostname.includes('xn--');
|
||||
out.push(isPunycode ? punycode.toUnicode(rootDomain) : rootDomain);
|
||||
if ( rootHostname === rootDomain ) { continue; }
|
||||
out.push(isPunycode ? punycode.toUnicode(rootHostname) : rootHostname);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
// My rules
|
||||
const getRules = function() {
|
||||
return {
|
||||
|
@ -1185,6 +1205,7 @@ const onMessage = function(request, sender, callback) {
|
|||
redirectResources: µb.redirectEngine.getResourceDetails(),
|
||||
preparseDirectiveTokens: µb.preparseDirectives.getTokens(),
|
||||
preparseDirectiveHints: µb.preparseDirectives.getHints(),
|
||||
originHints: getOriginHints(),
|
||||
expertMode: µb.hiddenSettings.filterAuthorMode,
|
||||
};
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue