PageRenderTime 48ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/third_party/blink/web_tests/external/wpt/dom/nodes/ParentNode-querySelector-All.js

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