--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -591,17 +591,16 @@ skip-if = toolkit == 'android'
[test_bug1281963.html]
[test_bug1295852.html]
[test_bug1307730.html]
[test_bug1308069.html]
[test_bug1314032.html]
[test_bug1318303.html]
[test_caretPositionFromPoint.html]
[test_change_policy.html]
-[test_classList.html]
[test_clearTimeoutIntervalNoArg.html]
[test_constructor-assignment.html]
[test_constructor.html]
[test_copyimage.html]
subsuite = clipboard
skip-if = toolkit == 'android' #bug 904183
[test_copypaste.html]
subsuite = clipboard
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -162608,17 +162608,17 @@
"e3daa6a1f0c1d87f0b02909affcf190bd29eadf9",
"testharness"
],
"dom/nodes/Element-children.html": [
"e3fe31ea198922fe64fbf985ae99d1cd4512567a",
"testharness"
],
"dom/nodes/Element-classlist.html": [
- "c6f2331b2479606064cc7d4428912ff275718390",
+ "46a9b0e29b876f32a47675eee1b7c8330dfa5625",
"testharness"
],
"dom/nodes/Element-closest.html": [
"4171fb8b70948ba2617e05b118aaf5d9367e916f",
"testharness"
],
"dom/nodes/Element-firstElementChild-entity-xhtml.xhtml": [
"d8babfc580fb43cfec2a2600be979ae769087c05",
--- a/testing/web-platform/meta/dom/nodes/Element-classlist.html.ini
+++ b/testing/web-platform/meta/dom/nodes/Element-classlist.html.ini
@@ -1,33 +1,377 @@
[Element-classlist.html]
type: testharness
- [classList must be correct for an element that has classes]
+ [classList.length when set to "a a" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (HTML node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (HTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (HTML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (HTML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (HTML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (HTML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (HTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (HTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (XHTML node)]
expected: FAIL
- bug: 869788, https://github.com/whatwg/dom/issues/105
+
+ [classList.item() when set to " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (XHTML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (XHTML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (XHTML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (XHTML node)]
+ expected: FAIL
- [empty classList should return the empty string since the ordered set parser skip the whitespaces]
+ [classList.toggle("b") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XHTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (XHTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (MathML node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (MathML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (MathML node)]
expected: FAIL
- [classList.remove must collapse whitespaces around each token and remove duplicates]
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (MathML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (MathML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (MathML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (MathML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (MathML node)]
expected: FAIL
- bug: 869788, https://github.com/whatwg/dom/issues/105
+
+ [classList.toggle("d") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (MathML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (MathML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (XML node with null namespace)]
+ expected: FAIL
- [classList.add must collapse whitespaces and remove duplicates when adding a token that already exists]
+ [classList.length when set to "a a b b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (XML node with null namespace)]
expected: FAIL
- bug: 869788, https://github.com/whatwg/dom/issues/105
+
+ [classList.add("c") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XML node with null namespace)]
+ expected: FAIL
- [classList.add should treat \\t as a space]
+ [classList.add("a", "a") with attribute value "a b c " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (XML node with null namespace)]
expected: FAIL
- [classList.add should treat \\r as a space]
+ [classList.toggle("a") with attribute value " \\f" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (XML node with null namespace)]
expected: FAIL
- [classList.add should treat \\n as a space]
+ [classList.length when set to "a a" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (foo node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (foo node)]
expected: FAIL
- [classList.add should treat \\f as a space]
+ [classList.add("a") with attribute value " \\f" (foo node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (foo node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (foo node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (foo node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (foo node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (foo node)]
expected: FAIL
- [classList.replace must collapse whitespaces around each token and remove duplicates]
+ [classList.toggle("a") with attribute value " " (foo node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (foo node)]
expected: FAIL
- bug: 869788, https://github.com/whatwg/dom/issues/105
+
+ [classList.toggle("b") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (foo node)]
+ expected: FAIL
+ [classList.replace("b", "c") with attribute value "a b a" (foo node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
--- a/testing/web-platform/mozilla/meta/MANIFEST.json
+++ b/testing/web-platform/mozilla/meta/MANIFEST.json
@@ -345,16 +345,22 @@
],
"wasm/js/unwind.wast.js": [
[
{}
]
]
},
"testharness": {
+ "dom/classList.html": [
+ [
+ "/_mozilla/dom/classList.html",
+ {}
+ ]
+ ],
"fetch/api/redirect/redirect-referrer.https.html": [
[
"/_mozilla/fetch/api/redirect/redirect-referrer.https.html",
{}
]
],
"focus/Range_collapse.html": [
[
@@ -826,16 +832,20 @@
]
}
},
"paths": {
"./placeholder": [
"74e16eb87ecdfeb2dfc28f36e0c73a584abdf9c2",
"support"
],
+ "dom/classList.html": [
+ "37b0684fa9b869ab3a538cceac4fb5a825f3fff9",
+ "testharness"
+ ],
"fetch/api/redirect/redirect-referrer-mixed-content.js": [
"f9d7ec9cf9fa8c847e45664b05482e3f8c191385",
"support"
],
"fetch/api/redirect/redirect-referrer.https.html": [
"99cbd16b78771f35e075e4012d8dbc5dce3209c0",
"testharness"
],
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/mozilla/meta/dom/classList.html.ini
@@ -0,0 +1,452 @@
+[classList.html]
+ type: testharness
+ [classList.length when set to "a a" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (HTML node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (HTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (HTML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (HTML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (HTML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (HTML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (HTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (HTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (HTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (XHTML node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XHTML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (XHTML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (XHTML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (XHTML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XHTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (XHTML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (XHTML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (XUL node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (XUL node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (XUL node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (XUL node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (XUL node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (XUL node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (XUL node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XUL node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (XUL node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (XUL node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (XUL node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XUL node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (XUL node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (XUL node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (MathML node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (MathML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (MathML node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (MathML node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (MathML node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (MathML node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (MathML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (MathML node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (MathML node)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (XML node with null namespace)]
+ expected: FAIL
+
+ [classList.length when set to "a a" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a a a a a a" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a a b b" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to "a b c c b a a b c c" (foo node)]
+ expected: FAIL
+
+ [classList.length when set to " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.item() when set to "aa AA aa" (foo node)]
+ expected: FAIL
+
+ [classList.item() when set to " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value "a a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " " (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " \\f" (foo node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("a") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.add("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (foo node)]
+ expected: FAIL
+
+ [classList.add("a", "a") with attribute value "a b c " (foo node)]
+ expected: FAIL
+
+ [classList.add() with attribute value "a b c a " (foo node)]
+ expected: FAIL
+
+ [classList.remove("AA") with attribute value "AA BB aa CC AA dd aa" (foo node)]
+ expected: FAIL
+
+ [classList.remove() with attribute value "a a" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " " (foo node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " \\f" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("d") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("a") with attribute value " A A A " (foo node)]
+ expected: FAIL
+
+ [classList.toggle("b") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
+ [classList.toggle("c") with attribute value "\\t\\n\\f\\r a\\t\\n\\f\\r b\\t\\n\\f\\r " (foo node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value "a b a" (foo node)]
+ expected: FAIL
+
+ [classList.replace("b", "c") with attribute value " a a b" (foo node)]
+ expected: FAIL
+
rename from dom/base/test/test_classList.html
rename to testing/web-platform/mozilla/tests/dom/classList.html
--- a/dom/base/test/test_classList.html
+++ b/testing/web-platform/mozilla/tests/dom/classList.html
@@ -1,315 +1,340 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=501257
--->
-<head>
- <title>Test for the classList element attribute</title>
- <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
- <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="http://www.whatwg.org/specs/web-apps/current-work/#dom-classlist">classList DOM attribute</a>
-<p id="display"></p>
-<div id="content" style="display: none">
-</div>
-<pre id="test">
-<script type="application/javascript">
+<!doctype html>
+<meta charset=utf-8>
+<title>Test for the classList element attribute</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="content"></div>
+<script>
+// This should be the same as dom/nodes/Element-classlist.html in the upstream
+// tests! We have a couple of bits changed, which are marked with comments
+// "LOCAL MODIFICATION". Do not change this without changing the upstream test
+// as well! Merging upstream changes here occasionally might also be nice.
-/** Test for Bug 501257 **/
-
+// BEGIN LOCAL MODIFICATION: XUL
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+// END LOCAL MODIFICATION
const SVG_NS = "http://www.w3.org/2000/svg";
const XHTML_NS = "http://www.w3.org/1999/xhtml"
const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
+// BEGIN LOCAL MODIFICATION: The spec does not have the onAttrModified event
+// and does not want it, but we still support it.
var gMutationEvents = [];
function onAttrModified(event) {
- is(event.attrName, "class", "mutation on unexpected attribute");
+ assert_equals(event.attrName, "class", "mutation on unexpected attribute");
gMutationEvents.push({
attrChange: event.attrChange,
prevValue: event.prevValue,
newValue: event.newValue,
});
}
+// END LOCAL MODIFICATION
-function checkModification(e, funcName, args, expectedRes, before, after, expectedException) {
+function setClass(e, newVal) {
+ if (newVal === null) {
+ e.removeAttribute("class");
+ } else {
+ e.setAttribute("class", newVal);
+ }
+}
+
+function checkModification(e, funcName, args, expectedRes, before, after,
+ expectedException, desc) {
if (!Array.isArray(args)) {
args = [args];
}
- var shouldThrow = typeof(expectedException) === "string";
- if (shouldThrow) {
- // If an exception is thrown, the class attribute shouldn't change.
- after = before;
- }
- if (before === null)
- e.removeAttribute("class");
- else
- e.setAttribute("class", before);
+ test(function() {
+ var shouldThrow = typeof(expectedException) === "string";
+ if (shouldThrow) {
+ // If an exception is thrown, the class attribute shouldn't change.
+ after = before;
+ }
+ setClass(e, before);
- var contextMsg = "(checkModification: funcName=" + funcName + ",args=" +
- JSON.stringify(args) + ",expectedRes=" + expectedRes +
- ",before=" + before + ",after=" + after + ")";
+ // BEGIN LOCAL MODIFICATION
+ gMutationEvents = [];
+ e.addEventListener("DOMAttrModified", onAttrModified);
+ // END LOCAL MODIFICATION
+ if (shouldThrow) {
+ assert_throws(expectedException, function() {
+ var list = e.classList;
+ var res = list[funcName].apply(list, args);
+ });
+ } else {
+ var list = e.classList;
+ var res = list[funcName].apply(list, args);
+ }
+ // BEGIN LOCAL MODIFICATION
+ e.removeEventListener("DOMAttrModified", onAttrModified);
+ // END LOCAL MODIFICATION
+ if (!shouldThrow) {
+ assert_equals(res, expectedRes, "wrong return value");
+ }
- gMutationEvents = [];
- e.addEventListener("DOMAttrModified", onAttrModified);
- try {
- var list = e.classList;
- var res = list[funcName].apply(list, args);
- if (shouldThrow)
- ok(false, "classList modification didn't throw " + contextMsg);
- } catch (e) {
- if (!shouldThrow)
- ok(false, "classList modification threw an exception " + contextMsg);
- is(e.name, expectedException, "wrong exception thrown " + contextMsg);
- }
- e.removeEventListener("DOMAttrModified", onAttrModified);
- if (expectedRes !== null)
- is(res, expectedRes, "wrong return value from " + funcName +
- " " + contextMsg);
+ var expectedAfter = after;
+ // BEGIN LOCAL MODIFICATION: XUL returns an empty string when getting a
+ // nonexistent class attribute.
+ if (e.namespaceURI == XUL_NS && expectedAfter === null)
+ expectedAfter = "";
+ // END LOCAL MODIFICATION
- var expectedAfter = after;
- // XUL returns an empty string when getting a nonexistent class attribute.
- if (e.namespaceURI == XUL_NS && expectedAfter === null)
- expectedAfter = "";
-
- is(e.getAttribute("class"), expectedAfter, "wrong class after modification " +
- contextMsg);
- var expectedMutation = before != after;
- is(gMutationEvents.length, expectedMutation ? 1 : 0,
- "unexpected mutation event count " + contextMsg);
- if (expectedMutation && gMutationEvents.length) {
- is(gMutationEvents[0].attrChange,
- before == null ? MutationEvent.ADDITION : MutationEvent.MODIFICATION,
- "wrong type of attribute change " + contextMsg);
- // If there wasn't any previous attribute, prevValue will return an empty
- // string.
- var expectedPrevValue = before === null ? "" : before;
- is(gMutationEvents[0].prevValue, expectedPrevValue,
- "wrong previous value " + contextMsg);
- is(gMutationEvents[0].newValue, after, "wrong new value " + contextMsg);
- }
+ assert_equals(e.getAttribute("class"), expectedAfter,
+ "wrong class after modification");
+ // BEGIN LOCAL MODIFICATION
+ var expectedMutation = before != after;
+ assert_equals(gMutationEvents.length, expectedMutation ? 1 : 0,
+ "unexpected mutation event count");
+ if (expectedMutation && gMutationEvents.length) {
+ assert_equals(gMutationEvents[0].attrChange,
+ before == null ? MutationEvent.ADDITION
+ : MutationEvent.MODIFICATION,
+ "wrong type of attribute change");
+ // If there wasn't any previous attribute, prevValue will return an empty
+ // string.
+ var expectedPrevValue = before === null ? "" : before;
+ assert_equals(gMutationEvents[0].prevValue, expectedPrevValue,
+ "wrong previous value");
+ assert_equals(gMutationEvents[0].newValue, after, "wrong new value");
+ }
+ // END LOCAL MODIFICATION
+ }, "classList." + funcName + "(" + args.map(format_value).join(", ") +
+ ") with attribute value " + format_value(before) + desc);
}
function assignToClassListStrict(e) {
"use strict";
- try {
- e.classList = "foo";
- ok(true, "assigning to classList didn't throw");
- e.removeAttribute("class");
- } catch (e) {
- ok(false, "assigning to classList threw");
- }
+ e.classList = "foo";
+ e.removeAttribute("class");
}
function assignToClassList(e) {
- try {
- var expect = e.classList;
- e.classList = "foo";
- ok(true, "assigning to classList didn't throw");
- is(e.classList, expect, "classList should be unchanged after assignment");
- e.removeAttribute("class");
- } catch (e) {
- ok(false, "assigning to classList threw");
- }
+ var expect = e.classList;
+ e.classList = "foo";
+ assert_equals(e.classList, expect,
+ "classList should be unchanged after assignment");
+ e.removeAttribute("class");
}
-function testClassList(e) {
+function testClassList(e, desc) {
- // basic tests
+ // assignment
- isnot(e.classList, undefined, "no classList attribute");
- is(typeof(e.classList.contains), "function",
- "no classList.contains function");
- is(typeof(e.classList.add), "function", "no classList.add function");
- is(typeof(e.classList.remove), "function", "no classList.remove function");
- is(typeof(e.classList.toggle), "function", "no classList.toggle function");
+ test(function() {
+ assignToClassListStrict(e);
+ assignToClassList(e);
+ }, "Assigning to classList" + desc);
- assignToClassListStrict(e);
- assignToClassList(e);
+ // supports
+ test(function() {
+ assert_throws(TypeError(), function() {
+ e.classList.supports("a");
+ })
+ }, ".supports() must throw TypeError" + desc);
// length attribute
- is(e.classList.length, 0, "wrong classList.length value");
- e.setAttribute("class", "");
- is(e.classList.length, 0, "wrong classList.length value");
- e.setAttribute("class", " \t \f");
- is(e.classList.length, 0, "wrong classList.length value");
-
- e.setAttribute("class", "a");
- is(e.classList.length, 1, "wrong classList.length value");
- e.setAttribute("class", "a A");
- is(e.classList.length, 2, "wrong classList.length value");
- e.setAttribute("class", "\r\na\t\f");
- is(e.classList.length, 1, "wrong classList.length value");
+ function checkLength(value, length) {
+ test(function() {
+ setClass(e, value);
+ assert_equals(e.classList.length, length);
+ }, "classList.length when " +
+ (value === null ? "removed" : "set to " + format_value(value)) + desc);
+ }
- e.setAttribute("class", "a a");
- is(e.classList.length, 2, "wrong classList.length value");
-
- e.setAttribute("class", "a a a a a a");
- is(e.classList.length, 6, "wrong classList.length value");
-
- e.setAttribute("class", "a a b b");
- is(e.classList.length, 4, "wrong classList.length value");
-
- e.setAttribute("class", "a A B b");
- is(e.classList.length, 4, "wrong classList.length value");
-
- e.setAttribute("class", "a b c c b a a b c c");
- is(e.classList.length, 10, "wrong classList.length value");
+ checkLength(null, 0);
+ checkLength("", 0);
+ checkLength(" \t \f", 0);
+ checkLength("a", 1);
+ checkLength("a A", 2);
+ checkLength("\r\na\t\f", 1);
+ checkLength("a a", 1);
+ checkLength("a a a a a a", 1);
+ checkLength("a a b b", 2);
+ checkLength("a A B b", 4);
+ checkLength("a b c c b a a b c c", 3);
+ checkLength(" a a b", 2);
+ checkLength("a\tb\nc\fd\re f", 6);
// [Stringifies]
- ok(DOMTokenList.prototype.hasOwnProperty("toString"),
- "Should have own toString on DOMTokenList")
+ function checkStringifier(value, expected) {
+ test(function() {
+ setClass(e, value);
+ assert_equals(e.classList.toString(), expected);
+ }, "classList.toString() when " +
+ (value === null ? "removed" : "set to " + format_value(value)) + desc);
+ }
- e.removeAttribute("class");
- is(e.classList.toString(), "", "wrong classList.toString() value");
- is(e.classList + "", "", "wrong classList string conversion value");
-
- e.setAttribute("class", "foo");
- is(e.classList.toString(), "foo", "wrong classList.toString() value");
- is(e.classList + "", "foo", "wrong classList string conversion value");
+ checkStringifier(null, "");
+ checkStringifier("foo", "foo");
+ checkStringifier(" a a b", " a a b");
// item() method
- e.setAttribute("class", "a");
- is(e.classList.item(-1), null, "wrong classList.item() result");
- is(e.classList[-1], undefined, "wrong classList[] result");
- is(e.classList.item(0), "a", "wrong classList.item() result");
- is(e.classList[0], "a", "wrong classList[] result");
- is(e.classList.item(1), null, "wrong classList.item() result");
- is(e.classList[1], undefined, "wrong classList[] result");
+ function checkItems(attributeValue, expectedValues) {
+ function checkItemFunction(index, expected) {
+ assert_equals(e.classList.item(index), expected,
+ "classList.item(" + index + ")");
+ }
+
+ function checkItemArray(index, expected) {
+ assert_equals(e.classList[index], expected, "classList[" + index + "]");
+ }
+
+ test(function() {
+ setClass(e, attributeValue);
+
+ checkItemFunction(-1, null);
+ checkItemArray(-1, undefined);
- e.setAttribute("class", "aa AA aa");
- is(e.classList.item(-1), null, "wrong classList.item() result");
- is(e.classList[-1], undefined, "wrong classList[] result");
- is(e.classList.item(0), "aa", "wrong classList.item() result");
- is(e.classList[0], "aa", "wrong classList[] result");
- is(e.classList.item(1), "AA", "wrong classList.item() result");
- is(e.classList[1], "AA", "wrong classList[] result");
- is(e.classList.item(2), "aa", "wrong classList.item() result");
- is(e.classList[2], "aa", "wrong classList[] result");
- is(e.classList.item(3), null, "wrong classList.item() result");
- is(e.classList[3], undefined, "wrong classList[] result");
- is(e.classList.item(0xffffffff), null, "wrong classList.item() result");
- is(e.classList[0xffffffff], undefined, "wrong classList[] result");
- is(e.classList.item(0xfffffffe), null, "wrong classList.item() result");
- is(e.classList[0xffffffe], undefined, "wrong classList[] result");
+ var i = 0;
+ while (i < expectedValues.length) {
+ checkItemFunction(i, expectedValues[i]);
+ checkItemArray(i, expectedValues[i]);
+ i++;
+ }
+
+ checkItemFunction(i, null);
+ checkItemArray(i, undefined);
- e.setAttribute("class", "a b");
- is(e.classList.item(-1), null, "wrong classList.item() result");
- is(e.classList[-1], undefined, "wrong classList[] result");
- is(e.classList.item(0), "a", "wrong classList.item() result");
- is(e.classList[0], "a", "wrong classList[] result");
- is(e.classList.item(1), "b", "wrong classList.item() result");
- is(e.classList[1], "b", "wrong classList[] result");
- is(e.classList.item(2), null, "wrong classList.item() result");
- is(e.classList[2], undefined, "wrong classList[] result");
+ checkItemFunction(0xffffffff, null);
+ checkItemArray(0xffffffff, undefined);
+
+ checkItemFunction(0xfffffffe, null);
+ checkItemArray(0xfffffffe, undefined);
+ }, "classList.item() when set to " + format_value(attributeValue) + desc);
+ }
+
+ checkItems(null, []);
+ checkItems("a", ["a"]);
+ checkItems("aa AA aa", ["aa", "AA"]);
+ checkItems("a b", ["a", "b"]);
+ checkItems(" a a b", ["a", "b"]);
+ checkItems("\t\n\f\r a\t\n\f\r b\t\n\f\r ", ["a", "b"]);
// contains() method
- e.removeAttribute("class");
- is(e.classList.contains("a"), false, "wrong classList.contains() result");
- try {
- e.classList.contains("");
- ok(true, "classList.contains(empty_string) didn't throw");
- } catch (e) {
- ok(false, "classList.contains(empty_string) threw");
- }
- try {
- e.classList.contains(" ");
- ok(true, "classList.contains(string_with_spaces) didn't throw");
- } catch (e) {
- ok(false, "classList.contains(string_with_spaces) threw");
- }
- try {
- e.classList.contains("aa ");
- ok(true, "classList.contains(string_with_spaces) didn't throw");
- } catch (e) {
- ok(false, "classList.contains(string_with_spaces) threw");
+ function checkContains(attributeValue, args, expectedRes) {
+ if (!Array.isArray(expectedRes)) {
+ expectedRes = Array(args.length).fill(expectedRes);
+ }
+ setClass(e, attributeValue);
+ for (var i = 0; i < args.length; i++) {
+ test(function() {
+ assert_equals(e.classList.contains(args[i]), expectedRes[i],
+ "classList.contains(\"" + args[i] + "\")");
+ }, "classList.contains(" + format_value(args[i]) + ") when set to " +
+ format_value(attributeValue) + desc);
+ }
}
- e.setAttribute("class", "");
- is(e.classList.contains("a"), false, "wrong classList.contains() result");
+ checkContains(null, ["a", "", " "], false);
+ checkContains("", ["a"], false);
- e.setAttribute("class", "a");
- is(e.classList.contains("a"), true, "wrong classList.contains() result");
- is(e.classList.contains("aa"), false, "wrong classList.contains() result");
- is(e.classList.contains("b"), false, "wrong classList.contains() result");
-
- e.setAttribute("class", "aa AA");
- is(e.classList.contains("aa"), true, "wrong classList.contains() result");
- is(e.classList.contains("AA"), true, "wrong classList.contains() result");
- is(e.classList.contains("aA"), false, "wrong classList.contains() result");
+ checkContains("a", ["a"], true);
+ checkContains("a", ["aa", "b", "A", "a.", "a)",, "a'", 'a"', "a$", "a~",
+ "a?", "a\\"], false);
- e.setAttribute("class", "a a a");
- is(e.classList.contains("a"), true, "wrong classList.contains() result");
- is(e.classList.contains("aa"), false, "wrong classList.contains() result");
- is(e.classList.contains("b"), false, "wrong classList.contains() result");
+ // All "ASCII whitespace" per spec, before and after
+ checkContains("a", ["a\t", "\ta", "a\n", "\na", "a\f", "\fa", "a\r", "\ra",
+ "a ", " a"], false);
- e.setAttribute("class", "a b c");
- is(e.classList.contains("a"), true, "wrong classList.contains() result");
- is(e.classList.contains("b"), true, "wrong classList.contains() result");
+ checkContains("aa AA", ["aa", "AA", "aA"], [true, true, false]);
+ checkContains("a a a", ["a", "aa", "b"], [true, false, false]);
+ checkContains("a b c", ["a", "b"], true);
- // Test for bug 530171
- e.setAttribute("class", "null undefined");
- is(e.classList.contains(null), true, "wrong classList.contains() result");
- is(e.classList.contains(undefined), true, "wrong classList.contains() result");
+ checkContains("null undefined", [null, undefined], true);
+ checkContains("\t\n\f\r a\t\n\f\r b\t\n\f\r ", ["a", "b"], true);
// add() method
function checkAdd(before, argument, after, expectedException) {
- checkModification(e, "add", argument, null, before, after, expectedException);
+ checkModification(e, "add", argument, undefined, before, after,
+ expectedException, desc);
+ // Also check force toggle
+ // XXX https://github.com/whatwg/dom/issues/443
+ //if (!Array.isArray(argument)) {
+ // checkModification(e, "toggle", [argument, true], true, before, after,
+ // expectedException);
+ //}
}
checkAdd(null, "", null, "SyntaxError");
checkAdd(null, ["a", ""], null, "SyntaxError");
checkAdd(null, " ", null, "InvalidCharacterError");
+ checkAdd(null, "\ta", null, "InvalidCharacterError");
+ checkAdd(null, "a\t", null, "InvalidCharacterError");
+ checkAdd(null, "\na", null, "InvalidCharacterError");
+ checkAdd(null, "a\n", null, "InvalidCharacterError");
+ checkAdd(null, "\fa", null, "InvalidCharacterError");
+ checkAdd(null, "a\f", null, "InvalidCharacterError");
+ checkAdd(null, "\ra", null, "InvalidCharacterError");
+ checkAdd(null, "a\r", null, "InvalidCharacterError");
+ checkAdd(null, " a", null, "InvalidCharacterError");
+ checkAdd(null, "a ", null, "InvalidCharacterError");
checkAdd(null, ["a", " "], null, "InvalidCharacterError");
checkAdd(null, ["a", "aa "], null, "InvalidCharacterError");
checkAdd("a", "a", "a");
checkAdd("aa", "AA", "aa AA");
checkAdd("a b c", "a", "a b c");
- checkAdd("a a a b", "a", "a a a b");
+ checkAdd("a a a b", "a", "a b");
checkAdd(null, "a", "a");
checkAdd("", "a", "a");
- checkAdd(" ", "a", " a");
- checkAdd(" \f", "a", " \fa");
+ checkAdd(" ", "a", "a");
+ checkAdd(" \f", "a", "a");
checkAdd("a", "b", "a b");
checkAdd("a b c", "d", "a b c d");
checkAdd("a b c ", "d", "a b c d");
+ checkAdd(" a a b", "c", "a b c");
+ checkAdd(" a a b", "a", "a b");
+ checkAdd("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "c", "a b c");
// multiple add
checkAdd("a b c ", ["d", "e"], "a b c d e");
- checkAdd("a b c ", ["a", "a"], "a b c ");
+ checkAdd("a b c ", ["a", "a"], "a b c");
checkAdd("a b c ", ["d", "d"], "a b c d");
- checkAdd("a b c ", [], "a b c ");
+ checkAdd("a b c a ", [], "a b c");
checkAdd(null, ["a", "b"], "a b");
checkAdd("", ["a", "b"], "a b");
- // Test for bug 530171
checkAdd(null, null, "null");
checkAdd(null, undefined, "undefined");
// remove() method
function checkRemove(before, argument, after, expectedException) {
- checkModification(e, "remove", argument, null, before, after, expectedException);
+ checkModification(e, "remove", argument, undefined, before, after,
+ expectedException, desc);
+ // Also check force toggle
+ // XXX https://github.com/whatwg/dom/issues/443
+ //if (!Array.isArray(argument)) {
+ // checkModification(e, "toggle", [argument, false], false, before, after,
+ // expectedException);
+ //}
}
checkRemove(null, "", null, "SyntaxError");
checkRemove(null, " ", null, "InvalidCharacterError");
- checkRemove(null, "aa ", null, "InvalidCharacterError");
+ checkRemove("\ta", "\ta", "\ta", "InvalidCharacterError");
+ checkRemove("a\t", "a\t", "a\t", "InvalidCharacterError");
+ checkRemove("\na", "\na", "\na", "InvalidCharacterError");
+ checkRemove("a\n", "a\n", "a\n", "InvalidCharacterError");
+ checkRemove("\fa", "\fa", "\fa", "InvalidCharacterError");
+ checkRemove("a\f", "a\f", "a\f", "InvalidCharacterError");
+ checkRemove("\ra", "\ra", "\ra", "InvalidCharacterError");
+ checkRemove("a\r", "a\r", "a\r", "InvalidCharacterError");
+ checkRemove(" a", " a", " a", "InvalidCharacterError");
+ checkRemove("a ", "a ", "a ", "InvalidCharacterError");
+ checkRemove("aa ", "aa ", null, "InvalidCharacterError");
checkRemove(null, "a", null);
checkRemove("", "a", "");
checkRemove("a b c", "d", "a b c");
checkRemove("a b c", "A", "a b c");
checkRemove(" a a a ", "a", "");
checkRemove("a b", "a", "b");
checkRemove("a b ", "a", "b");
@@ -322,105 +347,174 @@ function testClassList(e) {
checkRemove(" a b c ", "b", "a c");
checkRemove("a b b b c", "b", "a c");
checkRemove("a b c", "c", "a b");
checkRemove(" a b c ", "c", "a b");
checkRemove("a b c c c", "c", "a b");
checkRemove("a b a c a d a", "a", "b c d");
- checkRemove("AA BB aa CC AA dd aa", "AA", "BB aa CC dd aa");
+ checkRemove("AA BB aa CC AA dd aa", "AA", "BB aa CC dd");
checkRemove("\ra\na\ta\f", "a", "");
+ checkRemove("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", "b");
// multiple remove
checkRemove("a b c ", ["d", "e"], "a b c");
checkRemove("a b c ", ["a", "b"], "c");
checkRemove("a b c ", ["a", "c"], "b");
checkRemove("a b c ", ["a", "a"], "b c");
checkRemove("a b c ", ["d", "d"], "a b c");
checkRemove("a b c ", [], "a b c");
checkRemove(null, ["a", "b"], null);
checkRemove("", ["a", "b"], "");
+ checkRemove("a a", [], "a");
- // Test for bug 530171
checkRemove("null", null, "");
checkRemove("undefined", undefined, "");
// toggle() method
function checkToggle(before, argument, expectedRes, after, expectedException) {
- checkModification(e, "toggle", argument, expectedRes, before, after, expectedException);
+ checkModification(e, "toggle", argument, expectedRes, before, after,
+ expectedException, desc);
}
checkToggle(null, "", null, null, "SyntaxError");
checkToggle(null, "aa ", null, null, "InvalidCharacterError");
checkToggle(null, "a", true, "a");
checkToggle("", "a", true, "a");
- checkToggle(" ", "a", true, " a");
- checkToggle(" \f", "a", true, " \fa");
+ checkToggle(" ", "a", true, "a");
+ checkToggle(" \f", "a", true, "a");
checkToggle("a", "b", true, "a b");
checkToggle("a", "A", true, "a A");
checkToggle("a b c", "d", true, "a b c d");
- checkToggle("a b c", "d", true, "a b c d");
+ checkToggle(" a a b", "d", true, "a b d");
checkToggle("a", "a", false, "");
checkToggle(" a a a ", "a", false, "");
- checkToggle(" A A A ", "a", true, " A A A a");
+ checkToggle(" A A A ", "a", true, "A a");
checkToggle(" a b c ", "b", false, "a c");
checkToggle(" a b c b b", "b", false, "a c");
checkToggle(" a b c ", "c", false, "a b");
checkToggle(" a b c ", "a", false, "b c");
+ checkToggle(" a a b", "b", false, "a");
+ checkToggle("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", false, "b");
+ checkToggle("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "c", true, "a b c");
- // Test for bug 530171
checkToggle("null", null, false, "");
checkToggle("", null, true, "null");
checkToggle("undefined", undefined, false, "");
checkToggle("", undefined, true, "undefined");
// tests for the force argument handling
+ // XXX Remove these if https://github.com/whatwg/dom/issues/443 is fixed
function checkForceToggle(before, argument, force, expectedRes, after, expectedException) {
- checkModification(e, "toggle", [argument, force], expectedRes, before, after, expectedException);
+ checkModification(e, "toggle", [argument, force], expectedRes, before,
+ after, expectedException, desc);
}
checkForceToggle("", "a", true, true, "a");
checkForceToggle("a", "a", true, true, "a");
checkForceToggle("a", "b", true, true, "a b");
checkForceToggle("a b", "b", true, true, "a b");
checkForceToggle("", "a", false, false, "");
checkForceToggle("a", "a", false, false, "");
checkForceToggle("a", "b", false, false, "a");
checkForceToggle("a b", "b", false, false, "a");
+
+
+ // replace() method
+ function checkReplace(before, token, newToken, after, expectedException) {
+ checkModification(e, "replace", [token, newToken], undefined, before,
+ after, expectedException, desc);
+ }
+
+ checkReplace(null, "", "a", null, "SyntaxError");
+ checkReplace(null, "", " ", null, "SyntaxError");
+ checkReplace(null, " ", "a", null, "InvalidCharacterError");
+ checkReplace(null, "\ta", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\t", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\na", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\n", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\fa", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\f", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\ra", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\r", "b", null, "InvalidCharacterError");
+ checkReplace(null, " a", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a ", "b", null, "InvalidCharacterError");
+
+ checkReplace(null, "a", "", null, "SyntaxError");
+ checkReplace(null, " ", "", null, "SyntaxError");
+ checkReplace(null, "a", " ", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\ta", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\t", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\na", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\n", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\fa", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\f", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\ra", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\r", null, "InvalidCharacterError");
+ checkReplace(null, "b", " a", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a ", null, "InvalidCharacterError");
+
+ checkReplace("a", "a", "a", "a");
+ checkReplace("a", "a", "b", "b");
+ checkReplace("a", "A", "b", "a");
+ checkReplace("a b", "b", "A", "a A");
+ checkReplace("a b c", "d", "e", "a b c");
+ // https://github.com/whatwg/dom/issues/443
+ checkReplace("a a a b", "a", "a", "a b");
+ checkReplace("a a a b", "c", "d", "a a a b");
+ checkReplace(null, "a", "b", null);
+ checkReplace("", "a", "b", "");
+ checkReplace(" ", "a", "b", " ");
+ checkReplace(" a \f", "a", "b", "b");
+ checkReplace("a b c", "b", "d", "a d c");
+ // https://github.com/whatwg/dom/issues/442
+ // Implementations agree on the first one here, so I test it, but disagree on
+ // the second, so no test until the spec decides what to say.
+ checkReplace("a b c", "c", "a", "a b");
+ //checkReplace("c b a", "c", "a", ???);
+ checkReplace("a b a", "a", "c", "c b");
+ checkReplace("a b a", "b", "c", "a c");
+ checkReplace(" a a b", "a", "c", "c b");
+ checkReplace(" a a b", "b", "c", "a c");
+ checkReplace("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", "c", "c b");
+ checkReplace("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "b", "c", "a c");
+
+ checkReplace("a null", null, "b", "a b");
+ checkReplace("a b", "a", null, "null b");
+ checkReplace("a undefined", undefined, "b", "a b");
+ checkReplace("a b", "a", undefined, "undefined b");
}
var content = document.getElementById("content");
var htmlNode = document.createElement("div");
content.appendChild(htmlNode);
-testClassList(htmlNode);
+testClassList(htmlNode, " (HTML node)");
var xhtmlNode = document.createElementNS(XHTML_NS, "div");
content.appendChild(xhtmlNode);
-testClassList(xhtmlNode);
+testClassList(xhtmlNode, " (XHTML node)");
+// LOCAL MODIFICATION
var xulNode = document.createElementNS(XUL_NS, "box");
content.appendChild(xulNode);
-testClassList(xulNode);
+testClassList(xulNode, " (XUL node)");
+// END LOCAL MODIFICATION
var mathMLNode = document.createElementNS(MATHML_NS, "math");
content.appendChild(mathMLNode);
-testClassList(mathMLNode);
+testClassList(mathMLNode, " (MathML node)");
var xmlNode = document.createElementNS(null, "foo");
content.appendChild(xmlNode);
-testClassList(xmlNode);
+testClassList(xmlNode, " (XML node with null namespace)");
var fooNode = document.createElementNS("http://example.org/foo", "foo");
content.appendChild(fooNode);
-testClassList(fooNode);
-
+testClassList(fooNode, " (foo node)");
</script>
-</pre>
-</body>
-</html>
--- a/testing/web-platform/tests/dom/nodes/Element-classlist.html
+++ b/testing/web-platform/tests/dom/nodes/Element-classlist.html
@@ -1,407 +1,462 @@
<!doctype html>
-<html>
- <head class="test test">
- <title class=" ">Element.classList in case-sensitive documents</title>
- <link rel="help" href="https://dom.spec.whatwg.org/#concept-class">
- <script type="text/javascript" src="/resources/testharness.js"></script>
- <script type="text/javascript" src="/resources/testharnessreport.js"></script>
- <style type="text/css">
-.foo { font-style: italic; }
- </style>
- <script type="text/javascript">
-var elem = document.getElementsByTagName('title')[0], secondelem = document.getElementsByTagName('head')[0];
-test(function () {
- assert_equals( typeof elem.classList, 'object', 'critical test; ignore any results after this' );
-}, 'Element.classList must exist as an object');
-test(function () {
- assert_equals( typeof document.documentElement.classList, 'object' );
-}, 'Element.classList must exist as an object even if the element has no class attribute');
-test(function () {
- assert_true( !!window.DOMTokenList );
-}, 'DOMTokenList should be exposed for prototyping');
-test(function () {
- DOMTokenList.prototype.customProperty = true;
- assert_true( elem.classList.customProperty );
-}, 'prototyping DOMTokenList should work');
-test(function () {
- assert_true( elem.classList instanceof window.DOMTokenList );
- assert_equals( elem.classList.constructor, window.DOMTokenList );
-}, 'Element.classList must implement DOMTokenList');
-test(function () {
- assert_not_equals( getComputedStyle(elem,null).fontStyle, 'italic', 'critical test; required by the testsuite' );
-}, 'CSS .foo selectors must not match elements without any class');
-test(function () {
- assert_equals( secondelem.classList.length, 1, 'duplicates in initial string should be removed per https://dom.spec.whatwg.org/#concept-class' );
- assert_equals( secondelem.classList.item(0), 'test' );
- assert_true( secondelem.classList.contains('test') );
-}, 'classList must be correct for an element that has classes');
-test(function () {
- assert_equals( elem.classList.length, 0 );
-}, 'classList.length must be 0 for an element that has no classes');
-test(function () {
- assert_false( elem.classList.contains('foo') );
-}, 'classList must not contain an undefined class');
-test(function () {
- assert_equals( elem.classList.item(0), null );
-}, 'classList.item() must return null for out-of-range index');
-test(function () {
- assert_equals( elem.classList.item(-1), null );
-}, 'classList.item() must return null for negative index');
-test(function () {
- /* the normative part of the spec states that:
- "unless tokens is empty, in which case there are no supported property indices"
- ...
- "The term[...] supported property indices [is] used as defined in the WebIDL specification."
- WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
- assert_equals( elem.classList[0], undefined );
-}, 'classList[index] must be undefined for out-of-range index');
-test(function () {
- assert_equals( elem.classList[-1], undefined );
-}, 'classList[index] must be undefined for negative index');
-test(function () {
- assert_equals( elem.className, ' ' );
-}, 'className should contain initial markup whitespace');
-test(function () {
- assert_equals( elem.classList + '', ' ', 'implicit' );
- assert_equals( elem.classList.toString(), ' ', 'explicit' );
-}, 'classList should contain initial markup whitespace');
-test(function () {
- assert_false( elem.classList.contains('') );
-}, '.contains(empty_string) must return false');
-test(function () {
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.add(''); } );
-}, '.add(empty_string) must throw a SYNTAX_ERR');
-test(function () {
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.remove(''); } );
-}, '.remove(empty_string) must throw a SYNTAX_ERR');
-test(function () {
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.toggle(''); } );
-}, '.toggle(empty_string) must throw a SYNTAX_ERR');
-test(function () {
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('', 'foo'); } );
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('foo', ''); } );
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('', 'foo bar'); } );
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('foo bar', ''); } );
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('', ''); } );
-}, '.replace with empty_string must throw a SYNTAX_ERR');
-test(function () {
- assert_false( elem.classList.contains('a b') );
-}, '.contains(string_with_spaces) must return false');
-test(function () {
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.add('a b'); } );
-}, '.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
-test(function () {
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.remove('a b'); } );
-}, '.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
-test(function () {
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.toggle('a b'); } );
-}, '.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
-test(function () {
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.replace('z', 'a b'); } );
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.replace('a b', 'z'); } );
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.replace('a b', 'b c'); } );
-}, '.replace with string_with_spaces must throw a INVALID_CHARACTER_ERR');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'token1 token2 token3'
- foo.classList.replace('token1', 'token3');
- assert_equals( foo.classList.length, 2 );
- assert_false( foo.classList.contains('token1') );
- assert_true( foo.classList.contains('token2') );
- assert_true( foo.classList.contains('token3') );
-}, '.replace with an already existing token')
-elem.className = 'foo';
-test(function () {
- assert_equals( getComputedStyle(elem,null).fontStyle, 'italic', 'critical test; required by the testsuite' );
-}, 'computed style must update when setting .className');
-test(function () {
- assert_true( elem.classList.contains('foo') );
-}, 'classList.contains must update when .className is changed');
-test(function () {
- assert_false( elem.classList.contains('FOO') );
-}, 'classList.contains must be case sensitive');
-test(function () {
- assert_false( elem.classList.contains('foo.') );
- assert_false( elem.classList.contains('foo)') );
- assert_false( elem.classList.contains('foo\'') );
- assert_false( elem.classList.contains('foo$') );
- assert_false( elem.classList.contains('foo~') );
- assert_false( elem.classList.contains('foo?') );
- assert_false( elem.classList.contains('foo\\') );
-}, 'classList.contains must not match when punctuation characters are added');
-test(function () {
- elem.classList.add('FOO');
- assert_equals( getComputedStyle(elem,null).fontStyle, 'italic' );
-}, 'classList.add must not cause the CSS selector to stop matching');
-test(function () {
- assert_true( elem.classList.contains('foo') );
-}, 'classList.add must not remove existing classes');
-test(function () {
- assert_true( elem.classList.contains('FOO') );
-}, 'classList.contains case sensitivity must match a case-specific string');
-test(function () {
- assert_equals( elem.classList.length, 2 );
-}, 'classList.length must correctly reflect the number of tokens');
-test(function () {
- assert_equals( elem.classList.item(0), 'foo' );
-}, 'classList.item(0) must return the first token');
-test(function () {
- assert_equals( elem.classList.item(1), 'FOO' );
-}, 'classList.item must return case-sensitive strings and preserve token order');
-test(function () {
- assert_equals( elem.classList[0], 'foo' );
-}, 'classList[0] must return the first token');
-test(function () {
- assert_equals( elem.classList[1], 'FOO' );
-}, 'classList[index] must return case-sensitive strings and preserve token order');
-test(function () {
- /* the normative part of the spec states that:
- "The object's supported property indices are the numbers in the range zero to the number of tokens in tokens minus one"
- ...
- "The term[...] supported property indices [is] used as defined in the WebIDL specification."
- WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
- assert_equals( elem.classList[2], undefined );
-}, 'classList[index] must still be undefined for out-of-range index when earlier indexes exist');
-test(function () {
- assert_equals( elem.className, 'foo FOO' );
-}, 'className must update correctly when items have been added through classList');
-test(function () {
- assert_equals( elem.classList + '', 'foo FOO', 'implicit' );
- assert_equals( elem.classList.toString(), 'foo FOO', 'explicit' );
-}, 'classList must stringify correctly when items have been added');
-test(function () {
- elem.classList.add('foo');
- assert_equals( elem.classList.length, 2 );
- assert_equals( elem.classList + '', 'foo FOO', 'implicit' );
- assert_equals( elem.classList.toString(), 'foo FOO', 'explicit' );
-}, 'classList.add should not add a token if it already exists');
-test(function () {
- elem.classList.remove('bar');
- assert_equals( elem.classList.length, 2 );
- assert_equals( elem.classList + '', 'foo FOO', 'implicit' );
- assert_equals( elem.classList.toString(), 'foo FOO', 'explicit' );
-}, 'classList.remove removes arguments passed, if they are present.');
-test(function () {
- elem.classList.remove('foo');
- assert_equals( elem.classList.length, 1 );
- assert_equals( elem.classList + '', 'FOO', 'implicit' );
- assert_equals( elem.classList.toString(), 'FOO', 'explicit' );
- assert_false( elem.classList.contains('foo') );
- assert_true( elem.classList.contains('FOO') );
-}, 'classList.remove must remove existing tokens');
-test(function () {
- assert_not_equals( getComputedStyle(elem,null).fontStyle, 'italic' );
-}, 'classList.remove must not break case-sensitive CSS selector matching');
-test(function () {
- secondelem.classList.remove('test');
- assert_equals( secondelem.classList.length, 0 );
- assert_false( secondelem.classList.contains('test') );
-}, 'classList.remove must remove duplicated tokens');
-test(function () {
- secondelem.className = 'token1 token2 token3';
- secondelem.classList.remove('token2');
- assert_equals( secondelem.classList + '', 'token1 token3', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1 token3', 'explicit' );
-}, 'classList.remove must collapse whitespace around removed tokens');
-test(function () {
- secondelem.className = ' token1 token2 ';
- secondelem.classList.remove('token2');
- assert_equals( secondelem.classList + '', 'token1', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1', 'explicit' );
-}, 'classList.remove must collapse whitespaces around each token');
-test(function () {
- secondelem.className = ' token1 token2 token1 ';
- secondelem.classList.remove('token2');
- assert_equals( secondelem.classList + '', 'token1', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1', 'explicit' );
-}, 'classList.remove must collapse whitespaces around each token and remove duplicates');
-test(function () {
- secondelem.className = ' token1 token2 token1 ';
- secondelem.classList.remove('token1');
- assert_equals( secondelem.classList + '', 'token2', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token2', 'explicit' );
-}, 'classList.remove must collapse whitespace when removing duplicate tokens');
-test(function () {
- secondelem.className = ' token1 token1 ';
- secondelem.classList.add('token1');
- assert_equals( secondelem.classList + '', 'token1', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1', 'explicit' );
-}, 'classList.add must collapse whitespaces and remove duplicates when adding a token that already exists');
-test(function () {
- assert_true(elem.classList.toggle('foo'));
- assert_equals( elem.classList.length, 2 );
- assert_true( elem.classList.contains('foo') );
- assert_true( elem.classList.contains('FOO') );
-}, 'classList.toggle must toggle tokens case-sensitively when adding');
-test(function () {
- assert_equals( getComputedStyle(elem,null).fontStyle, 'italic' );
-}, 'classList.toggle must not break case-sensitive CSS selector matching');
-test(function () {
- assert_false(elem.classList.toggle('foo'));
-}, 'classList.toggle must be able to remove tokens');
-test(function () {
- //will return true if the last test incorrectly removed both
- assert_false(elem.classList.toggle('FOO'));
- assert_false( elem.classList.contains('foo') );
- assert_false( elem.classList.contains('FOO') );
-}, 'classList.toggle must be case-sensitive when removing tokens');
-test(function () {
- secondelem.className = 'foo FOO'
- secondelem.classList.replace('bar', 'baz');
- assert_equals( secondelem.classList.length, 2 );
- assert_equals( secondelem.classList + '', 'foo FOO', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'foo FOO', 'explicit' );
-}, 'classList.replace replaces arguments passed, if they are present.');
-test(function () {
- secondelem.classList.replace('foo', 'bar');
- assert_equals( secondelem.classList.length, 2 );
- assert_equals( secondelem.classList + '', 'bar FOO', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'bar FOO', 'explicit' );
- assert_false( secondelem.classList.contains('foo') );
- assert_true( secondelem.classList.contains('bar') );
- assert_true( secondelem.classList.contains('FOO') );
-}, 'classList.replace must replace existing tokens');
-test(function () {
- assert_not_equals( getComputedStyle(secondelem,null).fontStyle, 'italic' );
-}, 'classList.replace must not break case-sensitive CSS selector matching');
-test(function () {
- secondelem.className = 'token1 token2 token1'
- secondelem.classList.replace('token1', 'token3');
- assert_equals( secondelem.classList.length, 2 );
- assert_false( secondelem.classList.contains('token1') );
- assert_true( secondelem.classList.contains('token2') );
- assert_true( secondelem.classList.contains('token3') );
-}, 'classList.replace must replace duplicated tokens');
-test(function () {
- secondelem.className = 'token1 token2 token3';
- secondelem.classList.replace('token2', 'token4');
- assert_equals( secondelem.classList + '', 'token1 token4 token3', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1 token4 token3', 'explicit' );
-}, 'classList.replace must collapse whitespace around replaced tokens');
-test(function () {
- secondelem.className = ' token1 token2 ';
- secondelem.classList.replace('token2', 'token3');
- assert_equals( secondelem.classList.length, 2 );
- assert_equals( secondelem.classList + '', 'token1 token3', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1 token3', 'explicit' );
-}, 'classList.replace must collapse whitespaces around each token');
-test(function () {
- secondelem.className = ' token1 token2 token1 ';
- secondelem.classList.replace('token2', 'token3');
- assert_equals( secondelem.classList + '', 'token1 token3', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token1 token3', 'explicit' );
-}, 'classList.replace must collapse whitespaces around each token and remove duplicates');
-test(function () {
- secondelem.className = ' token1 token2 token1 ';
- secondelem.classList.replace('token1', 'token3');
- assert_equals( secondelem.classList + '', 'token3 token2', 'implicit' );
- assert_equals( secondelem.classList.toString(), 'token3 token2', 'explicit' );
-}, 'classList.replace must collapse whitespace when replacing duplicate tokens');
-test(function () {
- assert_not_equals( getComputedStyle(elem,null).fontStyle, 'italic' );
-}, 'CSS class selectors must stop matching when all classes have been removed');
-test(function () {
- assert_equals( elem.className, '' );
-}, 'className must be empty when all classes have been removed');
-test(function () {
- assert_equals( elem.classList + '', '', 'implicit' );
- assert_equals( elem.classList.toString(), '', 'explicit' );
-}, 'classList must stringify to an empty string when all classes have been removed');
-test(function () {
- assert_equals( elem.classList.item(0), null );
-}, 'classList.item(0) must return null when all classes have been removed');
-test(function () {
- /* the normative part of the spec states that:
- "unless the length is zero, in which case there are no supported property indices"
- ...
- "The term[...] supported property indices [is] used as defined in the WebIDL specification."
- WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
- assert_equals( elem.classList[0], undefined );
-}, 'classList[0] must be undefined when all classes have been removed');
-test(function () {
- var foo = document.createElement('div');
- foo.classList.add();
- assert_true( foo.hasAttribute('class') );
- assert_equals( foo.classList + '', '', 'implicit' );
- assert_equals( foo.classList.toString(), '', 'explicit' );
-}, 'Invoking add or remove should set the class attribute');
-// The ordered set parser must skip ASCII whitespace (U+0009, U+000A, U+000C, U+000D, and U+0020.)
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a ';
- foo.classList.add('b');
- assert_equals(foo.className,'a b');
-}, 'classList.add should treat " " as a space');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a\t';
- foo.classList.add('b');
- assert_equals(foo.className,'a b');
-}, 'classList.add should treat \\t as a space');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a\r';
- foo.classList.add('b');
- assert_equals(foo.className,'a b');
-}, 'classList.add should treat \\r as a space');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a\n';
- foo.classList.add('b');
- assert_equals(foo.className,'a b');
-}, 'classList.add should treat \\n as a space');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a\f';
- foo.classList.add('b');
- assert_equals(foo.className,'a b');
-}, 'classList.add should treat \\f as a space');
-test(function () {
- //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter
- //ES5 makes [[Put]] fail but not throw
- var failed = false;
- secondelem.className = 'token1';
- try {
- secondelem.classList.length = 0;
- } catch(e) {
- failed = e;
+<meta charset=utf-8>
+<title>Test for the classList element attribute</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="content"></div>
+<script>
+const SVG_NS = "http://www.w3.org/2000/svg";
+const XHTML_NS = "http://www.w3.org/1999/xhtml"
+const MATHML_NS = "http://www.w3.org/1998/Math/MathML";
+
+function setClass(e, newVal) {
+ if (newVal === null) {
+ e.removeAttribute("class");
+ } else {
+ e.setAttribute("class", newVal);
+ }
+}
+
+function checkModification(e, funcName, args, expectedRes, before, after,
+ expectedException, desc) {
+ if (!Array.isArray(args)) {
+ args = [args];
+ }
+
+ test(function() {
+ var shouldThrow = typeof(expectedException) === "string";
+ if (shouldThrow) {
+ // If an exception is thrown, the class attribute shouldn't change.
+ after = before;
+ }
+ setClass(e, before);
+
+ if (shouldThrow) {
+ assert_throws(expectedException, function() {
+ var list = e.classList;
+ var res = list[funcName].apply(list, args);
+ });
+ } else {
+ var list = e.classList;
+ var res = list[funcName].apply(list, args);
+ }
+ if (!shouldThrow) {
+ assert_equals(res, expectedRes, "wrong return value");
+ }
+
+ var expectedAfter = after;
+
+ assert_equals(e.getAttribute("class"), expectedAfter,
+ "wrong class after modification");
+ }, "classList." + funcName + "(" + args.map(format_value).join(", ") +
+ ") with attribute value " + format_value(before) + desc);
+}
+
+function assignToClassListStrict(e) {
+ "use strict";
+ e.classList = "foo";
+ e.removeAttribute("class");
+}
+
+function assignToClassList(e) {
+ var expect = e.classList;
+ e.classList = "foo";
+ assert_equals(e.classList, expect,
+ "classList should be unchanged after assignment");
+ e.removeAttribute("class");
+}
+
+function testClassList(e, desc) {
+
+ // assignment
+
+ test(function() {
+ assignToClassListStrict(e);
+ assignToClassList(e);
+ }, "Assigning to classList" + desc);
+
+ // supports
+ test(function() {
+ assert_throws(TypeError(), function() {
+ e.classList.supports("a");
+ })
+ }, ".supports() must throw TypeError" + desc);
+
+ // length attribute
+
+ function checkLength(value, length) {
+ test(function() {
+ setClass(e, value);
+ assert_equals(e.classList.length, length);
+ }, "classList.length when " +
+ (value === null ? "removed" : "set to " + format_value(value)) + desc);
+ }
+
+ checkLength(null, 0);
+ checkLength("", 0);
+ checkLength(" \t \f", 0);
+ checkLength("a", 1);
+ checkLength("a A", 2);
+ checkLength("\r\na\t\f", 1);
+ checkLength("a a", 1);
+ checkLength("a a a a a a", 1);
+ checkLength("a a b b", 2);
+ checkLength("a A B b", 4);
+ checkLength("a b c c b a a b c c", 3);
+ checkLength(" a a b", 2);
+ checkLength("a\tb\nc\fd\re f", 6);
+
+ // [Stringifies]
+
+ function checkStringifier(value, expected) {
+ test(function() {
+ setClass(e, value);
+ assert_equals(e.classList.toString(), expected);
+ }, "classList.toString() when " +
+ (value === null ? "removed" : "set to " + format_value(value)) + desc);
+ }
+
+ checkStringifier(null, "");
+ checkStringifier("foo", "foo");
+ checkStringifier(" a a b", " a a b");
+
+ // item() method
+
+ function checkItems(attributeValue, expectedValues) {
+ function checkItemFunction(index, expected) {
+ assert_equals(e.classList.item(index), expected,
+ "classList.item(" + index + ")");
+ }
+
+ function checkItemArray(index, expected) {
+ assert_equals(e.classList[index], expected, "classList[" + index + "]");
+ }
+
+ test(function() {
+ setClass(e, attributeValue);
+
+ checkItemFunction(-1, null);
+ checkItemArray(-1, undefined);
+
+ var i = 0;
+ while (i < expectedValues.length) {
+ checkItemFunction(i, expectedValues[i]);
+ checkItemArray(i, expectedValues[i]);
+ i++;
+ }
+
+ checkItemFunction(i, null);
+ checkItemArray(i, undefined);
+
+ checkItemFunction(0xffffffff, null);
+ checkItemArray(0xffffffff, undefined);
+
+ checkItemFunction(0xfffffffe, null);
+ checkItemArray(0xfffffffe, undefined);
+ }, "classList.item() when set to " + format_value(attributeValue) + desc);
+ }
+
+ checkItems(null, []);
+ checkItems("a", ["a"]);
+ checkItems("aa AA aa", ["aa", "AA"]);
+ checkItems("a b", ["a", "b"]);
+ checkItems(" a a b", ["a", "b"]);
+ checkItems("\t\n\f\r a\t\n\f\r b\t\n\f\r ", ["a", "b"]);
+
+ // contains() method
+
+ function checkContains(attributeValue, args, expectedRes) {
+ if (!Array.isArray(expectedRes)) {
+ expectedRes = Array(args.length).fill(expectedRes);
+ }
+ setClass(e, attributeValue);
+ for (var i = 0; i < args.length; i++) {
+ test(function() {
+ assert_equals(e.classList.contains(args[i]), expectedRes[i],
+ "classList.contains(\"" + args[i] + "\")");
+ }, "classList.contains(" + format_value(args[i]) + ") when set to " +
+ format_value(attributeValue) + desc);
+ }
+ }
+
+ checkContains(null, ["a", "", " "], false);
+ checkContains("", ["a"], false);
+
+ checkContains("a", ["a"], true);
+ checkContains("a", ["aa", "b", "A", "a.", "a)",, "a'", 'a"', "a$", "a~",
+ "a?", "a\\"], false);
+
+ // All "ASCII whitespace" per spec, before and after
+ checkContains("a", ["a\t", "\ta", "a\n", "\na", "a\f", "\fa", "a\r", "\ra",
+ "a ", " a"], false);
+
+ checkContains("aa AA", ["aa", "AA", "aA"], [true, true, false]);
+ checkContains("a a a", ["a", "aa", "b"], [true, false, false]);
+ checkContains("a b c", ["a", "b"], true);
+
+ checkContains("null undefined", [null, undefined], true);
+ checkContains("\t\n\f\r a\t\n\f\r b\t\n\f\r ", ["a", "b"], true);
+
+ // add() method
+
+ function checkAdd(before, argument, after, expectedException) {
+ checkModification(e, "add", argument, undefined, before, after,
+ expectedException, desc);
+ // Also check force toggle
+ // XXX https://github.com/whatwg/dom/issues/443
+ //if (!Array.isArray(argument)) {
+ // checkModification(e, "toggle", [argument, true], true, before, after,
+ // expectedException);
+ //}
}
- assert_equals(secondelem.classList.length,1);
- assert_false(failed,'an error was thrown');
-}, 'classList.length must be read-only');
-test(function () {
- var realList = secondelem.classList;
- secondelem.classList = 'foo bar';
- assert_equals(secondelem.classList,realList);
- assert_equals(secondelem.classList.length,2);
- assert_equals(secondelem.classList[0],'foo');
- assert_equals(secondelem.classList[1],'bar');
-}, 'classList must have [PutForwards=value]');
-test(function () {
- var foo = document.createElement('div');
- foo.className = 'a';
- foo.classList.replace('token1', 'token2');
+
+ checkAdd(null, "", null, "SyntaxError");
+ checkAdd(null, ["a", ""], null, "SyntaxError");
+ checkAdd(null, " ", null, "InvalidCharacterError");
+ checkAdd(null, "\ta", null, "InvalidCharacterError");
+ checkAdd(null, "a\t", null, "InvalidCharacterError");
+ checkAdd(null, "\na", null, "InvalidCharacterError");
+ checkAdd(null, "a\n", null, "InvalidCharacterError");
+ checkAdd(null, "\fa", null, "InvalidCharacterError");
+ checkAdd(null, "a\f", null, "InvalidCharacterError");
+ checkAdd(null, "\ra", null, "InvalidCharacterError");
+ checkAdd(null, "a\r", null, "InvalidCharacterError");
+ checkAdd(null, " a", null, "InvalidCharacterError");
+ checkAdd(null, "a ", null, "InvalidCharacterError");
+ checkAdd(null, ["a", " "], null, "InvalidCharacterError");
+ checkAdd(null, ["a", "aa "], null, "InvalidCharacterError");
+
+ checkAdd("a", "a", "a");
+ checkAdd("aa", "AA", "aa AA");
+ checkAdd("a b c", "a", "a b c");
+ checkAdd("a a a b", "a", "a b");
+ checkAdd(null, "a", "a");
+ checkAdd("", "a", "a");
+ checkAdd(" ", "a", "a");
+ checkAdd(" \f", "a", "a");
+ checkAdd("a", "b", "a b");
+ checkAdd("a b c", "d", "a b c d");
+ checkAdd("a b c ", "d", "a b c d");
+ checkAdd(" a a b", "c", "a b c");
+ checkAdd(" a a b", "a", "a b");
+ checkAdd("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "c", "a b c");
+
+ // multiple add
+ checkAdd("a b c ", ["d", "e"], "a b c d e");
+ checkAdd("a b c ", ["a", "a"], "a b c");
+ checkAdd("a b c ", ["d", "d"], "a b c d");
+ checkAdd("a b c a ", [], "a b c");
+ checkAdd(null, ["a", "b"], "a b");
+ checkAdd("", ["a", "b"], "a b");
+
+ checkAdd(null, null, "null");
+ checkAdd(null, undefined, "undefined");
+
+ // remove() method
+
+ function checkRemove(before, argument, after, expectedException) {
+ checkModification(e, "remove", argument, undefined, before, after,
+ expectedException, desc);
+ // Also check force toggle
+ // XXX https://github.com/whatwg/dom/issues/443
+ //if (!Array.isArray(argument)) {
+ // checkModification(e, "toggle", [argument, false], false, before, after,
+ // expectedException);
+ //}
+ }
- assert_equals(foo.className, 'a');
+ checkRemove(null, "", null, "SyntaxError");
+ checkRemove(null, " ", null, "InvalidCharacterError");
+ checkRemove("\ta", "\ta", "\ta", "InvalidCharacterError");
+ checkRemove("a\t", "a\t", "a\t", "InvalidCharacterError");
+ checkRemove("\na", "\na", "\na", "InvalidCharacterError");
+ checkRemove("a\n", "a\n", "a\n", "InvalidCharacterError");
+ checkRemove("\fa", "\fa", "\fa", "InvalidCharacterError");
+ checkRemove("a\f", "a\f", "a\f", "InvalidCharacterError");
+ checkRemove("\ra", "\ra", "\ra", "InvalidCharacterError");
+ checkRemove("a\r", "a\r", "a\r", "InvalidCharacterError");
+ checkRemove(" a", " a", " a", "InvalidCharacterError");
+ checkRemove("a ", "a ", "a ", "InvalidCharacterError");
+ checkRemove("aa ", "aa ", null, "InvalidCharacterError");
+
+ checkRemove(null, "a", null);
+ checkRemove("", "a", "");
+ checkRemove("a b c", "d", "a b c");
+ checkRemove("a b c", "A", "a b c");
+ checkRemove(" a a a ", "a", "");
+ checkRemove("a b", "a", "b");
+ checkRemove("a b ", "a", "b");
+ checkRemove("a a b", "a", "b");
+ checkRemove("aa aa bb", "aa", "bb");
+ checkRemove("a a b a a c a a", "a", "b c");
+
+ checkRemove("a b c", "b", "a c");
+ checkRemove("aaa bbb ccc", "bbb", "aaa ccc");
+ checkRemove(" a b c ", "b", "a c");
+ checkRemove("a b b b c", "b", "a c");
+
+ checkRemove("a b c", "c", "a b");
+ checkRemove(" a b c ", "c", "a b");
+ checkRemove("a b c c c", "c", "a b");
+
+ checkRemove("a b a c a d a", "a", "b c d");
+ checkRemove("AA BB aa CC AA dd aa", "AA", "BB aa CC dd");
+
+ checkRemove("\ra\na\ta\f", "a", "");
+ checkRemove("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", "b");
+
+ // multiple remove
+ checkRemove("a b c ", ["d", "e"], "a b c");
+ checkRemove("a b c ", ["a", "b"], "c");
+ checkRemove("a b c ", ["a", "c"], "b");
+ checkRemove("a b c ", ["a", "a"], "b c");
+ checkRemove("a b c ", ["d", "d"], "a b c");
+ checkRemove("a b c ", [], "a b c");
+ checkRemove(null, ["a", "b"], null);
+ checkRemove("", ["a", "b"], "");
+ checkRemove("a a", [], "a");
+
+ checkRemove("null", null, "");
+ checkRemove("undefined", undefined, "");
+
+ // toggle() method
+
+ function checkToggle(before, argument, expectedRes, after, expectedException) {
+ checkModification(e, "toggle", argument, expectedRes, before, after,
+ expectedException, desc);
+ }
+
+ checkToggle(null, "", null, null, "SyntaxError");
+ checkToggle(null, "aa ", null, null, "InvalidCharacterError");
- foo.classList.replace('a', 'b');
- assert_equals(foo.className, 'b');
+ checkToggle(null, "a", true, "a");
+ checkToggle("", "a", true, "a");
+ checkToggle(" ", "a", true, "a");
+ checkToggle(" \f", "a", true, "a");
+ checkToggle("a", "b", true, "a b");
+ checkToggle("a", "A", true, "a A");
+ checkToggle("a b c", "d", true, "a b c d");
+ checkToggle(" a a b", "d", true, "a b d");
+
+ checkToggle("a", "a", false, "");
+ checkToggle(" a a a ", "a", false, "");
+ checkToggle(" A A A ", "a", true, "A a");
+ checkToggle(" a b c ", "b", false, "a c");
+ checkToggle(" a b c b b", "b", false, "a c");
+ checkToggle(" a b c ", "c", false, "a b");
+ checkToggle(" a b c ", "a", false, "b c");
+ checkToggle(" a a b", "b", false, "a");
+ checkToggle("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", false, "b");
+ checkToggle("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "c", true, "a b c");
+
+ checkToggle("null", null, false, "");
+ checkToggle("", null, true, "null");
+ checkToggle("undefined", undefined, false, "");
+ checkToggle("", undefined, true, "undefined");
+
+
+ // tests for the force argument handling
+ // XXX Remove these if https://github.com/whatwg/dom/issues/443 is fixed
- assert_throws('SYNTAX_ERR', function () { foo.classList.replace('t with space', '') });
- assert_throws('INVALID_CHARACTER_ERR', function () { foo.classList.replace('t with space', 'foo') });
- assert_throws('SYNTAX_ERR', function () { foo.classList.replace('', 'foo') });
-}, 'classList.replace should work');
+ function checkForceToggle(before, argument, force, expectedRes, after, expectedException) {
+ checkModification(e, "toggle", [argument, force], expectedRes, before,
+ after, expectedException, desc);
+ }
+
+ checkForceToggle("", "a", true, true, "a");
+ checkForceToggle("a", "a", true, true, "a");
+ checkForceToggle("a", "b", true, true, "a b");
+ checkForceToggle("a b", "b", true, true, "a b");
+ checkForceToggle("", "a", false, false, "");
+ checkForceToggle("a", "a", false, false, "");
+ checkForceToggle("a", "b", false, false, "a");
+ checkForceToggle("a b", "b", false, false, "a");
+
+
+ // replace() method
+ function checkReplace(before, token, newToken, after, expectedException) {
+ checkModification(e, "replace", [token, newToken], undefined, before,
+ after, expectedException, desc);
+ }
+
+ checkReplace(null, "", "a", null, "SyntaxError");
+ checkReplace(null, "", " ", null, "SyntaxError");
+ checkReplace(null, " ", "a", null, "InvalidCharacterError");
+ checkReplace(null, "\ta", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\t", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\na", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\n", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\fa", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\f", "b", null, "InvalidCharacterError");
+ checkReplace(null, "\ra", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a\r", "b", null, "InvalidCharacterError");
+ checkReplace(null, " a", "b", null, "InvalidCharacterError");
+ checkReplace(null, "a ", "b", null, "InvalidCharacterError");
-test(function() {
- var foo = document.createElement('div');
- assert_throws(new TypeError(),
- function() { foo.classList.supports('hello') });
-}, 'classList.supports should throw');
- </script>
- </head>
- <body>
+ checkReplace(null, "a", "", null, "SyntaxError");
+ checkReplace(null, " ", "", null, "SyntaxError");
+ checkReplace(null, "a", " ", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\ta", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\t", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\na", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\n", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\fa", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\f", null, "InvalidCharacterError");
+ checkReplace(null, "b", "\ra", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a\r", null, "InvalidCharacterError");
+ checkReplace(null, "b", " a", null, "InvalidCharacterError");
+ checkReplace(null, "b", "a ", null, "InvalidCharacterError");
- <div id="log"></div>
+ checkReplace("a", "a", "a", "a");
+ checkReplace("a", "a", "b", "b");
+ checkReplace("a", "A", "b", "a");
+ checkReplace("a b", "b", "A", "a A");
+ checkReplace("a b c", "d", "e", "a b c");
+ // https://github.com/whatwg/dom/issues/443
+ checkReplace("a a a b", "a", "a", "a b");
+ checkReplace("a a a b", "c", "d", "a a a b");
+ checkReplace(null, "a", "b", null);
+ checkReplace("", "a", "b", "");
+ checkReplace(" ", "a", "b", " ");
+ checkReplace(" a \f", "a", "b", "b");
+ checkReplace("a b c", "b", "d", "a d c");
+ // https://github.com/whatwg/dom/issues/442
+ // Implementations agree on the first one here, so I test it, but disagree on
+ // the second, so no test until the spec decides what to say.
+ checkReplace("a b c", "c", "a", "a b");
+ //checkReplace("c b a", "c", "a", ???);
+ checkReplace("a b a", "a", "c", "c b");
+ checkReplace("a b a", "b", "c", "a c");
+ checkReplace(" a a b", "a", "c", "c b");
+ checkReplace(" a a b", "b", "c", "a c");
+ checkReplace("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "a", "c", "c b");
+ checkReplace("\t\n\f\r a\t\n\f\r b\t\n\f\r ", "b", "c", "a c");
- </body>
-</html>
+ checkReplace("a null", null, "b", "a b");
+ checkReplace("a b", "a", null, "null b");
+ checkReplace("a undefined", undefined, "b", "a b");
+ checkReplace("a b", "a", undefined, "undefined b");
+}
+
+var content = document.getElementById("content");
+
+var htmlNode = document.createElement("div");
+content.appendChild(htmlNode);
+testClassList(htmlNode, " (HTML node)");
+
+var xhtmlNode = document.createElementNS(XHTML_NS, "div");
+content.appendChild(xhtmlNode);
+testClassList(xhtmlNode, " (XHTML node)");
+
+var mathMLNode = document.createElementNS(MATHML_NS, "math");
+content.appendChild(mathMLNode);
+testClassList(mathMLNode, " (MathML node)");
+
+var xmlNode = document.createElementNS(null, "foo");
+content.appendChild(xmlNode);
+testClassList(xmlNode, " (XML node with null namespace)");
+
+var fooNode = document.createElementNS("http://example.org/foo", "foo");
+content.appendChild(fooNode);
+testClassList(fooNode, " (foo node)");
+</script>