mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-07 11:22:38 +01:00
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) {
|
constructor(task) {
|
||||||
super();
|
super();
|
||||||
this.name = task[1].name;
|
this.name = task[1].name;
|
||||||
|
this.pseudo = task[1].pseudo ? `::${task[1].pseudo}` : null;
|
||||||
let arg0 = task[1].value, arg1;
|
let arg0 = task[1].value, arg1;
|
||||||
if ( Array.isArray(arg0) ) {
|
if ( Array.isArray(arg0) ) {
|
||||||
arg1 = arg0[1]; arg0 = arg0[0];
|
arg1 = arg0[1]; arg0 = arg0[0];
|
||||||
@ -94,15 +95,19 @@ class PSelectorMatchesCSSTask extends PSelectorTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PSelectorMatchesCSSTask.prototype.pseudo = null;
|
|
||||||
|
|
||||||
class PSelectorMatchesCSSAfterTask extends PSelectorMatchesCSSTask {
|
class PSelectorMatchesCSSAfterTask extends PSelectorMatchesCSSTask {
|
||||||
|
constructor(task) {
|
||||||
|
super(task);
|
||||||
|
this.pseudo = 'after';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PSelectorMatchesCSSAfterTask.prototype.pseudo = ':after';
|
|
||||||
|
|
||||||
class PSelectorMatchesCSSBeforeTask extends PSelectorMatchesCSSTask {
|
class PSelectorMatchesCSSBeforeTask extends PSelectorMatchesCSSTask {
|
||||||
|
constructor(task) {
|
||||||
|
super(task);
|
||||||
|
this.pseudo = 'before';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PSelectorMatchesCSSBeforeTask.prototype.pseudo = ':before';
|
|
||||||
|
|
||||||
class PSelectorMatchesMediaTask extends PSelectorTask {
|
class PSelectorMatchesMediaTask extends PSelectorTask {
|
||||||
constructor(task) {
|
constructor(task) {
|
||||||
|
@ -1560,6 +1560,13 @@ Parser.prototype.SelectorCompiler = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileCSSDeclaration(s) {
|
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(':');
|
const pos = s.indexOf(':');
|
||||||
if ( pos === -1 ) { return; }
|
if ( pos === -1 ) { return; }
|
||||||
const name = s.slice(0, pos).trim();
|
const name = s.slice(0, pos).trim();
|
||||||
@ -1576,7 +1583,7 @@ Parser.prototype.SelectorCompiler = class {
|
|||||||
regexDetails = '^' + value.replace(this.reEscapeRegex, '\\$&') + '$';
|
regexDetails = '^' + value.replace(this.reEscapeRegex, '\\$&') + '$';
|
||||||
this.regexToRawValue.set(regexDetails, value);
|
this.regexToRawValue.set(regexDetails, value);
|
||||||
}
|
}
|
||||||
return { name: name, value: regexDetails };
|
return { name, pseudo, value: regexDetails };
|
||||||
}
|
}
|
||||||
|
|
||||||
compileInteger(s, min = 0, max = 0x7FFFFFFF) {
|
compileInteger(s, min = 0, max = 0x7FFFFFFF) {
|
||||||
@ -1711,7 +1718,11 @@ Parser.prototype.SelectorCompiler = class {
|
|||||||
value = `/${task[1].value}/`;
|
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;
|
break;
|
||||||
case ':not':
|
case ':not':
|
||||||
case ':if-not':
|
case ':if-not':
|
||||||
@ -1907,9 +1918,9 @@ Parser.prototype.SelectorCompiler = class {
|
|||||||
case ':matches-css':
|
case ':matches-css':
|
||||||
return this.compileCSSDeclaration(args);
|
return this.compileCSSDeclaration(args);
|
||||||
case ':matches-css-after':
|
case ':matches-css-after':
|
||||||
return this.compileCSSDeclaration(args);
|
return this.compileCSSDeclaration(`after, ${args}`);
|
||||||
case ':matches-css-before':
|
case ':matches-css-before':
|
||||||
return this.compileCSSDeclaration(args);
|
return this.compileCSSDeclaration(`before, ${args}`);
|
||||||
case ':matches-media':
|
case ':matches-media':
|
||||||
return this.compileMediaQuery(args);
|
return this.compileMediaQuery(args);
|
||||||
case ':matches-path':
|
case ':matches-path':
|
||||||
|
Loading…
Reference in New Issue
Block a user