Commit e4f9a66d authored by darin@apple.com's avatar darin@apple.com

WebCore:

        Reviewed by Eric.

        - fix http://bugs.webkit.org/show_bug.cgi?id=3492
          TreeWalker implementation needs to be fixed (affects Acid3)
        - fix http://bugs.webkit.org/show_bug.cgi?id=4714
          NodeIterator does not handle exceptions from the filter function (affects Acid3)
        - fix http://bugs.webkit.org/show_bug.cgi?id=4716
          NodeIterator will crash if the filter function removes the current node from the document

        Test: traversal/exception-forwarding.html

        This turned into a near-rewrite of NodeIterator and TreeWalker.

        * bindings/js/JSNodeFilterCondition.h:
        * bindings/js/JSNodeFilterCondition.cpp:
        (WebCore::takeException): Added.
        (WebCore::JSNodeFilterCondition::acceptNode): Added an out parameter to return
        a JavaScript exception.

        * bindings/js/JSNodeFilterCustom.cpp:
        (WebCore::JSNodeFilter::acceptNode): Wrote a custom binding for this that raises
        a JavaScript exception if the out parameter is set.

        * bindings/js/JSNodeIteratorCustom.cpp:
        (WebCore::JSNodeIterator::nextNode): Wrote a custom binding for this that raises
        a JavaScript exception if the out parameter is set.
        (WebCore::JSNodeIterator::previousNode): Ditto.

        * bindings/js/JSTreeWalkerCustom.cpp:
        (WebCore::JSTreeWalker::parentNode): Wrote a custom binding for this that raises
        a JavaScript exception if the out parameter is set.
        (WebCore::JSTreeWalker::firstChild): Ditto.
        (WebCore::JSTreeWalker::lastChild): Ditto.
        (WebCore::JSTreeWalker::nextSibling): Ditto.
        (WebCore::JSTreeWalker::previousSibling): Ditto.
        (WebCore::JSTreeWalker::previousNode): Ditto.
        (WebCore::JSTreeWalker::nextNode): Ditto.

        * bindings/objc/DOM.mm:
        (WebCore::ObjCNodeFilterCondition::acceptNode): Updated to include new exception
        out parameter.
        (-[DOMDocument createNodeIterator:whatToShow:filter:expandEntityReferences:]):
        Use RefPtr to make object lifetimes clearer.
        (-[DOMDocument createTreeWalker:whatToShow:filter:expandEntityReferences:]):
        Ditto.

        * bindings/scripts/CodeGeneratorJS.pm: Added include of NodeFilter.h for
        JSDocument.cpp.

        * dom/Document.h:
        * dom/Document.cpp:
        (WebCore::Document::createNodeIterator): Changed to use PassRefPtr.
        (WebCore::Document::createTreeWalker): Ditto.

        * dom/NodeFilter.h:
        * dom/NodeFilter.cpp:
        (WebCore::NodeFilter::NodeFilter): Changed to use PassRefPtr.
        (WebCore::NodeFilter::acceptNode): Added an out parameter to return
        a JavaScript exception.
        * dom/NodeFilter.idl: Custom binding for acceptNode.

        * dom/NodeFilterCondition.h:
        * dom/NodeFilterCondition.cpp:
        (WebCore::NodeFilterCondition::acceptNode): Added an out parameter to return
        a JavaScript exception.

        * dom/NodeIterator.cpp:
        (WebCore::NodeIterator::NodeIterator): Changed to use PassRefPtr more.
        Eliminated m_doc, using the root node instead, and unnecessary check for
        null -- rootNode must be non-null and all nodes have a non-null document.
        (WebCore::NodeIterator::~NodeIterator): Changed to get document from root.
        (WebCore::NodeIterator::nextNode): Rewrote to use a RefPtr since the
        acceptNode function could do anything, including removing the last
        reference to the current node. Also folded findNextNode into this function
        since it's the only one that needs to call it.
        (WebCore::NodeIterator::previousNode): Same thing, but the other direction.
        (WebCore::NodeIterator::detach): Changed to use the root node as the indication
        that we're detached rather than a separate boolean.
        (WebCore::NodeIterator::notifyBeforeNodeRemoval): Removed some unnneeded
        checks. Removed incorrect use of findNextNode/findPreviousNode -- those
        functions call acceptNode and the DOM standard is quite clear that these
        functions do not take that into account, allowing the current node to become
        one that's not accepted.

        * dom/NodeIterator.h: Changed constructor to use PassRefPtr more. Changed
        nextNode and previousNode to have an out parameter with a JavaScript exception.
        Removed helper functions setReferenceNode, setPointerBeforeReferenceNode,
        detached, setDetached, document, findNextNode, and findPreviousNode. All were
        unnecessary. Removed data member m_doc which was just rootNode()->document().

        * dom/NodeIterator.idl: Custom binding for nextNode and previousNode.

        * dom/Traversal.cpp:
        (WebCore::Traversal::Traversal): Use PassRefPtr more.
        (WebCore::Traversal::acceptNode): Added out parameter for JavaScript exception.
        Also rearranged the function a little bit for clarity.

        * dom/Traversal.h: Changed acceptNode to have an out parameter with a JavaScript
        exception and made it protected, since it's only for use by the derived classes.

        * dom/TreeWalker.cpp:
        (WebCore::TreeWalker::TreeWalker): Updated to use PassRefPtr.
        (WebCore::TreeWalker::setCurrentNode): Updated to use PassRefPtr and deleted
        the overloaded version since it's not needed.
        (WebCore::TreeWalker::parentNode): Rewrote to propagate the exception and also
        to implement rules about when to check things like whether we're in the tree.
        The previous fix where we called isDescendantOf was not entirely correct, because
        the specification allows you to walk outside the tree if you get there somehow.
        What it doesn't allow is walking outside the tree from inside. The new
        implementation handles this correctly.
        (WebCore::TreeWalker::firstChild): Ditto.
        (WebCore::TreeWalker::lastChild): Ditto.
        (WebCore::TreeWalker::previousSibling): Ditto.
        (WebCore::TreeWalker::nextSibling): Ditto.
        (WebCore::TreeWalker::previousNode): Ditto. Because of the need to check the
        acceptNode function on parents, this can't use traversePreviousNode (more's the
        pity, because it's a bit complicated).
        (WebCore::TreeWalker::nextNode): Ditto.

        * dom/TreeWalker.h: Changed constructor and setCurrentNode to use PassRefPtr
        more. Changed the navigation functions to have an out parameter with a JavaScript
        exception. Removed helper functions setCurrentNode and ancestorRejected.

        * dom/TreeWalker.idl: Custom binding for navigation functions.

