Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/content/elemHideEmulation.js

Issue 29676761: Issue 6296 - Handle relative prefix in :-abp-has() (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: No longer use regexp for relative selector. Created Jan. 30, 2018, 4:03 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/browser/elemHideEmulation.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/content/elemHideEmulation.js
===================================================================
--- a/lib/content/elemHideEmulation.js
+++ b/lib/content/elemHideEmulation.js
@@ -117,16 +117,65 @@
}
styles.sort();
return {
style: styles.join(" "),
subSelectors: splitSelector(rule.selectorText)
};
}
+let scopeSupported = null;
+
+function tryQuerySelector(subtree, selector, all)
+{
+ let elements = null;
+ try
+ {
+ elements = all ? subtree.querySelectorAll(selector) :
+ subtree.querySelector(selector);
+ scopeSupported = true;
+ }
+ catch (e)
+ {
+ // Edge doesn't support ":scope"
+ scopeSupported = false;
+ }
+ return elements;
+}
+
+/**
+ * Query selector. If it is relative, will try :scope.
+ * @param {Node} subtree the element to query selector
+ * @param {string} selector the selector to query
+ * @param {bool} [all=false] true to perform querySelectorAll()
+ * @returns {?(Node|NodeList)} result of the query. null in case of error.
+ */
+function scopedQuerySelector(subtree, selector, all)
+{
+ if (selector[0] == ">")
+ {
+ selector = ":scope" + selector;
+ if (scopeSupported)
+ {
+ return all ? subtree.querySelectorAll(selector) :
+ subtree.querySelector(selector);
+ }
+ if (scopeSupported == null)
+ return tryQuerySelector(subtree, selector, all);
+ return null;
+ }
+ return all ? subtree.querySelectorAll(selector) :
+ subtree.querySelector(selector);
+}
+
+function scopedQuerySelectorAll(subtree, selector)
+{
+ return scopedQuerySelector(subtree, selector, true);
+}
+
function* evaluate(chain, index, prefix, subtree, styles)
{
if (index >= chain.length)
{
yield prefix;
return;
}
for (let [selector, element] of
@@ -158,17 +207,16 @@
*/
*getSelectors(prefix, subtree, styles)
{
yield [prefix + this._selector, subtree];
}
};
const incompletePrefixRegexp = /[\s>+~]$/;
lainverse 2018/01/30 18:07:28 Since that other regexp were replaced with string
Manish Jethani 2018/01/30 20:23:20 If we do this then I think that it should be a sep
-const relativeSelectorRegexp = /^[>+~]/;
function HasSelector(selectors)
{
this._innerSelectors = selectors;
}
HasSelector.prototype = {
requiresHiding: true,
@@ -189,40 +237,31 @@
* @param {string} prefix the prefix for the selector.
* @param {Node} subtree the subtree we work on.
* @param {StringifiedStyle[]} styles the stringified style objects.
*/
*getElements(prefix, subtree, styles)
{
let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?
prefix + "*" : prefix;
- let elements = subtree.querySelectorAll(actualPrefix);
- for (let element of elements)
+ let elements = scopedQuerySelectorAll(subtree, actualPrefix);
+ if (elements)
{
- let iter = evaluate(this._innerSelectors, 0, "", element, styles);
- for (let selector of iter)
+ for (let element of elements)
{
- if (selector == null)
+ let iter = evaluate(this._innerSelectors, 0, "", element, styles);
+ for (let selector of iter)
{
- yield null;
- continue;
- }
- if (relativeSelectorRegexp.test(selector))
- selector = ":scope" + selector;
- try
- {
- if (element.querySelector(selector))
+ if (selector == null)
+ yield null;
+ else if (scopedQuerySelector(element, selector))
yield element;
}
- catch (e)
- {
- // :scope isn't supported on Edge, ignore error caused by it.
- }
+ yield null;
}
- yield null;
}
}
};
function ContainsSelector(textContent)
{
this._text = textContent;
}
@@ -235,24 +274,27 @@
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)
+ let elements = scopedQuerySelectorAll(subtree, actualPrefix);
+ if (elements)
{
- if (element.textContent.includes(this._text))
- yield element;
- else
- yield null;
+ for (let element of elements)
+ {
+ if (element.textContent.includes(this._text))
+ yield element;
+ else
+ yield null;
+ }
}
}
};
function PropsSelector(propertyExpression)
{
let regexpString;
if (propertyExpression.length >= 2 && propertyExpression[0] == "/" &&
« no previous file with comments | « no previous file | test/browser/elemHideEmulation.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld