mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-13 02:14:17 +01:00
Add new procedural operator: :min-text-length(x)
Where `x` is the minimal text length of the subject DOM element. DOM elements whose text length is greater than or equal to `x` will be selected. The original rationale for such procedural cosmetic operator[1] is to be able to remove inline script elements according to a minimum text length using HTML filtering. [1] As a result of internal discussion with filter list maintainers @ uAssets.
This commit is contained in:
parent
793aca7ddb
commit
b428a25c3f
3 changed files with 46 additions and 8 deletions
|
@ -540,6 +540,21 @@ vAPI.DOMFilterer = (function() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PSelectorMinTextLengthTask = class {
|
||||||
|
constructor(task) {
|
||||||
|
this.min = task[1];
|
||||||
|
}
|
||||||
|
exec(input) {
|
||||||
|
const output = [];
|
||||||
|
for ( const node of input ) {
|
||||||
|
if ( node.textContent.length >= this.min ) {
|
||||||
|
output.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const PSelectorNthAncestorTask = class {
|
const PSelectorNthAncestorTask = class {
|
||||||
constructor(task) {
|
constructor(task) {
|
||||||
this.nth = task[1];
|
this.nth = task[1];
|
||||||
|
@ -658,6 +673,7 @@ vAPI.DOMFilterer = (function() {
|
||||||
[ ':matches-css', PSelectorMatchesCSSTask ],
|
[ ':matches-css', PSelectorMatchesCSSTask ],
|
||||||
[ ':matches-css-after', PSelectorMatchesCSSAfterTask ],
|
[ ':matches-css-after', PSelectorMatchesCSSAfterTask ],
|
||||||
[ ':matches-css-before', PSelectorMatchesCSSBeforeTask ],
|
[ ':matches-css-before', PSelectorMatchesCSSBeforeTask ],
|
||||||
|
[ ':min-text-length', PSelectorMinTextLengthTask ],
|
||||||
[ ':not', PSelectorIfNotTask ],
|
[ ':not', PSelectorIfNotTask ],
|
||||||
[ ':nth-ancestor', PSelectorNthAncestorTask ],
|
[ ':nth-ancestor', PSelectorNthAncestorTask ],
|
||||||
[ ':spath', PSelectorSpathTask ],
|
[ ':spath', PSelectorSpathTask ],
|
||||||
|
|
|
@ -82,11 +82,26 @@
|
||||||
|
|
||||||
const PSelectorIfNotTask = class extends PSelectorIfTask {
|
const PSelectorIfNotTask = class extends PSelectorIfTask {
|
||||||
constructor(task) {
|
constructor(task) {
|
||||||
super.call(task);
|
super(task);
|
||||||
this.target = false;
|
this.target = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PSelectorMinTextLengthTask = class {
|
||||||
|
constructor(task) {
|
||||||
|
this.min = task[1];
|
||||||
|
}
|
||||||
|
exec(input) {
|
||||||
|
const output = [];
|
||||||
|
for ( const node of input ) {
|
||||||
|
if ( node.textContent.length >= this.min ) {
|
||||||
|
output.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const PSelectorNthAncestorTask = class {
|
const PSelectorNthAncestorTask = class {
|
||||||
constructor(task) {
|
constructor(task) {
|
||||||
this.nth = task[1];
|
this.nth = task[1];
|
||||||
|
@ -191,6 +206,7 @@
|
||||||
[ ':has-text', PSelectorHasTextTask ],
|
[ ':has-text', PSelectorHasTextTask ],
|
||||||
[ ':if', PSelectorIfTask ],
|
[ ':if', PSelectorIfTask ],
|
||||||
[ ':if-not', PSelectorIfNotTask ],
|
[ ':if-not', PSelectorIfNotTask ],
|
||||||
|
[ ':min-text-length', PSelectorMinTextLengthTask ],
|
||||||
[ ':not', PSelectorIfNotTask ],
|
[ ':not', PSelectorIfNotTask ],
|
||||||
[ ':nth-ancestor', PSelectorNthAncestorTask ],
|
[ ':nth-ancestor', PSelectorNthAncestorTask ],
|
||||||
[ ':xpath', PSelectorXpathTask ]
|
[ ':xpath', PSelectorXpathTask ]
|
||||||
|
|
|
@ -166,6 +166,7 @@
|
||||||
'matches-css',
|
'matches-css',
|
||||||
'matches-css-after',
|
'matches-css-after',
|
||||||
'matches-css-before',
|
'matches-css-before',
|
||||||
|
'min-text-length',
|
||||||
'not',
|
'not',
|
||||||
'nth-ancestor',
|
'nth-ancestor',
|
||||||
'watch-attrs',
|
'watch-attrs',
|
||||||
|
@ -231,6 +232,14 @@
|
||||||
return compile(s);
|
return compile(s);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const compileInteger = function(s, min = 0, max = 0x7FFFFFFF) {
|
||||||
|
if ( /^\d+$/.test(s) === false ) { return; }
|
||||||
|
const n = parseInt(s, 10);
|
||||||
|
if ( n >= min && n < max ) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const compileNotSelector = function(s) {
|
const compileNotSelector = function(s) {
|
||||||
// https://github.com/uBlockOrigin/uBlock-issues/issues/341#issuecomment-447603588
|
// https://github.com/uBlockOrigin/uBlock-issues/issues/341#issuecomment-447603588
|
||||||
// Reject instances of :not() filters for which the argument is
|
// Reject instances of :not() filters for which the argument is
|
||||||
|
@ -242,10 +251,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
const compileNthAncestorSelector = function(s) {
|
const compileNthAncestorSelector = function(s) {
|
||||||
const n = parseInt(s, 10);
|
return compileInteger(s, 1, 256);
|
||||||
if ( isNaN(n) === false && n >= 1 && n < 256 ) {
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const compileSpathExpression = function(s) {
|
const compileSpathExpression = function(s) {
|
||||||
|
@ -289,6 +295,7 @@
|
||||||
[ ':matches-css', compileCSSDeclaration ],
|
[ ':matches-css', compileCSSDeclaration ],
|
||||||
[ ':matches-css-after', compileCSSDeclaration ],
|
[ ':matches-css-after', compileCSSDeclaration ],
|
||||||
[ ':matches-css-before', compileCSSDeclaration ],
|
[ ':matches-css-before', compileCSSDeclaration ],
|
||||||
|
[ ':min-text-length', compileInteger ],
|
||||||
[ ':not', compileNotSelector ],
|
[ ':not', compileNotSelector ],
|
||||||
[ ':nth-ancestor', compileNthAncestorSelector ],
|
[ ':nth-ancestor', compileNthAncestorSelector ],
|
||||||
[ ':spath', compileSpathExpression ],
|
[ ':spath', compileSpathExpression ],
|
||||||
|
@ -344,12 +351,11 @@
|
||||||
case ':if-not':
|
case ':if-not':
|
||||||
raw.push(`:not(${decompile(task[1])})`);
|
raw.push(`:not(${decompile(task[1])})`);
|
||||||
break;
|
break;
|
||||||
case ':nth-ancestor':
|
|
||||||
raw.push(`:nth-ancestor(${task[1]})`);
|
|
||||||
break;
|
|
||||||
case ':spath':
|
case ':spath':
|
||||||
raw.push(task[1]);
|
raw.push(task[1]);
|
||||||
break;
|
break;
|
||||||
|
case ':min-text-length':
|
||||||
|
case ':nth-ancestor':
|
||||||
case ':watch-attrs':
|
case ':watch-attrs':
|
||||||
case ':xpath':
|
case ':xpath':
|
||||||
raw.push(`${task[0]}(${task[1]})`);
|
raw.push(`${task[0]}(${task[1]})`);
|
||||||
|
|
Loading…
Reference in a new issue