text: <!DOCTYPE html>
  <html>
  <!--
  Copyright 2008 The Closure Library Authors. All Rights Reserved.
  
  Use of this source code is governed by the Apache License, Version 2.0.
  See the COPYING file for details.
  -->
  <head>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>goog.dom.TagIterator Tests</title>
  <script src="../base.js"></script>
  <script>
    goog.require('goog.testing.dom');
    goog.require('goog.testing.jsunit');
    goog.require('goog.dom.TagIterator');
  </script>
  </head>
  <body>
  
  <div id="test"><a href="#">T<b>e</b>xt</a><span></span><p>Text</p></div>
  <ul id="test2"><li>Not<li>Closed</ul>
  <div id="test3">text</div>
  <div id="testSplice"></div>
  
  <script>
    var it;
    var pos;
  
    function assertStartTag(type) {
      assertEquals('Position ' + pos + ' should be start tag',
          goog.dom.TagWalkType.START_TAG, it.tagType);
      assertTrue('isStartTag should return true', it.isStartTag());
      assertFalse('isEndTag should return false', it.isEndTag());
      assertFalse('isNonElement should return false', it.isNonElement());
      assertEquals('Position ' + pos + ' should be ' + type, type,
          it.node.tagName);
    }
  
    function assertEndTag(type) {
      assertEquals('Position ' + pos + ' should be end tag',
          goog.dom.TagWalkType.END_TAG, it.tagType);
      assertFalse('isStartTag should return false', it.isStartTag());
      assertTrue('isEndTag should return true', it.isEndTag());
      assertFalse('isNonElement should return false', it.isNonElement());
      assertEquals('Position ' + pos + ' should be ' + type, type,
          it.node.tagName);
    }
  
    function assertTextNode(value) {
      assertEquals('Position ' + pos + ' should be text node',
          goog.dom.TagWalkType.OTHER, it.tagType);
      assertFalse('isStartTag should return false', it.isStartTag());
      assertFalse('isEndTag should return false', it.isEndTag());
      assertTrue('isNonElement should return true', it.isNonElement());
      assertEquals('Position ' + pos + ' should be "' + value + '"', value,
          it.node.nodeValue);
    }
  
    function testBasicHTML() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test'));
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertStartTag('A');
            break;
          case 3:
            assertTextNode('T');
            break;
          case 4:
            assertStartTag('B');
            assertEquals('Depth at <B> should be 3', 3, it.depth);
            break;
          case 5:
            assertTextNode('e');
            break;
          case 6:
            assertEndTag('B');
            break;
          case 7:
            assertTextNode('xt');
            break;
          case 8:
            assertEndTag('A');
            break;
          case 9:
            assertStartTag('SPAN');
            break;
          case 10:
            assertEndTag('SPAN');
            break;
          case 11:
            assertStartTag('P');
            break;
          case 12:
            assertTextNode('Text');
            break;
          case 13:
            assertEndTag('P');
            break;
          case 14:
            assertEndTag('DIV');
            assertEquals('Depth at end should be 0', 0, it.depth);
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
    function testSkipTag() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test'));
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertStartTag('A');
            it.skipTag();
            break;
          case 3:
            assertStartTag('SPAN');
            break;
          case 4:
            assertEndTag('SPAN');
            break;
          case 5:
            assertStartTag('P');
            break;
          case 6:
            assertTextNode('Text');
            break;
          case 7:
            assertEndTag('P');
            break;
          case 8:
            assertEndTag('DIV');
            assertEquals('Depth at end should be 0', 0, it.depth);
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
    function testRestartTag() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test'));
      pos = 0;
      var done = false;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertStartTag('A');
            it.skipTag();
            break;
          case 3:
            assertStartTag('SPAN');
            break;
          case 4:
            assertEndTag('SPAN');
            break;
          case 5:
            assertStartTag('P');
            break;
          case 6:
            assertTextNode('Text');
            break;
          case 7:
            assertEndTag('P');
            break;
          case 8:
            assertEndTag('DIV');
            assertEquals('Depth at end should be 0', 0, it.depth);
  
            // Do them all again, starting after this element.
            if (!done) {
              pos = 1;
              it.restartTag();
              done = true;
            }
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
  
    function testSkipTagReverse() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test'), true);
      pos = 9;
  
      goog.iter.forEach(it, function() {
        pos--;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            assertEquals('Depth at end should be 0', 0, it.depth);
            break;
          case 2:
            assertEndTag('A');
            it.skipTag();
            break;
          case 3:
            assertStartTag('SPAN');
            break;
          case 4:
            assertEndTag('SPAN');
            break;
          case 5:
            assertStartTag('P');
            break;
          case 6:
            assertTextNode('Text');
            break;
          case 7:
            assertEndTag('P');
            break;
          case 8:
            assertEndTag('DIV');
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
  
    function testUnclosedLI() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test2'));
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('UL');
            break;
          case 2:
            assertStartTag('LI');
            assertEquals('Depth at <LI> should be 2', 2, it.depth);
            break;
          case 3:
            assertTextNode('Not');
            break;
          case 4:
            assertEndTag('LI');
            break;
          case 5:
            assertStartTag('LI');
            assertEquals('Depth at second <LI> should be 2', 2, it.depth);
            break;
          case 6:
            assertTextNode('Closed');
            break;
          case 7:
            assertEndTag('LI');
            break;
          case 8:
            assertEndTag('UL');
            assertEquals('Depth at end should be 0', 0, it.depth);
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
    function testReversedUnclosedLI() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test2'), true);
      pos = 9;
  
      goog.iter.forEach(it, function() {
        pos--;
        switch (pos) {
          case 1:
            assertStartTag('UL');
            assertEquals('Depth at start should be 0', 0, it.depth);
            break;
          case 2:
            assertStartTag('LI');
            break;
          case 3:
            assertTextNode('Not');
            break;
          case 4:
            assertEndTag('LI');
            assertEquals('Depth at <LI> should be 2', 2, it.depth);
            break;
          case 5:
            assertStartTag('LI');
            break;
          case 6:
            assertTextNode('Closed');
            break;
          case 7:
            assertEndTag('LI');
            assertEquals('Depth at second <LI> should be 2', 2, it.depth);            
            break;
          case 8:
            assertEndTag('UL');
            break;
          default:
            throw goog.iter.StopIteration;
        }
      });
    }
  
    function testConstrained() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test3'), false, false);
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertTextNode('text');
            break;
          case 3:
            assertEndTag('DIV');
            break;
        }
      });
  
      assertEquals('Constrained iterator should stop at position 3.', 3, pos);
    }
  
    function testUnconstrained() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test3'), false, true);
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertTextNode('text');
            break;
          case 3:
            assertEndTag('DIV');
            break;
        }
      });
  
      assertNotEquals('Unonstrained iterator should not stop at position 3.', 3,
          pos);
    }
  
    function testConstrainedText() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test3').firstChild,
          false, false);
      pos = 0;
  
      goog.iter.forEach(it, function() {
        pos++;
        switch (pos) {
          case 1:
            assertTextNode('text');
            break;
        }
      });
  
      assertEquals('Constrained text iterator should stop at position 1.', 1,
          pos);
    }
  
    function testReverseConstrained() {
      it = new goog.dom.TagIterator(goog.dom.getElement('test3'), true, false);
      pos = 4;
  
      goog.iter.forEach(it, function() {
        pos--;
        switch (pos) {
          case 1:
            assertStartTag('DIV');
            break;
          case 2:
            assertTextNode('text');
            break;
          case 3:
            assertEndTag('DIV');
            break;
        }
      });
  
      assertEquals('Constrained reversed iterator should stop at position 1.', 1,
          pos);
    }
  
    function testSpliceRemoveSingleNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<br/>';
      it = new goog.dom.TagIterator(testDiv.firstChild);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        i.splice();
      });
  
      assertEquals('Node not removed', 0, testDiv.childNodes.length);
    }
  
    function testSpliceRemoveFirstTextNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = 'hello<b>world</b><em>goodbye</em>';
      it = new goog.dom.TagIterator(testDiv.firstChild, false, true);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        if (node.nodeType == 3 && node.data == 'hello') {
          i.splice();
        }
        if (node.nodeName == 'EM') {
          i.splice(goog.dom.createDom('I', null, node.childNodes));
        }
      });
  
      goog.testing.dom.assertHtmlMatches('<b>world</b><i>goodbye</i>',
          testDiv.innerHTML);
    }
  
    function testSpliceReplaceFirstTextNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = 'hello<b>world</b>';
      it = new goog.dom.TagIterator(testDiv.firstChild, false, true);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        if (node.nodeType == 3 && node.data == 'hello') {
          i.splice(goog.dom.createDom('EM', null, 'HELLO'));
        } else if (node.nodeName == 'EM') {
          i.splice(goog.dom.createDom('I', null, node.childNodes));
        }
      });
  
      goog.testing.dom.assertHtmlMatches('<i>HELLO</i><b>world</b>',
          testDiv.innerHTML);
    }
  
    function testSpliceReplaceSingleNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<br/>';
      it = new goog.dom.TagIterator(testDiv.firstChild);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        i.splice(goog.dom.createDom('link'), goog.dom.createDom('img'));
      });
  
      goog.testing.dom.assertHtmlMatches('<link><img>', testDiv.innerHTML);
    }
  
    function testSpliceFlattenSingleNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<div><b>one</b>two<i>three</i></div>';
      it = new goog.dom.TagIterator(testDiv.firstChild);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        i.splice(node.childNodes);
      });
  
      goog.testing.dom.assertHtmlMatches('<b>one</b>two<i>three</i>',
          testDiv.innerHTML);
    }
  
    function testSpliceMiddleNode() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = 'a<b>hello<span>world</span></b>c';
      it = new goog.dom.TagIterator(testDiv);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        if (node.nodeName == 'B') {
          i.splice(goog.dom.createDom('IMG'));
        }
      });
  
      goog.testing.dom.assertHtmlMatches('a<img>c', testDiv.innerHTML);
    }
  
    function testSpliceMiddleNodeReversed() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = 'a<b>hello<span>world</span></b>c';
      it = new goog.dom.TagIterator(testDiv, true);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        if (node.nodeName == 'B') {
          i.splice(goog.dom.createDom('IMG'));
        }
      });
  
      goog.testing.dom.assertHtmlMatches('a<img>c', testDiv.innerHTML);
    }
  
    function testSpliceMiddleNodeAtEndTag() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = 'a<b>hello<span>world</span></b>c';
      it = new goog.dom.TagIterator(testDiv);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        if (node.tagName == 'B' && i.isEndTag()) {
          i.splice(goog.dom.createDom('IMG'));
        }
      });
  
      goog.testing.dom.assertHtmlMatches('a<img>c', testDiv.innerHTML);
    }
  
    function testSpliceMultipleNodes() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<STRONG>this</STRONG> is <EM>from IE</EM>';
      it = new goog.dom.TagIterator(testDiv);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        var replace = null;
        if (node.nodeName == 'STRONG') {
          replace = goog.dom.createDom('B', null, node.childNodes);
        } else if (node.nodeName == 'EM') {
          replace = goog.dom.createDom('I', null, node.childNodes);
        }
        if (replace) {
          i.splice(replace);
        }
      });
  
      goog.testing.dom.assertHtmlMatches('<b>this</b> is <i>from IE</i>',
          testDiv.innerHTML);
    }
  
    function testSpliceMultipleNodesAtEnd() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<STRONG>this</STRONG> is <EM>from IE</EM>';
      it = new goog.dom.TagIterator(testDiv);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        var replace = null;
        if (node.nodeName == 'STRONG' && i.isEndTag()) {
          replace = goog.dom.createDom('B', null, node.childNodes);
        } else if (node.nodeName == 'EM' && i.isEndTag()) {
          replace = goog.dom.createDom('I', null, node.childNodes);
        }
        if (replace) {
          i.splice(replace);
        }
      });
  
      goog.testing.dom.assertHtmlMatches('<b>this</b> is <i>from IE</i>',
          testDiv.innerHTML);
    }
  
    function testSpliceMultipleNodesReversed() {
      var testDiv = goog.dom.getElement('testSplice');
      testDiv.innerHTML = '<STRONG>this</STRONG> is <EM>from IE</EM>';
      it = new goog.dom.TagIterator(testDiv, true);
  
      goog.iter.forEach(it, function(node, dummy, i) {
        var replace = null;
        if (node.nodeName == 'STRONG') {
          replace = goog.dom.createDom('B', null, node.childNodes);
        } else if (node.nodeName == 'EM') {
          replace = goog.dom.createDom('I', null, node.childNodes);
        }
        if (replace) {
          i.splice(replace);
        }
      });
  
      goog.testing.dom.assertHtmlMatches('<b>this</b> is <i>from IE</i>',
          testDiv.innerHTML);
    }
  
  </script>
  </body>
  </html>
  