Update web-platform-tests to revision 58133dd71b16037669a0aa011b2afd448b52d434.

This commit is contained in:
Ms2ger 2015-08-11 17:14:59 +02:00
parent 84c4a26e4d
commit 88ea7c4291
192 changed files with 50802 additions and 1334 deletions

View file

@ -163,6 +163,7 @@ function setupRangeTests() {
"[detachedForeignComment, 0, detachedForeignComment, 1]",
"[detachedXmlComment, 2, detachedXmlComment, 6]",
"[docfrag, 0, docfrag, 0]",
"[processingInstruction, 0, processingInstruction, 4]",
];
testRanges = testRangesShort.concat([
@ -825,96 +826,213 @@ function myExtractContents(range) {
}
/**
* insertNode() implementation, following the spec. If an exception is
* supposed to be thrown, will return a string with the name (e.g.,
* "HIERARCHY_REQUEST_ERR") instead of a document fragment. It might also
* return an arbitrary human-readable string if a condition is hit that implies
* a spec bug.
* insertNode() implementation, following the spec. If an exception is meant
* to be thrown, will return a string with the expected exception name, for
* instance "HIERARCHY_REQUEST_ERR".
*/
function myInsertNode(range, node) {
// "If the detached flag is set, throw an "InvalidStateError" exception and
// terminate these steps."
//
// Assume that if accessing collapsed throws, it's detached.
try {
range.collapsed;
} catch (e) {
return "INVALID_STATE_ERR";
// "If range's start node is either a ProcessingInstruction or Comment
// node, or a Text node whose parent is null, throw an
// "HierarchyRequestError" exception and terminate these steps."
if (range.startContainer.nodeType == Node.PROCESSING_INSTRUCTION_NODE
|| range.startContainer.nodeType == Node.COMMENT_NODE
|| (range.startContainer.nodeType == Node.TEXT_NODE
&& !range.startContainer.parentNode)) {
return "HIERARCHY_REQUEST_ERR";
}
// "If start node is a Comment node, or a Text node whose parent is null,
// throw an "HierarchyRequestError" exception and terminate these steps."
if (range.startContainer.nodeType == Node.COMMENT_NODE
|| (range.startContainer.nodeType == Node.TEXT_NODE
&& !range.startContainer.parentNode)) {
return "HIERARCHY_REQUEST_ERR";
}
// "Let referenceNode be null."
var referenceNode = null;
// "If start node is a Text node, split it with offset context object's
// start offset, and let reference node be the result."
var referenceNode;
// "If range's start node is a Text node, set referenceNode to that Text node."
if (range.startContainer.nodeType == Node.TEXT_NODE) {
// We aren't testing how ranges vary under mutations, and browsers vary
// in how they mutate for splitText, so let's just force the correct
// way.
var start = [range.startContainer, range.startOffset];
var end = [range.endContainer, range.endOffset];
referenceNode = range.startContainer;
referenceNode = range.startContainer.splitText(range.startOffset);
if (start[0] == end[0]
&& end[1] > start[1]) {
end[0] = referenceNode;
end[1] -= start[1];
} else if (end[0] == start[0].parentNode
&& end[1] > indexOf(referenceNode)) {
end[1]++;
}
range.setStart(start[0], start[1]);
range.setEnd(end[0], end[1]);
// "Otherwise, let reference node be the child of start node whose index is
// start offset, or null if there is no such child."
// "Otherwise, set referenceNode to the child of start node whose index is
// start offset, and null if there is no such child."
} else {
referenceNode = range.startContainer.childNodes[range.startOffset];
if (typeof referenceNode == "undefined") {
if (range.startOffset < range.startContainer.childNodes.length) {
referenceNode = range.startContainer.childNodes[range.startOffset];
} else {
referenceNode = null;
}
}
// "If reference node is null, let parent be start node."
var parent_;
if (!referenceNode) {
parent_ = range.startContainer;
// "Let parent be range's start node if referenceNode is null, and
// referenceNode's parent otherwise."
var parent_ = referenceNode === null ? range.startContainer :
referenceNode.parentNode;
// "Otherwise, let parent be the parent of reference node."
} else {
parent_ = referenceNode.parentNode;
// "Ensure pre-insertion validity of node into parent before
// referenceNode."
var error = ensurePreInsertionValidity(node, parent_, referenceNode);
if (error) {
return error;
}
// "Let new offset be the index of reference node, or parent's length if
// reference node is null."
var newOffset = referenceNode ? indexOf(referenceNode) : nodeLength(parent_);
// "Add node's length to new offset, if node is a DocumentFragment.
// Otherwise add one to new offset."
newOffset += node.nodeType == Node.DOCUMENT_FRAGMENT_NODE
? nodeLength(node)
: 1;
// "Pre-insert node into parent before reference node."
try {
parent_.insertBefore(node, referenceNode);
} catch (e) {
return getDomExceptionName(e);
// "If range's start node is a Text node, set referenceNode to the result
// of splitting it with offset range's start offset."
if (range.startContainer.nodeType == Node.TEXT_NODE) {
referenceNode = range.startContainer.splitText(range.startOffset);
}
// "If start and end are the same, set end to (parent, new offset)."
if (range.collapsed) {
// "If node is referenceNode, set referenceNode to its next sibling."
if (node == referenceNode) {
referenceNode = referenceNode.nextSibling;
}
// "If node's parent is not null, remove node from its parent."
if (node.parentNode) {
node.parentNode.removeChild(node);
}
// "Let newOffset be parent's length if referenceNode is null, and
// referenceNode's index otherwise."
var newOffset = referenceNode === null ? nodeLength(parent_) :
indexOf(referenceNode);
// "Increase newOffset by node's length if node is a DocumentFragment node,
// and one otherwise."
newOffset += node.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
nodeLength(node) : 1;
// "Pre-insert node into parent before referenceNode."
parent_.insertBefore(node, referenceNode);
// "If range's start and end are the same, set range's end to (parent,
// newOffset)."
if (range.startContainer == range.endContainer
&& range.startOffset == range.endOffset) {
range.setEnd(parent_, newOffset);
}
}
// To make filter() calls more readable
function isElement(node) {
return node.nodeType == Node.ELEMENT_NODE;
}
function isText(node) {
return node.nodeType == Node.TEXT_NODE;
}
function isDoctype(node) {
return node.nodeType == Node.DOCUMENT_TYPE_NODE;
}
function ensurePreInsertionValidity(node, parent_, child) {
// "If parent is not a Document, DocumentFragment, or Element node, throw a
// HierarchyRequestError."
if (parent_.nodeType != Node.DOCUMENT_NODE
&& parent_.nodeType != Node.DOCUMENT_FRAGMENT_NODE
&& parent_.nodeType != Node.ELEMENT_NODE) {
return "HIERARCHY_REQUEST_ERR";
}
// "If node is a host-including inclusive ancestor of parent, throw a
// HierarchyRequestError."
//
// XXX Does not account for host
if (isInclusiveAncestor(node, parent_)) {
return "HIERARCHY_REQUEST_ERR";
}
// "If child is not null and its parent is not parent, throw a NotFoundError
// exception."
if (child && child.parentNode != parent_) {
return "NOT_FOUND_ERR";
}
// "If node is not a DocumentFragment, DocumentType, Element, Text,
// ProcessingInstruction, or Comment node, throw a HierarchyRequestError."
if (node.nodeType != Node.DOCUMENT_FRAGMENT_NODE
&& node.nodeType != Node.DOCUMENT_TYPE_NODE
&& node.nodeType != Node.ELEMENT_NODE
&& node.nodeType != Node.TEXT_NODE
&& node.nodeType != Node.PROCESSING_INSTRUCTION_NODE
&& node.nodeType != Node.COMMENT_NODE) {
return "HIERARCHY_REQUEST_ERR";
}
// "If either node is a Text node and parent is a document, or node is a
// doctype and parent is not a document, throw a HierarchyRequestError."
if ((node.nodeType == Node.TEXT_NODE
&& parent_.nodeType == Node.DOCUMENT_NODE)
|| (node.nodeType == Node.DOCUMENT_TYPE_NODE
&& parent_.nodeType != Node.DOCUMENT_NODE)) {
return "HIERARCHY_REQUEST_ERR";
}
// "If parent is a document, and any of the statements below, switched on
// node, are true, throw a HierarchyRequestError."
if (parent_.nodeType == Node.DOCUMENT_NODE) {
switch (node.nodeType) {
case Node.DOCUMENT_FRAGMENT_NODE:
// "If node has more than one element child or has a Text node
// child. Otherwise, if node has one element child and either
// parent has an element child, child is a doctype, or child is not
// null and a doctype is following child."
if ([].filter.call(node.childNodes, isElement).length > 1) {
return "HIERARCHY_REQUEST_ERR";
}
if ([].some.call(node.childNodes, isText)) {
return "HIERARCHY_REQUEST_ERR";
}
if ([].filter.call(node.childNodes, isElement).length == 1) {
if ([].some.call(parent_.childNodes, isElement)) {
return "HIERARCHY_REQUEST_ERR";
}
if (child && child.nodeType == Node.DOCUMENT_TYPE_NODE) {
return "HIERARCHY_REQUEST_ERR";
}
if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
.filter(isDoctype)) {
return "HIERARCHY_REQUEST_ERR";
}
}
break;
case Node.ELEMENT_NODE:
// "parent has an element child, child is a doctype, or child is
// not null and a doctype is following child."
if ([].some.call(parent_.childNodes, isElement)) {
return "HIERARCHY_REQUEST_ERR";
}
if (child.nodeType == Node.DOCUMENT_TYPE_NODE) {
return "HIERARCHY_REQUEST_ERR";
}
if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
.filter(isDoctype)) {
return "HIERARCHY_REQUEST_ERR";
}
break;
case Node.DOCUMENT_TYPE_NODE:
// "parent has a doctype child, an element is preceding child, or
// child is null and parent has an element child."
if ([].some.call(parent_.childNodes, isDoctype)) {
return "HIERARCHY_REQUEST_ERR";
}
if (child && [].slice.call(parent_.childNodes, 0, indexOf(child))
.some(isElement)) {
return "HIERARCHY_REQUEST_ERR";
}
if (!child && [].some.call(parent_.childNodes, isElement)) {
return "HIERARCHY_REQUEST_ERR";
}
break;
}
}
}
/**
* Asserts that two nodes are equal, in the sense of isEqualNode(). If they
* aren't, tries to print a relatively informative reason why not. TODO: Move
@ -927,8 +1045,7 @@ function assertNodesEqual(actual, expected, msg) {
while (actual && expected) {
assert_true(actual.nodeType === expected.nodeType
&& actual.nodeName === expected.nodeName
&& actual.nodeValue === expected.nodeValue
&& actual.childNodes.length === expected.childNodes.length,
&& actual.nodeValue === expected.nodeValue,
"First differing node: expected " + format_value(expected)
+ ", got " + format_value(actual) + " [" + msg + "]");
actual = nextNode(actual);

View file

@ -43,6 +43,17 @@ function testNode(create, type) {
assert_equals(node.substringData(4, 1), "")
}, type + ".substringData() with in-bounds offset")
test(function() {
var node = create()
assert_equals(node.data, "test")
assert_equals(node.substringData(0, 0), "")
assert_equals(node.substringData(1, 0), "")
assert_equals(node.substringData(2, 0), "")
assert_equals(node.substringData(3, 0), "")
assert_equals(node.substringData(4, 0), "")
}, type + ".substringData() with zero count")
test(function() {
var node = create()
assert_equals(node.data, "test")

View file

@ -9,6 +9,22 @@
<script>
"use strict";
function check_iter(iter, root, whatToShowValue) {
whatToShowValue = whatToShowValue === undefined ? 0xFFFFFFFF : whatToShowValue;
assert_equals(iter.toString(), '[object NodeIterator]', 'toString');
assert_equals(iter.root, root, 'root');
assert_equals(iter.whatToShow, whatToShowValue, 'whatToShow');
assert_equals(iter.filter, null, 'filter');
assert_equals(iter.referenceNode, root, 'referenceNode');
assert_equals(iter.pointerBeforeReferenceNode, true, 'pointerBeforeReferenceNode');
assert_readonly(iter, 'root');
assert_readonly(iter, 'whatToShow');
assert_readonly(iter, 'filter');
assert_readonly(iter, 'referenceNode');
assert_readonly(iter, 'pointerBeforeReferenceNode');
}
test(function() {
var iter = document.createNodeIterator(document);
iter.detach();
@ -17,10 +33,19 @@ test(function() {
test(function() {
var iter = document.createNodeIterator(document);
assert_equals(iter.whatToShow, 0xFFFFFFFF, "whatToShow");
assert_equals(iter.filter, null, "filter");
check_iter(iter, document);
}, "createNodeIterator() parameter defaults");
test(function() {
var iter = document.createNodeIterator(document, null, null);
check_iter(iter, document, 0);
}, "createNodeIterator() with null as arguments");
test(function() {
var iter = document.createNodeIterator(document, undefined, undefined);
check_iter(iter, document);
}, "createNodeIterator() with undefined as arguments");
test(function() {
var iter = document.createNodeIterator(document, NodeFilter.SHOW_ALL,
function() { throw {name: "failed"} });

View file

@ -37,11 +37,11 @@ test(function()
function filter(node)
{
if (node.id == "B1")
return /*NodeFilter.*/FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
return NodeFilter.FILTER_ACCEPT;
}
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.currentNode, { type: Element, id: 'A1' });
@ -51,11 +51,11 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, {
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, {
acceptNode : function(node) {
if (node.id == "B1")
return /*NodeFilter.*/FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
return NodeFilter.FILTER_ACCEPT;
}
});
assert_node(walker.currentNode, { type: Element, id: 'root' });
@ -67,7 +67,7 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, null);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, null);
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.currentNode, { type: Element, id: 'A1' });
@ -77,7 +77,7 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, undefined);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, undefined);
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.currentNode, { type: Element, id: 'A1' });
@ -87,7 +87,7 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, {});
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, {});
assert_throws(new TypeError(), function () { walker.firstChild(); });
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_throws(new TypeError(), function () { walker.nextNode(); });
@ -96,7 +96,7 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, { acceptNode: "foo" });
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, { acceptNode: "foo" });
assert_throws(new TypeError(), function () { walker.firstChild(); });
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_throws(new TypeError(), function () { walker.nextNode(); });
@ -105,9 +105,9 @@ test(function()
test(function()
{
var filter = function() { return /*NodeFilter.*/FILTER_ACCEPT; };
filter.acceptNode = function(node) { return /*NodeFilter.*/FILTER_SKIP; };
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var filter = function() { return NodeFilter.FILTER_ACCEPT; };
filter.acceptNode = function(node) { return NodeFilter.FILTER_SKIP; };
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.nextNode(), { type: Element, id: 'B1' });
}, 'Testing with function having acceptNode function');
@ -116,17 +116,17 @@ test(function()
{
var filter = {
acceptNode: function(node) {
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
}
};
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
}, 'Testing acceptNode callee');
test(function()
{
var test_error = { name: "test" };
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT,
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT,
function(node) {
throw test_error;
});
@ -139,7 +139,7 @@ test(function()
test(function()
{
var test_error = { name: "test" };
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT,
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT,
{
acceptNode : function(node) {
throw test_error;

View file

@ -70,13 +70,15 @@ function createSampleDOM()
return div;
}
function check_walker(walker, root)
function check_walker(walker, root, whatToShowValue)
{
assert_equals(walker.toString(), '[object TreeWalker]');
assert_equals(walker.root, root);
assert_equals(walker.whatToShow, 0xFFFFFFFF);
assert_equals(walker.filter, null);
assert_equals(walker.currentNode, root);
whatToShowValue = whatToShowValue === undefined ? 0xFFFFFFFF : whatToShowValue;
assert_equals(walker.toString(), '[object TreeWalker]', 'toString');
assert_equals(walker.root, root, 'root');
assert_equals(walker.whatToShow, whatToShowValue, 'whatToShow');
assert_equals(walker.filter, null, 'filter');
assert_equals(walker.currentNode, root, 'currentNode');
assert_readonly(walker, 'root');
assert_readonly(walker, 'whatToShow');
assert_readonly(walker, 'filter');
@ -89,6 +91,13 @@ test(function ()
check_walker(walker, root);
}, 'Construct a TreeWalker by document.createTreeWalker(root).');
test(function ()
{
var root = createSampleDOM();
var walker = document.createTreeWalker(root, null, null);
check_walker(walker, root, 0);
}, 'Construct a TreeWalker by document.createTreeWalker(root, null, null).');
test(function ()
{
var root = createSampleDOM();

View file

@ -26,7 +26,7 @@ var all = function(node) { return true; }
test(function()
{
var w = document.createTreeWalker(subTree, /*NodeFilter.*/SHOW_ELEMENT, all);
var w = document.createTreeWalker(subTree, NodeFilter.SHOW_ELEMENT, all);
assert_node(w.currentNode, { type: Element, id: 'subTree' });
assert_equals(w.parentNode(), null);
assert_node(w.currentNode, { type: Element, id: 'subTree' });
@ -35,8 +35,8 @@ test(function()
test(function()
{
var w = document.createTreeWalker(subTree,
/*NodeFilter.*/SHOW_ELEMENT
| /*NodeFilter.*/SHOW_COMMENT,
NodeFilter.SHOW_ELEMENT
| NodeFilter.SHOW_COMMENT,
all);
w.currentNode = document.documentElement;
assert_equals(w.parentNode(), null);
@ -63,7 +63,7 @@ test(function()
test(function()
{
var w = document.createTreeWalker(subTree, /*NodeFilter.*/SHOW_ELEMENT, all);
var w = document.createTreeWalker(subTree, NodeFilter.SHOW_ELEMENT, all);
w.currentNode = subTree.previousSibling;
assert_equals(w.nextNode(), subTree);
w.currentNode = document.getElementById("parent");

View file

@ -66,11 +66,11 @@ test(function()
function filter(node)
{
if (node.id == "C2")
return /*NodeFilter.*/FILTER_REJECT;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_REJECT;
return NodeFilter.FILTER_ACCEPT;
}
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.currentNode, { type: Element, id: 'A1' });

View file

@ -66,11 +66,11 @@ test(function()
function filter(node)
{
if (node.id == "B1")
return /*NodeFilter.*/FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_SKIP;
return NodeFilter.FILTER_ACCEPT;
}
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.currentNode, { type: Element, id: 'root' });
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.currentNode, { type: Element, id: 'A1' });

View file

@ -45,24 +45,24 @@ setup(function() {
var rejectB1Filter = {
acceptNode: function(node) {
if (node.id == 'B1')
return /*NodeFilter.*/FILTER_REJECT;
return NodeFilter.FILTER_REJECT;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
}
}
var skipB2Filter = {
acceptNode: function(node) {
if (node.id == 'B2')
return /*NodeFilter.*/FILTER_SKIP;
return NodeFilter.FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
}
}
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, rejectB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, rejectB1Filter);
assert_node(walker.nextNode(), { type: Element, id: 'A1' });
assert_node(walker.nextNode(), { type: Element, id: 'B2' });
assert_node(walker.nextNode(), { type: Element, id: 'B3' });
@ -70,14 +70,14 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, rejectB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, rejectB1Filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.firstChild(), { type: Element, id: 'B2' });
}, 'Testing firstChild');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB2Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB2Filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.firstChild(), { type: Element, id: 'B1' });
assert_node(walker.nextSibling(), { type: Element, id: 'B3' });
@ -85,21 +85,21 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, rejectB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, rejectB1Filter);
walker.currentNode = testElement.querySelectorAll('#C1')[0];
assert_node(walker.parentNode(), { type: Element, id: 'A1' });
}, 'Testing parentNode');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB2Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB2Filter);
walker.currentNode = testElement.querySelectorAll('#B3')[0];
assert_node(walker.previousSibling(), { type: Element, id: 'B1' });
}, 'Testing previousSibling');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, rejectB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, rejectB1Filter);
walker.currentNode = testElement.querySelectorAll('#B3')[0];
assert_node(walker.previousNode(), { type: Element, id: 'B2' });
assert_node(walker.previousNode(), { type: Element, id: 'A1' });

View file

@ -42,22 +42,22 @@ setup(function() {
var filter = {
acceptNode: function(node) {
if (node.className == 'keep')
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
return /*NodeFilter.*/FILTER_SKIP;
return NodeFilter.FILTER_SKIP;
}
}
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
assert_node(walker.firstChild(), { type: Element, id: 'B1' });
assert_node(walker.nextSibling(), { type: Element, id: 'B3' });
}, 'Testing nextSibling');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, filter);
walker.currentNode = testElement.querySelectorAll('#B3')[0];
assert_node(walker.previousSibling(), { type: Element, id: 'B1' });
}, 'Testing previousSibling');

View file

@ -45,24 +45,24 @@ setup(function() {
var skipB1Filter = {
acceptNode: function(node) {
if (node.id == 'B1')
return /*NodeFilter.*/FILTER_SKIP;
return NodeFilter.FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
}
}
var skipB2Filter = {
acceptNode: function(node) {
if (node.id == 'B2')
return /*NodeFilter.*/FILTER_SKIP;
return NodeFilter.FILTER_SKIP;
return /*NodeFilter.*/FILTER_ACCEPT;
return NodeFilter.FILTER_ACCEPT;
}
}
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB1Filter);
assert_node(walker.nextNode(), { type: Element, id: 'A1' });
assert_node(walker.nextNode(), { type: Element, id: 'C1' });
assert_node(walker.nextNode(), { type: Element, id: 'B2' });
@ -71,14 +71,14 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB1Filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.firstChild(), { type: Element, id: 'C1' });
}, 'Testing firstChild');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB2Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB2Filter);
assert_node(walker.firstChild(), { type: Element, id: 'A1' });
assert_node(walker.firstChild(), { type: Element, id: 'B1' });
assert_node(walker.nextSibling(), { type: Element, id: 'B3' });
@ -86,21 +86,21 @@ test(function()
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB1Filter);
walker.currentNode = testElement.querySelectorAll('#C1')[0];
assert_node(walker.parentNode(), { type: Element, id: 'A1' });
}, 'Testing parentNode');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB2Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB2Filter);
walker.currentNode = testElement.querySelectorAll('#B3')[0];
assert_node(walker.previousSibling(), { type: Element, id: 'B1' });
}, 'Testing previousSibling');
test(function()
{
var walker = document.createTreeWalker(testElement, /*NodeFilter.*/SHOW_ELEMENT, skipB1Filter);
var walker = document.createTreeWalker(testElement, NodeFilter.SHOW_ELEMENT, skipB1Filter);
walker.currentNode = testElement.querySelectorAll('#B3')[0];
assert_node(walker.previousNode(), { type: Element, id: 'B2' });
assert_node(walker.previousNode(), { type: Element, id: 'C1' });

View file

@ -0,0 +1,298 @@
<!doctype html>
<title>TreeWalker tests</title>
<link rel="author" title="Aryeh Gregor" href=ayg@aryeh.name>
<meta name=timeout content=long>
<div id=log></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src=../common.js></script>
<script>
"use strict";
// TODO .previousNode, .nextNode
function filterNode(node, whatToShow, filter) {
// "If active flag is set throw an "InvalidStateError"."
// Ignore active flag for these tests, we aren't calling recursively
// TODO Test me
// "Let n be node's nodeType attribute value minus 1."
var n = node.nodeType - 1;
// "If the nth bit (where 0 is the least significant bit) of whatToShow is
// not set, return FILTER_SKIP."
if (!(whatToShow & (1 << n))) {
return NodeFilter.FILTER_SKIP;
}
// "If filter is null, return FILTER_ACCEPT."
if (!filter) {
return NodeFilter.FILTER_ACCEPT;
}
// "Set the active flag."
//
// "Let result be the return value of invoking filter."
//
// "Unset the active flag."
//
// "If an exception was thrown, re-throw the exception."
// TODO Test me
//
// "Return result."
return filter(node);
}
function testTraverseChildren(type, walker, root, whatToShow, filter) {
// TODO We don't test .currentNode other than the root
walker.currentNode = root;
assert_equals(walker.currentNode, root, "Setting .currentNode");
var expectedReturn = null;
var expectedCurrentNode = root;
// "To traverse children of type type, run these steps:
//
// "Let node be the value of the currentNode attribute."
var node = walker.currentNode;
// "Set node to node's first child if type is first, and node's last child
// if type is last."
node = type == "first" ? node.firstChild : node.lastChild;
// "Main: While node is not null, run these substeps:"
while (node) {
// "Filter node and let result be the return value."
var result = filterNode(node, whatToShow, filter);
// "If result is FILTER_ACCEPT, then set the currentNode attribute to
// node and return node."
if (result == NodeFilter.FILTER_ACCEPT) {
expectedCurrentNode = expectedReturn = node;
break;
}
// "If result is FILTER_SKIP, run these subsubsteps:"
if (result == NodeFilter.FILTER_SKIP) {
// "Let child be node's first child if type is first, and node's
// last child if type is last."
var child = type == "first" ? node.firstChild : node.lastChild;
// "If child is not null, set node to child and goto Main."
if (child) {
node = child;
continue;
}
}
// "While node is not null, run these subsubsteps:"
while (node) {
// "Let sibling be node's next sibling if type is first, and node's
// previous sibling if type is last."
var sibling = type == "first" ? node.nextSibling
: node.previousSibling;
// "If sibling is not null, set node to sibling and goto Main."
if (sibling) {
node = sibling;
break;
}
// "Let parent be node's parent."
var parent = node.parentNode;
// "If parent is null, parent is root, or parent is currentNode
// attribute's value, return null."
if (!parent || parent == root || parent == walker.currentNode) {
expectedReturn = node = null;
break;
} else {
// "Otherwise, set node to parent."
node = parent;
}
}
}
if (type == "first") {
assert_equals(walker.firstChild(), expectedReturn, ".firstChild()");
assert_equals(walker.currentNode, expectedCurrentNode,
".currentNode after .firstChild()");
} else {
assert_equals(walker.lastChild(), expectedReturn, ".lastChild()");
assert_equals(walker.currentNode, expectedCurrentNode,
".currentNode after .lastChild()");
}
}
function testTraverseSiblings(type, walker, root, whatToShow, filter) {
// TODO We don't test .currentNode other than the root's first or last child
if (!root.firstChild) {
// Nothing much to test
walker.currentNode = root;
assert_equals(walker.currentNode, root, "Setting .currentNode");
if (type == "next") {
assert_equals(walker.nextSibling(), null, ".nextSibling()");
assert_equals(walker.currentNode, root,
".currentNode after .nextSibling()")
} else {
assert_equals(walker.previousSibling(), null, ".previousSibling()");
assert_equals(walker.currentNode, root,
".currentNode after .previousSibling()")
}
return;
}
if (type == "next") {
walker.currentNode = root.firstChild;
assert_equals(walker.currentNode, root.firstChild,
"Setting .currentNode");
} else {
walker.currentNode = root.lastChild;
assert_equals(walker.currentNode, root.lastChild,
"Setting .currentNode");
}
var expectedReturn = null;
var expectedCurrentNode = type == "next" ? root.firstChild : root.lastChild;
// "To traverse siblings of type type run these steps:"
(function() {
// "Let node be the value of the currentNode attribute."
var node = type == "next" ? root.firstChild : root.lastChild;
// "If node is root, return null.
//
// "Run these substeps:
do {
// "Let sibling be node's next sibling if type is next, and node's
// previous sibling if type is previous."
var sibling = type == "next" ? node.nextSibling :
node.previousSibling;
// "While sibling is not null, run these subsubsteps:"
while (sibling) {
// "Set node to sibling."
node = sibling;
// "Filter node and let result be the return value."
var result = filterNode(node, whatToShow, filter);
// "If result is FILTER_ACCEPT, then set the currentNode
// attribute to node and return node."
if (result == NodeFilter.FILTER_ACCEPT) {
expectedCurrentNode = expectedReturn = node;
return;
}
// "Set sibling to node's first child if type is next, and
// node's last child if type is previous."
sibling = type == "next" ? node.firstChild : node.lastChild;
// "If result is FILTER_REJECT or sibling is null, then set
// sibling to node's next sibling if type is next, and node's
// previous sibling if type is previous."
if (result == NodeFilter.FILTER_REJECT || !sibling) {
sibling = type == "next" ? node.nextSibling :
node.previousSibling;
}
}
// "Set node to its parent."
node = node.parentNode;
// "If node is null or is root, return null.
if (!node || node == root) {
return;
}
// "Filter node and if the return value is FILTER_ACCEPT, then
// return null."
if (filterNode(node, whatToShow, filter)) {
return;
}
// "Run these substeps again."
} while (true);
})();
if (type == "next") {
assert_equals(walker.nextSibling(), expectedReturn, ".nextSibling()");
assert_equals(walker.currentNode, expectedCurrentNode,
".currentNode after .nextSibling()");
} else {
assert_equals(walker.previousSibling(), expectedReturn, ".previousSibling()");
assert_equals(walker.currentNode, expectedCurrentNode,
".currentNode after .previousSibling()");
}
}
function testWalker(root, whatToShow, filter) {
var walker = document.createTreeWalker(root, whatToShow, filter);
assert_equals(walker.root, root, ".root");
assert_equals(walker.whatToShow, whatToShow, ".whatToShow");
assert_equals(walker.filter, filter, ".filter");
assert_equals(walker.currentNode, root, ".currentNode");
var expectedReturn = null;
var expectedCurrentNode = walker.currentNode;
// "The parentNode() method must run these steps:"
//
// "Let node be the value of the currentNode attribute."
var node = walker.currentNode;
// "While node is not null and is not root, run these substeps:"
while (node && node != root) {
// "Let node be node's parent."
node = node.parentNode;
// "If node is not null and filtering node returns FILTER_ACCEPT, then
// set the currentNode attribute to node, return node."
if (node && filterNode(node, whatToShow, filter) ==
NodeFilter.FILTER_ACCEPT) {
expectedCurrentNode = expectedReturn = node;
}
}
assert_equals(walker.parentNode(), expectedReturn, ".parentNode()");
assert_equals(walker.currentNode, expectedCurrentNode,
".currentNode after .parentNode()");
testTraverseChildren("first", walker, root, whatToShow, filter);
testTraverseChildren("last", walker, root, whatToShow, filter);
testTraverseSiblings("next", walker, root, whatToShow, filter);
testTraverseSiblings("previous", walker, root, whatToShow, filter);
}
var whatToShows = [
"0",
"0xFFFFFFFF",
"NodeFilter.SHOW_ELEMENT",
"NodeFilter.SHOW_ATTRIBUTE",
"NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_DOCUMENT",
];
var callbacks = [
"null",
"(function(node) { return true })",
"(function(node) { return false })",
"(function(node) { return node.nodeName[0] == '#' })",
];
var tests = [];
for (var i = 0; i < testNodes.length; i++) {
for (var j = 0; j < whatToShows.length; j++) {
for (var k = 0; k < callbacks.length; k++) {
tests.push([
"document.createTreeWalker(" + testNodes[i] +
", " + whatToShows[j] + ", " + callbacks[k] + ")",
eval(testNodes[i]), eval(whatToShows[j]), eval(callbacks[k])
]);
}
}
}
generate_tests(testWalker, tests);
testDiv.style.display = "none";
</script>

View file

@ -8,21 +8,3 @@ function assert_node(actual, expected)
if (typeof(expected.nodeValue) !== 'undefined')
assert_equals(actual.nodeValue, expected.nodeValue);
}
// XXX Servo doesn't have these constants in NodeFilter yet
var FILTER_ACCEPT = 1;
var FILTER_REJECT = 2;
var FILTER_SKIP = 3;
var SHOW_ALL = 0xFFFFFFFF;
var SHOW_ELEMENT = 0x1;
var SHOW_ATTRIBUTE = 0x2;
var SHOW_TEXT = 0x4;
var SHOW_CDATA_SECTION = 0x8;
var SHOW_ENTITY_REFERENCE = 0x10;
var SHOW_ENTITY = 0x20;
var SHOW_PROCESSING_INSTRUCTION = 0x40;
var SHOW_COMMENT = 0x80;
var SHOW_DOCUMENT = 0x100;
var SHOW_DOCUMENT_TYPE = 0x200;
var SHOW_DOCUMENT_FRAGMENT = 0x400;
var SHOW_NOTATION = 0x800;