| Index: lib/content/elemHideEmulation.js | 
| =================================================================== | 
| --- a/lib/content/elemHideEmulation.js | 
| +++ b/lib/content/elemHideEmulation.js | 
| @@ -117,16 +117,62 @@ | 
| } | 
| 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) | 
| + { | 
| + scopeSupported = false; | 
| + } | 
| + return elements; | 
| +} | 
| + | 
| +/** | 
| + * Query selector. If it is relative, will try :scoped. | 
| + * @param {Node} subtree the element to query selector | 
| + * @param {string} selector the selector to query | 
| + * @param {bool} all True to perform querySelectorAll() | 
| + * @returns {Node|NodeList} result of the query. null in case of error. | 
| + */ | 
| +function scopedQuerySelector(subtree, selector, all) | 
| +{ | 
| + if (relativeSelectorRegexp.test(selector)) | 
| + { | 
| + selector = ":scope" + selector; | 
| + if (scopeSupported) | 
| 
 
Manish Jethani
2018/01/26 08:41:32
I think since the code in this if block spans mult
 
hub
2018/01/26 14:44:45
Done.
 
 | 
| + 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 +204,17 @@ | 
| */ | 
| *getSelectors(prefix, subtree, styles) | 
| { | 
| yield [prefix + this._selector, subtree]; | 
| } | 
| }; | 
| const incompletePrefixRegexp = /[\s>+~]$/; | 
| -const relativeSelectorRegexp = /^[>+~]/; | 
| +const relativeSelectorRegexp = /^[>]/; | 
| 
 
Manish Jethani
2018/01/26 08:41:32
Since there's only one character in the group, we
 
hub
2018/01/26 14:44:45
Done.
 
 | 
| function HasSelector(selectors) | 
| { | 
| this._innerSelectors = selectors; | 
| } | 
| HasSelector.prototype = { | 
| requiresHiding: true, | 
| @@ -189,40 +235,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 +272,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] == "/" && |