Index: test/browser/elemHideEmulation.js |
=================================================================== |
--- a/test/browser/elemHideEmulation.js |
+++ b/test/browser/elemHideEmulation.js |
@@ -43,16 +43,21 @@ |
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,75 +85,254 @@ |
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(); |
} |
-exports.testVerbatimPropertySelector = function(test) |
+// 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 selector = "div:has(span)"; |
+ // testing the regexp |
+ var match = pseudoClassHasSelectorRegExp.exec(selector); |
+ test.ok(match); |
+ test.equal(match[1], "span"); |
+ |
+ selector = ":has(div.inside)"; |
+ match = pseudoClassHasSelectorRegExp.exec(selector); |
+ test.ok(match); |
+ test.equal(match[1], "div.inside"); |
+ |
+ selector = "div[-abp-selector=':has(div.inside)']"; |
+ match = abpSelectorRegExp.exec(selector); |
+ test.ok(match); |
+ test.equal(match[2], ":has(div.inside)"); |
+ |
+ selector = "[-abp-selector=':has(div.inside)']"; |
+ match = abpSelectorRegExp.exec(selector); |
+ test.ok(match); |
+ test.equal(match[2], ":has(div.inside)"); |
+ |
+ selector = "div[-abp-selector=':has(:-abp-properties(\"background-color: rgb(0, 0, 0)\"))']"; |
+ match = abpSelectorRegExp.exec(selector); |
+ test.ok(match); |
+ test.equal(match[2], ":has(:-abp-properties(\"background-color: rgb(0, 0, 0)\"))"); |
+ |
+ 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(); |
+ }); |
+}; |
+ |
+function runTestVerbatimPropertySelector(test, selector) |
{ |
var toHide = createElementWithStyle("{background-color: #000}"); |
applyElemHideEmulation( |
- ["[-abp-properties='background-color: rgb(0, 0, 0)']"], |
+ [selector], |
function() |
{ |
expectHidden(test, toHide); |
test.done(); |
} |
); |
+} |
+ |
+exports.testVerbatimPropertySelector = function(test) |
+{ |
+ runTestVerbatimPropertySelector(test, "[-abp-properties='background-color: rgb(0, 0, 0)']"); |
+}; |
+ |
+/* Testing the new syntax */ |
+exports.testVerbatimPropertyPseudoSelector = function(test) |
+{ |
+ runTestVerbatimPropertySelector(test, "[-abp-selector=':-abp-properties(\"background-color: rgb(0, 0, 0)\")']"); |
+}; |
+ |
+function runTestVerbatimPropertySelectorWithPrefix(test, selector) |
+{ |
+ var parent = createElementWithStyle("{background-color: #000}"); |
+ var toHide = createElementWithStyle("{background-color: #000}", parent); |
+ applyElemHideEmulation( |
+ [selector], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+} |
+ |
+exports.testVerbatimPropertySelectorWithPrefix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-properties='background-color: rgb(0, 0, 0)']"); |
+}; |
+ |
+// testing the new syntax |
+exports.testVerbatimPropertyPseudoSelectorWithPrefix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithPrefix(test, "div > [-abp-selector=':-abp-properties(\"background-color: rgb(0, 0, 0)\")']"); |
+}; |
+ |
+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(); |
+ } |
+ ); |
+}; |
+ |
+function runTestVerbatimPropertySelectorWithSuffix(test, selector) |
+{ |
+ var parent = createElementWithStyle("{background-color: #000}"); |
+ var toHide = createElementWithStyle("{background-color: #000}", parent); |
+ applyElemHideEmulation( |
+ [selector], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+} |
+ |
+exports.testVerbatimPropertySelectorWithSuffix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-properties='background-color: rgb(0, 0, 0)'] > div"); |
+}; |
+ |
+exports.testVerbatimPropertyPseudoSelectorWithSuffix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithSuffix(test, "[-abp-selector=':-abp-properties(\"background-color: rgb(0, 0, 0)\")'] > div"); |
+}; |
+ |
+function runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, selector) |
+{ |
+ var parent = createElementWithStyle("{background-color: #000}"); |
+ var middle = createElementWithStyle("{background-color: #000}", parent); |
+ var toHide = createElementWithStyle("{background-color: #000}", middle); |
+ applyElemHideEmulation( |
+ [selector], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, middle); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+} |
+ |
+exports.testVerbatimPropertySelectorWithPrefixAndSuffix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-properties='background-color: rgb(0, 0, 0)'] > div"); |
+}; |
+ |
+exports.testVerbatimPropertyPseudoSelectorWithPrefixAndSuffix = function(test) |
+{ |
+ runTestVerbatimPropertySelectorWithPrefixAndSuffix(test, "div > [-abp-selector=':-abp-properties(\"background-color: rgb(0, 0, 0)\")'] > div"); |
}; |
exports.testPropertySelectorWithWildcard = function(test) |
{ |
var toHide = createElementWithStyle("{background-color: #000}"); |
applyElemHideEmulation( |
["[-abp-properties='*color: rgb(0, 0, 0)']"], |
function() |
@@ -210,8 +394,173 @@ |
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), true, "Parent should contain what is expected"); |
+ test.equal(matcher.match(child), false, "Child shouldn't match"); |
+ |
+ var matcher2 = new PseudoHasMatcher("span"); |
+ test.equal(matcher2.match(parent), false, "Doesn't have a <span> child, shouldn't match"); |
+ test.equal(matcher2.match(child), false, "Child shouldn't match"); |
+ |
+ test.done(); |
+ }); |
+}; |
+ |
+exports.testPseudoClassHasSelector = function(test) |
+{ |
+ var toHide = createElementWithStyle("{}"); |
+ applyElemHideEmulation( |
+ ["div[-abp-selector=':has(div)']"], |
+ function() |
+ { |
+ expectVisible(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+}; |
+ |
+exports.testPseudoClassHasSelectorWithPrefix = function(test) |
+{ |
+ var parent = createElementWithStyle("{}"); |
+ var child = createElementWithStyle("{}", parent); |
+ applyElemHideEmulation( |
+ ["div[-abp-selector=':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[-abp-selector=':has(div)'] > div"], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectHidden(test, middle); |
+ expectHidden(test, child); |
+ test.done(); |
+ } |
+ ); |
+}; |
+ |
+exports.testPseudoClassHasSelectorWithSuffixSibling = function(test) |
+{ |
+ var parent = createElementWithStyle("{}"); |
+ var middle = createElementWithStyle("{}", parent); |
+ var toHide = createElementWithStyle("{}"); |
+ applyElemHideEmulation( |
+ ["div[-abp-selector=':has(div)'] + div"], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, middle); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+}; |
+ |
+exports.testPseudoClassHasSelectorWithSuffixSiblingChild = function(test) |
+{ |
+ // <div> |
+ // <div></div> |
+ // <div> |
+ // <div>to hide</div> |
+ // </div> |
+ // </div> |
+ var parent = createElementWithStyle("{}"); |
+ var middle = createElementWithStyle("{}", parent); |
+ var sibling = createElementWithStyle("{}"); |
+ var toHide = createElementWithStyle("{}", sibling); |
+ applyElemHideEmulation( |
+ ["div[-abp-selector=':has(div)'] + div > div"], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, middle); |
+ expectVisible(test, sibling); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+}; |
+ |
+function runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, selector) |
+{ |
+ document.body.innerHTML = '<div id="parent">' + |
+ '<div id="middle">' + |
+ '<div id="middle.1"><div id="inside" class="inside"></div></div>' + |
+ '</div>' + |
+ '<div id="sibling">' + |
+ '<div id="tohide">to hide</div>' + |
+ '</div>' + |
+ '<div id="sibling2">' + |
+ '<div id="sibling2.1"><div id="sibling2.1.1" class="inside"></div></div>' + |
+ '</div>' + |
+ '</div>'; |
+ var parent = document.getElementById("parent"); |
+ var middle = document.getElementById("middle"); |
+ var inside = document.getElementById("inside"); |
+ var sibling = document.getElementById("sibling"); |
+ var sibling2 = document.getElementById("sibling2"); |
+ var toHide = document.getElementById("tohide"); |
+ |
+ applyElemHideEmulation( |
+ [selector], |
+ function() |
+ { |
+ expectVisible(test, parent); |
+ expectVisible(test, middle); |
+ expectVisible(test, inside); |
+ expectVisible(test, sibling); |
+ expectVisible(test, sibling2); |
+ expectHidden(test, toHide); |
+ test.done(); |
+ } |
+ ); |
+} |
+ |
+exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling = function(test) |
+{ |
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selector=':has(:has(div.inside))'] + div > div"); |
+}; |
+ |
+exports.testPseudoClassHasSelectorWithHasAndWithSuffixSibling2 = function(test) |
+{ |
+ runTestPseudoClassHasSelectorWithHasAndWithSuffixSibling(test, "div[-abp-selector=':has(:has(> div.inside))'] + div > div"); |
+}; |
+ |
+exports.testPseudoClassHasSelectorWithPropSelector = function(test) |
+{ |
+ var parent = createElementWithStyle("{}"); |
+ var child = createElementWithStyle("{background-color: #000}", parent); |
+ applyElemHideEmulation( |
+ ["div[-abp-selector=':has(:-abp-properties(\"background-color: rgb(0, 0, 0)\"))']"], |
+ function() |
+ { |
+ expectVisible(test, child); |
+ expectHidden(test, parent); |
+ test.done(); |
+ } |
+ ); |
+}; |