<!doctype html> <title>Range setting 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"; function testSetStart(range, node, offset) { if (node.nodeType == Node.DOCUMENT_TYPE_NODE) { assert_throws("INVALID_NODE_TYPE_ERR", function() { range.setStart(node, offset); }, "setStart() to a doctype must throw INVALID_NODE_TYPE_ERR"); return; } if (offset < 0 || offset > nodeLength(node)) { assert_throws("INDEX_SIZE_ERR", function() { range.setStart(node, offset); }, "setStart() to a too-large offset must throw INDEX_SIZE_ERR"); return; } var newRange = range.cloneRange(); newRange.setStart(node, offset); assert_equals(newRange.startContainer, node, "setStart() must change startContainer to the new node"); assert_equals(newRange.startOffset, offset, "setStart() must change startOffset to the new offset"); // FIXME: I'm assuming comparePoint() is correct, but the tests for that // will depend on setStart()/setEnd(). if (furthestAncestor(node) != furthestAncestor(range.startContainer) || range.comparePoint(node, offset) > 0) { assert_equals(newRange.endContainer, node, "setStart(node, offset) where node is after current end or in different document must set the end node to node too"); assert_equals(newRange.endOffset, offset, "setStart(node, offset) where node is after current end or in different document must set the end offset to offset too"); } else { assert_equals(newRange.endContainer, range.endContainer, "setStart() must not change the end node if the new start is before the old end"); assert_equals(newRange.endOffset, range.endOffset, "setStart() must not change the end offset if the new start is before the old end"); } } function testSetEnd(range, node, offset) { if (node.nodeType == Node.DOCUMENT_TYPE_NODE) { assert_throws("INVALID_NODE_TYPE_ERR", function() { range.setEnd(node, offset); }, "setEnd() to a doctype must throw INVALID_NODE_TYPE_ERR"); return; } if (offset < 0 || offset > nodeLength(node)) { assert_throws("INDEX_SIZE_ERR", function() { range.setEnd(node, offset); }, "setEnd() to a too-large offset must throw INDEX_SIZE_ERR"); return; } var newRange = range.cloneRange(); newRange.setEnd(node, offset); // FIXME: I'm assuming comparePoint() is correct, but the tests for that // will depend on setStart()/setEnd(). if (furthestAncestor(node) != furthestAncestor(range.startContainer) || range.comparePoint(node, offset) < 0) { assert_equals(newRange.startContainer, node, "setEnd(node, offset) where node is before current start or in different document must set the end node to node too"); assert_equals(newRange.startOffset, offset, "setEnd(node, offset) where node is before current start or in different document must set the end offset to offset too"); } else { assert_equals(newRange.startContainer, range.startContainer, "setEnd() must not change the start node if the new end is after the old start"); assert_equals(newRange.startOffset, range.startOffset, "setEnd() must not change the start offset if the new end is after the old start"); } assert_equals(newRange.endContainer, node, "setEnd() must change endContainer to the new node"); assert_equals(newRange.endOffset, offset, "setEnd() must change endOffset to the new offset"); } function testSetStartBefore(range, node) { var parent = node.parentNode; if (parent === null) { assert_throws("INVALID_NODE_TYPE_ERR", function () { range.setStartBefore(node); }, "setStartBefore() to a node with null parent must throw INVALID_NODE_TYPE_ERR"); return; } var idx = 0; while (node.parentNode.childNodes[idx] != node) { idx++; } testSetStart(range, node.parentNode, idx); } function testSetStartAfter(range, node) { var parent = node.parentNode; if (parent === null) { assert_throws("INVALID_NODE_TYPE_ERR", function () { range.setStartAfter(node); }, "setStartAfter() to a node with null parent must throw INVALID_NODE_TYPE_ERR"); return; } var idx = 0; while (node.parentNode.childNodes[idx] != node) { idx++; } testSetStart(range, node.parentNode, idx + 1); } function testSetEndBefore(range, node) { var parent = node.parentNode; if (parent === null) { assert_throws("INVALID_NODE_TYPE_ERR", function () { range.setEndBefore(node); }, "setEndBefore() to a node with null parent must throw INVALID_NODE_TYPE_ERR"); return; } var idx = 0; while (node.parentNode.childNodes[idx] != node) { idx++; } testSetEnd(range, node.parentNode, idx); } function testSetEndAfter(range, node) { var parent = node.parentNode; if (parent === null) { assert_throws("INVALID_NODE_TYPE_ERR", function () { range.setEndAfter(node); }, "setEndAfter() to a node with null parent must throw INVALID_NODE_TYPE_ERR"); return; } var idx = 0; while (node.parentNode.childNodes[idx] != node) { idx++; } testSetEnd(range, node.parentNode, idx + 1); } var startTests = []; var endTests = []; var startBeforeTests = []; var startAfterTests = []; var endBeforeTests = []; var endAfterTests = []; // Don't want to eval() each point a bazillion times var testPointsCached = testPoints.map(eval); var testNodesCached = testNodesShort.map(eval); for (var i = 0; i < testRangesShort.length; i++) { var endpoints = eval(testRangesShort[i]); var range; test(function() { range = ownerDocument(endpoints[0]).createRange(); range.setStart(endpoints[0], endpoints[1]); range.setEnd(endpoints[2], endpoints[3]); }, "Set up range " + i + " " + testRangesShort[i]); for (var j = 0; j < testPoints.length; j++) { startTests.push(["setStart() with range " + i + " " + testRangesShort[i] + ", point " + j + " " + testPoints[j], range, testPointsCached[j][0], testPointsCached[j][1] ]); endTests.push(["setEnd() with range " + i + " " + testRangesShort[i] + ", point " + j + " " + testPoints[j], range, testPointsCached[j][0], testPointsCached[j][1] ]); } for (var j = 0; j < testNodesShort.length; j++) { startBeforeTests.push(["setStartBefore() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j], range, testNodesCached[j] ]); startAfterTests.push(["setStartAfter() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j], range, testNodesCached[j] ]); endBeforeTests.push(["setEndBefore() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j], range, testNodesCached[j] ]); endAfterTests.push(["setEndAfter() with range " + i + " " + testRangesShort[i] + ", node " + j + " " + testNodesShort[j], range, testNodesCached[j] ]); } } generate_tests(testSetStart, startTests); generate_tests(testSetEnd, endTests); generate_tests(testSetStartBefore, startBeforeTests); generate_tests(testSetStartAfter, startAfterTests); generate_tests(testSetEndBefore, endBeforeTests); generate_tests(testSetEndAfter, endAfterTests); testDiv.style.display = "none"; </script>