1<html xmlns="http://www.w3.org/1999/xhtml"> 2<!-- NodeIterator basics and filters tests. 3 Originally written by Ian Hickson, Mochi-ified by Zack Weinberg. 4 This file based on 001.xml, 002.xml, and 010.xml from 5 http://hixie.ch/tests/adhoc/dom/traversal/node-iterator/ 6 with some additional cases. 7 --> 8<head> 9 <title>DOM Traversal: NodeIterator: Basics and Filters</title> 10 <script src="/tests/SimpleTest/SimpleTest.js"></script> 11 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 12</head> 13<body> 14<p id="display"></p> 15<div id="content" style="display: none"> 16<!-- comment --> 17<?body processing instruction?> 18</div> 19<pre id="test"> 20<script class="testbody" type="text/javascript"><![CDATA[ 21 function compare_arrays(e, f, label) { 22 var length = (e.length > f.length) ? e.length : f.length; 23 for (var i = 0; i < length; i += 1) { 24 if (e[i] > 0) 25 is(f[i], e[i], label + " - index " + i + ": "); 26 else 27 todo_is(f[i], -e[i], label + " - index " + i + ": "); 28 } 29 } 30 31 /** DOM Traversal: NodeIterator: Basics **/ 32 // NOTE: If you change the document structure, you have to make sure 33 // the magic numbers in this array (and 'expected_f', below) match. 34 var expected = new Array(9, // document 35 1, // html 36 3, 8, // leading comment 37 3, 1, // head 38 3, 1, 3, // title 39 3, 1, // first script tag 40 3, 1, // stylesheet tag 41 3, // close head 42 3, 1, // body 43 3, 1, // p#display 44 3, 1, // div#content 45 3, 8, // comment 46 3, 7, // processing instruction 47 3, // close div 48 3, 1, // pre#test 49 3, 1, 4, // script and CDATA block 50 -3, -3, -3); // close close close 51 // these aren't there 52 // not sure why 53 var found = new Array(); 54 55 var iterator = document.createNodeIterator(document, 56 NodeFilter.SHOW_ALL, 57 null); 58 var node; 59 60 // forwards 61 while (node = iterator.nextNode()) 62 found.push(node.nodeType); 63 compare_arrays(expected, found, 'basics forward'); 64 65 // backwards 66 found.length = 0; 67 while (node = iterator.previousNode()) 68 found.unshift(node.nodeType); 69 compare_arrays(expected, found, 'basics backward'); 70 71 /** DOM Traversal: NodeIterator: Filters **/ 72 function filter(n) { 73 if (n.nodeType == 3) { 74 return NodeFilter.FILTER_SKIP; 75 } else if (n.nodeName == 'body') { 76 return NodeFilter.FILTER_REJECT; // same as _SKIP 77 } 78 return 1; // FILTER_ACCEPT 79 } 80 81 // Same warning applies to this array as to 'expected'. 82 var expect_f = new Array(9, // document 83 1, // html 84 8, // leading comment 85 1, // head 86 1, // title 87 1, // first script tag 88 1, // stylesheet tag 89 // body skipped 90 1, // p#display 91 1, // div#content 92 8, // comment 93 // processing instruction skipped 94 1, // pre#test 95 1, 4); // script and CDATA block 96 97 found.length = 0; 98 iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, 99 filter); 100 101 // forwards 102 while (node = iterator.nextNode()) 103 found.push(node.nodeType); 104 compare_arrays(expect_f, found, 'filtered forward'); 105 106 // backwards 107 found.length = 0; 108 while (node = iterator.previousNode()) 109 found.unshift(node.nodeType); 110 compare_arrays(expect_f, found, 'filtered backward'); 111 112 function checkBadFilter(method, n) { 113 var iter = 114 document.createNodeIterator(document, NodeFilter.SHOW_ALL, 115 function() { 116 if (n < 0) 117 iter.detach(); 118 return NodeFilter.FILTER_ACCEPT; 119 }); 120 while (--n >= 0) 121 iter.nextNode(); 122 try { 123 iter[method](); 124 ok(true, "Able to call " + method + " on a NodeIterator after calling no-op detach()"); 125 } catch (x) { ok(false, x) } 126 } 127 checkBadFilter("nextNode", 2); 128 checkBadFilter("previousNode", 3); 129 130 (function() { 131 // Implementing the scenario outlined in 132 // http://bugzilla.mozilla.org/show_bug.cgi?id=552110#c4 133 134 var iter = (function(filt) { 135 var grandparent = document.createElement("div"), 136 parent = document.createElement("span"); 137 138 grandparent.appendChild(parent); 139 parent.appendChild(document.createElement("img")); 140 parent.appendChild(document.createElement("p")); 141 142 return document.createNodeIterator(grandparent, 143 NodeFilter.SHOW_ALL, 144 filt); 145 })(function(n) { 146 if (n.nodeName != "img") 147 return NodeFilter.FILTER_ACCEPT; 148 149 iter.detach(); 150 151 n.parentNode.remove(); 152 // Drop any node references passed into this function. 153 for (var i = 0; i < arguments.length; ++i) 154 arguments[i] = null; 155 ok(!n, "arguments[0] = null should have nulled out n"); 156 157 // Try to trigger GC. 158 var xhr = new XMLHttpRequest(); 159 xhr.open("GET", location.href, false); 160 xhr.send(); 161 162 return NodeFilter.FILTER_SKIP; 163 }); 164 165 is(iter.nextNode().nodeName, "div", 166 "iter.nextNode() returned the wrong node"); 167 is(iter.nextNode().nodeName, "span", 168 "iter.nextNode() returned the wrong node"); 169 try { 170 var p = iter.nextNode(); 171 ok(false, "iter.nextNode() should have thrown, but instead it returned <" + p.nodeName + ">"); 172 } catch (x) { ok(true, x) } 173 })(); 174 175]]></script> 176</pre> 177</body> 178</html> 179