// Copyright 2008 The Closure Library Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS-IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. goog.provide('goog.dom.TagIteratorTest'); goog.setTestOnly('goog.dom.TagIteratorTest'); goog.require('goog.dom'); goog.require('goog.dom.TagIterator'); goog.require('goog.dom.TagWalkType'); goog.require('goog.iter'); goog.require('goog.iter.StopIteration'); goog.require('goog.testing.dom'); goog.require('goog.testing.jsunit'); 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); }