| 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 = []; |