Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / editing / selection / addRange-merging.html
bloba4db81c85cccdceddeeb35fd43d3467200567459
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Range merging with Selection.addRange()</title>
5 <script src="../../resources/js-test.js"></script>
6 </head>
7 <body>
8 <script>
9 description('Selection.addRange() should properly merge intersecting (and don\'t merge discrete) ranges.');
11 var selection = window.getSelection();
13 // Utility functions:
14 function createPosition(container, offset)
16 return {'container': container, 'offset': offset};
19 function createRange(startPosition, endPosition)
21 var range = new Range();
22 range.setStart(startPosition.container, startPosition.offset);
23 range.setEnd(endPosition.container, endPosition.offset);
24 return range;
27 function nodeToString(node)
29 switch (node.nodeType) {
30 case Node.ELEMENT_NODE:
31 return '[<' + node.tagName + '>: #' + node.id + ']';
32 case Node.TEXT_NODE:
33 return '[Text: ' + node.data + ']';
34 default:
35 return node.toString();
39 function positionToString(position)
41 return '(' + nodeToString(position.container) + ', ' + position.offset + ')';
44 function selectionShouldBe(expectedStartPosition, expectedEndPosition)
46 var range = selection.getRangeAt(0);
47 var actualStartPosition = createPosition(range.startContainer, range.startOffset);
48 var actualEndPosition = createPosition(range.endContainer, range.endOffset);
49 if (actualStartPosition.container === expectedStartPosition.container
50 && actualStartPosition.offset === expectedStartPosition.offset
51 && actualEndPosition.container === expectedEndPosition.container
52 && actualEndPosition.offset === expectedEndPosition.offset) {
53 testPassed('Selection was: start = ' + positionToString(expectedStartPosition) + ', end = ' + positionToString(expectedEndPosition));
54 } else {
55 testFailed('Selection should be: start = ' + positionToString(expectedStartPosition) + ', end = ' + positionToString(expectedEndPosition) + '\nbut was: start = ' + positionToString(actualStartPosition) + ', end = ' + positionToString(actualEndPosition));
59 function runSingleTest(testFunction, initializePositionsFunction, containerIsEditable)
61 selection.removeAllRanges();
62 var container = document.createElement('div');
63 container.id = 'container';
64 if (containerIsEditable)
65 container.contentEditable = true;
66 document.body.appendChild(container);
67 var positions = initializePositionsFunction(container);
68 debug('Running: ' + testFunction.name + ' (initializePositionsFunction = ' + initializePositionsFunction.name + ', containerIsEditable = ' + containerIsEditable + ')');
69 testFunction(positions);
70 document.body.removeChild(container);
73 // Actual tests:
75 // To have better coverage over the possible code paths, each test is parametarized over four document positions;
76 // these positions are guaranteed to be ordered in the document order, but each position may vary in each test run.
78 // You can assume the selection is cleared before each test run.
80 function testExpandLeftToRight(positions)
82 selection.addRange(createRange(positions[0], positions[2]));
83 selection.addRange(createRange(positions[1], positions[3]));
84 selectionShouldBe(positions[0], positions[3]);
87 function testExpandRightToLeft(positions)
89 selection.addRange(createRange(positions[1], positions[3]));
90 selection.addRange(createRange(positions[0], positions[2]));
91 selectionShouldBe(positions[0], positions[3]);
94 function testExpandLeftToRightAdjacent(positions)
96 selection.addRange(createRange(positions[1], positions[2]));
97 selection.addRange(createRange(positions[2], positions[3]));
98 selectionShouldBe(positions[1], positions[3]);
101 function testExpandRightToLeftAdjacent(positions)
103 selection.addRange(createRange(positions[1], positions[2]));
104 selection.addRange(createRange(positions[0], positions[1]));
105 selectionShouldBe(positions[0], positions[2]);
108 function testExpandBothEnds(positions)
110 selection.addRange(createRange(positions[1], positions[2]));
111 selection.addRange(createRange(positions[0], positions[3]));
112 selectionShouldBe(positions[0], positions[3]);
115 function testDontExpand(positions)
117 selection.addRange(createRange(positions[0], positions[3]));
118 selection.addRange(createRange(positions[1], positions[2]));
119 selectionShouldBe(positions[0], positions[3]);
122 function testAddSameRange(positions)
124 selection.addRange(createRange(positions[1], positions[2]));
125 selection.addRange(createRange(positions[1], positions[2]));
126 selectionShouldBe(positions[1], positions[2]);
129 function testRejectDistantRangeAtRight(positions)
131 selection.addRange(createRange(positions[0], positions[1]));
132 selection.addRange(createRange(positions[2], positions[3]));
133 selectionShouldBe(positions[0], positions[1]);
136 function testRejectDistantRangeAtLeft(positions)
138 selection.addRange(createRange(positions[2], positions[3]));
139 selection.addRange(createRange(positions[0], positions[1]));
140 selectionShouldBe(positions[2], positions[3]);
143 function testRejectDistantCollapsedRangeAtRight(positions)
145 selection.addRange(createRange(positions[0], positions[1]));
146 selection.addRange(createRange(positions[2], positions[2]));
147 selectionShouldBe(positions[0], positions[1]);
150 function testRejectDistantCollapsedRangeAtLeft(positions)
152 selection.addRange(createRange(positions[2], positions[3]));
153 selection.addRange(createRange(positions[1], positions[1]));
154 selectionShouldBe(positions[2], positions[3]);
157 // Position initializers:
159 // Each initializer function takes an argument |container| which denotes the root element which can be filled with
160 // arbitrary contents. This element is created and added to the document before each test run, and removed from
161 // the document after each test run.
163 function initializeTextPositions(container)
165 container.innerHTML = '12345';
166 var text = container.firstChild;
167 return [createPosition(text, 1), createPosition(text, 2), createPosition(text, 3), createPosition(text, 4)];
170 function initializeOuterElementPositions(container)
172 container.innerHTML = '<span id="a">1</span><span id="b">2</span><span id="c">3</span><span id="d">4</span><span id="e">5</span>';
173 return [createPosition(container, 1), createPosition(container, 2), createPosition(container, 3), createPosition(container, 4)];
176 function initializeInnerElementPositions(container)
178 container.innerHTML = '<span id="a">1</span><span id="b">2</span><span id="c">3</span><span id="d">4</span><span id="e">5</span>';
179 return [createPosition(container.childNodes[1], 0), createPosition(container.childNodes[2], 0), createPosition(container.childNodes[3], 0), createPosition(container.childNodes[4], 0)];
182 function initializeVisiblyEquivalentPositionsBeforeNodes(container)
184 container.innerHTML = '<span id="a"><span id="b"><span id="c"></span></span></span>';
185 return [createPosition(container, 0), createPosition(container.firstChild, 0), createPosition(container.firstChild.firstChild, 0), createPosition(container.firstChild.firstChild.firstChild, 0)];
188 function initializeVisiblyEquivalentPositionsAfterNodes(container)
190 container.innerHTML = '<span id="a"><span id="b"><span id="c"></span></span></span>';
191 return [createPosition(container.firstChild.firstChild.firstChild, 0), createPosition(container.firstChild.firstChild, 1), createPosition(container.firstChild, 1), createPosition(container, 1)];
194 var tests = [
195 testExpandLeftToRight,
196 testExpandRightToLeft,
197 testExpandLeftToRightAdjacent,
198 testExpandRightToLeftAdjacent,
199 testExpandBothEnds,
200 testDontExpand,
201 testAddSameRange,
202 testRejectDistantRangeAtRight,
203 testRejectDistantRangeAtLeft,
204 testRejectDistantCollapsedRangeAtRight,
205 testRejectDistantCollapsedRangeAtLeft
207 var positionInitializers = [
208 initializeTextPositions,
209 initializeOuterElementPositions,
210 initializeInnerElementPositions,
211 initializeVisiblyEquivalentPositionsBeforeNodes,
212 initializeVisiblyEquivalentPositionsAfterNodes
215 tests.forEach(function (testFunction) {
216 positionInitializers.forEach(function (initializePositionsFunction) {
217 [false, true].forEach(function (containerIsEditable) {
218 runSingleTest(testFunction, initializePositionsFunction, containerIsEditable);
222 </script>
223 </body>
224 </html>