| // 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); |
| } |