mirror of https://github.com/gorhill/uBlock.git
Add auto-completion for procedural operators
Related commit:
- 3e72a47c1f
This commit is contained in:
parent
de8d217983
commit
aa000e282e
|
@ -127,3 +127,7 @@ div.CodeMirror span.CodeMirror-matchingbracket {
|
|||
.CodeMirror-merge-gap {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.CodeMirror-hints {
|
||||
z-index: 10000;
|
||||
}
|
||||
|
|
|
@ -262,8 +262,13 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
const parser = new StaticFilteringParser();
|
||||
const redirectNames = new Map();
|
||||
const scriptletNames = new Map();
|
||||
const proceduralOperatorNames = new Map(
|
||||
Array.from(parser.proceduralOperatorTokens).filter(item => {
|
||||
return (item[1] & 0b01) !== 0;
|
||||
})
|
||||
);
|
||||
|
||||
const getNetOptionHint = function(cursor, isNegated, seedLeft, seedRight) {
|
||||
const getNetOptionHints = function(cursor, isNegated, seedLeft, seedRight) {
|
||||
const assignPos = seedRight.indexOf('=');
|
||||
if ( assignPos !== -1 ) { seedRight = seedRight.slice(0, assignPos); }
|
||||
const seed = (seedLeft + seedRight).trim();
|
||||
|
@ -289,7 +294,7 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
};
|
||||
};
|
||||
|
||||
const getNetRedirectHint = function(cursor, seedLeft, seedRight) {
|
||||
const getNetRedirectHints = function(cursor, seedLeft, seedRight) {
|
||||
const seed = (seedLeft + seedRight).trim();
|
||||
const out = [];
|
||||
for ( let text of redirectNames.keys() ) {
|
||||
|
@ -303,7 +308,7 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
};
|
||||
};
|
||||
|
||||
const getNetHint = function(cursor, line) {
|
||||
const getNetHints = function(cursor, line) {
|
||||
const beg = cursor.ch;
|
||||
if ( beg < parser.optionsSpan ) { return; }
|
||||
const lineBefore = line.slice(0, beg);
|
||||
|
@ -313,21 +318,41 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
if ( matchLeft === null || matchRight === null ) { return; }
|
||||
let pos = matchLeft[1].indexOf('=');
|
||||
if ( pos === -1 ) {
|
||||
return getNetOptionHint(
|
||||
return getNetOptionHints(
|
||||
cursor,
|
||||
matchLeft[0].startsWith('~'),
|
||||
matchLeft[1],
|
||||
matchRight[1]
|
||||
);
|
||||
}
|
||||
return getNetRedirectHint(
|
||||
return getNetRedirectHints(
|
||||
cursor,
|
||||
matchLeft[1].slice(pos + 1),
|
||||
matchRight[1]
|
||||
);
|
||||
};
|
||||
|
||||
const getExtScriptletHint = function(cursor, line) {
|
||||
const getExtSelectorHints = function(cursor, line) {
|
||||
const beg = cursor.ch;
|
||||
const matchLeft = /#\^?.*:([^:]*)$/.exec(line.slice(0, beg));
|
||||
const matchRight = /^([a-z-]*)\(?/.exec(line.slice(beg));
|
||||
if ( matchLeft === null || matchRight === null ) { return; }
|
||||
const isStaticDOM = matchLeft[0].indexOf('^') !== -1;
|
||||
const seed = (matchLeft[1] + matchRight[1]).trim();
|
||||
const out = [];
|
||||
for ( let [ text, bits ] of proceduralOperatorNames ) {
|
||||
if ( text.startsWith(seed) === false ) { continue; }
|
||||
if ( isStaticDOM && (bits & 0b10) !== 0 ) { continue; }
|
||||
out.push(text);
|
||||
}
|
||||
return {
|
||||
from: { line: cursor.line, ch: cursor.ch - matchLeft[1].length },
|
||||
to: { line: cursor.line, ch: cursor.ch + matchRight[1].length },
|
||||
list: out,
|
||||
};
|
||||
};
|
||||
|
||||
const getExtScriptletHints = function(cursor, line) {
|
||||
const beg = cursor.ch;
|
||||
const matchLeft = /#\+\js\(([^,]*)$/.exec(line.slice(0, beg));
|
||||
const matchRight = /^([^,)]*)/.exec(line.slice(beg));
|
||||
|
@ -353,14 +378,14 @@ CodeMirror.defineMode('ubo-static-filtering', function() {
|
|||
const cursor = cm.getCursor();
|
||||
const line = cm.getLine(cursor.line);
|
||||
parser.analyze(line);
|
||||
if (
|
||||
parser.category === parser.CATStaticExtFilter &&
|
||||
parser.hasFlavor(parser.BITFlavorExtScriptlet)
|
||||
) {
|
||||
return getExtScriptletHint(cursor, line);
|
||||
if ( parser.category === parser.CATStaticExtFilter ) {
|
||||
if ( parser.hasFlavor(parser.BITFlavorExtScriptlet) ) {
|
||||
return getExtScriptletHints(cursor, line);
|
||||
}
|
||||
return getExtSelectorHints(cursor, line);
|
||||
}
|
||||
if ( parser.category === parser.CATStaticNetFilter ) {
|
||||
return getNetHint(cursor, line);
|
||||
return getNetHints(cursor, line);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1101,27 +1101,7 @@ Parser.prototype.SelectorCompiler = class {
|
|||
this.rePseudoClass = /:(?::?after|:?before|:[a-z][a-z-]*[a-z])$/;
|
||||
this.reProceduralOperator = new RegExp([
|
||||
'^(?:',
|
||||
[
|
||||
'-abp-contains',
|
||||
'-abp-has',
|
||||
'contains',
|
||||
'has',
|
||||
'has-text',
|
||||
'if',
|
||||
'if-not',
|
||||
'matches-css',
|
||||
'matches-css-after',
|
||||
'matches-css-before',
|
||||
'min-text-length',
|
||||
'not',
|
||||
'nth-ancestor',
|
||||
'remove',
|
||||
'style',
|
||||
'upward',
|
||||
'watch-attr',
|
||||
'watch-attrs',
|
||||
'xpath'
|
||||
].join('|'),
|
||||
Array.from(parser.proceduralOperatorTokens.keys()).join('|'),
|
||||
')\\('
|
||||
].join(''));
|
||||
this.reEatBackslashes = /\\([()])/g;
|
||||
|
@ -1627,6 +1607,28 @@ Parser.prototype.SelectorCompiler = class {
|
|||
}
|
||||
};
|
||||
|
||||
Parser.prototype.proceduralOperatorTokens = new Map([
|
||||
[ '-abp-contains', 0b00 ],
|
||||
[ '-abp-has', 0b00, ],
|
||||
[ 'contains', 0b00, ],
|
||||
[ 'has', 0b01 ],
|
||||
[ 'has-text', 0b01 ],
|
||||
[ 'if', 0b00 ],
|
||||
[ 'if-not', 0b00 ],
|
||||
[ 'matches-css', 0b11 ],
|
||||
[ 'matches-css-after', 0b11 ],
|
||||
[ 'matches-css-before', 0b11 ],
|
||||
[ 'min-text-length', 0b01 ],
|
||||
[ 'not', 0b01 ],
|
||||
[ 'nth-ancestor', 0b00 ],
|
||||
[ 'remove', 0b11 ],
|
||||
[ 'style', 0b11 ],
|
||||
[ 'upward', 0b01 ],
|
||||
[ 'watch-attr', 0b11 ],
|
||||
[ 'watch-attrs', 0b00 ],
|
||||
[ 'xpath', 0b01 ],
|
||||
]);
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const hasNoBits = (v, bits) => (v & bits) === 0;
|
||||
|
|
Loading…
Reference in New Issue