| OLD | NEW |
| (Empty) | |
| 1 // Require selectors.js to be included before this. |
| 2 |
| 3 /* |
| 4 * Create and append special elements that cannot be created correctly with HTML
markup alone. |
| 5 */ |
| 6 function setupSpecialElements(doc, parent) { |
| 7 // Setup null and undefined tests |
| 8 parent.appendChild(doc.createElement("null")); |
| 9 parent.appendChild(doc.createElement("undefined")); |
| 10 |
| 11 // Setup namespace tests |
| 12 var anyNS = doc.createElement("div"); |
| 13 var noNS = doc.createElement("div"); |
| 14 anyNS.id = "any-namespace"; |
| 15 noNS.id = "no-namespace"; |
| 16 |
| 17 var divs; |
| 18 div = [doc.createElement("div"), |
| 19 doc.createElementNS("http://www.w3.org/1999/xhtml", "div"), |
| 20 doc.createElementNS("", "div"), |
| 21 doc.createElementNS("http://www.example.org/ns", "div")]; |
| 22 |
| 23 div[0].id = "any-namespace-div1"; |
| 24 div[1].id = "any-namespace-div2"; |
| 25 div[2].setAttribute("id", "any-namespace-div3"); // Non-HTML elements can't us
e .id property |
| 26 div[3].setAttribute("id", "any-namespace-div4"); |
| 27 |
| 28 for (var i = 0; i < div.length; i++) { |
| 29 anyNS.appendChild(div[i]) |
| 30 } |
| 31 |
| 32 div = [doc.createElement("div"), |
| 33 doc.createElementNS("http://www.w3.org/1999/xhtml", "div"), |
| 34 doc.createElementNS("", "div"), |
| 35 doc.createElementNS("http://www.example.org/ns", "div")]; |
| 36 |
| 37 div[0].id = "no-namespace-div1"; |
| 38 div[1].id = "no-namespace-div2"; |
| 39 div[2].setAttribute("id", "no-namespace-div3"); // Non-HTML elements can't use
.id property |
| 40 div[3].setAttribute("id", "no-namespace-div4"); |
| 41 |
| 42 for (i = 0; i < div.length; i++) { |
| 43 noNS.appendChild(div[i]) |
| 44 } |
| 45 |
| 46 parent.appendChild(anyNS); |
| 47 parent.appendChild(noNS); |
| 48 } |
| 49 |
| 50 /* |
| 51 * Check that the querySelector and querySelectorAll methods exist on the given
Node |
| 52 */ |
| 53 function interfaceCheck(type, obj) { |
| 54 test(function() { |
| 55 var q = typeof obj.querySelector === "function"; |
| 56 assert_true(q, type + " supports querySelector."); |
| 57 }, type + " supports querySelector") |
| 58 |
| 59 test(function() { |
| 60 var qa = typeof obj.querySelectorAll === "function"; |
| 61 assert_true( qa, type + " supports querySelectorAll."); |
| 62 }, type + " supports querySelectorAll") |
| 63 |
| 64 test(function() { |
| 65 var list = obj.querySelectorAll("div"); |
| 66 if (obj.ownerDocument) { // The object is not a Document |
| 67 assert_true(list instanceof obj.ownerDocument.defaultView.NodeList, "The r
esult should be an instance of a NodeList") |
| 68 } else { // The object is a Document |
| 69 assert_true(list instanceof obj.defaultView.NodeList, "The result should b
e an instance of a NodeList") |
| 70 } |
| 71 }, type + ".querySelectorAll returns NodeList instance") |
| 72 } |
| 73 |
| 74 /* |
| 75 * Verify that the NodeList returned by querySelectorAll is static and and that
a new list is created after |
| 76 * each call. A static list should not be affected by subsequent changes to the
DOM. |
| 77 */ |
| 78 function verifyStaticList(type, doc, root) { |
| 79 var pre, post, preLength; |
| 80 |
| 81 test(function() { |
| 82 pre = root.querySelectorAll("div"); |
| 83 preLength = pre.length; |
| 84 |
| 85 var div = doc.createElement("div"); |
| 86 (root.body || root).appendChild(div); |
| 87 |
| 88 assert_equals(pre.length, preLength, "The length of the NodeList should not
change.") |
| 89 }, type + ": static NodeList") |
| 90 |
| 91 test(function() { |
| 92 post = root.querySelectorAll("div"), |
| 93 assert_equals(post.length, preLength + 1, "The length of the new NodeList sh
ould be 1 more than the previous list.") |
| 94 }, type + ": new NodeList") |
| 95 } |
| 96 |
| 97 /* |
| 98 * Verify handling of special values for the selector parameter, including strin
gification of |
| 99 * null and undefined, and the handling of the empty string. |
| 100 */ |
| 101 function runSpecialSelectorTests(type, root) { |
| 102 test(function() { // 1 |
| 103 assert_equals(root.querySelectorAll(null).length, 1, "This should find one e
lement with the tag name 'NULL'."); |
| 104 }, type + ".querySelectorAll null") |
| 105 |
| 106 test(function() { // 2 |
| 107 assert_equals(root.querySelectorAll(undefined).length, 1, "This should find
one element with the tag name 'UNDEFINED'."); |
| 108 }, type + ".querySelectorAll undefined") |
| 109 |
| 110 test(function() { // 3 |
| 111 assert_throws(TypeError(), function() { |
| 112 root.querySelectorAll(); |
| 113 }, "This should throw a TypeError.") |
| 114 }, type + ".querySelectorAll no parameter") |
| 115 |
| 116 test(function() { // 4 |
| 117 var elm = root.querySelector(null) |
| 118 assert_not_equals(elm, null, "This should find an element."); |
| 119 assert_equals(elm.tagName.toUpperCase(), "NULL", "The tag name should be 'NU
LL'.") |
| 120 }, type + ".querySelector null") |
| 121 |
| 122 test(function() { // 5 |
| 123 var elm = root.querySelector(undefined) |
| 124 assert_not_equals(elm, undefined, "This should find an element."); |
| 125 assert_equals(elm.tagName.toUpperCase(), "UNDEFINED", "The tag name should b
e 'UNDEFINED'.") |
| 126 }, type + ".querySelector undefined") |
| 127 |
| 128 test(function() { // 6 |
| 129 assert_throws(TypeError(), function() { |
| 130 root.querySelector(); |
| 131 }, "This should throw a TypeError.") |
| 132 }, type + ".querySelector no parameter") |
| 133 |
| 134 test(function() { // 7 |
| 135 result = root.querySelectorAll("*"); |
| 136 var i = 0; |
| 137 traverse(root, function(elem) { |
| 138 if (elem !== root) { |
| 139 assert_equals(elem, result[i], "The result in index " + i + " should be
in tree order."); |
| 140 i++; |
| 141 } |
| 142 }) |
| 143 }, type + ".querySelectorAll tree order"); |
| 144 } |
| 145 |
| 146 /* |
| 147 * Execute queries with the specified valid selectors for both querySelector() a
nd querySelectorAll() |
| 148 * Only run these tests when results are expected. Don't run for syntax error te
sts. |
| 149 */ |
| 150 function runValidSelectorTest(type, root, selectors, testType, docType) { |
| 151 var nodeType = ""; |
| 152 switch (root.nodeType) { |
| 153 case Node.DOCUMENT_NODE: |
| 154 nodeType = "document"; |
| 155 break; |
| 156 case Node.ELEMENT_NODE: |
| 157 nodeType = root.parentNode ? "element" : "detached"; |
| 158 break; |
| 159 case Node.DOCUMENT_FRAGMENT_NODE: |
| 160 nodeType = "fragment"; |
| 161 break; |
| 162 default: |
| 163 assert_unreached(); |
| 164 nodeType = "unknown"; // This should never happen. |
| 165 } |
| 166 |
| 167 for (var i = 0; i < selectors.length; i++) { |
| 168 var s = selectors[i]; |
| 169 var n = s["name"]; |
| 170 var q = s["selector"]; |
| 171 var e = s["expect"]; |
| 172 |
| 173 if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"]
.indexOf(docType) === -1)) |
| 174 && (s["testType"] & testType) ) { |
| 175 var foundall, found; |
| 176 |
| 177 test(function() { |
| 178 foundall = root.querySelectorAll(q); |
| 179 assert_not_equals(foundall, null, "The method should not return null.") |
| 180 assert_equals(foundall.length, e.length, "The method should return the e
xpected number of matches.") |
| 181 |
| 182 for (var i = 0; i < e.length; i++) { |
| 183 assert_not_equals(foundall[i], null, "The item in index " + i + " shou
ld not be null.") |
| 184 assert_equals(foundall[i].getAttribute("id"), e[i], "The item in index
" + i + " should have the expected ID."); |
| 185 assert_false(foundall[i].hasAttribute("data-clone"), "This should not
be a cloned element."); |
| 186 } |
| 187 }, type + ".querySelectorAll: " + n + ": " + q); |
| 188 |
| 189 test(function() { |
| 190 found = root.querySelector(q); |
| 191 |
| 192 if (e.length > 0) { |
| 193 assert_not_equals(found, null, "The method should return a match.") |
| 194 assert_equals(found.getAttribute("id"), e[0], "The method should retur
n the first match."); |
| 195 assert_equals(found, foundall[0], "The result should match the first i
tem from querySelectorAll."); |
| 196 assert_false(found.hasAttribute("data-clone"), "This should not be ann
otated as a cloned element."); |
| 197 } else { |
| 198 assert_equals(found, null, "The method should not match anything."); |
| 199 } |
| 200 }, type + ".querySelector: " + n + ": " + q); |
| 201 } |
| 202 } |
| 203 } |
| 204 |
| 205 /* |
| 206 * Execute queries with the specified invalid selectors for both querySelector()
and querySelectorAll() |
| 207 * Only run these tests when errors are expected. Don't run for valid selector t
ests. |
| 208 */ |
| 209 function runInvalidSelectorTest(type, root, selectors) { |
| 210 for (var i = 0; i < selectors.length; i++) { |
| 211 var s = selectors[i]; |
| 212 var n = s["name"]; |
| 213 var q = s["selector"]; |
| 214 |
| 215 test(function() { |
| 216 assert_throws("SyntaxError", function() { |
| 217 root.querySelector(q) |
| 218 }) |
| 219 }, type + ".querySelector: " + n + ": " + q); |
| 220 |
| 221 test(function() { |
| 222 assert_throws("SyntaxError", function() { |
| 223 root.querySelectorAll(q) |
| 224 }) |
| 225 }, type + ".querySelectorAll: " + n + ": " + q); |
| 226 } |
| 227 } |
| 228 |
| 229 function traverse(elem, fn) { |
| 230 if (elem.nodeType === elem.ELEMENT_NODE) { |
| 231 fn(elem); |
| 232 } |
| 233 elem = elem.firstChild; |
| 234 while (elem) { |
| 235 traverse(elem, fn); |
| 236 elem = elem.nextSibling; |
| 237 } |
| 238 } |
| 239 |
| 240 function getNodeType(node) { |
| 241 switch (node.nodeType) { |
| 242 case Node.DOCUMENT_NODE: |
| 243 return "document"; |
| 244 case Node.ELEMENT_NODE: |
| 245 return node.parentNode ? "element" : "detached"; |
| 246 case Node.DOCUMENT_FRAGMENT_NODE: |
| 247 return "fragment"; |
| 248 default: |
| 249 assert_unreached(); |
| 250 return "unknown"; // This should never happen. |
| 251 } |
| 252 } |
| OLD | NEW |