tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_content_iterator_pre_order.html (48288B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Test for pre-order content 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   * Basic behavior tests of first(), last(), prev() and next() after initialized with an empty element.
     84   */
     85  document.body.innerHTML = "<div></div>";
     86  let description = "Initialized with empty <div> as root node:";
     87  iter.initWithRootNode(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, document.body.firstChild);
     88  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
     89    `${description} currentNode should be the <div> immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
     90  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
     91 
     92  iter.first();
     93  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
     94    `${description} currentNode should be the <div> after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
     95  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`);
     96 
     97  iter.last();
     98  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
     99    `${description} currentNode should be the <div> after calling last() (got: ${getNodeDescription(iter.currentNode)})`);
    100  ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`);
    101 
    102  iter.prev();
    103  is(SpecialPowers.unwrap(iter.currentNode), null,
    104    `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`);
    105  ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected?
    106 
    107  iter.first();
    108  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    109    `${description} currentNode should be the <div> after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`);
    110  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`);
    111 
    112  iter.next();
    113  is(SpecialPowers.unwrap(iter.currentNode), null,
    114    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    115  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    116 
    117  /**
    118   * Basic behavior tests of first(), last(), prev() and next() after initialized with a range which selects empty element.
    119   */
    120  let range = document.createRange();
    121  range.selectNode(document.body.firstChild);
    122  description = "Initialized with range including only empty <div>:";
    123  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    124  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    125    `${description} currentNode should be the <div> immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    126  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    127 
    128  iter.first();
    129  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    130    `${description} currentNode should be the <div> after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    131  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`);
    132 
    133  iter.last();
    134  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    135    `${description} currentNode should be the <div> after calling last() (got: ${getNodeDescription(iter.currentNode)})`);
    136  ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`);
    137 
    138  iter.prev();
    139  is(SpecialPowers.unwrap(iter.currentNode), null,
    140    `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`);
    141  ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected?
    142 
    143  iter.first();
    144  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    145    `${description} currentNode should be the <div> after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`);
    146  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`);
    147 
    148  iter.next();
    149  is(SpecialPowers.unwrap(iter.currentNode), null,
    150    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    151  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    152 
    153  /**
    154   * Basic behavior tests of first(), last(), prev() and next() after initialized with positions which select empty element.
    155   */
    156  range.selectNode(document.body.firstChild);
    157  description = "Initialized with positions including only empty <div>:";
    158  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    159                         range.startContainer, range.startOffset,
    160                         range.endContainer, range.endOffset);
    161  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    162    `${description} currentNode should be the <div> immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    163  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    164 
    165  iter.first();
    166  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    167    `${description} currentNode should be the <div> after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    168  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`);
    169 
    170  iter.last();
    171  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    172    `${description} currentNode should be the <div> after calling last() (got: ${getNodeDescription(iter.currentNode)})`);
    173  ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`);
    174 
    175  iter.prev();
    176  is(SpecialPowers.unwrap(iter.currentNode), null,
    177    `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`);
    178  ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected?
    179 
    180  iter.first();
    181  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    182    `${description} currentNode should be the <div> after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`);
    183  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`);
    184 
    185  iter.next();
    186  is(SpecialPowers.unwrap(iter.currentNode), null,
    187    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    188  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    189 
    190  /**
    191   * Tests to initializing with collapsed range in an empty element.
    192   */
    193  range = document.createRange();
    194  range.collapse(document.body.firstChild, 0);
    195  description = "Initialized with range collapsed in empty <div>:";
    196  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    197  is(SpecialPowers.unwrap(iter.currentNode), null,
    198    `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    199  ok(iter.isDone, `${description} isDone should be true immediately after initialization`);
    200 
    201  iter.first();
    202  is(SpecialPowers.unwrap(iter.currentNode), null,
    203    `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    204  ok(iter.isDone, `${description} isDone should be true even after calling first()`);
    205 
    206  /**
    207   * Tests to initializing with collapsed range in an empty element.
    208   */
    209  description = "Initialized with a position in empty <div>:";
    210  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    211                         document.body.firstChild, 0, document.body.firstChild, 0);
    212  is(SpecialPowers.unwrap(iter.currentNode), null,
    213    `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    214  ok(iter.isDone, `${description} isDone should be true immediately after initialization`);
    215 
    216  iter.first();
    217  is(SpecialPowers.unwrap(iter.currentNode), null,
    218    `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    219  ok(iter.isDone, `${description} isDone should be true even after calling first()`);
    220 
    221  /**
    222   * Basic behavior tests of first(), last(), prev() and next() after initialized with the text element.
    223   */
    224  document.body.innerHTML = "<div>some text.</div>";
    225  description = "Initialized with a text node as root node:";
    226  iter.initWithRootNode(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, document.body.firstChild.firstChild);
    227  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    228    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    229  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    230 
    231  iter.first();
    232  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    233    `${description} currentNode should be the text node after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    234  ok(!iter.isDone, `${description} isDone shouldn't be the text node after calling first()`);
    235 
    236  iter.last();
    237  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    238    `${description} currentNode should be the text node after calling last() (got: ${getNodeDescription(iter.currentNode)})`);
    239  ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`);
    240 
    241  iter.prev();
    242  is(SpecialPowers.unwrap(iter.currentNode), null,
    243    `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`);
    244  ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected?
    245 
    246  iter.first();
    247  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    248    `${description} currentNode should be the text node after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`);
    249  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`);
    250 
    251  iter.next();
    252  is(SpecialPowers.unwrap(iter.currentNode), null,
    253    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    254  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    255 
    256  /**
    257   * Basic behavior tests of first(), last(), prev() and next() after initialized with a range which selects the text node.
    258   */
    259  range = document.createRange();
    260  range.selectNode(document.body.firstChild.firstChild);
    261  description = "Initialized with range including only text node:";
    262  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    263  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    264    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    265  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    266 
    267  iter.first();
    268  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    269    `${description} currentNode should be the text node after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    270  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`);
    271 
    272  iter.last();
    273  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    274    `${description} currentNode should be the text node after calling last() (got: ${getNodeDescription(iter.currentNode)})`);
    275  ok(!iter.isDone, `${description} isDone shouldn't be true after calling last()`);
    276 
    277  iter.prev();
    278  is(SpecialPowers.unwrap(iter.currentNode), null,
    279    `${description} currentNode should be null after calling prev() (got: ${getNodeDescription(iter.currentNode)})`);
    280  ok(iter.isDone, `${description} isDone should be true after calling prev()`); // XXX Is this expected?
    281 
    282  iter.first();
    283  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    284    `${description} currentNode should be the text node after calling first() even after once done (got: ${getNodeDescription(iter.currentNode)})`);
    285  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first() even after once done`);
    286 
    287  iter.next();
    288  is(SpecialPowers.unwrap(iter.currentNode), null,
    289    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    290  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    291 
    292  /**
    293   * Basic behavior tests of first() and next() after initialized with positions which select the text node.
    294   * XXX In this case, content iterator lists up the parent <div> element.  Not sure if this is intentional difference
    295   *     from initWithRange().
    296   */
    297  range.selectNode(document.body.firstChild);
    298  description = "Initialized with positions including only text node:";
    299  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    300                         range.startContainer, range.startOffset,
    301                         range.endContainer, range.endOffset);
    302  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    303    `${description} currentNode should be the <div> element immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    304  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    305 
    306  iter.first();
    307  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild,
    308    `${description} currentNode should be the <div> element after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    309  ok(!iter.isDone, `${description} isDone shouldn't be true after calling first()`);
    310 
    311  iter.next();
    312  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    313    `${description} currentNode should be the text node after calling next() from first position (got: ${getNodeDescription(iter.currentNode)})`);
    314  ok(!iter.isDone, `${description} isDone shouldn't be true after calling next() from first position`);
    315 
    316  iter.next();
    317  is(SpecialPowers.unwrap(iter.currentNode), null,
    318    `${description} currentNode should be null after calling next() from second position (got: ${getNodeDescription(iter.currentNode)})`);
    319  ok(iter.isDone, `${description} isDone should be true after calling next() from second position`);
    320 
    321  /**
    322   * Tests to initializing with collapsed range at start of a text node.
    323   */
    324  range = document.createRange();
    325  range.collapse(document.body.firstChild.firstChild, 0);
    326  description = "Initialized with range collapsed at start of text node:";
    327  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    328  is(SpecialPowers.unwrap(iter.currentNode), null,
    329    `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    330  ok(iter.isDone, `${description} isDone should be true immediately after initialization`);
    331 
    332  iter.first();
    333  is(SpecialPowers.unwrap(iter.currentNode), null,
    334    `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    335  ok(iter.isDone, `${description} isDone should be true even after calling first()`);
    336 
    337  /**
    338   * Tests to initializing with collapsed range at start of a text node.
    339   * XXX In this case, content iterator lists up the text node.  Not sure if this is intentional difference
    340   *     from initWithRange().
    341   */
    342  description = "Initialized with a position at start of text node:";
    343  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    344                         document.body.firstChild.firstChild, 0, document.body.firstChild.firstChild, 0);
    345  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    346    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    347  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    348 
    349  iter.next();
    350  is(SpecialPowers.unwrap(iter.currentNode), null,
    351    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    352  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    353 
    354  /**
    355   * Tests to initializing with collapsed range at end of a text node.
    356   */
    357  range = document.createRange();
    358  range.collapse(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length);
    359  description = "Initialized with range collapsed at end of text node:";
    360  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    361  is(SpecialPowers.unwrap(iter.currentNode), null,
    362    `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    363  ok(iter.isDone, `${description} isDone should be true immediately after initialization`);
    364 
    365  iter.first();
    366  is(SpecialPowers.unwrap(iter.currentNode), null,
    367    `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    368  ok(iter.isDone, `${description} isDone should be true even after calling first()`);
    369 
    370  /**
    371   * Tests to initializing with collapsed range at end of a text node.
    372   * XXX In this case, content iterator lists up the text node.  Not sure if this is intentional difference
    373   *     from initWithRange().
    374   */
    375  description = "Initialized with a position at end of text node:";
    376  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    377                         document.body.firstChild.firstChild, document.body.firstChild.firstChild.length,
    378                         document.body.firstChild.firstChild, document.body.firstChild.firstChild.length);
    379  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    380    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    381  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    382 
    383  iter.next();
    384  is(SpecialPowers.unwrap(iter.currentNode), null,
    385    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    386  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    387 
    388  /**
    389   * Tests to initializing with collapsed range at middle of a text node.
    390   */
    391  range = document.createRange();
    392  range.collapse(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2);
    393  description = "Initialized with range collapsed at end of text node:";
    394  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    395  is(SpecialPowers.unwrap(iter.currentNode), null,
    396    `${description} currentNode should be null immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    397  ok(iter.isDone, `${description} isDone should be true immediately after initialization`);
    398 
    399  iter.first();
    400  is(SpecialPowers.unwrap(iter.currentNode), null,
    401    `${description} currentNode should be null even after calling first() (got: ${getNodeDescription(iter.currentNode)})`);
    402  ok(iter.isDone, `${description} isDone should be true even after calling first()`);
    403 
    404  /**
    405   * Tests to initializing with collapsed range at middle of a text node.
    406   * XXX In this case, content iterator lists up the text node.  Not sure if this is intentional difference
    407   *     from initWithRange().
    408   */
    409  description = "Initialized with a position at end of text node:";
    410  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    411                         document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2,
    412                         document.body.firstChild.firstChild, document.body.firstChild.firstChild.length / 2);
    413  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    414    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    415  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    416 
    417  iter.next();
    418  is(SpecialPowers.unwrap(iter.currentNode), null,
    419    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    420  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    421 
    422  /**
    423   * Tests to initializing with a range selecting all text in a text node.
    424   */
    425  range = document.createRange();
    426  range.setStart(document.body.firstChild.firstChild, 0);
    427  range.setEnd(document.body.firstChild.firstChild, document.body.firstChild.firstChild.length);
    428  description = "Initialized with range selecting all text in text node:";
    429  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    430  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    431    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    432  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    433 
    434  iter.next();
    435  is(SpecialPowers.unwrap(iter.currentNode), null,
    436    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    437  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    438 
    439  /**
    440   * Tests to initializing with positions selecting all text in a text node.
    441   */
    442  description = "Initialized with positions selecting all text in text node:";
    443  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    444                         document.body.firstChild.firstChild, 0,
    445                         document.body.firstChild.firstChild, document.body.firstChild.firstChild.length);
    446  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    447    `${description} currentNode should be the text node immediately after initialization (got: ${getNodeDescription(iter.currentNode)})`);
    448  ok(!iter.isDone, `${description} isDone shouldn't be true immediately after initialization`);
    449 
    450  iter.next();
    451  is(SpecialPowers.unwrap(iter.currentNode), null,
    452    `${description} currentNode should be null after calling next() (got: ${getNodeDescription(iter.currentNode)})`);
    453  ok(iter.isDone, `${description} isDone should be true after calling next()`);
    454 
    455  /**
    456   * Basic tests with complicated tree.
    457   */
    458  function check(aIter, aExpectedResult, aDescription) {
    459    if (aExpectedResult.length) {
    460      is(SpecialPowers.unwrap(aIter.currentNode), aExpectedResult[0],
    461        `${aDescription}: currentNode should be the text node immediately after initialization (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(aExpectedResult[0])})`);
    462      ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true immediately after initialization`);
    463 
    464      aIter.first();
    465      is(SpecialPowers.unwrap(aIter.currentNode), aExpectedResult[0],
    466        `${aDescription}: currentNode should be the text node after calling first() (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(aExpectedResult[0])})`);
    467      ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true after calling first()`);
    468 
    469      for (let expected of aExpectedResult) {
    470        is(SpecialPowers.unwrap(aIter.currentNode), expected,
    471          `${aDescription}: currentNode should be the node (got: ${getNodeDescription(aIter.currentNode)}, expected: ${getNodeDescription(expected)})`);
    472        ok(!aIter.isDone, `${aDescription}: isDone shouldn't be true when ${getNodeDescription(expected)} is expected`);
    473        aIter.next();
    474      }
    475 
    476      is(SpecialPowers.unwrap(aIter.currentNode), null,
    477        `${aDescription}: currentNode should be null after calling next() finally (got: ${getNodeDescription(aIter.currentNode)}`);
    478      ok(aIter.isDone, `${aDescription}: isDone should be true after calling next() finally`);
    479    } else {
    480      is(SpecialPowers.unwrap(aIter.currentNode), null,
    481        `${aDescription}: currentNode should be null immediately after initialization (got: ${getNodeDescription(aIter.currentNode)})`);
    482      ok(aIter.isDone, `${aDescription}: isDone should be true immediately after initialization`);
    483 
    484      aIter.first();
    485      is(SpecialPowers.unwrap(aIter.currentNode), null,
    486        `${aDescription}: currentNode should be null after calling first() (got: ${getNodeDescription(aIter.currentNode)})`);
    487      ok(aIter.isDone, `${aDescription}: isDone should be true after calling first()`);
    488    }
    489  }
    490 
    491  document.body.innerHTML = "<p>" +
    492                              "Here is <b>bold</b> and <i><u>underlined and </u>italic </i><span>or no style text.</span><br>" +
    493                            "</p>" +
    494                            "<p>" +
    495                              "Here is an &lt;input&gt; element: <input type=\"text\" value=\"default value\"><br>\n" +
    496                              "and a &lt;textarea&gt; element: <textarea>text area's text node</textarea><br><br>\n" +
    497                              "<!-- and here is comment node -->" +
    498                            "</p>";
    499 
    500  let expectedResult =
    501    [document.body, // <body>
    502     document.body.firstChild, // first <p>
    503     document.body.firstChild.firstChild, // the first text node
    504     document.body.firstChild.firstChild.nextSibling, // <b>
    505     document.body.firstChild.firstChild.nextSibling.firstChild, // text in <b>
    506     document.body.firstChild.firstChild.nextSibling.nextSibling, // text next to <b>
    507     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling, // <i>
    508     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild, // <u>
    509     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild.firstChild, // text in <u>
    510     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild.nextSibling, // text next to <u>
    511     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling, // <span>
    512     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.firstChild, // text in <span>
    513     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <span>
    514     document.body.firstChild.nextSibling, // second <p>
    515     document.body.firstChild.nextSibling.firstChild, // the first text node in second <p>
    516     document.body.firstChild.nextSibling.firstChild.nextSibling, // <input>
    517     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling, // <br> next to <input>
    518     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling, // text next to <input>
    519     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling, // <textarea>
    520     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.firstChild, // text in <textarea>
    521     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <textarea>
    522     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <br>
    523     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // text next to <br>
    524     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling] // comment
    525 
    526  iter.initWithRootNode(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, document.body);
    527  check(iter, expectedResult, "Initialized with the <body> as root element");
    528 
    529  /**
    530   * Selects the <body> with a range.
    531   */
    532  range = document.createRange();
    533  range.selectNode(document.body);
    534  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    535  check(iter, expectedResult, "Initialized with range selecting the <body>");
    536 
    537  /**
    538   * Selects the <body> with positions.
    539   */
    540  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    541                         range.startContainer, range.startOffset, range.endContainer, range.endOffset);
    542  check(iter, expectedResult, "Initialized with positions selecting the <body>");
    543 
    544  /**
    545   * Selects all children in the <body> with a range.
    546   */
    547  expectedResult.shift(); // <body> shouldn't be listed up.
    548  range = document.createRange();
    549  range.selectNodeContents(document.body);
    550  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    551  check(iter, expectedResult, "Initialized with range selecting all children in the <body>");
    552 
    553  /**
    554   * Selects all children in the <body> with positions.
    555   */
    556  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    557                         range.startContainer, range.startOffset, range.endContainer, range.endOffset);
    558  check(iter, expectedResult, "Initialized with positions selecting all children in the <body>");
    559 
    560  /**
    561   * range/positions around elements.
    562   */
    563  document.body.innerHTML = "abc<b>def</b><i>ghi</i>jkl";
    564  range = document.createRange();
    565 
    566  range.setStart(document.body.firstChild, 0);
    567  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    568  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    569  check(iter,
    570        [document.body.firstChild, // text before <b>
    571         document.body.firstChild.nextSibling, // <b>
    572         document.body.firstChild.nextSibling.firstChild], // text in <b>
    573        "Initialized with range selecting '[abc<b>de]f'");
    574  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    575                         range.startContainer, range.startOffset,
    576                         range.endContainer, range.endOffset);
    577  check(iter,
    578        [document.body.firstChild, // text before <b>
    579         document.body.firstChild.nextSibling, // <b>
    580         document.body.firstChild.nextSibling.firstChild], // text in <b>
    581        "Initialized with positions selecting '[abc<b>de]f'");
    582 
    583  range.setStart(document.body.firstChild, 2);
    584  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    585  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    586  check(iter,
    587        [document.body.firstChild, // text before <b>
    588         document.body.firstChild.nextSibling, // <b>
    589         document.body.firstChild.nextSibling.firstChild], // text in <b>
    590        "Initialized with range selecting 'ab[c<b>de]f'");
    591  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    592                         range.startContainer, range.startOffset,
    593                         range.endContainer, range.endOffset);
    594  check(iter,
    595        [document.body.firstChild, // text before <b>
    596         document.body.firstChild.nextSibling, // <b>
    597         document.body.firstChild.nextSibling.firstChild], // text in <b>
    598        "Initialized with positions selecting 'ab[c<b>de]f'");
    599 
    600  range.setStart(document.body.firstChild, 3);
    601  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    602  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    603  check(iter,
    604        [document.body.firstChild, // text before <b>
    605         document.body.firstChild.nextSibling, // <b>
    606         document.body.firstChild.nextSibling.firstChild], // text in <b>
    607        "Initialized with range selecting 'abc[<b>de]f'");
    608  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    609                         range.startContainer, range.startOffset,
    610                         range.endContainer, range.endOffset);
    611  check(iter,
    612        [document.body.firstChild, // text before <b>
    613         document.body.firstChild.nextSibling, // <b>
    614         document.body.firstChild.nextSibling.firstChild], // text in <b>
    615        "Initialized with positions selecting 'abc[<b>de]f'");
    616 
    617  range.setStart(document.body, 1);
    618  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    619  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    620  check(iter,
    621        [document.body.firstChild.nextSibling, // <b>
    622         document.body.firstChild.nextSibling.firstChild], // text in <b>
    623        "Initialized with range selecting 'abc{<b>de]f'");
    624  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    625                         range.startContainer, range.startOffset,
    626                         range.endContainer, range.endOffset);
    627  check(iter,
    628        [document.body.firstChild.nextSibling, // <b>
    629         document.body.firstChild.nextSibling.firstChild], // text in <b>
    630        "Initialized with positions selecting 'abc{<b>de]f'");
    631 
    632  range.setStart(document.body.firstChild.nextSibling, 0);
    633  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    634  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    635  check(iter,
    636        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    637        "Initialized with range selecting '<b>{de]f'");
    638  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    639                         range.startContainer, range.startOffset,
    640                         range.endContainer, range.endOffset);
    641  check(iter,
    642        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    643        "Initialized with positions selecting '<b>{de]f'");
    644 
    645  range.setStart(document.body.firstChild.nextSibling, 0);
    646  range.setEnd(document.body.firstChild.nextSibling.firstChild, 3);
    647  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    648  check(iter,
    649        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    650        "Initialized with range selecting '<b>{def]</b>'");
    651  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    652                         range.startContainer, range.startOffset,
    653                         range.endContainer, range.endOffset);
    654  check(iter,
    655        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    656        "Initialized with positions selecting '<b>{def]</b>'");
    657 
    658  range.setStart(document.body.firstChild.nextSibling, 0);
    659  range.setEnd(document.body.firstChild.nextSibling, 1);
    660  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    661  check(iter,
    662        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    663        "Initialized with range selecting '<b>{def}</b>'");
    664  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    665                         range.startContainer, range.startOffset,
    666                         range.endContainer, range.endOffset);
    667  check(iter,
    668        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    669        "Initialized with positions selecting '<b>{def}</b>'");
    670 
    671  range.setStart(document.body.firstChild.nextSibling, 0);
    672  range.setEnd(document.body, 2);
    673  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    674  check(iter,
    675        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    676        "Initialized with range selecting '<b>{def</b>}<i>ghi'");
    677  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    678                         range.startContainer, range.startOffset,
    679                         range.endContainer, range.endOffset);
    680  check(iter,
    681        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    682        "Initialized with positions selecting '<b>{def</b>}<i>ghi'");
    683 
    684  range.setStart(document.body.firstChild.nextSibling.firstChild, 3);
    685  range.setEnd(document.body, 2);
    686  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    687  check(iter,
    688        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    689        "Initialized with range selecting '<b>def[</b>}<i>ghi'");
    690  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    691                         range.startContainer, range.startOffset,
    692                         range.endContainer, range.endOffset);
    693  check(iter,
    694        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    695        "Initialized with positions selecting '<b>def[</b>}<i>ghi'");
    696 
    697  range.setStart(document.body.firstChild.nextSibling, 1);
    698  range.setEnd(document.body, 2);
    699  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    700  check(iter, [],
    701        "Initialized with range selecting '<b>def{</b>}<i>ghi'");
    702  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    703                         range.startContainer, range.startOffset,
    704                         range.endContainer, range.endOffset);
    705  check(iter, [],
    706        "Initialized with positions selecting '<b>def{</b>}<i>ghi'");
    707 
    708  range.setStart(document.body.firstChild.nextSibling, 1);
    709  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    710  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    711  check(iter,
    712        [document.body.firstChild.nextSibling.nextSibling], // <i>
    713        "Initialized with range selecting '<b>def{</b><i>}ghi'");
    714  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    715                         range.startContainer, range.startOffset,
    716                         range.endContainer, range.endOffset);
    717  check(iter,
    718        [document.body.firstChild.nextSibling.nextSibling], // <i>
    719        "Initialized with positions selecting '<b>def{</b><i>}ghi'");
    720 
    721  range.setStart(document.body.firstChild.nextSibling, 1);
    722  range.setEnd(document.body.firstChild.nextSibling.nextSibling.firstChild, 0);
    723  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    724  check(iter,
    725        [document.body.firstChild.nextSibling.nextSibling, // <i>
    726         document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    727        "Initialized with range selecting '<b>def{</b><i>]ghi'");
    728  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    729                         range.startContainer, range.startOffset,
    730                         range.endContainer, range.endOffset);
    731  check(iter,
    732        [document.body.firstChild.nextSibling.nextSibling, // <i>
    733         document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    734        "Initialized with positions selecting '<b>def{</b><i>]ghi'");
    735 
    736  range.setStart(document.body.firstChild.nextSibling.nextSibling, 0);
    737  range.setEnd(document.body, 3);
    738  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    739  check(iter,
    740        [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    741        "Initialized with range selecting '<i>{ghi</i>}jkl'");
    742  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    743                         range.startContainer, range.startOffset,
    744                         range.endContainer, range.endOffset);
    745  check(iter,
    746        [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    747        "Initialized with positions selecting '<i>{ghi</i>}jkl'");
    748 
    749  range.setStart(document.body.firstChild.nextSibling.nextSibling.firstChild, 3);
    750  range.setEnd(document.body, 3);
    751  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    752  check(iter,
    753        [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    754        "Initialized with range selecting '<i>ghi[</i>}jkl'");
    755  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    756                         range.startContainer, range.startOffset,
    757                         range.endContainer, range.endOffset);
    758  check(iter,
    759        [document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    760        "Initialized with positions selecting '<i>ghi[</i>}jkl'");
    761 
    762  range.setStart(document.body.firstChild.nextSibling.nextSibling, 1);
    763  range.setEnd(document.body, 3);
    764  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    765  check(iter, [],
    766        "Initialized with range selecting '<i>ghi{</i>}jkl'");
    767  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    768                         range.startContainer, range.startOffset,
    769                         range.endContainer, range.endOffset);
    770  check(iter, [],
    771        "Initialized with positions selecting '<i>ghi{</i>}jkl'");
    772 
    773  range.setStart(document.body.firstChild.nextSibling.nextSibling, 1);
    774  range.setEnd(document.body.firstChild.nextSibling.nextSibling.nextSibling, 0);
    775  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    776  check(iter,
    777        [document.body.firstChild.nextSibling.nextSibling.nextSibling], // text after <i>
    778        "Initialized with range selecting '<i>ghi{</i>]jkl'");
    779  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    780                         range.startContainer, range.startOffset,
    781                         range.endContainer, range.endOffset);
    782  check(iter,
    783        [document.body.firstChild.nextSibling.nextSibling.nextSibling], // text after <i>
    784        "Initialized with positions selecting '<i>ghi{</i>]jkl'");
    785 
    786  /**
    787   * range/positions around <br> elements.
    788   */
    789  document.body.innerHTML = "abc<br>def";
    790  range = document.createRange();
    791  range.setStart(document.body.firstChild, 3);
    792  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    793  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    794  check(iter,
    795        [document.body.firstChild, // text before <br>
    796         document.body.firstChild.nextSibling, // <br>
    797         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    798        "Initialized with range selecting 'abc[<br>]def'");
    799  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    800                         range.startContainer, range.startOffset,
    801                         range.endContainer, range.endOffset);
    802  check(iter,
    803        [document.body.firstChild, // text before <br>
    804         document.body.firstChild.nextSibling, // <br>
    805         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    806        "Initialized with positions selecting 'abc[<br>]def'");
    807 
    808  range.setStart(document.body, 1);
    809  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    810  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    811  check(iter,
    812        [document.body.firstChild.nextSibling, // <br>
    813         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    814        "Initialized with range selecting 'abc{<br>]def'");
    815  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    816                         range.startContainer, range.startOffset,
    817                         range.endContainer, range.endOffset);
    818  check(iter,
    819        [document.body.firstChild.nextSibling, // <br>
    820         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    821        "Initialized with positions selecting 'abc{<br>]def'");
    822 
    823  range.setStart(document.body.firstChild.nextSibling, 0);
    824  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    825  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    826  check(iter,
    827        [document.body.firstChild.nextSibling, // <br>
    828         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    829        "Initialized with range selecting 'abc{<br>]def' (starting in <br>)");
    830  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    831                         range.startContainer, range.startOffset,
    832                         range.endContainer, range.endOffset);
    833  check(iter,
    834        [document.body.firstChild.nextSibling, // <br>
    835         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    836        "Initialized with positions selecting 'abc{<br>]def' (starting in <br>)");
    837 
    838  range.setStart(document.body, 1);
    839  range.setEnd(document.body, 2);
    840  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    841  check(iter,
    842        [document.body.firstChild.nextSibling], // <br>
    843        "Initialized with range selecting 'abc{<br>}def'");
    844  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    845                         range.startContainer, range.startOffset,
    846                         range.endContainer, range.endOffset);
    847  check(iter,
    848        [document.body.firstChild.nextSibling], // <br>
    849        "Initialized with positions selecting 'abc{<br>}def'");
    850 
    851  range.setStart(document.body.firstChild, 3);
    852  range.setEnd(document.body.firstChild.nextSibling, 0);
    853  iter.initWithRange(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR, range);
    854  check(iter,
    855        [document.body.firstChild], // text before <br>
    856        "Initialized with range selecting 'abc[}<br>def' (ending in <br>)");
    857  iter.initWithPositions(Ci.nsIScriptableContentIterator.PRE_ORDER_ITERATOR,
    858                         range.startContainer, range.startOffset,
    859                         range.endContainer, range.endOffset);
    860  check(iter,
    861        [document.body.firstChild], // text before <br>
    862        "Initialized with positions selecting 'abc[}<br>def' (ending in <br>)");
    863 
    864  finish();
    865 });
    866 </script>
    867 </head>
    868 <body></body>
    869 </html>