LayoutTests:

        Reviewed by Eric.

        - test for http://bugs.webkit.org/show_bug.cgi?id=4714
          NodeIterator does not handle exceptions from the filter function (affects Acid3)

        - grabbed NodeIterator and TreeWalker tests from Hixie's site and KHTML

        * traversal/exception-forwarding-expected.txt: Added.
        * traversal/exception-forwarding.html: Added.
        * traversal/resources: Added.
        * traversal/resources/TEMPLATE.html: Copied from LayoutTests/fast/js/resources/TEMPLATE.html.
        * traversal/resources/exception-forwarding.js: Added.

        * traversal/node-iterator-001-expected.txt: Updated to reflect correct results.
        The old results reflected a bug in our NodeIterator.
        * traversal/node-iterator-001.html: Ditto.

        * traversal/node-iterator-006.html: Changed test so there's no whitespace node after
        the <span> elements inside the test root element (a <div>). The old test results were
        incorrect; the new NodeIterator implementation correctly returned the whitespace node
        for this test.

        * traversal/node-iterator-006a.html: Copied from traversal/node-iterator-006.html.
        Preserve the original test, which now has a strange result. But the result is correct,
        so it's worth keeping around.
        * traversal/node-iterator-006a-expected.txt: Added.

        * fast/dom/TreeWalker/TreeWalker-currentNode-expected.txt: Regenerated.
        * fast/dom/TreeWalker/resources/TreeWalker-currentNode.js: Updated test to expect results
        that match the DOM specification.

        * traversal/hixie-node-iterator/001-expected.txt: Added.
        * traversal/hixie-node-iterator/001.xml: Added.
        * traversal/hixie-node-iterator/002-expected.txt: Added.
        * traversal/hixie-node-iterator/002.xml: Added.
        * traversal/hixie-node-iterator/003-expected.txt: Added.
        * traversal/hixie-node-iterator/003.xml: Added.
        * traversal/hixie-node-iterator/004-expected.txt: Added.
        * traversal/hixie-node-iterator/004.xml: Added.
        * traversal/hixie-node-iterator/005-expected.txt: Added.
        * traversal/hixie-node-iterator/005.xml: Added.
        * traversal/hixie-node-iterator/006-expected.txt: Added.
        * traversal/hixie-node-iterator/006.xml: Added.
        * traversal/hixie-node-iterator/007-expected.txt: Added.
        * traversal/hixie-node-iterator/007.xml: Added.
        * traversal/hixie-node-iterator/008-expected.txt: Added.
        * traversal/hixie-node-iterator/008.xml: Added.
        * traversal/hixie-node-iterator/009-expected.txt: Added.
        * traversal/hixie-node-iterator/009.xml: Added.
        * traversal/hixie-node-iterator/010-expected.txt: Added.
        * traversal/hixie-node-iterator/010.xml: Added.
        * traversal/hixie-node-iterator/origin.txt: Added.

        * traversal/tree-walker-filter-1-expected.txt: Added.
        * traversal/tree-walker-filter-1.html: Added.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@30089 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 62f0c4ab
