1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/imptests/editing/selecttest/test_extend.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,148 @@ 1.4 +<!doctype html> 1.5 +<title>Selection extend() tests</title> 1.6 +<meta charset=utf-8> 1.7 +<body> 1.8 +<script src=/resources/testharness.js></script> 1.9 +<script src=/resources/testharnessreport.js></script> 1.10 +<script src=common.js></script> 1.11 +<div id=log></div> 1.12 +<script> 1.13 +"use strict"; 1.14 + 1.15 +// Also test a selection with no ranges 1.16 +testRanges.unshift("[]"); 1.17 + 1.18 +/** 1.19 + * We test Selections that go both forwards and backwards here. In the latter 1.20 + * case we need to use extend() to force it to go backwards, which is fair 1.21 + * enough, since that's what we're testing. We test collapsed selections only 1.22 + * once. 1.23 + */ 1.24 +for (var i = 0; i < testRanges.length; i++) { 1.25 + var endpoints = eval(testRanges[i]); 1.26 + for (var j = 0; j < testPoints.length; j++) { 1.27 + if (endpoints[0] == endpoints[2] 1.28 + && endpoints[1] == endpoints[3]) { 1.29 + // Test collapsed selections only once 1.30 + test(function() { 1.31 + setSelectionForwards(endpoints); 1.32 + testExtend(endpoints, eval(testPoints[j])); 1.33 + }, "extend() with range " + i + " " + testRanges[i] 1.34 + + " and point " + j + " " + testPoints[j]); 1.35 + } else { 1.36 + test(function() { 1.37 + setSelectionForwards(endpoints); 1.38 + testExtend(endpoints, eval(testPoints[j])); 1.39 + }, "extend() forwards with range " + i + " " + testRanges[i] 1.40 + + " and point " + j + " " + testPoints[j]); 1.41 + 1.42 + test(function() { 1.43 + setSelectionBackwards(endpoints); 1.44 + testExtend(endpoints, eval(testPoints[j])); 1.45 + }, "extend() backwards with range " + i + " " + testRanges[i] 1.46 + + " and point " + j + " " + testPoints[j]); 1.47 + } 1.48 + } 1.49 +} 1.50 + 1.51 +function testExtend(endpoints, target) { 1.52 + assert_equals(getSelection().rangeCount, endpoints.length/4, 1.53 + "Sanity check: rangeCount must be correct"); 1.54 + 1.55 + var node = target[0]; 1.56 + var offset = target[1]; 1.57 + 1.58 + // "If the context object's range is null, throw an InvalidStateError 1.59 + // exception and abort these steps." 1.60 + if (getSelection().rangeCount == 0) { 1.61 + assert_throws("INVALID_STATE_ERR", function() { 1.62 + selection.extend(node, offset); 1.63 + }, "extend() when rangeCount is 0 must throw InvalidStateError"); 1.64 + return; 1.65 + } 1.66 + 1.67 + assert_equals(getSelection().getRangeAt(0).startContainer, endpoints[0], 1.68 + "Sanity check: startContainer must be correct"); 1.69 + assert_equals(getSelection().getRangeAt(0).startOffset, endpoints[1], 1.70 + "Sanity check: startOffset must be correct"); 1.71 + assert_equals(getSelection().getRangeAt(0).endContainer, endpoints[2], 1.72 + "Sanity check: endContainer must be correct"); 1.73 + assert_equals(getSelection().getRangeAt(0).endOffset, endpoints[3], 1.74 + "Sanity check: endOffset must be correct"); 1.75 + 1.76 + // "Let anchor and focus be the context object's anchor and focus, and let 1.77 + // new focus be the boundary point (node, offset)." 1.78 + var anchorNode = getSelection().anchorNode; 1.79 + var anchorOffset = getSelection().anchorOffset; 1.80 + var focusNode = getSelection().focusNode; 1.81 + var focusOffset = getSelection().focusOffset; 1.82 + 1.83 + // "Let new range be a new range." 1.84 + // 1.85 + // We'll always be setting either new range's start or its end to new 1.86 + // focus, so we'll always throw at some point. Test that now. 1.87 + // 1.88 + // From DOM4's "set the start or end of a range": "If node is a doctype, 1.89 + // throw an "InvalidNodeTypeError" exception and terminate these steps." 1.90 + if (node.nodeType == Node.DOCUMENT_TYPE_NODE) { 1.91 + assert_throws("INVALID_NODE_TYPE_ERR", function() { 1.92 + selection.extend(node, offset); 1.93 + }, "extend() to a doctype must throw InvalidNodeTypeError"); 1.94 + return; 1.95 + } 1.96 + 1.97 + // From DOM4's "set the start or end of a range": "If offset is greater 1.98 + // than node's length, throw an "IndexSizeError" exception and terminate 1.99 + // these steps." 1.100 + // 1.101 + // FIXME: We should be casting offset to an unsigned int per WebIDL. Until 1.102 + // we do, we need the offset < 0 check too. 1.103 + if (offset < 0 || offset > getNodeLength(node)) { 1.104 + assert_throws("INDEX_SIZE_ERR", function() { 1.105 + selection.extend(node, offset); 1.106 + }, "extend() to an offset that's greater than node length (" + getNodeLength(node) + ") must throw IndexSizeError"); 1.107 + return; 1.108 + } 1.109 + 1.110 + // Now back to the editing spec. 1.111 + var originalRange = getSelection().getRangeAt(0); 1.112 + 1.113 + // "If node's root is not the same as the context object's range's root, 1.114 + // set new range's start and end to (node, offset)." 1.115 + // 1.116 + // "Otherwise, if anchor is before or equal to new focus, set new range's 1.117 + // start to anchor, then set its end to new focus." 1.118 + // 1.119 + // "Otherwise, set new range's start to new focus, then set its end to 1.120 + // anchor." 1.121 + // 1.122 + // "Set the context object's range to new range." 1.123 + // 1.124 + // "If new focus is before anchor, set the context object's direction to 1.125 + // backwards. Otherwise, set it to forwards." 1.126 + // 1.127 + // The upshot of all these is summed up by just testing the anchor and 1.128 + // offset. 1.129 + getSelection().extend(node, offset); 1.130 + 1.131 + if (furthestAncestor(anchorNode) == furthestAncestor(node)) { 1.132 + assert_equals(getSelection().anchorNode, anchorNode, 1.133 + "anchorNode must not change if the node passed to extend() has the same root as the original range"); 1.134 + assert_equals(getSelection().anchorOffset, anchorOffset, 1.135 + "anchorOffset must not change if the node passed to extend() has the same root as the original range"); 1.136 + } else { 1.137 + assert_equals(getSelection().anchorNode, node, 1.138 + "anchorNode must be the node passed to extend() if it has a different root from the original range"); 1.139 + assert_equals(getSelection().anchorOffset, offset, 1.140 + "anchorOffset must be the offset passed to extend() if the node has a different root from the original range"); 1.141 + } 1.142 + assert_equals(getSelection().focusNode, node, 1.143 + "focusNode must be the node passed to extend()"); 1.144 + assert_equals(getSelection().focusOffset, offset, 1.145 + "focusOffset must be the offset passed to extend()"); 1.146 + assert_not_equals(getSelection().getRangeAt(0), originalRange, 1.147 + "extend() must replace any existing range with a new one, not mutate the existing one"); 1.148 +} 1.149 + 1.150 +testDiv.style.display = "none"; 1.151 +</script>