Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / editing / selection / resources / move-by-word-visually.js
1 var messages = [];
2
3 function log(message)
4 {
5     messages.push(message);
6 }
7
8 function flushLog()
9 {
10     document.getElementById("console").appendChild(document.createTextNode(messages.join("")));
11 }
12
13 function fold(string)
14 {
15     var result = "";
16     for (var i = 0; i < string.length; ++i) {
17         var char = string.charCodeAt(i);
18         if (char >= 0x05d0)
19             char -= 0x058f;
20         else if (char == 10) {
21             result += "\\n";
22             continue;
23         }
24         result += String.fromCharCode(char);
25     }
26     return result;
27 }
28
29 function logPositions(positions)
30 {
31     for (var i = 0; i < positions.length; ++i) {
32         if (i) {
33             if (positions[i].node != positions[i - 1].node)
34                 log("]");
35             log(", ");
36         }
37         if (!i || positions[i].node != positions[i - 1].node)
38             log((positions[i].node instanceof Text ? '"' + fold(positions[i].node.data) + '"' : "<" + positions[i].node.tagName + ">") + "[");
39         log(positions[i].offset);
40     }
41     log("]");
42 }
43
44 function nodeOfWordBreak(nodeAndOffset)
45 {
46     var node = document.getElementById(nodeAndOffset[0]).firstChild;
47     if (nodeAndOffset.length == 3) {
48         var childIndex = nodeAndOffset[2];
49         for (var i = 0; i < childIndex - 1; ++i) {
50             node = node.nextSibling;
51         }
52     }
53     return node;
54 }
55
56 var wordBreaks;
57
58 function logWordBreak(index, first)
59 {
60     var withNodeData = false;
61     var wordBreak = wordBreaks[index];
62     if (wordBreak.search(',') == -1)
63         log(wordBreak);
64     else {
65         var nodeAndOffset = wordBreak.split(',');
66         var node = nodeOfWordBreak(nodeAndOffset);
67
68         var differentNode = false;
69         if (first == false) {
70             differentNode = nodeOfWordBreak(nodeAndOffset) != nodeOfWordBreak(wordBreaks[index - 1].split(','));
71         
72         }
73
74         if (differentNode == true)
75             log("]");
76
77         if (first == true || differentNode == true) {
78             withNodeData = (node instanceof Text);
79             log((node instanceof Text ? '"' + fold(node.data) + '"' : "<" + node.tagName + ">") + "[");
80         }
81         log(nodeAndOffset[1]);
82     }
83     return withNodeData;
84 }
85
86 function positionEqualToWordBreak(position, wordBreak)
87 {
88     if (wordBreak.search(',') == -1)
89         return position.offset == wordBreak;
90     else {
91         var nodeAndOffset = wordBreak.split(',');
92         return position.node == nodeOfWordBreak(nodeAndOffset) && position.offset == nodeAndOffset[1];
93     }
94 }
95
96 function validateData(positions)
97 {
98     var equal = true;
99     if (positions.length != wordBreaks.length)
100         equal = false;
101     else {
102         for (var i = 0; i < wordBreaks.length - 1; ++i) {
103             if (!positionEqualToWordBreak(positions[i], wordBreaks[i])) {
104                 equal = false;
105                 break;
106             }
107         }
108     }
109     if (equal == false) {
110         log("    FAIL expected: [");
111         for (var i = 0; i < wordBreaks.length; ++i) {
112             logWordBreak(i, i == 0);
113             if (i != wordBreaks.length - 1)
114                 log(", ");
115         }
116         log("]");
117     }
118 }
119
120 function collectWordBreaks(test, searchDirection)
121 {
122     var title;
123     if (searchDirection == "right") 
124         title = test.title.split("|")[0];
125     else
126         title = test.title.split("|")[1];
127
128     var pattern = /\[(.+?)\]/g;
129     var result;
130     wordBreaks = [];
131     while ((result = pattern.exec(title)) != null) {
132         wordBreaks.push(result[1]);
133     }
134     if (wordBreaks.length == 0) {
135         wordBreaks = title.split(" ");
136     }
137 }
138
139 function collapse(sel, node, wordBreak)
140 {
141     if (wordBreak.search(',') == -1)
142         sel.collapse(node, wordBreak);
143     else {
144         var nodeAndOffset = wordBreak.split(',');
145         sel.collapse(nodeOfWordBreak(nodeAndOffset), nodeAndOffset[1]);
146     }
147 }
148
149 function moveByWord(sel, test, searchDirection, dir)
150 {
151     log("Move " + searchDirection + " by one word\n");
152     var prevOffset = sel.anchorOffset;
153     var prevNode = sel.anchorNode;
154     var positions = [];
155     positions.push({ node: sel.anchorNode, offset: sel.anchorOffset });
156
157     while (1) {
158         sel.modify("move", searchDirection, "word");
159         if (prevNode == sel.anchorNode && prevOffset == sel.anchorOffset)
160             break;
161         positions.push({ node: sel.anchorNode, offset: sel.anchorOffset });
162         prevNode = sel.anchorNode;
163         prevOffset = sel.anchorOffset;
164     };
165     logPositions(positions);
166     collectWordBreaks(test, searchDirection);
167     validateData(positions);
168     log("\n");
169 }
170
171 function moveByWordOnEveryChar(sel, test, searchDirection, dir)
172 {
173     collectWordBreaks(test, searchDirection);
174     var wordBreakIndex = 1;
175     var prevOffset = sel.anchorOffset;
176     var prevNode = sel.anchorNode;
177
178     // advance is used to special handling the case that arrow key is not able to reach certain position.
179     // In which case, we will need to manually skip this word break position in order to report correct log.
180     var advance = true; 
181
182     while (1) {
183         var positions = [];
184         positions.push({ node: sel.anchorNode, offset: sel.anchorOffset });
185         sel.modify("move", searchDirection, "word");
186
187         var position = { node: sel.anchorNode, offset: sel.anchorOffset };
188
189         if (wordBreakIndex >= wordBreaks.length) {
190             if (sel.anchorNode != prevNode || sel.anchorOffset != prevOffset) {
191                 positions.push(position);
192                 logPositions(positions);
193                 log("   FAIL expected to stay in the same position\n");
194             }
195         } else if (!positionEqualToWordBreak(position, wordBreaks[wordBreakIndex])) {
196             positions.push(position);
197             logPositions(positions);
198             log("   FAIL expected ");
199             var withNodeData = logWordBreak(wordBreakIndex, true);
200             if (withNodeData)
201                 log("]");
202             log("\n");
203         }
204
205         // Restore position and move by 1 character.
206         sel.collapse(prevNode, prevOffset);
207         sel.modify("move", searchDirection, "character");
208         if (prevNode == sel.anchorNode && prevOffset == sel.anchorOffset)
209             break;
210
211         position = { node: sel.anchorNode, offset: sel.anchorOffset };
212         if ((wordBreakIndex < wordBreaks.length 
213             && positionEqualToWordBreak(position, wordBreaks[wordBreakIndex]))
214             || (test == document.getElementById("notReachablePosition")
215             && sel.anchorOffset > wordBreaks[wordBreakIndex]
216             && advance
217             && searchDirection == "right")) {
218             ++wordBreakIndex;
219             advance = false;
220         }
221
222         prevNode = sel.anchorNode;
223         prevOffset = sel.anchorOffset;
224     };
225 }
226
227 function moveByWordForEveryPosition(sel, test, dir)
228 {
229     // Check ctrl-right-arrow works for every position.
230     sel.collapse(test, 0);
231     var direction = "right";
232     if (dir == "rtl")
233         direction = "left";    
234     moveByWord(sel, test, direction, dir);    
235     sel.collapse(test, 0);
236     moveByWordOnEveryChar(sel, test, direction, dir);
237
238     sel.modify("move", "forward", "lineBoundary");
239     var position = { node: sel.anchorNode, offset: sel.anchorOffset };
240
241     // Check ctrl-left-arrow works for every position.
242     if (dir == "ltr")
243         direction = "left";
244     else
245         direction = "right";    
246     moveByWord(sel, test, direction, dir);    
247
248     sel.collapse(position.node, position.offset);
249     moveByWordOnEveryChar(sel, test, direction, dir);
250 }
251
252 function setWidth(test)
253 {
254     if (test.className.search("fix_width") != -1) {
255         var span = document.getElementById("span_size");
256         var length = span.offsetWidth;
257         test.style.width = length + "px";
258     }
259 }
260
261 function runMoveLeftRight(tests, unit)
262 {
263     var sel = getSelection();
264     for (var i = 0; i < tests.length; ++i) {
265         var positionsMovingRight;
266         var positionsMovingLeft;
267
268         setWidth(tests[i]);
269
270         if (tests[i].getAttribute("dir") == 'ltr')
271         {
272             log("Test " + (i + 1) + ", LTR:\n");
273             moveByWordForEveryPosition(sel, tests[i], "ltr");
274         } else {
275             log("Test " + (i + 1) + ", RTL:\n");
276             moveByWordForEveryPosition(sel, tests[i], "rtl");
277         }
278     }
279     if (document.getElementById("testMoveByWord"))
280         document.getElementById("testMoveByWord").style.display = "none";
281 }
282
283 function runTest() {
284     log("\n======== Move By Word ====\n");
285     var tests = document.getElementsByClassName("test_move_by_word");
286     runMoveLeftRight(tests, "word");
287 }