Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / editing / selection / resources / extend-selection.js
1 function log(message)
2 {
3     document.getElementById("console").appendChild(document.createTextNode(message));
4 }
5
6 function getSerializedSelection()
7 {
8     return {
9         node: getSelection().extentNode,
10         begin: getSelection().baseOffset,
11         end: getSelection().extentOffset
12     };
13 }
14
15 function extendSelectionWithinBlock(direction, granularity)
16 {
17     var positions = [];
18     var leftIterations = (granularity === "character") ? 5 : 1;
19     var rightIterations = (granularity === "character") ? 15 : 3;
20
21     for (var index = 0; index <= leftIterations; ++index) {
22         positions.push(getSerializedSelection());
23         getSelection().modify("extend", direction, granularity);
24     }
25
26     for (var index = 0; index <= rightIterations; ++index) {
27         positions.push(getSerializedSelection());
28         getSelection().modify("extend", (direction === "left") ? "right" : "left", granularity);
29     }
30
31     for (var index = 0; index < leftIterations; ++index) {
32         positions.push(getSerializedSelection());
33         getSelection().modify("extend", direction, granularity);
34     }
35
36     return positions;
37 }
38
39 function extendSelectionWithinBlockWin(direction, granularity)
40 {
41     if (granularity === "character")
42         return extendSelectionWithinBlock(direction, granularity);
43
44     var positions = [];
45
46     if (direction === "right") {
47         positions.push(getSerializedSelection());
48         getSelection().modify("extend", "right", granularity);
49
50         for (var index = 0; index < 3; ++index) {
51             positions.push(getSerializedSelection());
52             getSelection().modify("extend", "left", granularity);
53         }
54
55         positions.push(getSerializedSelection());
56         getSelection().modify("extend", "right", granularity);
57
58         positions.push(getSerializedSelection());
59     } else {
60         for (var index = 0; index < 2; ++index) {
61             positions.push(getSerializedSelection());
62             getSelection().modify("extend", "left", granularity);
63         }
64         for (var index = 0; index < 3; ++index) {
65             positions.push(getSerializedSelection());
66             getSelection().modify("extend", "right", granularity);
67         }
68     }
69     return positions;
70 }
71
72 function extendSelectionToEnd(direction, granularity)
73 {
74     var positions = [];
75     do {
76         var position = getSerializedSelection();
77         positions.push(position);
78         getSelection().modify("extend", direction, granularity);
79     } while (position.node !== getSerializedSelection().node || position.end !== getSerializedSelection().end);
80     return positions;
81 }
82
83 function fold(string)
84 {
85     var result = "";
86     for (var i = 0; i < string.length; ++i) {
87         var char = string.charCodeAt(i);
88         if (char >= 0x05d0)
89             char -= 0x058f;
90         else if (char == 10) {
91             result +="\\n";
92             continue;
93         }
94         result += String.fromCharCode(char);
95     }
96     return result;
97 }
98
99 function logPositions(positions)
100 {
101     for (var i = 0; i < positions.length; ++i) {
102         if (i) {
103             if (positions[i].node != positions[i - 1].node)
104                 log("]");
105             log(", ");
106         }
107         if (!i || positions[i].node != positions[i - 1].node)
108             log((positions[i].node instanceof Text ? '"' + fold(positions[i].node.data) + '"' : "<" + positions[i].node.tagName + ">") + "[");
109         log("(" + positions[i].begin + "," + positions[i].end + ")");
110     }
111     log("]");
112 }
113
114 function logMismatchingPositions(positions, comparisonPositions)
115 {
116     if (positions.length !== comparisonPositions.length) {
117         log("WARNING: positions should be the same, but the length are not the same " +  positions.length + " vs. " + comparisonPositions.length + "\n");
118         return;
119     }
120
121     for (var i = 0; i < positions.length; ++i) {
122         var pos = positions[i];
123         var comparison = comparisonPositions[i];
124
125         if (pos.node !== comparison.node)
126             log("WARNING: positions should be the same, but node are not the same\n");
127         if (pos.begin !== comparison.begin)
128             log("WARNING: positions should be the same, but begin are not the same " + pos.begin + " vs. " + comparison.begin + "\n");
129         if (pos.end !== comparison.end)
130             log("WARNING: positions should be the same, but end are not the same " + pos.end + " vs. " + comparison.end + "\n");
131     }
132 }
133
134 function extendAndLogSelection(functionToExtendSelection, direction, granularity)
135 {
136     var positions = functionToExtendSelection(direction, granularity);
137     logPositions(positions);
138     log("\n");
139     return positions;
140 }
141
142 function extendAndLogSelectionWithinBlock(direction, granularity, platform)
143 {
144     return extendAndLogSelection({'mac': extendSelectionWithinBlock, 'win': extendSelectionWithinBlockWin}[platform], direction, granularity);
145 }
146
147 function extendAndLogSelectionToEnd(direction, granularity)
148 {
149     return extendAndLogSelection(extendSelectionToEnd, direction, granularity);
150 }
151
152 function runSelectionTestsWithGranularity(testNodes, granularity)
153 {
154     for (var i = 0; i < testNodes.length; ++i) {
155         var testNode = testNodes[i];
156
157         log("Test " + (i + 1) + ", LTR:\n");
158         testNode.style.direction = "ltr";
159
160         log("  Extending right:    ");
161         getSelection().collapse(testNode);
162         var ltrRightPos = extendAndLogSelectionToEnd("right", granularity);
163
164         log("  Extending left:     ");
165         var ltrLeftPos = extendAndLogSelectionToEnd("left", granularity);
166
167         log("  Extending forward:  ");
168         getSelection().collapse(testNode);
169         var ltrForwardPos = extendAndLogSelectionToEnd("forward", granularity);
170
171         log("  Extending backward: ");
172         var ltrBackwardPos = extendAndLogSelectionToEnd("backward", granularity);
173
174         log("Test " + (i + 1) + ", RTL:\n");
175         testNode.style.direction = "rtl";
176
177         log("  Extending left:     ");
178         getSelection().collapse(testNode);
179         var rtlLeftPos = extendAndLogSelectionToEnd("left", granularity);
180
181         log("  Extending right:    ");
182         var rtlRightPos = extendAndLogSelectionToEnd("right", granularity);
183
184         log("  Extending forward:  ");
185         getSelection().collapse(testNode);
186         var rtlForwardPos = extendAndLogSelectionToEnd("forward", granularity);
187
188         log("  Extending backward: ");
189         var rtlBackwardPos = extendAndLogSelectionToEnd("backward", granularity);
190
191         // validations
192         log("\n\n  validating ltrRight and ltrLeft\n");
193         if (granularity === "character")
194             logMismatchingPositions(ltrRightPos, ltrLeftPos.slice().reverse());
195         // Order might not be reversed for extending by word because the 1-point shift by space.
196
197         log("  validating ltrRight and ltrForward\n");
198         logMismatchingPositions(ltrRightPos, ltrForwardPos);
199         log("  validating ltrForward and rtlForward\n");
200         logMismatchingPositions(ltrForwardPos, rtlForwardPos);
201         log("  validating ltrLeft and ltrBackward\n");
202         logMismatchingPositions(ltrLeftPos, ltrBackwardPos);
203         log("  validating ltrBackward and rtlBackward\n");
204         logMismatchingPositions(ltrBackwardPos, rtlBackwardPos);
205         log("  validating ltrRight and rtlLeft\n");
206         logMismatchingPositions(ltrRightPos, rtlLeftPos);
207         log("  validating ltrLeft and rtlRight\n");
208         logMismatchingPositions(ltrLeftPos, rtlRightPos);
209         log("\n\n");
210     }
211 }
212
213 function getTestNodeContainer()
214 {
215     var tests = document.getElementById("tests");
216     if (!tests) {
217         tests = document.createElement("div");
218         tests.id = "tests";
219         document.body.insertBefore(tests, document.getElementById("console"));
220
221         function createButton(name, onclick)
222         {
223             var button = document.createElement("button");
224             button.innerText = name;
225             button.onclick = onclick;
226             button.onmousedown = function(event) {
227                 // Prevent the mouse event from cancelling the current selection.
228                 event.preventDefault();
229             };
230             return button;
231         }
232
233         function createButtonToSwitchDirection(direction)
234         {
235             return createButton(direction, function() {
236                 for (var i = 0; i < tests.childNodes.length; ++i) {
237                     var node = tests.childNodes[i];
238                     if (node.className === "testNode")
239                         node.style.direction = direction;
240                 }
241             });
242         }
243
244         tests.appendChild(document.createTextNode("Use these buttons to help run the tests manually: "));
245         tests.appendChild(createButtonToSwitchDirection("ltr"));
246         tests.appendChild(createButtonToSwitchDirection("rtl"));
247     }
248     return tests;
249 }
250
251 function createNode(content, style)
252 {
253     var node = document.createElement("div");
254     node.innerHTML = content;
255     node.className = "testNode";
256     node.contentEditable = true;
257     if (style)
258         node.setAttribute("style", style);
259     getTestNodeContainer().appendChild(node);
260     return node;
261 }
262
263 function createCharAndWordNodes()
264 {
265     return [
266         createNode('\nabc &#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def\n'),
267         createNode('\n&#1488;&#1489;&#1490; xyz &#1491;&#1492;&#1493; def &#1494;&#1495;&#1496;\n'),
268         createNode('\n&#1488;&#1489;&#1490; &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;\n'),
269         createNode('\nabc efd dabeb\n'),
270         createNode('Lorem <span style="direction: rtl">ipsum dolor sit</span> amet'),
271         createNode('Lorem <span dir="rtl">ipsum dolor sit</span> amet'),
272         createNode('Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'),
273         createNode('Lorem <span dir="ltr">ipsum dolor sit</span> amet')
274     ];
275 }
276
277 function createEnclosingBlockNodes()
278 {
279     return [
280         createNode('Lorem <div  dir="rtl">ipsum dolor sit</div> amett')
281     ];
282 }
283
284 function createHomeEndNodes()
285 {
286     return [
287         createNode('Lorem <span style="direction: ltr">ipsum dolor sit</span> amet'),
288         createNode('Lorem <span style="direction: ltr">ipsum dolor<div > just a test</div> sit</span> amet'),
289         createNode('Lorem <span dir="ltr">ipsum dolor sit</span> amet'),
290         createNode('Lorem <div  dir="ltr">ipsum dolor sit</div> amet'),
291         createNode('\n Just\n <span>testing רק</span>\n בודק\n'),
292         createNode('\n Just\n <span>testing what</span>\n ever\n'),
293         createNode('car means &#1488;&#1489;&#1490;.'),
294         createNode('&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;.&#x202c;'),
295         createNode('he said "&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;."'),
296         createNode('&#1494;&#1495;&#1496; &#1497;&#1498;&#1499; &#1500;&#1501;&#1502; \'&#x202a;he said ' +
297                    '"&#x202B;car &#1491;&#1492;&#1493; &#1488;&#1489;&#1490;&#x202c;"&#x202c;\'?'),
298         createNode('&#1488;&#1489;&#1490; abc &#1491;&#1492;&#1493;<br />edf &#1494;&#1495;&#1496; abrebg'),
299         createNode('abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ',
300                    'line-break:before-white-space; width:5em'),
301         createNode('abcdefg abcdefg abcdefg a abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg abcdefg ',
302                    'line-break:after-white-space; width:5em')
303     ];
304 }
305
306 function createAllNodes()
307 {
308     return createCharAndWordNodes().concat(
309            createEnclosingBlockNodes()).concat(
310            createHomeEndNodes());
311 }
312
313 if (window.testRunner) {
314     var originalOnload = window.onload;
315     window.onload = function() {
316         if (originalOnload)
317             originalOnload();
318         testRunner.dumpAsText();
319         document.body.removeChild(getTestNodeContainer());
320     };
321 }