2008-02-08 Darin Adler <darin@apple.com>
Reviewed by Eric.
- test for http://bugs.webkit.org/show_bug.cgi?id=4714
NodeIterator does not handle exceptions from the filter function (affects Acid3)
- grabbed NodeIterator and TreeWalker tests from Hixie's site and KHTML
* traversal/exception-forwarding-expected.txt: Added.
* traversal/exception-forwarding.html: Added.
* traversal/resources: Added.
* traversal/resources/TEMPLATE.html: Copied from LayoutTests/fast/js/resources/TEMPLATE.html.
* traversal/resources/exception-forwarding.js: Added.
* traversal/node-iterator-001-expected.txt: Updated to reflect correct results.
The old results reflected a bug in our NodeIterator.
* traversal/node-iterator-001.html: Ditto.
* traversal/node-iterator-006.html: Changed test so there's no whitespace node after
the <span> elements inside the test root element (a <div>). The old test results were
incorrect; the new NodeIterator implementation correctly returned the whitespace node
for this test.
* traversal/node-iterator-006a.html: Copied from traversal/node-iterator-006.html.
Preserve the original test, which now has a strange result. But the result is correct,
so it's worth keeping around.
* traversal/node-iterator-006a-expected.txt: Added.
* fast/dom/TreeWalker/TreeWalker-currentNode-expected.txt: Regenerated.
* fast/dom/TreeWalker/resources/TreeWalker-currentNode.js: Updated test to expect results
that match the DOM specification.
* traversal/hixie-node-iterator/001-expected.txt: Added.
* traversal/hixie-node-iterator/001.xml: Added.
* traversal/hixie-node-iterator/002-expected.txt: Added.
* traversal/hixie-node-iterator/002.xml: Added.
* traversal/hixie-node-iterator/003-expected.txt: Added.
* traversal/hixie-node-iterator/003.xml: Added.
* traversal/hixie-node-iterator/004-expected.txt: Added.
* traversal/hixie-node-iterator/004.xml: Added.
* traversal/hixie-node-iterator/005-expected.txt: Added.
* traversal/hixie-node-iterator/005.xml: Added.
* traversal/hixie-node-iterator/006-expected.txt: Added.
* traversal/hixie-node-iterator/006.xml: Added.
* traversal/hixie-node-iterator/007-expected.txt: Added.
* traversal/hixie-node-iterator/007.xml: Added.
* traversal/hixie-node-iterator/008-expected.txt: Added.
* traversal/hixie-node-iterator/008.xml: Added.
* traversal/hixie-node-iterator/009-expected.txt: Added.
* traversal/hixie-node-iterator/009.xml: Added.
* traversal/hixie-node-iterator/010-expected.txt: Added.
* traversal/hixie-node-iterator/010.xml: Added.
* traversal/hixie-node-iterator/origin.txt: Added.
* traversal/tree-walker-filter-1-expected.txt: Added.
* traversal/tree-walker-filter-1.html: Added.
2008-02-08 Eric Seidel <eric@webkit.org>
Reviewed by darin.
......@@ -13,14 +13,14 @@ Test that we handle setting the currentNode to arbitrary nodes not under the roo
PASS w.parentNode() is null
PASS w.currentNode is document.documentElement
PASS w.nextNode() is null
PASS w.currentNode is document.documentElement
PASS w.nextNode() is document.documentElement.firstChild
PASS w.currentNode is document.documentElement.firstChild
PASS w.previousNode() is null
PASS w.currentNode is document.documentElement
PASS w.firstChild() is null
PASS w.currentNode is document.documentElement
PASS w.lastChild() is null
PASS w.currentNode is document.documentElement
PASS w.firstChild() is document.documentElement.firstChild
PASS w.currentNode is document.documentElement.firstChild
PASS w.lastChild() is document.documentElement.lastChild
PASS w.currentNode is document.documentElement.lastChild
PASS w.nextSibling() is null
PASS w.currentNode is document.documentElement
PASS w.previousSibling() is null
......
......@@ -21,16 +21,22 @@ debug("");
w.currentNode = document.documentElement;
shouldBeNull("w.parentNode()");
shouldBe("w.currentNode", "document.documentElement");
shouldBeNull("w.nextNode()");
shouldBe("w.currentNode", "document.documentElement");
w.currentNode = document.documentElement;
shouldBe("w.nextNode()", "document.documentElement.firstChild");
shouldBe("w.currentNode", "document.documentElement.firstChild");
w.currentNode = document.documentElement;
shouldBeNull("w.previousNode()");
shouldBe("w.currentNode", "document.documentElement");
shouldBeNull("w.firstChild()");
shouldBe("w.currentNode", "document.documentElement");
shouldBeNull("w.lastChild()");
shouldBe("w.currentNode", "document.documentElement");
w.currentNode = document.documentElement;
shouldBe("w.firstChild()", "document.documentElement.firstChild");
shouldBe("w.currentNode", "document.documentElement.firstChild");
w.currentNode = document.documentElement;
shouldBe("w.lastChild()", "document.documentElement.lastChild");
shouldBe("w.currentNode", "document.documentElement.lastChild");
w.currentNode = document.documentElement;
shouldBeNull("w.nextSibling()");
shouldBe("w.currentNode", "document.documentElement");
w.currentNode = document.documentElement;
shouldBeNull("w.previousSibling()");
shouldBe("w.currentNode", "document.documentElement");
......@@ -40,7 +46,7 @@ debug("");
w.currentNode = subTree.previousSibling;
shouldBe("w.nextNode()", "subTree");
w.currentNode = document.body
w.currentNode = document.body;
shouldBe("w.lastChild()", "subTree");
// Cleanup
......
Test of exception forwarding for NodeIterator and TreeWalker, derived from an early version of Acid3
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS i.nextNode() threw exception Roses.
PASS i.nextNode() is document.documentElement
PASS i.previousNode() threw exception Roses.
PASS w.nextNode() threw exception Roses.
PASS w.nextNode() is document.documentElement.firstChild
PASS w.previousNode() threw exception Roses.
PASS w.firstChild() threw exception Roses.
PASS w.lastChild() threw exception Roses.
PASS w.nextSibling() threw exception Roses.
PASS w.previousSibling() is null
PASS w.nextSibling() is document.body
PASS w.previousSibling() is document.body.previousSibling
PASS iteration is 11
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="../fast/js/resources/js-test-style.css">
<script src="../fast/js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="resources/exception-forwarding.js"></script>
<script src="../fast/js/resources/js-test-post.js"></script>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Basics</title>
<script type="text/javascript"> <![CDATA[
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);
var expected = new Array(9, // document
1, // html
3, 1, // head
3, 1, 3, // title
3, 1, 3, 4, // script and CDATA block
3, 3, 1, // body
3, 1, 3, // pre
3, // </body>
3, 8, // <!-- -->
3, 7, // <? ?>,
3, 4, 3); // CDATA
var found = new Array();
// walk document
var node;
while (node = iterator.nextNode())
found.push(node.nodeType);
// check results
var errors = 0;
var s = '';
var length = (found.length > expected.length) ? found.length : expected.length;
s += 'EXPECTED FOUND\n';
for (var i = 0; i < length; i += 1) {
s += ' ' + (expected[i] ? expected[i] : '-') +
' ' + (found[i] ? found[i] : '-');
if (found[i] != expected[i]) {
s += ' MISMATCH';
errors += 1;
}
s += '\n';
}
var p = document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'pre')[0];
if (errors)
p.firstChild.data = 'FAIL: ' + errors + ' errors found:\n\n' + s;
else
p.firstChild.data = 'PASS';
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script failed to run.</pre>
</body>
<!-- some more nodes to test this: -->
<?test node?>
<![CDATA[ ]]>
</html>
\ No newline at end of file
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Basics Backwards</title>
<script type="text/javascript"> <![CDATA[
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document, NodeFilter.SHOW_ALL, null, false);
var expected = new Array(9, // document
1, // html
3, 1, // head
3, 1, 3, // title
3, 1, 3, 4, // script and CDATA block
3, 3, 1, // body
3, 1, 3, // pre
3, // </body>
3, 8, // <!-- -->
3, 7, // <? ?>,
3, 4, 3); // CDATA
var found = new Array();
// walk document
var node;
while (node = iterator.nextNode());
while (node = iterator.previousNode())
found.unshift(node.nodeType);
// check results
var errors = 0;
var s = '';
var length = (found.length > expected.length) ? found.length : expected.length;
s += 'EXPECTED FOUND\n';
for (var i = 0; i < length; i += 1) {
s += ' ' + (expected[i] ? expected[i] : '-') +
' ' + (found[i] ? found[i] : '-');
if (found[i] != expected[i]) {
s += ' MISMATCH';
errors += 1;
}
s += '\n';
}
var p = document.getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'pre')[0];
if (errors)
p.firstChild.data = 'FAIL: ' + errors + ' errors found:\n\n' + s;
else
p.firstChild.data = 'PASS';
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script failed to run.</pre>
</body>
<!-- some more nodes to test this: -->
<?test node?>
<![CDATA[ ]]>
</html>
\ No newline at end of file
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of nodes that should have no effect</title>
<!--
This tests these cases that should have no effect:
1. Remove a node unrelated to the reference node
2. Remove an ancestor of the root node
3. Remove the root node itself
4. Remove descendant of reference node
-->
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var B = document.getElementById('B');
var C = document.getElementById('C');
var D = document.getElementById('D');
var E = document.getElementById('E');
check(iterator.nextNode(), root);
remove(document.getElementById('X'));
check(iterator.nextNode(), A);
remove(document.getElementById('Y'));
check(iterator.nextNode(), B);
remove(root);
check(iterator.nextNode(), C);
remove(E);
check(iterator.nextNode(), D);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}
}
function remove(a) {
if (!a) {
errors += 1;
log += 'Tried removing null node.\n';
} else
a.parentNode.removeChild(a);
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script did not complete.</pre>
<p><span id="X"></span><span id="Y"><span id="root"><span id="A"><span id="B"><span id="C"><span id="D"><span id="E"></span></span></span></span></span></span></span></p>
</body>
</html>
\ No newline at end of file
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of the Reference Node</title>
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var AA = document.getElementById('AA');
var B = document.getElementById('B');
var C = document.getElementById('C');
check(iterator.nextNode(), root);
check(iterator.nextNode(), A);
check(iterator.nextNode(), AA);
check(iterator.nextNode(), B);
remove(B);
check(iterator.previousNode(), AA);
remove(AA);
check(iterator.nextNode(), C);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}
}
function remove(a) {
if (!a) {
errors += 1;
log += 'Tried removing null node.\n';
} else
a.parentNode.removeChild(a);
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script did not complete.</pre>
<p><span id="root"><span id="A"><span id="AA"></span></span><span id="B"></span><span id="C"><span id="CC"></span></span></span></p>
</body>
</html>
\ No newline at end of file
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of the Reference Node (deep check)</title>
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var AA = document.getElementById('AA');
var B = document.getElementById('B');
var C = document.getElementById('C');
check(iterator.nextNode(), root);
check(iterator.nextNode(), A);
check(iterator.nextNode(), AA);
check(iterator.nextNode(), B);
remove(B);
var X = addChildTo(AA);
check(iterator.nextNode(), X);
check(iterator.previousNode(), X);
remove(X);
var Y = addChildTo(AA);
check(iterator.previousNode(), Y);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}
}
function remove(a) {
if (!a) {
errors += 1;
log += 'Tried removing null node.\n';
} else
a.parentNode.removeChild(a);
}
function addChildTo(a) {
var x = document.createElementNS('http://www.w3.org/1999/xhtml', 'span');
a.appendChild(x);
return x;
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script did not complete.</pre>
<p><span id="root"><span id="A"><span id="AA"></span></span><span id="B"></span><span id="C"><span id="CC"></span></span></span></p>
</body>
</html>
\ No newline at end of file
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (forwards)</title>
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var B = document.getElementById('B');
var BB = document.getElementById('BB');
var C = document.getElementById('C');
check(iterator.nextNode(), root);
check(iterator.nextNode(), A);
check(iterator.nextNode(), B);
check(iterator.nextNode(), BB);
remove(B);
check(iterator.previousNode(), A);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}
}
function remove(a) {
if (!a) {
errors += 1;
log += 'Tried removing null node.\n';
} else
a.parentNode.removeChild(a);
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script did not complete.</pre>
<p><span id="root"><span id="A"></span><span id="B"><span id="BB"></span></span><span id="C"></span></span></p>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (forwards) (deep check)</title>
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var B = document.getElementById('B');
var BB = document.getElementById('BB');
var C = document.getElementById('C');
check(iterator.nextNode(), root);
check(iterator.nextNode(), A);
check(iterator.nextNode(), B);
check(iterator.nextNode(), BB);
remove(B);
var X = addChildTo(A);
check(iterator.nextNode(), X);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}
}
function remove(a) {
if (!a) {
errors += 1;
log += 'Tried removing null node.\n';
} else
a.parentNode.removeChild(a);
}
function addChildTo(a) {
var x = document.createElementNS('http://www.w3.org/1999/xhtml', 'span');
x.id = 'X';
a.appendChild(x);
return x;
}
]]></script>
</head>
<body onload="doTest()">
<pre id="result">FAIL: Script did not complete.</pre>
<p><span id="root"><span id="A"></span><span id="B"><span id="BB"></span></span><span id="C"></span></span></p>
</body>
</html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (backwards)</title>
<script type="text/javascript"> <![CDATA[
var errors = 0;
var log = '';
function doTest() {
if (window.layoutTestController) layoutTestController.dumpAsText();
var iterator = document.createNodeIterator(document.getElementById('root'), NodeFilter.SHOW_ALL, null, false);
var root = document.getElementById('root');
var A = document.getElementById('A');
var B = document.getElementById('B');
var BB = document.getElementById('BB');
var C = document.getElementById('C');
check(iterator.nextNode(), root);
check(iterator.nextNode(), A);
check(iterator.nextNode(), B);
check(iterator.nextNode(), BB);
check(iterator.previousNode(), BB);
remove(B);
check(iterator.nextNode(), C);
if (errors)
document.getElementById('result').firstChild.data = 'FAIL: ' + errors + ' errors:\n' + log;
else
document.getElementById('result').firstChild.data = 'PASS';
}
function check(a, b) {
if (!a) {
errors += 1;
log += 'Found null but expected ' + b + ' (' + b.id + ').\n';
} else if (a != b) {
errors += 1;
log += 'Found ' + a + ' (' + a.id + ') but expected ' + b + ' (' + b.id + ').\n';
}