| 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(); |
| + } |
| + ); |
| +}; |