mirror of
https://github.com/gorhill/uBlock.git
synced 2024-10-06 09:37:12 +02:00
revise matches-css implementation as per #1930 and https://github.com/uBlockOrigin/uAssets/issues/212
This commit is contained in:
parent
a6d402aefe
commit
98d2bbada7
@ -137,7 +137,7 @@ var jobQueue = [
|
|||||||
{ t: 'css-csel', _0: [] } // to manually hide (not incremental)
|
{ t: 'css-csel', _0: [] } // to manually hide (not incremental)
|
||||||
];
|
];
|
||||||
|
|
||||||
var reParserEx = /:(?:matches-css|has|style|xpath)\(.+?\)$/;
|
var reParserEx = /:(?:has|matches-css|matches-css-before|matches-css-after|style|xpath)\(.+?\)$/;
|
||||||
|
|
||||||
var allExceptions = createSet(),
|
var allExceptions = createSet(),
|
||||||
allSelectors = createSet(),
|
allSelectors = createSet(),
|
||||||
@ -201,48 +201,45 @@ var runHasJob = function(job, fn) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var csspropDictFromString = function(s) {
|
// '/' = ascii 0x2F */
|
||||||
var aa = s.split(/;\s+|;$/),
|
|
||||||
i = aa.length,
|
var parseMatchesCSSJob = function(raw) {
|
||||||
dict = Object.create(null),
|
var prop = raw.trim();
|
||||||
prop, pos;
|
if ( prop === '' ) { return null; }
|
||||||
while ( i-- ) {
|
var pos = prop.indexOf(':'),
|
||||||
prop = aa[i].trim();
|
v = pos !== -1 ? prop.slice(pos + 1).trim() : '',
|
||||||
if ( prop === '' ) { continue; }
|
vlen = v.length;
|
||||||
pos = prop.indexOf(':');
|
if (
|
||||||
if ( pos === -1 ) { continue; }
|
vlen > 1 &&
|
||||||
dict[prop.slice(0, pos).trim()] = prop.slice(pos + 1).trim();
|
v.charCodeAt(0) === 0x2F &&
|
||||||
|
v.charCodeAt(vlen-1) === 0x2F
|
||||||
|
) {
|
||||||
|
try { v = new RegExp(v.slice(1, -1)); } catch(ex) { return null; }
|
||||||
}
|
}
|
||||||
return dict;
|
return { k: prop.slice(0, pos).trim(), v: v };
|
||||||
};
|
};
|
||||||
|
|
||||||
var runMatchesCSSJob = function(job, fn) {
|
var runMatchesCSSJob = function(job, fn) {
|
||||||
if ( job._2 === undefined ) {
|
|
||||||
if ( job._0.indexOf(':after', job._0.length - 6) !== -1 ) {
|
|
||||||
job._0 = job._0.slice(0, -6);
|
|
||||||
job._2 = ':after';
|
|
||||||
} else {
|
|
||||||
job._2 = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var nodes = document.querySelectorAll(job._0),
|
var nodes = document.querySelectorAll(job._0),
|
||||||
i = nodes.length;
|
i = nodes.length;
|
||||||
if ( i === 0 ) { return; }
|
if ( i === 0 ) { return; }
|
||||||
if ( typeof job._1 === 'string' ) {
|
if ( typeof job._1 === 'string' ) {
|
||||||
job._1 = csspropDictFromString(job._1);
|
job._1 = parseMatchesCSSJob(job._1);
|
||||||
}
|
}
|
||||||
var node, match, style;
|
if ( job._1 === null ) { return; }
|
||||||
|
var k = job._1.k,
|
||||||
|
v = job._1.v,
|
||||||
|
node, style, match;
|
||||||
while ( i-- ) {
|
while ( i-- ) {
|
||||||
node = nodes[i];
|
node = nodes[i];
|
||||||
style = window.getComputedStyle(node, job._2);
|
style = window.getComputedStyle(node, job._2);
|
||||||
match = undefined;
|
if ( style === null ) { continue; } /* FF */
|
||||||
for ( var prop in job._1 ) {
|
if ( v instanceof RegExp ) {
|
||||||
match = style[prop] === job._1[prop];
|
match = v.test(style[k]);
|
||||||
if ( match === false ) {
|
} else {
|
||||||
break;
|
match = style[k] === v;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if ( match === true ) {
|
if ( match ) {
|
||||||
fn(node, job);
|
fn(node, job);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -332,7 +329,13 @@ var domFilterer = {
|
|||||||
if ( sel1.lastIndexOf(':has', 0) === 0 ) {
|
if ( sel1.lastIndexOf(':has', 0) === 0 ) {
|
||||||
this.jobQueue.push({ t: 'has-hide', raw: s, _0: sel0, _1: sel1.slice(5, -1) });
|
this.jobQueue.push({ t: 'has-hide', raw: s, _0: sel0, _1: sel1.slice(5, -1) });
|
||||||
} else if ( sel1.lastIndexOf(':matches-css', 0) === 0 ) {
|
} else if ( sel1.lastIndexOf(':matches-css', 0) === 0 ) {
|
||||||
this.jobQueue.push({ t: 'matches-css-hide', raw: s, _0: sel0, _1: sel1.slice(13, -1) });
|
if ( sel1.lastIndexOf(':matches-css-before', 0) === 0 ) {
|
||||||
|
this.jobQueue.push({ t: 'matches-css-hide', raw: s, _0: sel0, _1: sel1.slice(20, -1), _2: ':before' });
|
||||||
|
} else if ( sel1.lastIndexOf(':matches-css-after', 0) === 0 ) {
|
||||||
|
this.jobQueue.push({ t: 'matches-css-hide', raw: s, _0: sel0, _1: sel1.slice(19, -1), _2: ':after' });
|
||||||
|
} else {
|
||||||
|
this.jobQueue.push({ t: 'matches-css-hide', raw: s, _0: sel0, _1: sel1.slice(13, -1), _2: null });
|
||||||
|
}
|
||||||
} else if ( sel1.lastIndexOf(':style', 0) === 0 ) {
|
} else if ( sel1.lastIndexOf(':style', 0) === 0 ) {
|
||||||
this.job1._0.push(sel0 + ' { ' + sel1.slice(7, -1) + ' }');
|
this.job1._0.push(sel0 + ' { ' + sel1.slice(7, -1) + ' }');
|
||||||
this.job1._1 = undefined;
|
this.job1._1 = undefined;
|
||||||
|
@ -218,7 +218,7 @@ var FilterParser = function() {
|
|||||||
this.hostnames = [];
|
this.hostnames = [];
|
||||||
this.invalid = false;
|
this.invalid = false;
|
||||||
this.cosmetic = true;
|
this.cosmetic = true;
|
||||||
this.reNeedHostname = /^(?:script:contains|script:inject|.+?:has|.+?:matches-css|:xpath)\(.+?\)$/;
|
this.reNeedHostname = /^(?:script:contains|script:inject|.+?:has|.+?:matches-css(?:-before|-after)?|:xpath)\(.+?\)$/;
|
||||||
};
|
};
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -721,7 +721,7 @@ FilterContainer.prototype.isValidSelector = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var reHasSelector = /^(.+?):has\((.+?)\)$/,
|
var reHasSelector = /^(.+?):has\((.+?)\)$/,
|
||||||
reMatchesCSSSelector = /^(.+?):matches-css\((.+?)\)$/,
|
reMatchesCSSSelector = /^(.+?):matches-css(?:-before|-after)?\((.+?)\)$/,
|
||||||
reXpathSelector = /^:xpath\((.+?)\)$/,
|
reXpathSelector = /^:xpath\((.+?)\)$/,
|
||||||
reStyleSelector = /^(.+?):style\((.+?)\)$/,
|
reStyleSelector = /^(.+?):style\((.+?)\)$/,
|
||||||
reStyleBad = /url\([^)]+\)/,
|
reStyleBad = /url\([^)]+\)/,
|
||||||
|
Loading…
Reference in New Issue
Block a user