<?xml version="1.0"?> <?xml-stylesheet type="text/css" href="chrome://global/skin"?> <?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> <?xml-stylesheet type="text/css" href="test_bug708874.css"?> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=708874 --> <window title="Mozilla Bug 708874" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="RunTests();"> <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> <script type="application/javascript"> <![CDATA[ /** Test for Bug 708874 - API for locking pseudo-class state of an element **/ var DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); var DOMWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); var defaultColor = "rgb(0, 0, 0)"; var disabledColor = "rgb(40, 0, 0)"; function RunTests() { testLockEnabled(); testLockDisabled(); testVisited(); testMultiple(); testInvalid(); testNotElement(); } function testLockEnabled() { var button = document.getElementById("test-button"); /* starting state is enabled */ button.removeAttribute("disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false, "doesn't have lock at start"); is(window.getComputedStyle(button).color, defaultColor, "color is default color before locking on"); is(button.matches(":disabled"), false, "doesn't match selector at start"); /* lock */ DOMUtils.addPseudoClassLock(button, ":disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), true, "hasPseudoClassLock is true after locking"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style applied after adding lock"); is(button.matches(":disabled"), true, "matches selector after adding lock"); /* change state to disabled */ button.setAttribute("disabled", "disabled"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style still applied after really disabling"); is(button.matches(":disabled"), true, "matches selector after adding lock"); /* remove lock */ DOMUtils.removePseudoClassLock(button, ":disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false, "hasPseudoClassLock is false after removing on lock"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style still applied after removing lock"); is(button.matches(":disabled"), true, "matches selector after removing lock"); /* change state to enabled */ button.removeAttribute("disabled"); is(window.getComputedStyle(button).color, defaultColor, "back to default style after un-disabling"); is(button.matches(":disabled"), false, "doesn't match selector after enabling"); } function testLockDisabled() { var button = document.getElementById("test-button"); /* starting state is disabled */ button.setAttribute("disabled", "disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false, "doesn't have lock at start"); is(window.getComputedStyle(button).color, disabledColor, "color is :disabled color before locking"); is(button.matches(":disabled"), true, "matches selector before locking"); /* lock */ DOMUtils.addPseudoClassLock(button, ":disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), true, "hasPseudoClassLock is true after locking"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style still applied after adding on lock"); is(button.matches(":disabled"), true, "matches selector after locking"); /* change state to enabled */ button.removeAttribute("disabled"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style applied after enabling"); is(button.matches(":disabled"), true, "matches selector after enabling with lock on"); /* remove lock */ DOMUtils.removePseudoClassLock(button, ":disabled"); is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false, "hasPseudoClassLock is false after removing on lock"); is(window.getComputedStyle(button).color, defaultColor, "default style applied after removing lock"); is(button.matches(":disabled"), false, "doesn't match selector after unlocking"); /* change state to disabled */ button.setAttribute("disabled", "disabled"); is(window.getComputedStyle(button).color, disabledColor, ":disabled style applied after disabling after unlocking"); is(button.matches(":disabled"), true, "matches selector again after disabling"); } function testVisited() { var link = document.getElementById("test-link"); var visitedColor = "rgb(20, 0, 0)"; var unvisitedColor = "rgb(30, 0, 0)"; /* lock visited */ DOMUtils.addPseudoClassLock(link, ":visited"); is(DOMUtils.hasPseudoClassLock(link, ":visited"), true, "hasPseudoClassLock is true after adding lock"); var color = DOMWindowUtils.getVisitedDependentComputedStyle(link, null, "color"); is(color, visitedColor, "color is :visited color after locking"); /* lock unvisited */ DOMUtils.addPseudoClassLock(link, ":link"); is(DOMUtils.hasPseudoClassLock(link, ":link"), true, "hasPseudoClassLock is true after adding :link lock"); is(DOMUtils.hasPseudoClassLock(link, ":visited"), false, "hasPseudoClassLock is false for :visited after adding :link lock"); var color = DOMWindowUtils.getVisitedDependentComputedStyle(link, null, "color"); is(color, unvisitedColor, "color is :link color after locking :link"); /* lock visited back on */ DOMUtils.addPseudoClassLock(link, ":visited"); is(DOMUtils.hasPseudoClassLock(link, ":visited"), true, "hasPseudoClassLock is true after adding :visited lock"); is(DOMUtils.hasPseudoClassLock(link, ":link"), false, "hasPseudoClassLock is false for :link after adding :visited lock"); var color = DOMWindowUtils.getVisitedDependentComputedStyle(link, null, "color"); is(color, visitedColor, "color is :visited color after locking back on"); } function testMultiple() { var div = document.getElementById("test-div"); var styles = { ":hover": { property: "color", value: "rgb(10, 0, 0)", defaultValue: "rgb(0, 0, 0)" }, ":active": { property: "font-family", value: "Arial", defaultValue: "serif" }, ":focus": { property: "font-weight", value: "800", defaultValue: "400" } }; for (var pseudo in styles) { DOMUtils.addPseudoClassLock(div, pseudo); } for (var pseudo in styles) { is(DOMUtils.hasPseudoClassLock(div, pseudo), true, "hasPseudoClassLock is true after locking"); var style = styles[pseudo]; is(window.getComputedStyle(div).getPropertyValue(style.property), style.value, "style for pseudo-class is applied after locking"); is(div.matches(pseudo), true, "matches selector after locking"); } DOMUtils.clearPseudoClassLocks(div); for (var pseudo in styles) { is(DOMUtils.hasPseudoClassLock(div, pseudo), false, "hasPseudoClassLock is false after clearing"); is(window.getComputedStyle(div).getPropertyValue(style.property), style.defaultValue, "style is back to default after clearing"); is(div.matches(pseudo), false, "doesn't match selector after unlocking"); } } function testInvalid() { var div = document.getElementById("test-div"); var pseudos = ["not a valid pseudo-class", ":ny-link", ":first-child"]; for (var i = 0; i < pseudos.length; i++) { var pseudo = pseudos[i]; // basically make sure these don't crash the browser. DOMUtils.addPseudoClassLock(div, pseudo); is(DOMUtils.hasPseudoClassLock(div, pseudo), false); DOMUtils.removePseudoClassLock(div, pseudo); } } function testNotElement() { for (var value of [null, undefined, {}]) { SimpleTest.doesThrow(() => DOMUtils.hasPseudoClassLock(value, ":hover"), "hasPseudoClassLock should throw for " + value); SimpleTest.doesThrow(() => DOMUtils.addPseudoClassLock(value, ":hover"), "addPseudoClassLock should throw for " + value); SimpleTest.doesThrow(() => DOMUtils.removePseudoClassLock(value, ":hover"), "removePseudoClassLock should throw for " + value); SimpleTest.doesThrow(() => DOMUtils.clearPseudoClassLocks(value), "clearPseudoClassLocks should throw for " + value); } } ]]> </script> <body xmlns="http://www.w3.org/1999/xhtml"> <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=708874" target="_blank">Mozilla Bug 708874</a> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=708874"> Mozilla Bug 708874 - API for locking pseudo-class state of an element </a> <a id="test-link" href="http://notavisitedwebsite.com"> test link </a> <div id="test-div"> test div </div> <button id="test-button"> test button </button> </body> </window>