Index: chrome/content/elemHideEmulation.js |
=================================================================== |
--- a/chrome/content/elemHideEmulation.js |
+++ b/chrome/content/elemHideEmulation.js |
@@ -250,40 +250,52 @@ |
prefix + "*" : prefix; |
let elements = subtree.querySelectorAll(actualPrefix); |
for (let element of elements) |
if (element.textContent.includes(this._text)) |
yield element; |
} |
}; |
-function PropsSelector(propertyExpression) |
+function PropsSelector(propertyExpression, pseudoElem) |
{ |
let regexpString; |
if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && |
propertyExpression[propertyExpression.length - 1] == "/") |
{ |
regexpString = propertyExpression.slice(1, -1) |
.replace("\\x7B ", "{").replace("\\x7D ", "}"); |
} |
else |
regexpString = filterToRegExp(propertyExpression); |
this._regexp = new RegExp(regexpString, "i"); |
+ this._pseudoElem = pseudoElem || ""; |
} |
PropsSelector.prototype = { |
preferHideWithSelector: true, |
*findPropsSelectors(styles, prefix, regexp) |
{ |
for (let style of styles) |
if (regexp.test(style.style)) |
for (let subSelector of style.subSelectors) |
+ { |
+ if (this._pseudoElem) |
+ { |
+ let idx = subSelector.lastIndexOf(this._pseudoElem); |
+ if (idx != subSelector.length - this._pseudoElem.length) |
+ continue; |
+ if (idx > 0 && subSelector[idx - 1] == ":") |
+ idx--; |
+ subSelector = subSelector.substring(0, idx); |
+ } |
yield prefix + subSelector; |
+ } |
}, |
*getSelectors(prefix, subtree, styles) |
{ |
for (let selector of this.findPropsSelectors(styles, prefix, this._regexp)) |
yield [selector, subtree]; |
} |
}; |
@@ -336,16 +348,20 @@ |
this.window.console.error( |
new SyntaxError("Failed to parse Adblock Plus " + |
`selector ${selector} ` + |
"due to unmatched parentheses.")); |
return null; |
} |
if (match[1] == "properties") |
selectors.push(new PropsSelector(content.text)); |
+ else if (match[1] == "properties-before") |
+ selectors.push(new PropsSelector(content.text, ":before")); |
+ else if (match[1] == "properties-after") |
+ selectors.push(new PropsSelector(content.text, ":after")); |
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") |