test_content_iterator_subtree.html (37125B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Test for content subtree iterator</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" href="/tests/SimpleTest/test.css"> 8 <script> 9 var Cc = SpecialPowers.Cc; 10 var Ci = SpecialPowers.Ci; 11 function finish() { 12 // The SimpleTest may require usual elements in the template, but they shouldn't be during test. 13 // So, let's create them at end of the test. 14 document.body.innerHTML = '<div id="display"></div><div id="content"></div><pre id="test"></pre>'; 15 SimpleTest.finish(); 16 } 17 18 function createContentIterator() { 19 return Cc["@mozilla.org/scriptable-content-iterator;1"] 20 .createInstance(Ci.nsIScriptableContentIterator); 21 } 22 23 function getNodeDescription(aNode) { 24 if (aNode === undefined) { 25 return "undefine"; 26 } 27 if (aNode === null) { 28 return "null"; 29 } 30 function getElementDescription(aElement) { 31 if (aElement.tagName === "BR") { 32 if (aElement.previousSibling) { 33 return `<br> element after ${getNodeDescription(aElement.previousSibling)}`; 34 } 35 return `<br> element in ${getElementDescription(aElement.parentElement)}`; 36 } 37 let hasHint = aElement == document.body; 38 let tag = `<${aElement.tagName.toLowerCase()}`; 39 if (aElement.getAttribute("id")) { 40 tag += ` id="${aElement.getAttribute("id")}"`; 41 hasHint = true; 42 } 43 if (aElement.getAttribute("class")) { 44 tag += ` class="${aElement.getAttribute("class")}"`; 45 hasHint = true; 46 } 47 if (aElement.getAttribute("type")) { 48 tag += ` type="${aElement.getAttribute("type")}"`; 49 } 50 if (aElement.getAttribute("name")) { 51 tag += ` name="${aElement.getAttribute("name")}"`; 52 } 53 if (aElement.getAttribute("value")) { 54 tag += ` value="${aElement.getAttribute("value")}"`; 55 hasHint = true; 56 } 57 if (aElement.getAttribute("style")) { 58 tag += ` style="${aElement.getAttribute("style")}"`; 59 hasHint = true; 60 } 61 if (hasHint) { 62 return tag + ">"; 63 } 64 return `${tag}> in ${getElementDescription(aElement.parentElement)}`; 65 } 66 switch (aNode.nodeType) { 67 case aNode.TEXT_NODE: 68 return `text node, "${aNode.wholeText.replace(/\n/g, '\\n')}"`; 69 case aNode.COMMENT_NODE: 70 return `comment node, "${aNode.data.replace(/\n/g, '\\n')}"`; 71 case aNode.ELEMENT_NODE: 72 return getElementDescription(SpecialPowers.unwrap(aNode)); 73 default: 74 return "unknown node"; 75 } 76 } 77 78 SimpleTest.waitForExplicitFinish(); 79 SimpleTest.waitForFocus(function () { 80 let iter = createContentIterator(); 81 82 /** 83 * FYI: ContentSubtreeIterator does not support initWithRootNode() nor positionAt(). 84 */ 85 86 /** 87 * Basic behavior tests of first(), last(), prev() and next() after initialized with a range which selects empty element. 88 */ 89 document.body.innerHTML = "<div></div>"; 90 let range = document.createRange(); 91 range.selectNode(document.body.firstChild); 92 let description = "Initialized with range including only empty <div>:"; 93 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 94 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 95 `${description} currentNode should be the <div> immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 96 ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`); 97 98 iter.first(); 99 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 100 `${description} currentNode should be the <div> after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 101 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`); 102 103 iter.last(); 104 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 105 `${description} currentNode should be the <div> after calling last() (got: ${getNodeDescription(iter.currentNode)})`); 106 ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`); 107 108 iter.prev(); 109 is(SpecialPowers.unwrap(iter.currentNode), null, 110 `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`); 111 ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected? 112 113 iter.first(); 114 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 115 `${description} currentNode should be the <div> after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`); 116 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`); 117 118 iter.next(); 119 is(SpecialPowers.unwrap(iter.currentNode), null, 120 `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`); 121 ok(iter.isDone, `${description} isDone should be true after calling next()`); 122 123 /** 124 * Basic behavior tests of first(), last(), prev() and next() after initialized with positions which select empty element. 125 */ 126 range.selectNode(document.body.firstChild); 127 description = "Initialized with positions including only empty <div>:"; 128 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 129 range.startContainer, range.startOffset, 130 range.endContainer, range.endOffset); 131 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 132 `${description} currentNode should be the <div> immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 133 ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`); 134 135 iter.first(); 136 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 137 `${description} currentNode should be the <div> after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 138 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`); 139 140 iter.last(); 141 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 142 `${description} currentNode should be the <div> after calling last() (got: ${getNodeDescription(iter.currentNode)})`); 143 ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`); 144 145 iter.prev(); 146 is(SpecialPowers.unwrap(iter.currentNode), null, 147 `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`); 148 ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected? 149 150 iter.first(); 151 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 152 `${description} currentNode should be the <div> after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`); 153 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`); 154 155 iter.next(); 156 is(SpecialPowers.unwrap(iter.currentNode), null, 157 `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`); 158 ok(iter.isDone, `${description} isDone should be true after calling next()`); 159 160 /** 161 * Tests to initializing with collapsed range in an empty element. 162 */ 163 range = document.createRange(); 164 range.collapse(document.body.firstChild, 0); 165 description = "Initialized with range collapsed in empty <div>:"; 166 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 167 is(SpecialPowers.unwrap(iter.currentNode), null, 168 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 169 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 170 171 iter.first(); 172 is(SpecialPowers.unwrap(iter.currentNode), null, 173 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 174 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 175 176 /** 177 * Tests to initializing with collapsed range in an empty element. 178 */ 179 description = "Initialized with a position in empty <div>:"; 180 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 181 document.body.firstChild, 0, document.body.firstChild, 0); 182 is(SpecialPowers.unwrap(iter.currentNode), null, 183 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 184 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 185 186 iter.first(); 187 is(SpecialPowers.unwrap(iter.currentNode), null, 188 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 189 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 190 191 /** 192 * Basic behavior tests of first(), last(), prev() and next() after initialized with a range which selects the text node. 193 */ 194 document.body.innerHTML = "<div>some text.</div>"; 195 range = document.createRange(); 196 range.selectNode(document.body.firstChild.firstChild); 197 description = "Initialized with range including only text node:"; 198 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 199 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild, 200 `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 201 ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`); 202 203 iter.first(); 204 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild, 205 `${description} currentNode should be the text node after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 206 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`); 207 208 iter.last(); 209 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild, 210 `${description} currentNode should be the text node after calling last() (got: ${getNodeDescription(iter.currentNode)})`); 211 ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`); 212 213 iter.prev(); 214 is(SpecialPowers.unwrap(iter.currentNode), null, 215 `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`); 216 ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected? 217 218 iter.first(); 219 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild, 220 `${description} currentNode should be the text node after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`); 221 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`); 222 223 iter.next(); 224 is(SpecialPowers.unwrap(iter.currentNode), null, 225 `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`); 226 ok(iter.isDone, `${description} isDone should be true after calling next()`); 227 228 /** 229 * Basic behavior tests of first() and next() after initialized with positions which select the text node. 230 * XXX In this case, content iterator lists up the parent <div> element. Not sure if this is intentional difference 231 * from initWithRange(). 232 */ 233 range.selectNode(document.body.firstChild); 234 description = "Initialized with positions including only text node:"; 235 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 236 range.startContainer, range.startOffset, 237 range.endContainer, range.endOffset); 238 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 239 `${description} currentNode should be the <div> element immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 240 ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`); 241 242 iter.first(); 243 is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild, 244 `${description} currentNode should be the <div> element after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 245 ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`); 246 247 iter.next(); 248 is(SpecialPowers.unwrap(iter.currentNode), null, 249 `${description} currentNode should be null after calling next() from first position (got: ${getNodeDescription(iter.currentNode)})`); 250 ok(iter.isDone, `${description} isDone should be true after calling next() from first position`); 251 252 /** 253 * Tests to initializing with collapsed range at start of a text node. 254 */ 255 range = document.createRange(); 256 range.collapse(document.body.firstChild.firstChild, 0); 257 description = "Initialized with range collapsed at start of text node:"; 258 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 259 is(SpecialPowers.unwrap(iter.currentNode), null, 260 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 261 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 262 263 iter.first(); 264 is(SpecialPowers.unwrap(iter.currentNode), null, 265 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 266 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 267 268 /** 269 * Tests to initializing with collapsed range at start of a text node. 270 */ 271 description = "Initialized with a position at start of text node:"; 272 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 273 document.body.firstChild.firstChild, 0, document.body.firstChild.firstChild, 0); 274 is(SpecialPowers.unwrap(iter.currentNode), null, 275 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 276 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 277 278 iter.first(); 279 is(SpecialPowers.unwrap(iter.currentNode), null, 280 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 281 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 282 283 /** 284 * Tests to initializing with collapsed range at end of a text node. 285 */ 286 range = document.createRange(); 287 range.collapse(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length); 288 description = "Initialized with range collapsed at end of text node:"; 289 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 290 is(SpecialPowers.unwrap(iter.currentNode), null, 291 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 292 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 293 294 iter.first(); 295 is(SpecialPowers.unwrap(iter.currentNode), null, 296 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 297 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 298 299 /** 300 * Tests to initializing with collapsed range at end of a text node. 301 */ 302 description = "Initialized with a position at end of text node:"; 303 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 304 document.body.firstChild.firstChild, document.body.firstChild.firstChild.length, 305 document.body.firstChild.firstChild, document.body.firstChild.firstChild.length); 306 is(SpecialPowers.unwrap(iter.currentNode), null, 307 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 308 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 309 310 iter.first(); 311 is(SpecialPowers.unwrap(iter.currentNode), null, 312 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 313 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 314 315 /** 316 * Tests to initializing with collapsed range at middle of a text node. 317 */ 318 range = document.createRange(); 319 range.collapse(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2); 320 description = "Initialized with range collapsed at end of text node:"; 321 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 322 is(SpecialPowers.unwrap(iter.currentNode), null, 323 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 324 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 325 326 iter.first(); 327 is(SpecialPowers.unwrap(iter.currentNode), null, 328 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 329 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 330 331 /** 332 * Tests to initializing with collapsed range at middle of a text node. 333 */ 334 description = "Initialized with a position at end of text node:"; 335 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 336 document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2, 337 document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2); 338 is(SpecialPowers.unwrap(iter.currentNode), null, 339 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 340 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 341 342 iter.first(); 343 is(SpecialPowers.unwrap(iter.currentNode), null, 344 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 345 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 346 347 /** 348 * Tests to initializing with a range selecting all text in a text node. 349 */ 350 range = document.createRange(); 351 range.setStart(document.body.firstChild.firstChild, 0); 352 range.setEnd(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length); 353 description = "Initialized with range selecting all text in text node:"; 354 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 355 is(SpecialPowers.unwrap(iter.currentNode), null, 356 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 357 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 358 359 iter.first(); 360 is(SpecialPowers.unwrap(iter.currentNode), null, 361 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 362 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 363 364 /** 365 * Tests to initializing with positions selecting all text in a text node. 366 */ 367 description = "Initialized with positions selecting all text in text node:"; 368 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 369 document.body.firstChild.firstChild, 0, 370 document.body.firstChild.firstChild, document.body.firstChild.firstChild.length); 371 is(SpecialPowers.unwrap(iter.currentNode), null, 372 `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`); 373 ok(iter.isDone, `${description} isDone should be true immediately after initialization`); 374 375 iter.first(); 376 is(SpecialPowers.unwrap(iter.currentNode), null, 377 `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`); 378 ok(iter.isDone, `${description} isDone should be true even after calling first()`); 379 380 /** 381 * Basic tests with complicated tree. 382 */ 383 function check(aIter, aExpectedResult, aDescription) { 384 if (aExpectedResult.length) { 385 is(SpecialPowers.unwrap(aIter.currentNode), aExpectedResult[0], 386 `${aDescription}: currentNode should be the text node immediately after initialization (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(aExpectedResult[0])})`); 387 ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true immediately after initialization`); 388 389 aIter.first(); 390 is(SpecialPowers.unwrap(aIter.currentNode), aExpectedResult[0], 391 `${aDescription}: currentNode should be the text node after calling first() (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(aExpectedResult[0])})`); 392 ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true after calling first()`); 393 394 for (let expected of aExpectedResult) { 395 is(SpecialPowers.unwrap(aIter.currentNode), expected, 396 `${aDescription}: currentNode should be the node (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(expected)})`); 397 ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true when ${getNodeDescription(expected)} is expected`); 398 aIter.next(); 399 } 400 401 is(SpecialPowers.unwrap(aIter.currentNode), null, 402 `${aDescription}: currentNode should be null after calling next() finally (got: ${getNodeDescription(aIter.currentNode)}`); 403 ok(aIter.isDone, `${aDescription}: isDone should be true after calling next() finally`); 404 } else { 405 is(SpecialPowers.unwrap(aIter.currentNode), null, 406 `${aDescription}: currentNode should be null immediately after initialization (got: ${getNodeDescription(aIter.currentNode)})`); 407 ok(aIter.isDone, `${aDescription}: isDone should be true immediately after initialization`); 408 409 aIter.first(); 410 is(SpecialPowers.unwrap(aIter.currentNode), null, 411 `${aDescription}: currentNode should be null after calling first() (got: ${getNodeDescription(aIter.currentNode)})`); 412 ok(aIter.isDone, `${aDescription}: isDone should be true after calling first()`); 413 } 414 } 415 416 document.body.innerHTML = "<p>" + 417 "Here is <b>bold</b> and <i><u>underlined and </u>italic </i><span>or no style text.</span><br>" + 418 "</p>" + 419 "<p>" + 420 "Here is an <input> element: <input type=\"text\" value=\"default value\"><br>\n" + 421 "and a <textarea> element: <textarea>text area's text node</textarea><br><br>\n" + 422 "<!-- and here is comment node -->" + 423 "</p>"; 424 425 /** 426 * Selects the <body> with a range. 427 */ 428 range = document.createRange(); 429 range.selectNode(document.body); 430 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 431 check(iter, [document.body], "Initialized with range selecting the <body>"); 432 433 /** 434 * Selects the <body> with positions. 435 */ 436 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 437 range.startContainer, range.startOffset, range.endContainer, range.endOffset); 438 check(iter, [document.body], "Initialized with positions selecting the <body>"); 439 440 /** 441 * Selects all children in the <body> with a range. 442 */ 443 range = document.createRange(); 444 range.selectNodeContents(document.body); 445 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 446 check(iter, 447 [document.body.firstChild, // first <p> 448 document.body.firstChild.nextSibling], // second <p> 449 "Initialized with range selecting all children in the <body>"); 450 451 /** 452 * Selects all children in the <body> with positions. 453 */ 454 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 455 range.startContainer, range.startOffset, range.endContainer, range.endOffset); 456 check(iter, 457 [document.body.firstChild, // first <p> 458 document.body.firstChild.nextSibling], // second <p> 459 "Initialized with positions selecting all children in the <body>"); 460 461 /** 462 * range/positions around elements. 463 */ 464 document.body.innerHTML = "abc<b>def</b><i>ghi</i>jkl"; 465 range = document.createRange(); 466 467 range.setStart(document.body.firstChild, 0); 468 range.setEnd(document.body.firstChild.nextSibling.firstChild, 2); 469 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 470 check(iter, [], "Initialized with range selecting '[abc<b>de]f'"); 471 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 472 range.startContainer, range.startOffset, 473 range.endContainer, range.endOffset); 474 check(iter, [], "Initialized with positions selecting '[abc<b>de]f'"); 475 476 range.setStart(document.body.firstChild, 2); 477 range.setEnd(document.body.firstChild.nextSibling.firstChild, 2); 478 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 479 check(iter,[], "Initialized with range selecting 'ab[c<b>de]f'"); 480 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 481 range.startContainer, range.startOffset, 482 range.endContainer, range.endOffset); 483 check(iter, [], "Initialized with positions selecting 'ab[c<b>de]f'"); 484 485 range.setStart(document.body.firstChild, 3); 486 range.setEnd(document.body.firstChild.nextSibling.firstChild, 2); 487 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 488 check(iter, [], "Initialized with range selecting 'abc[<b>de]f'"); 489 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 490 range.startContainer, range.startOffset, 491 range.endContainer, range.endOffset); 492 check(iter, [], "Initialized with positions selecting 'abc[<b>de]f'"); 493 494 range.setStart(document.body, 1); 495 range.setEnd(document.body.firstChild.nextSibling.firstChild, 2); 496 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 497 check(iter, [], "Initialized with range selecting 'abc{<b>de]f'"); 498 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 499 range.startContainer, range.startOffset, 500 range.endContainer, range.endOffset); 501 check(iter, [], "Initialized with positions selecting 'abc{<b>de]f'"); 502 503 range.setStart(document.body.firstChild.nextSibling, 0); 504 range.setEnd(document.body.firstChild.nextSibling.firstChild, 2); 505 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 506 check(iter, [], "Initialized with range selecting '<b>{de]f'"); 507 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 508 range.startContainer, range.startOffset, 509 range.endContainer, range.endOffset); 510 check(iter, [], "Initialized with positions selecting '<b>{de]f'"); 511 512 range.setStart(document.body.firstChild.nextSibling, 0); 513 range.setEnd(document.body.firstChild.nextSibling.firstChild, 3); 514 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 515 check(iter, [], "Initialized with range selecting '<b>{def]</b>'"); 516 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 517 range.startContainer, range.startOffset, 518 range.endContainer, range.endOffset); 519 check(iter, [], "Initialized with positions selecting '<b>{def]</b>'"); 520 521 range.setStart(document.body.firstChild.nextSibling, 0); 522 range.setEnd(document.body.firstChild.nextSibling, 1); 523 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 524 check(iter, 525 [document.body.firstChild.nextSibling.firstChild], // text in <b> 526 "Initialized with range selecting '<b>{def}</b>'"); 527 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 528 range.startContainer, range.startOffset, 529 range.endContainer, range.endOffset); 530 check(iter, 531 [document.body.firstChild.nextSibling.firstChild], // text in <b> 532 "Initialized with positions selecting '<b>{def}</b>'"); 533 534 range.setStart(document.body.firstChild.nextSibling, 0); 535 range.setEnd(document.body, 2); 536 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 537 check(iter, 538 [document.body.firstChild.nextSibling.firstChild], // text in <b> 539 "Initialized with range selecting '<b>{def</b>}<i>ghi'"); 540 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 541 range.startContainer, range.startOffset, 542 range.endContainer, range.endOffset); 543 check(iter, 544 [document.body.firstChild.nextSibling.firstChild], // text in <b> 545 "Initialized with positions selecting '<b>{def</b>}<i>ghi'"); 546 547 range.setStart(document.body.firstChild.nextSibling.firstChild, 3); 548 range.setEnd(document.body, 2); 549 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 550 check(iter, [], "Initialized with range selecting '<b>def[</b>}<i>ghi'"); 551 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 552 range.startContainer, range.startOffset, 553 range.endContainer, range.endOffset); 554 check(iter, [], "Initialized with positions selecting '<b>def[</b>}<i>ghi'"); 555 556 range.setStart(document.body.firstChild.nextSibling, 1); 557 range.setEnd(document.body, 2); 558 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 559 check(iter, [], "Initialized with range selecting '<b>def{</b>}<i>ghi'"); 560 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 561 range.startContainer, range.startOffset, 562 range.endContainer, range.endOffset); 563 check(iter, [], "Initialized with positions selecting '<b>def{</b>}<i>ghi'"); 564 565 range.setStart(document.body.firstChild.nextSibling, 1); 566 range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0); 567 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 568 check(iter, [], "Initialized with range selecting '<b>def{</b><i>}ghi'"); 569 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 570 range.startContainer, range.startOffset, 571 range.endContainer, range.endOffset); 572 check(iter, [], "Initialized with positions selecting '<b>def{</b><i>}ghi'"); 573 574 range.setStart(document.body.firstChild.nextSibling, 1); 575 range.setEnd(document.body.firstChild.nextSibling.nextSibling.firstChild, 0); 576 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 577 check(iter, [], "Initialized with range selecting '<b>def{</b><i>]ghi'"); 578 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 579 range.startContainer, range.startOffset, 580 range.endContainer, range.endOffset); 581 check(iter, [], "Initialized with positions selecting '<b>def{</b><i>]ghi'"); 582 583 range.setStart(document.body.firstChild.nextSibling.nextSibling, 0); 584 range.setEnd(document.body, 3); 585 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 586 check(iter, 587 [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i> 588 "Initialized with range selecting '<i>{ghi</i>}jkl'"); 589 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 590 range.startContainer, range.startOffset, 591 range.endContainer, range.endOffset); 592 check(iter, 593 [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i> 594 "Initialized with positions selecting '<i>{ghi</i>}jkl'"); 595 596 range.setStart(document.body.firstChild.nextSibling.nextSibling.firstChild, 3); 597 range.setEnd(document.body, 3); 598 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 599 check(iter, [], "Initialized with range selecting '<i>ghi[</i>}jkl'"); 600 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 601 range.startContainer, range.startOffset, 602 range.endContainer, range.endOffset); 603 check(iter, [], "Initialized with positions selecting '<i>ghi[</i>}jkl'"); 604 605 range.setStart(document.body.firstChild.nextSibling.nextSibling, 1); 606 range.setEnd(document.body, 3); 607 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 608 check(iter, [], "Initialized with range selecting '<i>ghi{</i>}jkl'"); 609 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 610 range.startContainer, range.startOffset, 611 range.endContainer, range.endOffset); 612 check(iter, [], "Initialized with positions selecting '<i>ghi{</i>}jkl'"); 613 614 range.setStart(document.body.firstChild.nextSibling.nextSibling, 1); 615 range.setEnd(document.body.firstChild.nextSibling.nextSibling.nextSibling, 0); 616 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 617 check(iter, [], "Initialized with range selecting '<i>ghi{</i>]jkl'"); 618 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 619 range.startContainer, range.startOffset, 620 range.endContainer, range.endOffset); 621 check(iter, [], "Initialized with positions selecting '<i>ghi{</i>]jkl'"); 622 623 /** 624 * range/positions around <br> elements. 625 */ 626 document.body.innerHTML = "abc<br>def"; 627 range = document.createRange(); 628 range.setStart(document.body.firstChild, 3); 629 range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0); 630 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 631 check(iter, 632 [document.body.firstChild.nextSibling], // <br> 633 "Initialized with range selecting 'abc[<br>]def'"); 634 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 635 range.startContainer, range.startOffset, 636 range.endContainer, range.endOffset); 637 check(iter, 638 [document.body.firstChild.nextSibling], // <br> 639 "Initialized with positions selecting 'abc[<br>]def'"); 640 641 range.setStart(document.body, 1); 642 range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0); 643 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 644 check(iter, 645 [document.body.firstChild.nextSibling], // <br> 646 "Initialized with range selecting 'abc{<br>]def'"); 647 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 648 range.startContainer, range.startOffset, 649 range.endContainer, range.endOffset); 650 check(iter, 651 [document.body.firstChild.nextSibling], // <br> 652 "Initialized with positions selecting 'abc{<br>]def'"); 653 654 range.setStart(document.body.firstChild.nextSibling, 0); 655 range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0); 656 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 657 check(iter, [], "Initialized with range selecting 'abc{<br>]def' (starting in <br>)"); 658 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 659 range.startContainer, range.startOffset, 660 range.endContainer, range.endOffset); 661 check(iter, [], "Initialized with positions selecting 'abc{<br>]def' (starting in <br>)"); 662 663 range.setStart(document.body, 1); 664 range.setEnd(document.body, 2); 665 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 666 check(iter, 667 [document.body.firstChild.nextSibling], // <br> 668 "Initialized with range selecting 'abc{<br>}def'"); 669 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 670 range.startContainer, range.startOffset, 671 range.endContainer, range.endOffset); 672 check(iter, 673 [document.body.firstChild.nextSibling], // <br> 674 "Initialized with positions selecting 'abc{<br>}def'"); 675 676 range.setStart(document.body.firstChild, 3); 677 range.setEnd(document.body.firstChild.nextSibling, 0); 678 iter.initWithRange(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, range); 679 check(iter, [], "Initialized with range selecting 'abc[}<br>def' (ending in <br>)"); 680 iter.initWithPositions(Ci.nsIScriptableContentIterator.SUBTREE_ITERATOR, 681 range.startContainer, range.startOffset, 682 range.endContainer, range.endOffset); 683 check(iter, [], "Initialized with positions selecting 'abc[}<br>def' (ending in <br>)"); 684 685 finish(); 686 }); 687 </script> 688 </head> 689 <body></body> 690 </html>