| <!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> |