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

Unified Diff: test/browser/elemHideEmulation.js

Issue 29383960: Issue 3143 - Filter elements with :-abp-has() (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Patch Set: Updated patch following feedback. Created March 29, 2017, 2 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 | « lib/filterClasses.js ('k') | test/filterClasses.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/browser/elemHideEmulation.js
===================================================================
--- a/test/browser/elemHideEmulation.js
+++ b/test/browser/elemHideEmulation.js
@@ -43,16 +43,21 @@ exports.setUp = function(callback)
callback();
};
exports.tearDown = function(callback)
{
var styleElements = document.head.getElementsByTagName("style");
while (styleElements.length)
styleElements[0].parentNode.removeChild(styleElements[0]);
+ var child;
+ while(child = document.body.firstChild)
+ {
+ document.body.removeChild(child);
+ }
callback();
};
function expectHidden(test, element)
{
test.equal(window.getComputedStyle(element).display, "none",
"The element's display property should be set to 'none'");
}
@@ -80,77 +85,227 @@ function insertStyleRule(rule)
else
{
styleElement = document.createElement("style");
document.head.appendChild(styleElement);
}
styleElement.sheet.insertRule(rule, styleElement.sheet.cssRules.length);
}
-function createElementWithStyle(styleBlock)
+// insert a <div> with a unique id and and empty CSS rule
+// for the the selector matching the id.
+function createElementWithStyle(styleBlock, parent)
{
var element = document.createElement("div");
element.id = findUniqueId();
- document.body.appendChild(element);
+ if (!parent)
+ document.body.appendChild(element);
+ else
+ parent.appendChild(element);
insertStyleRule("#" + element.id + " " + styleBlock);
return element;
}
-function applyElemHideEmulation(selectors, callback)
+// Will ensure the class ElemHideEmulation is loaded
+// and then will call the callback.
+// NOTE: if it never loads, this will probably hang in an infinite
+// loop
+function loadElemHideEmulation(callback)
{
if (typeof ElemHideEmulation == "undefined")
{
loadScript(myUrl + "/../../../lib/common.js", function()
{
loadScript(myUrl + "/../../../chrome/content/elemHideEmulation.js",
function()
{
- applyElemHideEmulation(selectors, callback);
+ loadElemHideEmulation(callback);
});
});
return;
}
- var elemHideEmulation = new ElemHideEmulation(
- window,
- function(callback)
- {
- var patterns = [];
- selectors.forEach(function(selector)
- {
- patterns.push({selector: selector});
- });
- callback(patterns);
- },
- function(selectors)
- {
- if (!selectors.length)
- return;
- var selector = selectors.join(", ");
- insertStyleRule(selector + "{display: none !important;}");
- }
- );
-
- elemHideEmulation.apply();
callback();
}
+// instantiate a ElemHideEmulation with @selectors.
+function applyElemHideEmulation(selectors, callback)
+{
+ loadElemHideEmulation(function()
+ {
+ var elemHideEmulation = new ElemHideEmulation(
+ window,
+ function(callback)
+ {
+ var patterns = [];
+ selectors.forEach(function(selector)
+ {
+ patterns.push({selector: selector});
+ });
+ callback(patterns);
+ },
+ function(selectors)
+ {
+ if (!selectors.length)
+ return;
+ var selector = selectors.join(", ");
+ insertStyleRule(selector + "{display: none !important;}");
+ },
+ function(elements)
+ {
+ if (!elements.length)
+ return;
+ for (var i = 0; i < elements.length; i++)
+ elements[i].style.display = "none";
+ }
+ );
+
+ elemHideEmulation.apply();
+ callback();
+ }.bind(this));
+}
+
+exports.testPseudoHasRule = function(test)
+{
+ loadElemHideEmulation(function()
+ {
+ var selectors = ["div:has(span)"];
+ // testing the regexp
+ var match = pseudoClassHasSelectorRegExp.exec(selectors[0]);
+ test.ok(match);
+ test.equal(match[1], "span");
+
+ selectors = [":has(div.inside)"];
+ match = pseudoClassHasSelectorRegExp.exec(selectors[0]);
+ test.ok(match);
+ test.equal(match[1], "div.inside");
+
+ test.done();
+ });
+};
+
+exports.testExtraFirstSelector = function(test)
+{
+ loadElemHideEmulation(function()
+ {
+ var myselector = "elem.class1.class2";
+ var shortSel = extractFirstSelector(myselector);
+
+ test.equal(shortSel, myselector);
+
+ myselector = "elem > elem2";
+ shortSel = extractFirstSelector(myselector);
+
+ test.equal(shortSel, "elem");
+
+ myselector = "elem+elem2 > elem3";
+ shortSel = extractFirstSelector(myselector);
+
+ test.equal(shortSel, "elem");
+
+ myselector = "elem~elem2 > elem3";
+ shortSel = extractFirstSelector(myselector);
+
+ test.equal(shortSel, "elem");
+
+ test.done();
+ });
+};
+
+exports.testSplitStyleRule = function(test)
+{
+ loadElemHideEmulation(function()
+ {
+ var selectors = splitSelector("div:has(div) > [-abp-properties='background-color: rgb(0, 0, 0)'] > span");
+ test.ok(selectors);
+ test.equal(selectors.length, 1, "There is only one selector");
+
+ selectors = splitSelector("div:has(div), [-abp-properties='background-color: rgb(0, 0, 0)']");
+ test.ok(selectors);
+ test.equal(selectors.length, 2, "There are two selectors");
+
+ test.done();
+ });
+};
+
exports.testVerbatimPropertySelector = function(test)
{
var toHide = createElementWithStyle("{background-color: #000}");
applyElemHideEmulation(
["[-abp-properties='background-color: rgb(0, 0, 0)']"],
function()
{
expectHidden(test, toHide);
test.done();
}
);
};
+exports.testVerbatimPropertySelectorWithPrefix = function(test)
+{
+ var parent = createElementWithStyle("{background-color: #000}");
+ var toHide = createElementWithStyle("{background-color: #000}", parent);
+ applyElemHideEmulation(
+ ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testVerbatimPropertySelectorWithPrefixNoMatch = function(test)
+{
+ var parent = createElementWithStyle("{background-color: #000}");
+ var toHide = createElementWithStyle("{background-color: #fff}", parent);
+ applyElemHideEmulation(
+ ["div > [-abp-properties='background-color: rgb(0, 0, 0)']"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testVerbatimPropertySelectorWithSuffix = function(test)
+{
+ var parent = createElementWithStyle("{background-color: #000}");
+ var toHide = createElementWithStyle("{background-color: #000}", parent);
+ applyElemHideEmulation(
+ ["[-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test)
+{
+ var parent = createElementWithStyle("{background-color: #000}");
+ var middle = createElementWithStyle("{background-color: #000}", parent);
+ var toHide = createElementWithStyle("{background-color: #000}", middle);
+ applyElemHideEmulation(
+ ["div > [-abp-properties='background-color: rgb(0, 0, 0)'] > div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, middle);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
exports.testPropertySelectorWithWildcard = function(test)
{
var toHide = createElementWithStyle("{background-color: #000}");
applyElemHideEmulation(
["[-abp-properties='*color: rgb(0, 0, 0)']"],
function()
{
expectHidden(test, toHide);
@@ -210,8 +365,165 @@ exports.testDynamicallyChangedProperty =
window.setTimeout(function()
{
expectHidden(test, toHide);
test.done();
}, 0);
}
);
};
+
+exports.testPseudoClassHasMatcher = function(test)
+{
+ var parent = createElementWithStyle("{}");
+ var child = createElementWithStyle("{}", parent);
+ loadElemHideEmulation(function()
+ {
+ var matcher = new PseudoHasMatcher("div");
+ test.equal(matcher.match(parent).length, 1, "Parent should contain what is expected");
+ test.equal(matcher.match(child).length, 0, "Child shouldn't match");
+
+ var matcher2 = new PseudoHasMatcher("span");
+ test.equal(matcher2.match(parent), 0, "Doesn't have a <span> child, shouldn't mactch");
+ test.equal(matcher2.match(child), 0, "Child shouldn't match");
+
+ test.done();
+ });
+};
+
+exports.testPseudoClassHasSelector = function(test)
+{
+ var toHide = createElementWithStyle("{}");
+ applyElemHideEmulation(
+ ["div:has(div)"],
+ function()
+ {
+ expectVisible(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testPseudoClassHasSelectorWithPrefix = function(test)
+{
+ var parent = createElementWithStyle("{}");
+ var child = createElementWithStyle("{}", parent);
+ applyElemHideEmulation(
+ ["div:has(div)"],
+ function()
+ {
+ expectHidden(test, parent);
+ expectVisible(test, child);
+ test.done();
+ }
+ );
+};
+
+exports.testPseudoClassHasSelectorWithSuffix = function(test)
+{
+ var parent = createElementWithStyle("{}");
+ var middle = createElementWithStyle("{}", parent);
+ var child = createElementWithStyle("{}", middle);
+ applyElemHideEmulation(
+ ["div:has(div) > div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, middle);
+ expectHidden(test, child);
+ test.done();
+ }
+ );
+};
+
+exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
+{
+ var parent = createElementWithStyle("{}");
+ var middle = createElementWithStyle("{}", parent);
+ var toHide = createElementWithStyle("{}", parent);
+ applyElemHideEmulation(
+ ["div:has(div) + div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, middle);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testPseudoClassHasSelectorWithSuffixSibling = function(test)
+{
+ // <div>
+ // <div></div>
+ // <div>
+ // <div>to hide</div>
+ // </div>
+ // </div>
+ var parent = createElementWithStyle("{}");
+ var middle = createElementWithStyle("{}", parent);
+ var sibling = createElementWithStyle("{}", parent);
+ var toHide = createElementWithStyle("{}", sibling);
+ applyElemHideEmulation(
+ ["div:has(div) + div > div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, middle);
+ expectVisible(test, sibling);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
+exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test)
+{
+ // <div id="parent">
+ // <div id="middle">
+ // <div id="inside" class="inside"></div>
+ // </div>
+ // <div id="sibling">
+ // <div id="tohide">to hide</div>
+ // </div>
+ // </div>
+ var parent = createElementWithStyle("{}");
+ parent.id = "parent";
+ var middle = createElementWithStyle("{}", parent);
+ middle.id = "middle";
+ var inside = createElementWithStyle("{}", middle);
+ inside.id = "inside";
+ inside.className = "inside";
+ var sibling = createElementWithStyle("{}", parent);
+ sibling.id = "sibling";
+ var toHide = createElementWithStyle("{}", sibling);
+ toHide.id = "tohide";
+
+ applyElemHideEmulation(
+ ["div:has(:has(div.inside)) + div > div"],
+ function()
+ {
+ expectVisible(test, parent);
+ expectVisible(test, middle);
+ expectVisible(test, inside);
+ expectVisible(test, sibling);
+ expectHidden(test, toHide);
+ test.done();
+ }
+ );
+};
+
+
+exports.testPseudoClassHasSelectorWithPropSelector = function(test)
+{
+ var parent = createElementWithStyle("{}");
+ var child = createElementWithStyle("{background-color: #000}", parent);
+ applyElemHideEmulation(
+ ["div:has([-abp-properties='background-color: rgb(0, 0, 0)'])"],
+ function()
+ {
+ expectVisible(test, child);
+ expectHidden(test, parent);
+ test.done();
+ }
+ );
+};
« no previous file with comments | « lib/filterClasses.js ('k') | test/filterClasses.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld