content/base/test/test_classList.html

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 <!DOCTYPE HTML>
     2 <html>
     3 <!--
     4 https://bugzilla.mozilla.org/show_bug.cgi?id=501257
     5 -->
     6 <head>
     7   <title>Test for the classList element attribute</title>
     8   <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
     9   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
    10 </head>
    11 <body>
    12 <a target="_blank" href="http://www.whatwg.org/specs/web-apps/current-work/#dom-classlist">classList DOM attribute</a>
    13 <p id="display"></p>
    14 <div id="content" style="display: none">
    15 </div>
    16 <pre id="test">
    17 <script type="application/javascript">
    19 /** Test for Bug 501257 **/
    21 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    22 const SVG_NS = "http://www.w3.org/2000/svg";
    23 const XHTML_NS = "http://www.w3.org/1999/xhtml"
    24 const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
    26 var gMutationEvents = [];
    28 function onAttrModified(event) {
    29   is(event.attrName, "class", "mutation on unexpected attribute");
    31   gMutationEvents.push({
    32     attrChange: event.attrChange,
    33     prevValue: event.prevValue,
    34     newValue: event.newValue,
    35   });
    36 }
    38 function checkModification(e, funcName, args, expectedRes, before, after, expectedException) {
    39   if (!Array.isArray(args)) {
    40     args = [args];
    41   }
    43   var shouldThrow = typeof(expectedException) === "string";
    44   if (shouldThrow) {
    45     // If an exception is thrown, the class attribute shouldn't change.
    46     after = before;
    47   }
    48   if (before === null)
    49     e.removeAttribute("class");
    50   else
    51     e.setAttribute("class", before);
    53   var contextMsg = "(checkModification: funcName=" + funcName + ",args=" +
    54                    JSON.stringify(args) + ",expectedRes=" + expectedRes +
    55                    ",before=" + before + ",after=" + after + ")";
    57   gMutationEvents = [];
    58   e.addEventListener("DOMAttrModified", onAttrModified, false);
    59   try {
    60     var list = e.classList;
    61     var res = list[funcName].apply(list, args);
    62     if (shouldThrow)
    63       ok(false, "classList modification didn't throw " + contextMsg);
    64   } catch (e) {
    65     if (!shouldThrow)
    66       ok(false, "classList modification threw an exception " + contextMsg);
    67     is(e.name, expectedException, "wrong exception thrown " + contextMsg);
    68   }
    69   e.removeEventListener("DOMAttrModified", onAttrModified, false);
    70   if (expectedRes !== null)
    71     is(res, expectedRes, "wrong return value from " + funcName +
    72        " " + contextMsg);
    74   var expectedAfter = after;
    75   // XUL returns an empty string when getting a nonexistent class attribute.
    76   if (e.namespaceURI == XUL_NS && expectedAfter === null)
    77     expectedAfter = "";
    79   is(e.getAttribute("class"), expectedAfter, "wrong class after modification " +
    80      contextMsg);
    81   var expectedMutation = before != after;
    82   is(gMutationEvents.length, expectedMutation ? 1 : 0,
    83      "unexpected mutation event count " + contextMsg);
    84   if (expectedMutation && gMutationEvents.length) {
    85     is(gMutationEvents[0].attrChange,
    86        before == null ? MutationEvent.ADDITION : MutationEvent.MODIFICATION,
    87        "wrong type of attribute change " + contextMsg);
    88     // If there wasn't any previous attribute, prevValue will return an empty
    89     // string.
    90     var expectedPrevValue = before === null ? "" : before;
    91     is(gMutationEvents[0].prevValue, expectedPrevValue,
    92        "wrong previous value " + contextMsg);
    93     is(gMutationEvents[0].newValue, after, "wrong new value " + contextMsg);
    94   }
    95 }
    97 function assignToClassListStrict(e) {
    98   "use strict";
    99   try {
   100     e.classList = "foo";
   101     ok(false, "assigning to classList didn't throw");
   102   } catch (e) { }
   103 }
   105 function assignToClassList(e) {
   106   try {
   107     var expect = e.classList;
   108     e.classList = "foo";
   109     is(e.classList, expect, "classList should be unchanged after assignment");
   110   } catch (e) {
   111     ok(false, "assigning to classList threw");
   112   }
   113 }
   115 function testClassList(e) {
   117   // basic tests
   119   isnot(e.classList, undefined, "no classList attribute");
   120   is(typeof(e.classList.contains), "function",
   121      "no classList.contains function");
   122   is(typeof(e.classList.add), "function", "no classList.add function");
   123   is(typeof(e.classList.remove), "function", "no classList.remove function");
   124   is(typeof(e.classList.toggle), "function", "no classList.toggle function");
   126   assignToClassListStrict(e);
   127   assignToClassList(e);
   129   // length attribute
   131   is(e.classList.length, 0, "wrong classList.length value");
   132   e.setAttribute("class", "");
   133   is(e.classList.length, 0, "wrong classList.length value");
   134   e.setAttribute("class", "   \t  \f");
   135   is(e.classList.length, 0, "wrong classList.length value");
   137   e.setAttribute("class", "a");
   138   is(e.classList.length, 1, "wrong classList.length value");
   139   e.setAttribute("class", "a A");
   140   is(e.classList.length, 2, "wrong classList.length value");
   141   e.setAttribute("class", "\r\na\t\f");
   142   is(e.classList.length, 1, "wrong classList.length value");
   144   e.setAttribute("class", "a a");
   145   is(e.classList.length, 2, "wrong classList.length value");
   147   e.setAttribute("class", "a a a a a a");
   148   is(e.classList.length, 6, "wrong classList.length value");
   150   e.setAttribute("class", "a a b b");
   151   is(e.classList.length, 4, "wrong classList.length value");
   153   e.setAttribute("class", "a A B b");
   154   is(e.classList.length, 4, "wrong classList.length value");
   156   e.setAttribute("class", "a b c c b a a b c c");
   157   is(e.classList.length, 10, "wrong classList.length value");
   159   // [Stringifies]
   161   ok(DOMTokenList.prototype.hasOwnProperty("toString"),
   162      "Should have own toString on DOMTokenList")
   163   ok(!DOMSettableTokenList.prototype.hasOwnProperty("toString"),
   164      "Should not have own toString on DOMSettableTokenList")
   166   e.removeAttribute("class");
   167   is(e.classList.toString(), "", "wrong classList.toString() value");
   168   is(e.classList + "", "", "wrong classList string conversion value");
   170   e.setAttribute("class", "foo");
   171   is(e.classList.toString(), "foo", "wrong classList.toString() value");
   172   is(e.classList + "", "foo", "wrong classList string conversion value");
   174   // item() method
   176   e.setAttribute("class", "a");
   177   is(e.classList.item(-1), null, "wrong classList.item() result");
   178   is(e.classList[-1], undefined, "wrong classList[] result");
   179   is(e.classList.item(0), "a", "wrong classList.item() result");
   180   is(e.classList[0], "a", "wrong classList[] result");
   181   is(e.classList.item(1), null, "wrong classList.item() result");
   182   is(e.classList[1], undefined, "wrong classList[] result");
   184   e.setAttribute("class", "aa AA aa");
   185   is(e.classList.item(-1), null, "wrong classList.item() result");
   186   is(e.classList[-1], undefined, "wrong classList[] result");
   187   is(e.classList.item(0), "aa", "wrong classList.item() result");
   188   is(e.classList[0], "aa", "wrong classList[] result");
   189   is(e.classList.item(1), "AA", "wrong classList.item() result");
   190   is(e.classList[1], "AA", "wrong classList[] result");
   191   is(e.classList.item(2), "aa", "wrong classList.item() result");
   192   is(e.classList[2], "aa", "wrong classList[] result");
   193   is(e.classList.item(3), null, "wrong classList.item() result");
   194   is(e.classList[3], undefined, "wrong classList[] result");
   195   is(e.classList.item(0xffffffff), null, "wrong classList.item() result");
   196   is(e.classList[0xffffffff], undefined, "wrong classList[] result");
   197   is(e.classList.item(0xfffffffe), null, "wrong classList.item() result");
   198   is(e.classList[0xffffffe], undefined, "wrong classList[] result");
   200   e.setAttribute("class", "a b");
   201   is(e.classList.item(-1), null, "wrong classList.item() result");
   202   is(e.classList[-1], undefined, "wrong classList[] result");
   203   is(e.classList.item(0), "a", "wrong classList.item() result");
   204   is(e.classList[0], "a", "wrong classList[] result");
   205   is(e.classList.item(1), "b", "wrong classList.item() result");
   206   is(e.classList[1], "b", "wrong classList[] result");
   207   is(e.classList.item(2), null, "wrong classList.item() result");
   208   is(e.classList[2], undefined, "wrong classList[] result");
   210   // contains() method
   212   e.removeAttribute("class");
   213   is(e.classList.contains("a"), false, "wrong classList.contains() result");
   214   try {
   215     e.classList.contains("");
   216     ok(false, "classList.contains() didn't throw");
   217   } catch (e) {
   218     is(e.name, "SyntaxError", "wrong exception thrown");
   219     is(e.code, DOMException.SYNTAX_ERR, "wrong exception thrown");
   220   }
   221   try {
   222     e.classList.contains("  ");
   223     ok(false, "classList.contains() didn't throw");
   224   } catch (e) {
   225     is(e.name, "InvalidCharacterError", "wrong exception thrown");
   226     is(e.code, DOMException.INVALID_CHARACTER_ERR, "wrong exception thrown");
   227   }
   228   try {
   229     e.classList.contains("aa ");
   230     ok(false, "classList.contains() didn't throw");
   231   } catch (e) {
   232     is(e.name, "InvalidCharacterError", "wrong exception thrown");
   233     is(e.code, DOMException.INVALID_CHARACTER_ERR, "wrong exception thrown");
   234   }
   236   e.setAttribute("class", "");
   237   is(e.classList.contains("a"), false, "wrong classList.contains() result");
   239   e.setAttribute("class", "a");
   240   is(e.classList.contains("a"), true, "wrong classList.contains() result");
   241   is(e.classList.contains("aa"), false, "wrong classList.contains() result");
   242   is(e.classList.contains("b"), false, "wrong classList.contains() result");
   244   e.setAttribute("class", "aa AA");
   245   is(e.classList.contains("aa"), true, "wrong classList.contains() result");
   246   is(e.classList.contains("AA"), true, "wrong classList.contains() result");
   247   is(e.classList.contains("aA"), false, "wrong classList.contains() result");
   249   e.setAttribute("class", "a a a");
   250   is(e.classList.contains("a"), true, "wrong classList.contains() result");
   251   is(e.classList.contains("aa"), false, "wrong classList.contains() result");
   252   is(e.classList.contains("b"), false, "wrong classList.contains() result");
   254   e.setAttribute("class", "a b c");
   255   is(e.classList.contains("a"), true, "wrong classList.contains() result");
   256   is(e.classList.contains("b"), true, "wrong classList.contains() result");
   258   // Test for bug 530171
   259   e.setAttribute("class", "null undefined");
   260   is(e.classList.contains(null), true, "wrong classList.contains() result");
   261   is(e.classList.contains(undefined), true, "wrong classList.contains() result");
   263   // add() method
   265   function checkAdd(before, argument, after, expectedException) {
   266     checkModification(e, "add", argument, null, before, after, expectedException);
   267   }
   269   checkAdd(null, "", null, "SyntaxError");
   270   checkAdd(null, ["a", ""], null, "SyntaxError");
   271   checkAdd(null, " ", null, "InvalidCharacterError");
   272   checkAdd(null, ["a", " "], null, "InvalidCharacterError");
   273   checkAdd(null, ["a", "aa "], null, "InvalidCharacterError");
   275   checkAdd("a", "a", "a");
   276   checkAdd("aa", "AA", "aa AA");
   277   checkAdd("a b c", "a", "a b c");
   278   checkAdd("a a a  b", "a", "a a a  b");
   279   checkAdd(null, "a", "a");
   280   checkAdd("", "a", "a");
   281   checkAdd(" ", "a", " a");
   282   checkAdd("   \f", "a", "   \fa");
   283   checkAdd("a", "b", "a b");
   284   checkAdd("a b c", "d", "a b c d");
   285   checkAdd("a b c ", "d", "a b c d");
   287   // multiple add
   288   checkAdd("a b c ", ["d", "e"], "a b c d e");
   289   checkAdd("a b c ", ["a", "a"], "a b c ");
   290   checkAdd("a b c ", ["d", "d"], "a b c d");
   291   checkAdd("a b c ", [], "a b c ");
   292   checkAdd(null, ["a", "b"], "a b");
   293   checkAdd("", ["a", "b"], "a b");
   295   // Test for bug 530171
   296   checkAdd(null, null, "null");
   297   checkAdd(null, undefined, "undefined");
   299   // remove() method
   301   function checkRemove(before, argument, after, expectedException) {
   302     checkModification(e, "remove", argument, null, before, after, expectedException);
   303   }
   305   checkRemove(null, "", null, "SyntaxError");
   306   checkRemove(null, " ", null, "InvalidCharacterError");
   307   checkRemove(null, "aa ", null, "InvalidCharacterError");
   309   checkRemove(null, "a", null);
   310   checkRemove("", "a", "");
   311   checkRemove("a b  c", "d", "a b  c");
   312   checkRemove("a b  c", "A", "a b  c");
   313   checkRemove(" a a a ", "a", "");
   314   checkRemove("a  b", "a", "b");
   315   checkRemove("a  b  ", "a", "b  ");
   316   checkRemove("a a b", "a", "b");
   317   checkRemove("aa aa bb", "aa", "bb");
   318   checkRemove("a a b a a c a a", "a", "b c");
   320   checkRemove("a  b  c", "b", "a c");
   321   checkRemove("aaa  bbb  ccc", "bbb", "aaa ccc");
   322   checkRemove(" a  b  c ", "b", " a c ");
   323   checkRemove("a b b b c", "b", "a c");
   325   checkRemove("a  b  c", "c", "a  b");
   326   checkRemove(" a  b  c ", "c", " a  b");
   327   checkRemove("a b c c c", "c", "a b");
   329   checkRemove("a b a c a d a", "a", "b c d");
   330   checkRemove("AA BB aa CC AA dd aa", "AA", "BB aa CC dd aa");
   332   checkRemove("\ra\na\ta\f", "a", "");
   334   // multiple remove
   335   checkRemove("a b c ", ["d", "e"], "a b c ");
   336   checkRemove("a b c ", ["a", "b"], "c ");
   337   checkRemove("a b c ", ["a", "c"], "b");
   338   checkRemove("a b c ", ["a", "a"], "b c ");
   339   checkRemove("a b c ", ["d", "d"], "a b c ");
   340   checkRemove("a b c ", [], "a b c ");
   341   checkRemove(null, ["a", "b"], null);
   342   checkRemove("", ["a", "b"], "");
   344   // Test for bug 530171
   345   checkRemove("null", null, "");
   346   checkRemove("undefined", undefined, "");
   348   // toggle() method
   350   function checkToggle(before, argument, expectedRes, after, expectedException) {
   351     checkModification(e, "toggle", argument, expectedRes, before, after, expectedException);
   352   }
   354   checkToggle(null, "", null, null, "SyntaxError");
   355   checkToggle(null, "aa ", null, null, "InvalidCharacterError");
   357   checkToggle(null, "a", true, "a");
   358   checkToggle("", "a", true, "a");
   359   checkToggle(" ", "a", true, " a");
   360   checkToggle("   \f", "a", true, "   \fa");
   361   checkToggle("a", "b", true, "a b");
   362   checkToggle("a", "A", true, "a A");
   363   checkToggle("a b c", "d", true, "a b c d");
   364   checkToggle("a b c", "d", true, "a b c d");
   366   checkToggle("a", "a", false, "");
   367   checkToggle(" a a a ", "a", false, "");
   368   checkToggle(" A A A ", "a", true, " A A A a");
   369   checkToggle(" a b c ", "b", false, " a c ");
   370   checkToggle(" a b c b b", "b", false, " a c");
   371   checkToggle(" a b  c  ", "c", false, " a b");
   372   checkToggle(" a b c ", "a", false, "b c ");
   374   // Test for bug 530171
   375   checkToggle("null", null, false, "");
   376   checkToggle("", null, true, "null");
   377   checkToggle("undefined", undefined, false, "");
   378   checkToggle("", undefined, true, "undefined");
   381   // tests for the force argument handling
   383   function checkForceToggle(before, argument, force, expectedRes, after, expectedException) {
   384     checkModification(e, "toggle", [argument, force], expectedRes, before, after, expectedException);
   385   }
   387   checkForceToggle("", "a", true, true, "a");
   388   checkForceToggle("a", "a", true, true, "a");
   389   checkForceToggle("a", "b", true, true, "a b");
   390   checkForceToggle("a b", "b", true, true, "a b");
   391   checkForceToggle("", "a", false, false, "");
   392   checkForceToggle("a", "a", false, false, "");
   393   checkForceToggle("a", "b", false, false, "a");
   394   checkForceToggle("a b", "b", false, false, "a");
   395 }
   397 var content = document.getElementById("content");
   399 var htmlNode = document.createElement("div");
   400 content.appendChild(htmlNode);
   401 testClassList(htmlNode);
   403 var xhtmlNode = document.createElementNS(XHTML_NS, "div");
   404 content.appendChild(xhtmlNode);
   405 testClassList(xhtmlNode);
   407 var xulNode = document.createElementNS(XUL_NS, "box");
   408 content.appendChild(xulNode);
   409 testClassList(xulNode);
   411 var mathMLNode = document.createElementNS(MATHML_NS, "math");
   412 content.appendChild(mathMLNode);
   413 testClassList(mathMLNode);
   415 // Nodes not meant to be styled have a null classList property.
   417 var xmlNode = document.createElementNS(null, "foo");
   418 content.appendChild(xmlNode);
   419 is(xmlNode.classList, null, "classList is not null for plain XML nodes");
   421 var fooNode = document.createElementNS("http://example.org/foo", "foo");
   422 content.appendChild(fooNode);
   423 is(fooNode.classList, null, "classList is not null for nodes in " +
   424                             " http://example.org/foo namespace");
   426 </script>
   427 </pre>
   428 </body>
   429 </html>

mercurial