Index: chrome/content/elemHideEmulation.js |
=================================================================== |
--- a/chrome/content/elemHideEmulation.js |
+++ b/chrome/content/elemHideEmulation.js |
@@ -225,16 +225,41 @@ |
// we insert a space between the two. It becomes a no-op if selector |
// doesn't have a combinator |
if (subtree.querySelector(selector)) |
yield element; |
} |
} |
}; |
+function ContainsSelector(textContent) |
+{ |
+ this._text = textContent; |
+} |
+ |
+ContainsSelector.prototype = { |
+ requiresHiding: true, |
+ |
+ *getSelectors(prefix, subtree, stylesheet) |
+ { |
+ for (let element of this.getElements(prefix, subtree, stylesheet)) |
+ yield [makeSelector(element, ""), subtree]; |
+ }, |
+ |
+ *getElements(prefix, subtree, stylesheet) |
+ { |
+ let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ? |
+ prefix + "*" : prefix; |
+ let elements = subtree.querySelectorAll(actualPrefix); |
+ for (let element of elements) |
+ if (element.textContent.includes(this._text)) |
+ yield element; |
+ } |
+}; |
+ |
function PropsSelector(propertyExpression) |
{ |
let regexpString; |
if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && |
propertyExpression[propertyExpression.length - 1] == "/") |
{ |
regexpString = propertyExpression.slice(1, -1) |
.replace("\\x7B ", "{").replace("\\x7D ", "}"); |
@@ -318,32 +343,42 @@ |
selectors.push(new PropsSelector(content.text)); |
else if (match[1] == "has") |
{ |
let hasSelectors = this.parseSelector(content.text); |
if (hasSelectors == null) |
return null; |
selectors.push(new HasSelector(hasSelectors)); |
} |
+ else if (match[1] == "contains") |
+ selectors.push(new ContainsSelector(content.text)); |
else |
{ |
// this is an error, can't parse selector. |
this.window.console.error( |
new SyntaxError("Failed to parse Adblock Plus " + |
`selector ${selector}, invalid ` + |
`pseudo-class :-abp-${match[1]}().`)); |
return null; |
} |
let suffix = this.parseSelector(selector.substr(content.end + 1)); |
if (suffix == null) |
return null; |
selectors.push(...suffix); |
+ if (selectors.length == 1 && selectors[0] instanceof ContainsSelector) |
+ { |
+ this.window.console.error( |
+ new SyntaxError("Failed to parse Adblock Plus " + |
+ `selector ${selector}, can't ` + |
+ "have a lonely :-abp-contains().")); |
+ return null; |
+ } |
return selectors; |
}, |
addSelectors(stylesheets) |
{ |
let selectors = []; |
let selectorFilters = []; |