mirror of https://github.com/gorhill/uBlock.git
Extend matches-css() to support any pseudo-element
This commit deprecates matches-css-before() and matches-css-after(): these should no longer be used once 1.45.0 is published and widespread. The deprecated syntax will eventually be removed in some future. The syntax of procedural operator matches-css() has been extended to also be able to target pesudo elements. Examples: Same as before: example.com##p:matches-css(opacity: 0.5) This is the new way to target an `::after` pseudo-element: example.com##p:matches-css(after, content: Ads) This is the new way to target a `::before` pseudo-element: example.com##p:matches-css(before, content: Ads) The new syntax also means any valid pseudo-element can now be used as a target: example.com##p:matches-css(first-letter, opacity: 0.5) If the first argument does not match the pattern "property name: value", then it will be deemed a pseudo-element to target, and the second argument will be the "property name: value". Related issue: - https://github.com/AdguardTeam/ExtendedCss/issues/150
This commit is contained in:
parent
bdc68f3a81
commit
7bc0b5d2bd
|
@ -81,6 +81,7 @@ class PSelectorMatchesCSSTask extends PSelectorTask {
|
|||
constructor(task) {
|
||||
super();
|
||||
this.name = task[1].name;
|
||||
this.pseudo = task[1].pseudo ? `::${task[1].pseudo}` : null;
|
||||
let arg0 = task[1].value, arg1;
|
||||
if ( Array.isArray(arg0) ) {
|
||||
arg1 = arg0[1]; arg0 = arg0[0];
|
||||
|
@ -94,15 +95,19 @@ class PSelectorMatchesCSSTask extends PSelectorTask {
|
|||
}
|
||||
}
|
||||
}
|
||||
PSelectorMatchesCSSTask.prototype.pseudo = null;
|
||||
|
||||
class PSelectorMatchesCSSAfterTask extends PSelectorMatchesCSSTask {
|
||||
constructor(task) {
|
||||
super(task);
|
||||
this.pseudo = 'after';
|
||||
}
|
||||
}
|
||||
PSelectorMatchesCSSAfterTask.prototype.pseudo = ':after';
|
||||
|
||||
class PSelectorMatchesCSSBeforeTask extends PSelectorMatchesCSSTask {
|
||||
constructor(task) {
|
||||
super(task);
|
||||
this.pseudo = 'before';
|
||||
}
|
||||
}
|
||||
PSelectorMatchesCSSBeforeTask.prototype.pseudo = ':before';
|
||||
|
||||
class PSelectorMatchesMediaTask extends PSelectorTask {
|
||||
constructor(task) {
|
||||
|
|
|
@ -1560,6 +1560,13 @@ Parser.prototype.SelectorCompiler = class {
|
|||
}
|
||||
|
||||
compileCSSDeclaration(s) {
|
||||
let pseudo; {
|
||||
const match = /^[a-z-]+,/.exec(s);
|
||||
if ( match !== null ) {
|
||||
pseudo = match[0].slice(0, -1);
|
||||
s = s.slice(match[0].length).trim();
|
||||
}
|
||||
}
|
||||
const pos = s.indexOf(':');
|
||||
if ( pos === -1 ) { return; }
|
||||
const name = s.slice(0, pos).trim();
|
||||
|
@ -1576,7 +1583,7 @@ Parser.prototype.SelectorCompiler = class {
|
|||
regexDetails = '^' + value.replace(this.reEscapeRegex, '\\$&') + '$';
|
||||
this.regexToRawValue.set(regexDetails, value);
|
||||
}
|
||||
return { name: name, value: regexDetails };
|
||||
return { name, pseudo, value: regexDetails };
|
||||
}
|
||||
|
||||
compileInteger(s, min = 0, max = 0x7FFFFFFF) {
|
||||
|
@ -1711,7 +1718,11 @@ Parser.prototype.SelectorCompiler = class {
|
|||
value = `/${task[1].value}/`;
|
||||
}
|
||||
}
|
||||
raw.push(`${task[0]}(${task[1].name}: ${value})`);
|
||||
if ( task[1].pseudo ) {
|
||||
raw.push(`:matches-css(${task[1].pseudo}, ${task[1].name}: ${value})`);
|
||||
} else {
|
||||
raw.push(`:matches-css(${task[1].name}: ${value})`);
|
||||
}
|
||||
break;
|
||||
case ':not':
|
||||
case ':if-not':
|
||||
|
@ -1907,9 +1918,9 @@ Parser.prototype.SelectorCompiler = class {
|
|||
case ':matches-css':
|
||||
return this.compileCSSDeclaration(args);
|
||||
case ':matches-css-after':
|
||||
return this.compileCSSDeclaration(args);
|
||||
return this.compileCSSDeclaration(`after, ${args}`);
|
||||
case ':matches-css-before':
|
||||
return this.compileCSSDeclaration(args);
|
||||
return this.compileCSSDeclaration(`before, ${args}`);
|
||||
case ':matches-media':
|
||||
return this.compileMediaQuery(args);
|
||||
case ':matches-path':
|
||||
|
|
Loading…
Reference in New Issue