tor-browser

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

test_content_iterator_post_order.html (48719B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4  <meta charset="utf-8">
      5  <title>Test for post-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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_ORDER_ITERATOR,
    300                         range.startContainer, range.startOffset,
    301                         range.endContainer, range.endOffset);
    302  is(SpecialPowers.unwrap(iter.currentNode), document.body.firstChild.firstChild,
    303    `${description} currentNode should be the text node 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.firstChild,
    308    `${description} currentNode should be the text node 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,
    313    `${description} currentNode should be the <div> element 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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_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.POST_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.firstChild.firstChild, // the first text node
    502     document.body.firstChild.firstChild.nextSibling.firstChild, // text in <b>
    503     document.body.firstChild.firstChild.nextSibling, // <b>
    504     document.body.firstChild.firstChild.nextSibling.nextSibling, // text next to <b>
    505     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild.firstChild, // text in <u>
    506     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild, // <u>
    507     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.firstChild.nextSibling, // text next to <u>
    508     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling, // <i>
    509     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.firstChild, // text in <span>
    510     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling, // <span>
    511     document.body.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <span>
    512     document.body.firstChild, // first <p>
    513     document.body.firstChild.nextSibling.firstChild, // the first text node in second <p>
    514     document.body.firstChild.nextSibling.firstChild.nextSibling, // <input>
    515     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling, // <br> next to <input>
    516     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling, // text next to <input>
    517     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.firstChild, // text in <textarea>
    518     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling, // <textarea>
    519     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <textarea>
    520     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // <br> next to <br>
    521     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // text next to <br>
    522     document.body.firstChild.nextSibling.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling, // comment
    523     document.body.firstChild.nextSibling, // second <p>
    524     document.body]; // <body>
    525 
    526  iter.initWithRootNode(Ci.nsIScriptableContentIterator.POST_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.POST_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.POST_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.pop(); // <body> shouldn't be listed up.
    548  range = document.createRange();
    549  range.selectNodeContents(document.body);
    550  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_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.POST_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.POST_ORDER_ITERATOR, range);
    569  check(iter,
    570        [document.body.firstChild, // text before <b>
    571         document.body.firstChild.nextSibling.firstChild], // text in <b>
    572        "Initialized with range selecting '[abc<b>de]f'");
    573  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    574                         range.startContainer, range.startOffset,
    575                         range.endContainer, range.endOffset);
    576  check(iter,
    577        [document.body.firstChild, // text before <b>
    578         document.body.firstChild.nextSibling.firstChild], // text in <b>
    579        "Initialized with positions selecting '[abc<b>de]f'");
    580 
    581  range.setStart(document.body.firstChild, 2);
    582  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    583  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    584  check(iter,
    585        [document.body.firstChild, // text before <b>
    586         document.body.firstChild.nextSibling.firstChild], // text in <b>
    587        "Initialized with range selecting 'ab[c<b>de]f'");
    588  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    589                         range.startContainer, range.startOffset,
    590                         range.endContainer, range.endOffset);
    591  check(iter,
    592        [document.body.firstChild, // text before <b>
    593         document.body.firstChild.nextSibling.firstChild], // text in <b>
    594        "Initialized with positions selecting 'ab[c<b>de]f'");
    595 
    596  range.setStart(document.body.firstChild, 3);
    597  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    598  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    599  check(iter,
    600        [document.body.firstChild, // text before <b>
    601         document.body.firstChild.nextSibling.firstChild], // text in <b>
    602        "Initialized with range selecting 'abc[<b>de]f'");
    603  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    604                         range.startContainer, range.startOffset,
    605                         range.endContainer, range.endOffset);
    606  check(iter,
    607        [document.body.firstChild, // text before <b>
    608         document.body.firstChild.nextSibling.firstChild], // text in <b>
    609        "Initialized with positions selecting 'abc[<b>de]f'");
    610 
    611  range.setStart(document.body, 1);
    612  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    613  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    614  check(iter,
    615        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    616        "Initialized with range selecting 'abc{<b>de]f'");
    617  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    618                         range.startContainer, range.startOffset,
    619                         range.endContainer, range.endOffset);
    620  check(iter,
    621        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    622        "Initialized with positions selecting 'abc{<b>de]f'");
    623 
    624  range.setStart(document.body.firstChild.nextSibling, 0);
    625  range.setEnd(document.body.firstChild.nextSibling.firstChild, 2);
    626  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    627  check(iter,
    628        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    629        "Initialized with range selecting '<b>{de]f'");
    630  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    631                         range.startContainer, range.startOffset,
    632                         range.endContainer, range.endOffset);
    633  check(iter,
    634        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    635        "Initialized with positions selecting '<b>{de]f'");
    636 
    637  range.setStart(document.body.firstChild.nextSibling, 0);
    638  range.setEnd(document.body.firstChild.nextSibling.firstChild, 3);
    639  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    640  check(iter,
    641        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    642        "Initialized with range selecting '<b>{def]</b>'");
    643  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    644                         range.startContainer, range.startOffset,
    645                         range.endContainer, range.endOffset);
    646  check(iter,
    647        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    648        "Initialized with positions selecting '<b>{def]</b>'");
    649 
    650  range.setStart(document.body.firstChild.nextSibling, 0);
    651  range.setEnd(document.body.firstChild.nextSibling, 1);
    652  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    653  check(iter,
    654        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    655        "Initialized with range selecting '<b>{def}</b>'");
    656  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    657                         range.startContainer, range.startOffset,
    658                         range.endContainer, range.endOffset);
    659  check(iter,
    660        [document.body.firstChild.nextSibling.firstChild], // text in <b>
    661        "Initialized with positions selecting '<b>{def}</b>'");
    662 
    663  range.setStart(document.body.firstChild.nextSibling, 0);
    664  range.setEnd(document.body, 2);
    665  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    666  check(iter,
    667        [document.body.firstChild.nextSibling.firstChild, // text in <b>
    668         document.body.firstChild.nextSibling], // <b>
    669        "Initialized with range selecting '<b>{def</b>}<i>ghi'");
    670  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    671                         range.startContainer, range.startOffset,
    672                         range.endContainer, range.endOffset);
    673  check(iter,
    674        [document.body.firstChild.nextSibling.firstChild, // text in <b>
    675         document.body.firstChild.nextSibling], // <b>
    676        "Initialized with positions selecting '<b>{def</b>}<i>ghi'");
    677 
    678  range.setStart(document.body.firstChild.nextSibling.firstChild, 3);
    679  range.setEnd(document.body, 2);
    680  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    681  check(iter,
    682        [document.body.firstChild.nextSibling.firstChild, // text in <b>
    683         document.body.firstChild.nextSibling], // <b>
    684        "Initialized with range selecting '<b>def[</b>}<i>ghi'");
    685  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    686                         range.startContainer, range.startOffset,
    687                         range.endContainer, range.endOffset);
    688  check(iter,
    689        [document.body.firstChild.nextSibling.firstChild, // text in <b>
    690         document.body.firstChild.nextSibling], // <b>
    691        "Initialized with positions selecting '<b>def[</b>}<i>ghi'");
    692 
    693  range.setStart(document.body.firstChild.nextSibling, 1);
    694  range.setEnd(document.body, 2);
    695  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    696  check(iter,
    697        [document.body.firstChild.nextSibling], // <b>
    698        "Initialized with range selecting '<b>def{</b>}<i>ghi'");
    699  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    700                         range.startContainer, range.startOffset,
    701                         range.endContainer, range.endOffset);
    702  check(iter,
    703        [document.body.firstChild.nextSibling], // <b>
    704        "Initialized with positions selecting '<b>def{</b>}<i>ghi'");
    705 
    706  range.setStart(document.body.firstChild.nextSibling, 1);
    707  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    708  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    709  check(iter,
    710        [document.body.firstChild.nextSibling], // <b>
    711        "Initialized with range selecting '<b>def{</b><i>}ghi'");
    712  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    713                         range.startContainer, range.startOffset,
    714                         range.endContainer, range.endOffset);
    715  check(iter,
    716        [document.body.firstChild.nextSibling], // <b>
    717        "Initialized with positions selecting '<b>def{</b><i>}ghi'");
    718 
    719  range.setStart(document.body.firstChild.nextSibling, 1);
    720  range.setEnd(document.body.firstChild.nextSibling.nextSibling.firstChild, 0);
    721  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    722  check(iter,
    723        [document.body.firstChild.nextSibling, // <b>
    724         document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    725        "Initialized with range selecting '<b>def{</b><i>]ghi'");
    726  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    727                         range.startContainer, range.startOffset,
    728                         range.endContainer, range.endOffset);
    729  check(iter,
    730        [document.body.firstChild.nextSibling, // <b>
    731         document.body.firstChild.nextSibling.nextSibling.firstChild], // text in <i>
    732        "Initialized with positions selecting '<b>def{</b><i>]ghi'");
    733 
    734  range.setStart(document.body.firstChild.nextSibling.nextSibling, 0);
    735  range.setEnd(document.body, 3);
    736  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    737  check(iter,
    738        [document.body.firstChild.nextSibling.nextSibling.firstChild, // text in <i>
    739         document.body.firstChild.nextSibling.nextSibling], // <i>
    740        "Initialized with range selecting '<i>{ghi</i>}jkl'");
    741  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    742                         range.startContainer, range.startOffset,
    743                         range.endContainer, range.endOffset);
    744  check(iter,
    745        [document.body.firstChild.nextSibling.nextSibling.firstChild, // text in <i>
    746         document.body.firstChild.nextSibling.nextSibling], // <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.POST_ORDER_ITERATOR, range);
    752  check(iter,
    753        [document.body.firstChild.nextSibling.nextSibling.firstChild, // text in <i>
    754         document.body.firstChild.nextSibling.nextSibling], // <i>
    755        "Initialized with range selecting '<i>ghi[</i>}jkl'");
    756  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    757                         range.startContainer, range.startOffset,
    758                         range.endContainer, range.endOffset);
    759  check(iter,
    760        [document.body.firstChild.nextSibling.nextSibling.firstChild, // text in <i>
    761         document.body.firstChild.nextSibling.nextSibling], // <i>
    762        "Initialized with positions selecting '<i>ghi[</i>}jkl'");
    763 
    764  range.setStart(document.body.firstChild.nextSibling.nextSibling, 1);
    765  range.setEnd(document.body, 3);
    766  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    767  check(iter,
    768        [document.body.firstChild.nextSibling.nextSibling], // <i>
    769        "Initialized with range selecting '<i>ghi{</i>}jkl'");
    770  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    771                         range.startContainer, range.startOffset,
    772                         range.endContainer, range.endOffset);
    773  check(iter,
    774        [document.body.firstChild.nextSibling.nextSibling], // <i>
    775        "Initialized with positions selecting '<i>ghi{</i>}jkl'");
    776 
    777  range.setStart(document.body.firstChild.nextSibling.nextSibling, 1);
    778  range.setEnd(document.body.firstChild.nextSibling.nextSibling.nextSibling, 0);
    779  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    780  check(iter,
    781        [document.body.firstChild.nextSibling.nextSibling, // <i>
    782         document.body.firstChild.nextSibling.nextSibling.nextSibling], // text after <i>
    783        "Initialized with range selecting '<i>ghi{</i>]jkl'");
    784  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    785                         range.startContainer, range.startOffset,
    786                         range.endContainer, range.endOffset);
    787  check(iter,
    788        [document.body.firstChild.nextSibling.nextSibling, // <i>
    789         document.body.firstChild.nextSibling.nextSibling.nextSibling], // text after <i>
    790        "Initialized with positions selecting '<i>ghi{</i>]jkl'");
    791 
    792  /**
    793   * range/positions around <br> elements.
    794   */
    795  document.body.innerHTML = "abc<br>def";
    796  range = document.createRange();
    797  range.setStart(document.body.firstChild, 3);
    798  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    799  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    800  check(iter,
    801        [document.body.firstChild, // text before <br>
    802         document.body.firstChild.nextSibling, // <br>
    803         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    804        "Initialized with range selecting 'abc[<br>]def'");
    805  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    806                         range.startContainer, range.startOffset,
    807                         range.endContainer, range.endOffset);
    808  check(iter,
    809        [document.body.firstChild, // text before <br>
    810         document.body.firstChild.nextSibling, // <br>
    811         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    812        "Initialized with positions selecting 'abc[<br>]def'");
    813 
    814  range.setStart(document.body, 1);
    815  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    816  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    817  check(iter,
    818        [document.body.firstChild.nextSibling, // <br>
    819         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    820        "Initialized with range selecting 'abc{<br>]def'");
    821  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    822                         range.startContainer, range.startOffset,
    823                         range.endContainer, range.endOffset);
    824  check(iter,
    825        [document.body.firstChild.nextSibling, // <br>
    826         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    827        "Initialized with positions selecting 'abc{<br>]def'");
    828 
    829  range.setStart(document.body.firstChild.nextSibling, 0);
    830  range.setEnd(document.body.firstChild.nextSibling.nextSibling, 0);
    831  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    832  check(iter,
    833        [document.body.firstChild.nextSibling, // <br>
    834         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    835        "Initialized with range selecting 'abc{<br>]def' (starting in <br>)");
    836  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    837                         range.startContainer, range.startOffset,
    838                         range.endContainer, range.endOffset);
    839  check(iter,
    840        [document.body.firstChild.nextSibling, // <br>
    841         document.body.firstChild.nextSibling.nextSibling], // text after <br>
    842        "Initialized with positions selecting 'abc{<br>]def' (starting in <br>)");
    843 
    844  range.setStart(document.body, 1);
    845  range.setEnd(document.body, 2);
    846  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    847  check(iter,
    848        [document.body.firstChild.nextSibling], // <br>
    849        "Initialized with range selecting 'abc{<br>}def'");
    850  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    851                         range.startContainer, range.startOffset,
    852                         range.endContainer, range.endOffset);
    853  check(iter,
    854        [document.body.firstChild.nextSibling], // <br>
    855        "Initialized with positions selecting 'abc{<br>}def'");
    856 
    857  range.setStart(document.body.firstChild, 3);
    858  range.setEnd(document.body.firstChild.nextSibling, 0);
    859  iter.initWithRange(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR, range);
    860  check(iter,
    861        [document.body.firstChild], // text before <br>
    862        "Initialized with range selecting 'abc[}<br>def' (ending in <br>)");
    863  iter.initWithPositions(Ci.nsIScriptableContentIterator.POST_ORDER_ITERATOR,
    864                         range.startContainer, range.startOffset,
    865                         range.endContainer, range.endOffset);
    866  check(iter,
    867        [document.body.firstChild], // text before <br>
    868        "Initialized with positions selecting 'abc[}<br>def' (ending in <br>)");
    869 
    870  finish();
    871 });
    872 </script>
    873 </head>
    874 <body></body>
    875 </html>