blob: 6a625c02254176c620f9b0f84a73acf82ad8a509 [file] [log] [blame]
// 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);
}