1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-11-07 03:12:33 +01:00
This commit is contained in:
gorhill 2017-05-20 15:35:19 -04:00
parent 3109d19e3c
commit be9d76f43d
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2

View File

@ -733,11 +733,16 @@ FilterContainer.prototype.freeze = function() {
// implemented (if ever). Unlikely, see: // implemented (if ever). Unlikely, see:
// https://github.com/gorhill/uBlock/issues/1752 // https://github.com/gorhill/uBlock/issues/1752
// https://github.com/gorhill/uBlock/issues/2624
// Convert Adguard's `-ext-has='...'` into uBO's `:has(...)`.
FilterContainer.prototype.compileSelector = (function() { FilterContainer.prototype.compileSelector = (function() {
var reAfterBeforeSelector = /^(.+?)(::?after|::?before)$/, var reAfterBeforeSelector = /^(.+?)(::?after|::?before)$/,
reStyleSelector = /^(.+?):style\((.+?)\)$/, reStyleSelector = /^(.+?):style\((.+?)\)$/,
reStyleBad = /url\([^)]+\)/, reStyleBad = /url\([^)]+\)/,
reScriptSelector = /^script:(contains|inject)\((.+)\)$/, reScriptSelector = /^script:(contains|inject)\((.+)\)$/,
reExtendedSyntax = /\[-(?:abp|ext)-[a-z-]+=(['"])(?:.+?)(?:\1)\]/,
reExtendedSyntaxHas = /\[-ext-has=(['"])(.+?)\1\]/,
div = document.createElement('div'); div = document.createElement('div');
var isValidStyleProperty = function(cssText) { var isValidStyleProperty = function(cssText) {
@ -749,15 +754,36 @@ FilterContainer.prototype.compileSelector = (function() {
}; };
var entryPoint = function(raw) { var entryPoint = function(raw) {
if ( isValidCSSSelector(raw) && raw.indexOf('[-abp-properties=') === -1 ) { if ( isValidCSSSelector(raw) && reExtendedSyntax.test(raw) === false ) {
return raw; return raw;
} }
// We rarely reach this point. // We rarely reach this point -- majority of selectors are plain
var matches, // CSS selectors.
selector = raw,
pseudoclass, // Unsupported ABP's advanced selector syntax.
style; if ( raw.indexOf('[-abp-properties=') !== -1 ) {
return;
}
var matches;
// Supported Adguard's advanced selector syntax: will translate into
// uBO's syntax before further processing.
//
// [-ext-has=...]
// Converted to `:if(...)`, because Adguard accepts procedural
// selectors within its `:has(...)` selector.
if ( (matches = reExtendedSyntaxHas.exec(raw)) !== null ) {
return this.compileSelector(
raw.slice(0, matches.index) +
':if('+ matches[2].replace(/:contains\(/g, ':has-text(') + ')' +
raw.slice(matches.index + matches[0].length)
);
}
var selector = raw,
pseudoclass, style;
// `:style` selector? // `:style` selector?
if ( (matches = reStyleSelector.exec(selector)) !== null ) { if ( (matches = reStyleSelector.exec(selector)) !== null ) {
@ -827,12 +853,18 @@ FilterContainer.prototype.compileProceduralSelector = (function() {
var reOperatorParser = /(:(?:has|has-text|if|if-not|matches-css|matches-css-after|matches-css-before|xpath))\(.+\)$/, var reOperatorParser = /(:(?:has|has-text|if|if-not|matches-css|matches-css-after|matches-css-before|xpath))\(.+\)$/,
reFirstParentheses = /^\(*/, reFirstParentheses = /^\(*/,
reLastParentheses = /\)*$/, reLastParentheses = /\)*$/,
reEscapeRegex = /[.*+?^${}()|[\]\\]/g; reEscapeRegex = /[.*+?^${}()|[\]\\]/g,
reNeedScope = /^\s*[+>~]/;
var lastProceduralSelector = '', var lastProceduralSelector = '',
lastProceduralSelectorCompiled; lastProceduralSelectorCompiled;
var compileCSSSelector = function(s) { var compileCSSSelector = function(s) {
// https://github.com/AdguardTeam/ExtendedCss/issues/31#issuecomment-302391277
// Prepend `:scope ` if needed.
if ( reNeedScope.test(s) ) {
s = ':scope ' + s;
}
if ( isValidCSSSelector(s) ) { if ( isValidCSSSelector(s) ) {
return s; return s;
} }
@ -864,6 +896,11 @@ FilterContainer.prototype.compileProceduralSelector = (function() {
}; };
var compileConditionalSelector = function(s) { var compileConditionalSelector = function(s) {
// https://github.com/AdguardTeam/ExtendedCss/issues/31#issuecomment-302391277
// Prepend `:scope ` if needed.
if ( reNeedScope.test(s) ) {
s = ':scope ' + s;
}
return compile(s); return compile(s);
}; };
@ -1056,7 +1093,7 @@ FilterContainer.prototype.compileGenericHideSelector = function(parsed, out) {
return; return;
} }
// Composite CSS rule. // Composite CSS rule.
if ( this.compileSelector(selector) ) { if ( this.compileSelector(selector) !== undefined ) {
out.push(4, 'lg+\v' + key + '\v' + selector); out.push(4, 'lg+\v' + key + '\v' + selector);
} }
return; return;