1
0
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:
gorhill 2016-12-01 11:55:05 -05:00
parent a6d402aefe
commit 98d2bbada7
2 changed files with 36 additions and 33 deletions

View File

@ -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;

View File

@ -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\([^)]+\)/,