tor-browser

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

NodeIterator.html (7359B)


      1 <!doctype html>
      2 <title>NodeIterator tests</title>
      3 <link rel="author" title="Aryeh Gregor" href=ayg@aryeh.name>
      4 <meta name=timeout content=long>
      5 <div id=log></div>
      6 <script src=/resources/testharness.js></script>
      7 <script src=/resources/testharnessreport.js></script>
      8 <script src=../common.js></script>
      9 <script>
     10 "use strict";
     11 
     12 function check_iter(iter, root, whatToShowValue) {
     13    whatToShowValue = whatToShowValue === undefined ? 0xFFFFFFFF : whatToShowValue;
     14 
     15    assert_equals(iter.toString(), '[object NodeIterator]', 'toString');
     16    assert_equals(iter.root, root, 'root');
     17    assert_equals(iter.whatToShow, whatToShowValue, 'whatToShow');
     18    assert_equals(iter.filter, null, 'filter');
     19    assert_equals(iter.referenceNode, root, 'referenceNode');
     20    assert_equals(iter.pointerBeforeReferenceNode, true, 'pointerBeforeReferenceNode');
     21    assert_readonly(iter, 'root');
     22    assert_readonly(iter, 'whatToShow');
     23    assert_readonly(iter, 'filter');
     24    assert_readonly(iter, 'referenceNode');
     25    assert_readonly(iter, 'pointerBeforeReferenceNode');
     26 }
     27 
     28 test(function() {
     29  var iter = document.createNodeIterator(document);
     30  iter.detach();
     31  iter.detach();
     32 }, "detach() should be a no-op");
     33 
     34 test(function() {
     35  var iter = document.createNodeIterator(document);
     36  check_iter(iter, document);
     37 }, "createNodeIterator() parameter defaults");
     38 
     39 test(function() {
     40  var iter = document.createNodeIterator(document, null, null);
     41  check_iter(iter, document, 0);
     42 }, "createNodeIterator() with null as arguments");
     43 
     44 test(function() {
     45  var iter = document.createNodeIterator(document, undefined, undefined);
     46  check_iter(iter, document);
     47 }, "createNodeIterator() with undefined as arguments");
     48 
     49 test(function() {
     50  var err = {name: "failed"};
     51  var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL,
     52                                         function() { throw err; });
     53  assert_throws_exactly(err, function() { iter.nextNode() });
     54 }, "Propagate exception from filter function");
     55 
     56 test(function() {
     57  var depth = 0;
     58  var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL,
     59    function() {
     60      if (iter.referenceNode != document && depth == 0) {
     61        depth++;
     62        iter.nextNode();
     63      }
     64      return NodeFilter.FILTER_ACCEPT;
     65    });
     66  iter.nextNode();
     67  iter.nextNode();
     68  assert_throws_dom("InvalidStateError", function() { iter.nextNode() });
     69  depth--;
     70  assert_throws_dom("InvalidStateError", function() { iter.previousNode() });
     71 }, "Recursive filters need to throw");
     72 
     73 function testIterator(root, whatToShow, filter) {
     74  var iter = document.createNodeIterator(root, whatToShow, filter);
     75 
     76  assert_equals(iter.root, root, ".root");
     77  assert_equals(iter.referenceNode, root, "Initial .referenceNode");
     78  assert_equals(iter.pointerBeforeReferenceNode, true,
     79                ".pointerBeforeReferenceNode");
     80  assert_equals(iter.whatToShow, whatToShow, ".whatToShow");
     81  assert_equals(iter.filter, filter, ".filter");
     82 
     83  var expectedReferenceNode = root;
     84  var expectedBeforeNode = true;
     85  // "Let node be the value of the referenceNode attribute."
     86  var node = root;
     87  // "Let before node be the value of the pointerBeforeReferenceNode
     88  // attribute."
     89  var beforeNode = true;
     90  var i = 1;
     91  // Each loop iteration runs nextNode() once.
     92  while (node) {
     93    do {
     94      if (!beforeNode) {
     95        // "If before node is false, let node be the first node following node
     96        // in the iterator collection. If there is no such node return null."
     97        node = nextNode(node);
     98        if (!isInclusiveDescendant(node, root)) {
     99          node = null;
    100          break;
    101        }
    102      } else {
    103        // "If before node is true, set it to false."
    104        beforeNode = false;
    105      }
    106      // "Filter node and let result be the return value.
    107      //
    108      // "If result is FILTER_ACCEPT, go to the next step in the overall set of
    109      // steps.
    110      //
    111      // "Otherwise, run these substeps again."
    112      if (!((1 << (node.nodeType - 1)) & whatToShow)
    113          || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) {
    114        continue;
    115      }
    116 
    117      // "Set the referenceNode attribute to node, set the
    118      // pointerBeforeReferenceNode attribute to before node, and return node."
    119      expectedReferenceNode = node;
    120      expectedBeforeNode = beforeNode;
    121 
    122      break;
    123    } while (true);
    124 
    125    assert_equals(iter.nextNode(), node, ".nextNode() " + i + " time(s)");
    126    assert_equals(iter.referenceNode, expectedReferenceNode,
    127                  ".referenceNode after nextNode() " + i + " time(s)");
    128    assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode,
    129             ".pointerBeforeReferenceNode after nextNode() " + i + " time(s)");
    130 
    131    i++;
    132  }
    133 
    134  // Same but for previousNode() (mostly copy-pasted, oh well)
    135  var iter = document.createNodeIterator(root, whatToShow, filter);
    136 
    137  var expectedReferenceNode = root;
    138  var expectedBeforeNode = true;
    139  // "Let node be the value of the referenceNode attribute."
    140  var node = root;
    141  // "Let before node be the value of the pointerBeforeReferenceNode
    142  // attribute."
    143  var beforeNode = true;
    144  var i = 1;
    145  // Each loop iteration runs previousNode() once.
    146  while (node) {
    147    do {
    148      if (beforeNode) {
    149        // "If before node is true, let node be the first node preceding node
    150        // in the iterator collection. If there is no such node return null."
    151        node = previousNode(node);
    152        if (!isInclusiveDescendant(node, root)) {
    153          node = null;
    154          break;
    155        }
    156      } else {
    157        // "If before node is false, set it to true."
    158        beforeNode = true;
    159      }
    160      // "Filter node and let result be the return value.
    161      //
    162      // "If result is FILTER_ACCEPT, go to the next step in the overall set of
    163      // steps.
    164      //
    165      // "Otherwise, run these substeps again."
    166      if (!((1 << (node.nodeType - 1)) & whatToShow)
    167          || (filter && filter(node) != NodeFilter.FILTER_ACCEPT)) {
    168        continue;
    169      }
    170 
    171      // "Set the referenceNode attribute to node, set the
    172      // pointerBeforeReferenceNode attribute to before node, and return node."
    173      expectedReferenceNode = node;
    174      expectedBeforeNode = beforeNode;
    175 
    176      break;
    177    } while (true);
    178 
    179    assert_equals(iter.previousNode(), node, ".previousNode() " + i + " time(s)");
    180    assert_equals(iter.referenceNode, expectedReferenceNode,
    181                  ".referenceNode after previousNode() " + i + " time(s)");
    182    assert_equals(iter.pointerBeforeReferenceNode, expectedBeforeNode,
    183         ".pointerBeforeReferenceNode after previousNode() " + i + " time(s)");
    184 
    185    i++;
    186  }
    187 }
    188 
    189 var whatToShows = [
    190  "0",
    191  "0xFFFFFFFF",
    192  "NodeFilter.SHOW_ELEMENT",
    193  "NodeFilter.SHOW_ATTRIBUTE",
    194  "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT",
    195 ];
    196 
    197 var callbacks = [
    198  "null",
    199  "(function(node) { return true })",
    200  "(function(node) { return false })",
    201  "(function(node) { return node.nodeName[0] == '#' })",
    202 ];
    203 
    204 for (var i = 0; i < testNodes.length; i++) {
    205  for (var j = 0; j < whatToShows.length; j++) {
    206    for (var k = 0; k < callbacks.length; k++) {
    207      test(() => {
    208        testIterator(eval(testNodes[i]), eval(whatToShows[j]), eval(callbacks[k]));
    209      }, "document.createNodeIterator(" + testNodes[i] + ", " + whatToShows[j] + ", " + callbacks[k] + ")");
    210    }
    211  }
    212 }
    213 
    214 testDiv.style.display = "none";
    215 </script>