|
1 <?xml version="1.0"?> |
|
2 <?xml-stylesheet href="chrome://global/skin" type="text/css"?> |
|
3 <?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" |
|
4 type="text/css"?> |
|
5 <window title="Testing composition, text and query content events" |
|
6 xmlns:html="http://www.w3.org/1999/xhtml" |
|
7 xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" |
|
8 onunload="onunload();"> |
|
9 |
|
10 <script type="application/javascript" |
|
11 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" /> |
|
12 <script type="application/javascript" |
|
13 src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" /> |
|
14 <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script> |
|
15 |
|
16 <panel id="panel" hidden="true" |
|
17 orient="vertical" |
|
18 onpopupshown="onPanelShown(event);" |
|
19 onpopuphidden="onPanelHidden(event);"> |
|
20 <vbox id="vbox"> |
|
21 <textbox id="textbox" onfocus="onFocusPanelTextbox(event);" |
|
22 multiline="true" cols="20" rows="4"/> |
|
23 </vbox> |
|
24 </panel> |
|
25 |
|
26 <body xmlns="http://www.w3.org/1999/xhtml"> |
|
27 <p id="display"> |
|
28 <div id="div" style="margin: 0; padding: 0; font-size: 24px;">Here is a text frame.</div> |
|
29 <textarea style="margin: 0;" id="textarea" cols="20" rows="4"></textarea><br/> |
|
30 <iframe id="iframe" width="300" height="150" |
|
31 src="data:text/html,<textarea id='textarea' cols='20' rows='4'></textarea>"></iframe><br/> |
|
32 <iframe id="iframe2" width="300" height="150" |
|
33 src="data:text/html,<body onload='document.designMode=%22on%22'>body content</body>"></iframe><br/> |
|
34 <iframe id="iframe3" width="300" height="150" |
|
35 src="data:text/html,<body onload='document.designMode=%22on%22'>body content</body>"></iframe><br/> |
|
36 <input id="input" type="text"/><br/> |
|
37 </p> |
|
38 <div id="content" style="display: none"> |
|
39 |
|
40 </div> |
|
41 <pre id="test"> |
|
42 </pre> |
|
43 </body> |
|
44 |
|
45 <script class="testbody" type="application/javascript"> |
|
46 <![CDATA[ |
|
47 |
|
48 window.opener.wrappedJSObject.SimpleTest.waitForFocus(runTest, window); |
|
49 |
|
50 function ok(aCondition, aMessage) |
|
51 { |
|
52 window.opener.wrappedJSObject.SimpleTest.ok(aCondition, aMessage); |
|
53 } |
|
54 |
|
55 function is(aLeft, aRight, aMessage) |
|
56 { |
|
57 window.opener.wrappedJSObject.SimpleTest.is(aLeft, aRight, aMessage); |
|
58 } |
|
59 |
|
60 function isnot(aLeft, aRight, aMessage) |
|
61 { |
|
62 window.opener.wrappedJSObject.SimpleTest.isnot(aLeft, aRight, aMessage); |
|
63 } |
|
64 |
|
65 function finish() |
|
66 { |
|
67 window.close(); |
|
68 } |
|
69 |
|
70 function onunload() |
|
71 { |
|
72 window.opener.wrappedJSObject.SimpleTest.finish(); |
|
73 } |
|
74 |
|
75 var div = document.getElementById("div"); |
|
76 var textarea = document.getElementById("textarea"); |
|
77 var panel = document.getElementById("panel"); |
|
78 var textbox = document.getElementById("textbox"); |
|
79 var iframe = document.getElementById("iframe"); |
|
80 var iframe2 = document.getElementById("iframe2"); |
|
81 var iframe3 = document.getElementById("iframe3"); |
|
82 var input = document.getElementById("input"); |
|
83 var textareaInFrame; |
|
84 |
|
85 const nsIDOMNSEditableElement = Components.interfaces.nsIDOMNSEditableElement; |
|
86 const nsIEditorIMESupport = Components.interfaces.nsIEditorIMESupport; |
|
87 const nsIInterfaceRequestor = Components.interfaces.nsIInterfaceRequestor; |
|
88 const nsIWebNavigation = Components.interfaces.nsIWebNavigation; |
|
89 const nsIDocShell = Components.interfaces.nsIDocShell; |
|
90 |
|
91 function hitEventLoop(aFunc, aTimes) |
|
92 { |
|
93 if (--aTimes) { |
|
94 setTimeout(hitEventLoop, 0, aFunc, aTimes); |
|
95 } else { |
|
96 setTimeout(aFunc, 20); |
|
97 } |
|
98 } |
|
99 |
|
100 function getEditorIMESupport(aNode) |
|
101 { |
|
102 return aNode.QueryInterface(nsIDOMNSEditableElement). |
|
103 editor. |
|
104 QueryInterface(nsIEditorIMESupport); |
|
105 } |
|
106 |
|
107 function getHTMLEditorIMESupport(aWindow) |
|
108 { |
|
109 return aWindow.QueryInterface(nsIInterfaceRequestor). |
|
110 getInterface(nsIWebNavigation). |
|
111 QueryInterface(nsIDocShell). |
|
112 editor; |
|
113 } |
|
114 |
|
115 const kIsWin = (navigator.platform.indexOf("Win") == 0); |
|
116 const kIsMac = (navigator.platform.indexOf("Mac") == 0); |
|
117 |
|
118 const kLFLen = kIsWin ? 2 : 1; |
|
119 |
|
120 function checkQueryContentResult(aResult, aMessage) |
|
121 { |
|
122 ok(aResult, aMessage + ": the result is null"); |
|
123 if (!aResult) { |
|
124 return false; |
|
125 } |
|
126 ok(aResult.succeeded, aMessage + ": the query content failed"); |
|
127 return aResult.succeeded; |
|
128 } |
|
129 |
|
130 function checkContent(aExpectedText, aMessage, aID) |
|
131 { |
|
132 var textContent = synthesizeQueryTextContent(0, 100); |
|
133 if (!checkQueryContentResult(textContent, aMessage + |
|
134 ": synthesizeQueryTextContent " + aID)) { |
|
135 return false; |
|
136 } |
|
137 is(textContent.text, aExpectedText, |
|
138 aMessage + ": composition string is wrong" + aID); |
|
139 return textContent.text == aExpectedText; |
|
140 } |
|
141 |
|
142 function checkSelection(aExpectedOffset, aExpectedText, aMessage, aID) |
|
143 { |
|
144 var selectedText = synthesizeQuerySelectedText(); |
|
145 if (!checkQueryContentResult(selectedText, aMessage + |
|
146 ": synthesizeQuerySelectedText " + aID)) { |
|
147 return false; |
|
148 } |
|
149 is(selectedText.offset, aExpectedOffset, |
|
150 aMessage + ": selection offset is wrong" + aID); |
|
151 is(selectedText.text, aExpectedText, |
|
152 aMessage + ": selected text is wrong" + aID); |
|
153 return selectedText.offset == aExpectedOffset && |
|
154 selectedText.text == aExpectedText; |
|
155 } |
|
156 |
|
157 function checkRect(aRect, aExpectedRect, aMessage) |
|
158 { |
|
159 is(aRect.left, aExpectedRect.left, aMessage + ": left is wrong"); |
|
160 is(aRect.top, aExpectedRect.top, aMessage + " top is wrong"); |
|
161 is(aRect.width, aExpectedRect.width, aMessage + ": width is wrong"); |
|
162 is(aRect.height, aExpectedRect.height, aMessage + ": height is wrong"); |
|
163 return aRect.left == aExpectedRect.left && |
|
164 aRect.top == aExpectedRect.top && |
|
165 aRect.width == aExpectedRect.width && |
|
166 aRect.height == aExpectedRect.height; |
|
167 } |
|
168 |
|
169 function checkRectContainsRect(aRect, aContainer, aMessage) |
|
170 { |
|
171 var container = { left: Math.ceil(aContainer.left), |
|
172 top: Math.ceil(aContainer.top), |
|
173 width: Math.floor(aContainer.width), |
|
174 height: Math.floor(aContainer.height) }; |
|
175 |
|
176 var ret = container.left <= aRect.left && |
|
177 container.top <= aRect.top && |
|
178 container.left + container.width >= aRect.left + aRect.width && |
|
179 container.top + container.height >= aRect.top + aRect.height; |
|
180 ret = ret && aMessage; |
|
181 ok(ret, aMessage + " container={ left=" + container.left + ", top=" + |
|
182 container.top + ", width=" + container.width + ", height=" + |
|
183 container.height + " } rect={ left=" + aRect.left + ", top=" + aRect.top + |
|
184 ", width=" + aRect.width + ", height=" + aRect.height + " }"); |
|
185 return ret; |
|
186 } |
|
187 |
|
188 function runUndoRedoTest() |
|
189 { |
|
190 textarea.value = ""; |
|
191 textarea.focus(); |
|
192 |
|
193 // start composition |
|
194 synthesizeComposition({ type: "compositionstart" }); |
|
195 |
|
196 // input raw characters |
|
197 synthesizeComposition({ type: "compositionupdate", data: "\u306D" }); |
|
198 synthesizeText( |
|
199 { "composition": |
|
200 { "string": "\u306D", |
|
201 "clauses": |
|
202 [ |
|
203 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
204 ] |
|
205 }, |
|
206 "caret": { "start": 1, "length": 0 } |
|
207 }); |
|
208 |
|
209 synthesizeComposition({ type: "compositionupdate", data: "\u306D\u3053" }); |
|
210 synthesizeText( |
|
211 { "composition": |
|
212 { "string": "\u306D\u3053", |
|
213 "clauses": |
|
214 [ |
|
215 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
216 ] |
|
217 }, |
|
218 "caret": { "start": 2, "length": 0 } |
|
219 }); |
|
220 |
|
221 // convert |
|
222 synthesizeComposition({ type: "compositionupdate", data: "\u732B" }); |
|
223 synthesizeText( |
|
224 { "composition": |
|
225 { "string": "\u732B", |
|
226 "clauses": |
|
227 [ |
|
228 { "length": 1, |
|
229 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
230 ] |
|
231 }, |
|
232 "caret": { "start": 1, "length": 0 } |
|
233 }); |
|
234 |
|
235 // commit |
|
236 synthesizeText( |
|
237 { "composition": |
|
238 { "string": "\u732B", |
|
239 "clauses": |
|
240 [ |
|
241 { "length": 0, "attr": 0 } |
|
242 ] |
|
243 }, |
|
244 "caret": { "start": 1, "length": 0 } |
|
245 }); |
|
246 |
|
247 // end composition |
|
248 synthesizeComposition({ type: "compositionend", data: "\u732B" }); |
|
249 |
|
250 // start composition |
|
251 synthesizeComposition({ type: "compositionstart" }); |
|
252 |
|
253 // input raw characters |
|
254 synthesizeComposition({ type: "compositionupdate", data: "\u307E" }); |
|
255 synthesizeText( |
|
256 { "composition": |
|
257 { "string": "\u307E", |
|
258 "clauses": |
|
259 [ |
|
260 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
261 ] |
|
262 }, |
|
263 "caret": { "start": 1, "length": 0 } |
|
264 }); |
|
265 |
|
266 // cancel the composition |
|
267 synthesizeComposition({ type: "compositionupdate", data: "" }); |
|
268 synthesizeText( |
|
269 { "composition": |
|
270 { "string": "", |
|
271 "clauses": |
|
272 [ |
|
273 { "length": 0, "attr": 0 } |
|
274 ] |
|
275 }, |
|
276 "caret": { "start": 0, "length": 0 } |
|
277 }); |
|
278 |
|
279 // end composition |
|
280 synthesizeComposition({ type: "compositionend", data: "" }); |
|
281 |
|
282 // start composition |
|
283 synthesizeComposition({ type: "compositionstart" }); |
|
284 |
|
285 // input raw characters |
|
286 synthesizeComposition({ type: "compositionupdate", data: "\u3080" }); |
|
287 synthesizeText( |
|
288 { "composition": |
|
289 { "string": "\u3080", |
|
290 "clauses": |
|
291 [ |
|
292 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
293 ] |
|
294 }, |
|
295 "caret": { "start": 1, "length": 0 } |
|
296 }); |
|
297 |
|
298 synthesizeComposition({ type: "compositionupdate", data: "\u3080\u3059" }); |
|
299 synthesizeText( |
|
300 { "composition": |
|
301 { "string": "\u3080\u3059", |
|
302 "clauses": |
|
303 [ |
|
304 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
305 ] |
|
306 }, |
|
307 "caret": { "start": 2, "length": 0 } |
|
308 }); |
|
309 |
|
310 synthesizeComposition({ type: "compositionupdate", |
|
311 data: "\u3080\u3059\u3081" }); |
|
312 synthesizeText( |
|
313 { "composition": |
|
314 { "string": "\u3080\u3059\u3081", |
|
315 "clauses": |
|
316 [ |
|
317 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
318 ] |
|
319 }, |
|
320 "caret": { "start": 3, "length": 0 } |
|
321 }); |
|
322 |
|
323 // convert |
|
324 synthesizeComposition({ type: "compositionupdate", data: "\u5A18" }); |
|
325 synthesizeText( |
|
326 { "composition": |
|
327 { "string": "\u5A18", |
|
328 "clauses": |
|
329 [ |
|
330 { "length": 1, |
|
331 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
332 ] |
|
333 }, |
|
334 "caret": { "start": 1, "length": 0 } |
|
335 }); |
|
336 |
|
337 // commit |
|
338 synthesizeText( |
|
339 { "composition": |
|
340 { "string": "\u5A18", |
|
341 "clauses": |
|
342 [ |
|
343 { "length": 0, "attr": 0 } |
|
344 ] |
|
345 }, |
|
346 "caret": { "start": 1, "length": 0 } |
|
347 }); |
|
348 |
|
349 // end composition |
|
350 synthesizeComposition({ type: "compositionend", data: "\u5A18" }); |
|
351 |
|
352 synthesizeKey(" ", {}); |
|
353 synthesizeKey("m", {}); |
|
354 synthesizeKey("e", {}); |
|
355 synthesizeKey("a", {}); |
|
356 synthesizeKey("n", {}); |
|
357 synthesizeKey("t", {}); |
|
358 synthesizeKey("VK_BACK_SPACE", {}); |
|
359 synthesizeKey("s", {}); |
|
360 synthesizeKey(" ", {}); |
|
361 synthesizeKey("\"", {}); |
|
362 synthesizeKey("c", {}); |
|
363 synthesizeKey("a", {}); |
|
364 synthesizeKey("t", {}); |
|
365 synthesizeKey("-", {}); |
|
366 synthesizeKey("g", {}); |
|
367 synthesizeKey("i", {}); |
|
368 synthesizeKey("r", {}); |
|
369 synthesizeKey("l", {}); |
|
370 synthesizeKey("\"", {}); |
|
371 synthesizeKey(".", {}); |
|
372 synthesizeKey(" ", {}); |
|
373 synthesizeKey("VK_SHIFT", { type: "keydown" }); |
|
374 synthesizeKey("S", { shiftKey: true }); |
|
375 synthesizeKey("VK_SHIFT", { type: "keyup" }); |
|
376 synthesizeKey("h", {}); |
|
377 synthesizeKey("e", {}); |
|
378 synthesizeKey(" ", {}); |
|
379 synthesizeKey("i", {}); |
|
380 synthesizeKey("s", {}); |
|
381 synthesizeKey(" ", {}); |
|
382 synthesizeKey("a", {}); |
|
383 synthesizeKey(" ", {}); |
|
384 |
|
385 // start composition |
|
386 synthesizeComposition({ type: "compositionstart" }); |
|
387 |
|
388 // input raw characters |
|
389 synthesizeComposition({ type: "compositionupdate", data: "\u3088" }); |
|
390 synthesizeText( |
|
391 { "composition": |
|
392 { "string": "\u3088", |
|
393 "clauses": |
|
394 [ |
|
395 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
396 ] |
|
397 }, |
|
398 "caret": { "start": 1, "length": 0 } |
|
399 }); |
|
400 |
|
401 synthesizeComposition({ type: "compositionupdate", data: "\u3088\u3046" }); |
|
402 synthesizeText( |
|
403 { "composition": |
|
404 { "string": "\u3088\u3046", |
|
405 "clauses": |
|
406 [ |
|
407 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
408 ] |
|
409 }, |
|
410 "caret": { "start": 2, "length": 0 } |
|
411 }); |
|
412 |
|
413 synthesizeComposition({ type: "compositionupdate", |
|
414 data: "\u3088\u3046\u304b" }); |
|
415 synthesizeText( |
|
416 { "composition": |
|
417 { "string": "\u3088\u3046\u304b", |
|
418 "clauses": |
|
419 [ |
|
420 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
421 ] |
|
422 }, |
|
423 "caret": { "start": 3, "length": 0 } |
|
424 }); |
|
425 |
|
426 synthesizeComposition({ type: "compositionupdate", |
|
427 data: "\u3088\u3046\u304b\u3044" }); |
|
428 synthesizeText( |
|
429 { "composition": |
|
430 { "string": "\u3088\u3046\u304b\u3044", |
|
431 "clauses": |
|
432 [ |
|
433 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
434 ] |
|
435 }, |
|
436 "caret": { "start": 4, "length": 0 } |
|
437 }); |
|
438 |
|
439 // convert |
|
440 synthesizeComposition({ type: "compositionupdate", data: "\u5996\u602a" }); |
|
441 synthesizeText( |
|
442 { "composition": |
|
443 { "string": "\u5996\u602a", |
|
444 "clauses": |
|
445 [ |
|
446 { "length": 2, "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
447 ] |
|
448 }, |
|
449 "caret": { "start": 2, "length": 0 } |
|
450 }); |
|
451 |
|
452 // commit |
|
453 synthesizeText( |
|
454 { "composition": |
|
455 { "string": "\u5996\u602a", |
|
456 "clauses": |
|
457 [ |
|
458 { "length": 0, "attr": 0 } |
|
459 ] |
|
460 }, |
|
461 "caret": { "start": 2, "length": 0 } |
|
462 }); |
|
463 |
|
464 // end composition |
|
465 synthesizeComposition({ type: "compositionend", data: "\u5996\u602a" }); |
|
466 |
|
467 synthesizeKey("VK_BACK_SPACE", {}); |
|
468 synthesizeKey("VK_BACK_SPACE", {}); |
|
469 synthesizeKey("VK_BACK_SPACE", {}); |
|
470 synthesizeKey("VK_BACK_SPACE", {}); |
|
471 synthesizeKey("VK_BACK_SPACE", {}); |
|
472 synthesizeKey("VK_BACK_SPACE", {}); |
|
473 synthesizeKey("VK_BACK_SPACE", {}); |
|
474 synthesizeKey("VK_BACK_SPACE", {}); |
|
475 synthesizeKey("VK_BACK_SPACE", {}); |
|
476 synthesizeKey("VK_BACK_SPACE", {}); |
|
477 synthesizeKey("VK_BACK_SPACE", {}); |
|
478 synthesizeKey("VK_BACK_SPACE", {}); |
|
479 |
|
480 var i = 0; |
|
481 if (!checkContent("\u732B\u5A18 means \"cat-girl\".", |
|
482 "runUndoRedoTest", "#" + ++i) || |
|
483 !checkSelection(20, "", "runUndoRedoTest", "#" + i)) { |
|
484 return; |
|
485 } |
|
486 |
|
487 synthesizeKey("Z", {accelKey: true}); |
|
488 |
|
489 if (!checkContent("\u732B\u5A18 means \"cat-girl\". She is a \u5996\u602A", |
|
490 "runUndoRedoTest", "#" + ++i) || |
|
491 !checkSelection(32, "", "runUndoRedoTest", "#" + i)) { |
|
492 return; |
|
493 } |
|
494 |
|
495 synthesizeKey("Z", {accelKey: true}); |
|
496 |
|
497 if (!checkContent("\u732B\u5A18 means \"cat-girl\". She is a ", |
|
498 "runUndoRedoTest", "#" + ++i) || |
|
499 !checkSelection(30, "", "runUndoRedoTest", "#" + i)) { |
|
500 return; |
|
501 } |
|
502 |
|
503 synthesizeKey("Z", {accelKey: true}); |
|
504 |
|
505 if (!checkContent("\u732B\u5A18 mean", |
|
506 "runUndoRedoTest", "#" + ++i) || |
|
507 !checkSelection(7, "", "runUndoRedoTest", "#" + i)) { |
|
508 return; |
|
509 } |
|
510 |
|
511 synthesizeKey("Z", {accelKey: true}); |
|
512 |
|
513 if (!checkContent("\u732B\u5A18 meant", |
|
514 "runUndoRedoTest", "#" + ++i) || |
|
515 !checkSelection(8, "", "runUndoRedoTest", "#" + i)) { |
|
516 return; |
|
517 } |
|
518 |
|
519 synthesizeKey("Z", {accelKey: true}); |
|
520 |
|
521 if (!checkContent("\u732B\u5A18", |
|
522 "runUndoRedoTest", "#" + ++i) || |
|
523 !checkSelection(2, "", "runUndoRedoTest", "#" + i)) { |
|
524 return; |
|
525 } |
|
526 |
|
527 synthesizeKey("Z", {accelKey: true}); |
|
528 |
|
529 if (!checkContent("\u732B", |
|
530 "runUndoRedoTest", "#" + ++i) || |
|
531 !checkSelection(1, "", "runUndoRedoTest", "#" + i)) { |
|
532 return; |
|
533 } |
|
534 |
|
535 synthesizeKey("Z", {accelKey: true}); |
|
536 |
|
537 // XXX this is unexpected behavior, see bug 258291 |
|
538 if (!checkContent("\u732B", |
|
539 "runUndoRedoTest", "#" + ++i) || |
|
540 !checkSelection(1, "", "runUndoRedoTest", "#" + i)) { |
|
541 return; |
|
542 } |
|
543 |
|
544 synthesizeKey("Z", {accelKey: true}); |
|
545 |
|
546 if (!checkContent("", |
|
547 "runUndoRedoTest", "#" + ++i) || |
|
548 !checkSelection(0, "", "runUndoRedoTest", "#" + i)) { |
|
549 return; |
|
550 } |
|
551 |
|
552 synthesizeKey("Z", {accelKey: true}); |
|
553 |
|
554 if (!checkContent("", |
|
555 "runUndoRedoTest", "#" + ++i) || |
|
556 !checkSelection(0, "", "runUndoRedoTest", "#" + i)) { |
|
557 return; |
|
558 } |
|
559 |
|
560 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
561 |
|
562 if (!checkContent("\u732B", |
|
563 "runUndoRedoTest", "#" + ++i) || |
|
564 !checkSelection(1, "", "runUndoRedoTest", "#" + i)) { |
|
565 return; |
|
566 } |
|
567 |
|
568 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
569 |
|
570 // XXX this is unexpected behavior, see bug 258291 |
|
571 if (!checkContent("\u732B", |
|
572 "runUndoRedoTest", "#" + ++i) || |
|
573 !checkSelection(1, "", "runUndoRedoTest", "#" + i)) { |
|
574 return; |
|
575 } |
|
576 |
|
577 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
578 |
|
579 if (!checkContent("\u732B\u5A18", |
|
580 "runUndoRedoTest", "#" + ++i) || |
|
581 !checkSelection(2, "", "runUndoRedoTest", "#" + i)) { |
|
582 return; |
|
583 } |
|
584 |
|
585 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
586 |
|
587 if (!checkContent("\u732B\u5A18 meant", |
|
588 "runUndoRedoTest", "#" + ++i) || |
|
589 !checkSelection(8, "", "runUndoRedoTest", "#" + i)) { |
|
590 return; |
|
591 } |
|
592 |
|
593 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
594 |
|
595 if (!checkContent("\u732B\u5A18 mean", |
|
596 "runUndoRedoTest", "#" + ++i) || |
|
597 !checkSelection(7, "", "runUndoRedoTest", "#" + i)) { |
|
598 return; |
|
599 } |
|
600 |
|
601 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
602 |
|
603 if (!checkContent("\u732B\u5A18 means \"cat-girl\". She is a ", |
|
604 "runUndoRedoTest", "#" + ++i) || |
|
605 !checkSelection(30, "", "runUndoRedoTest", "#" + i)) { |
|
606 return; |
|
607 } |
|
608 |
|
609 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
610 |
|
611 if (!checkContent("\u732B\u5A18 means \"cat-girl\". She is a \u5996\u602A", |
|
612 "runUndoRedoTest", "#" + ++i) || |
|
613 !checkSelection(32, "", "runUndoRedoTest", "#" + i)) { |
|
614 return; |
|
615 } |
|
616 |
|
617 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
618 |
|
619 if (!checkContent("\u732B\u5A18 means \"cat-girl\".", |
|
620 "runUndoRedoTest", "#" + ++i) || |
|
621 !checkSelection(20, "", "runUndoRedoTest", "#" + i)) { |
|
622 return; |
|
623 } |
|
624 |
|
625 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
626 |
|
627 if (!checkContent("\u732B\u5A18 means \"cat-girl\".", |
|
628 "runUndoRedoTest", "#" + ++i) || |
|
629 !checkSelection(20, "", "runUndoRedoTest", "#" + i)) { |
|
630 return; |
|
631 } |
|
632 } |
|
633 |
|
634 function runCompositionTest() |
|
635 { |
|
636 textarea.value = ""; |
|
637 textarea.focus(); |
|
638 var caretRects = []; |
|
639 |
|
640 var caretRect = synthesizeQueryCaretRect(0); |
|
641 if (!checkQueryContentResult(caretRect, |
|
642 "runCompositionTest: synthesizeQueryCaretRect #0")) { |
|
643 return false; |
|
644 } |
|
645 caretRects[0] = caretRect; |
|
646 |
|
647 // start composition |
|
648 synthesizeComposition({ type: "compositionstart" }); |
|
649 |
|
650 // input first character |
|
651 synthesizeComposition({ type: "compositionupdate", data: "\u3089" }); |
|
652 synthesizeText( |
|
653 { "composition": |
|
654 { "string": "\u3089", |
|
655 "clauses": |
|
656 [ |
|
657 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
658 ] |
|
659 }, |
|
660 "caret": { "start": 1, "length": 0 } |
|
661 }); |
|
662 |
|
663 if (!checkContent("\u3089", "runCompositionTest", "#1-1") || |
|
664 !checkSelection(1, "", "runCompositionTest", "#1-1")) { |
|
665 return; |
|
666 } |
|
667 |
|
668 caretRect = synthesizeQueryCaretRect(1); |
|
669 if (!checkQueryContentResult(caretRect, |
|
670 "runCompositionTest: synthesizeQueryCaretRect #1-1")) { |
|
671 return false; |
|
672 } |
|
673 caretRects[1] = caretRect; |
|
674 |
|
675 // input second character |
|
676 synthesizeComposition({ type: "compositionupdate", data: "\u3089\u30FC" }); |
|
677 synthesizeText( |
|
678 { "composition": |
|
679 { "string": "\u3089\u30FC", |
|
680 "clauses": |
|
681 [ |
|
682 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
683 ] |
|
684 }, |
|
685 "caret": { "start": 2, "length": 0 } |
|
686 }); |
|
687 |
|
688 if (!checkContent("\u3089\u30FC", "runCompositionTest", "#1-2") || |
|
689 !checkSelection(2, "", "runCompositionTest", "#1-2")) { |
|
690 return; |
|
691 } |
|
692 |
|
693 caretRect = synthesizeQueryCaretRect(2); |
|
694 if (!checkQueryContentResult(caretRect, |
|
695 "runCompositionTest: synthesizeQueryCaretRect #1-2")) { |
|
696 return false; |
|
697 } |
|
698 caretRects[2] = caretRect; |
|
699 |
|
700 isnot(caretRects[2].left, caretRects[1].left, |
|
701 "runCompositionTest: caret isn't moved (#1-2)"); |
|
702 is(caretRects[2].top, caretRects[1].top, |
|
703 "runCompositionTest: caret is moved to another line (#1-2)"); |
|
704 is(caretRects[2].width, caretRects[1].width, |
|
705 "runCompositionTest: caret width is wrong (#1-2)"); |
|
706 is(caretRects[2].height, caretRects[1].height, |
|
707 "runCompositionTest: caret width is wrong (#1-2)"); |
|
708 |
|
709 // input third character |
|
710 synthesizeComposition({ type: "compositionupdate", |
|
711 data: "\u3089\u30FC\u3081" }); |
|
712 synthesizeText( |
|
713 { "composition": |
|
714 { "string": "\u3089\u30FC\u3081", |
|
715 "clauses": |
|
716 [ |
|
717 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
718 ] |
|
719 }, |
|
720 "caret": { "start": 3, "length": 0 } |
|
721 }); |
|
722 |
|
723 if (!checkContent("\u3089\u30FC\u3081", "runCompositionTest", "#1-3") || |
|
724 !checkSelection(3, "", "runCompositionTest", "#1-3")) { |
|
725 return; |
|
726 } |
|
727 |
|
728 caretRect = synthesizeQueryCaretRect(3); |
|
729 if (!checkQueryContentResult(caretRect, |
|
730 "runCompositionTest: synthesizeQueryCaretRect #1-3")) { |
|
731 return false; |
|
732 } |
|
733 caretRects[3] = caretRect; |
|
734 |
|
735 isnot(caretRects[3].left, caretRects[2].left, |
|
736 "runCompositionTest: caret isn't moved (#1-3)"); |
|
737 is(caretRects[3].top, caretRects[2].top, |
|
738 "runCompositionTest: caret is moved to another line (#1-3)"); |
|
739 is(caretRects[3].width, caretRects[2].width, |
|
740 "runCompositionTest: caret width is wrong (#1-3)"); |
|
741 is(caretRects[3].height, caretRects[2].height, |
|
742 "runCompositionTest: caret height is wrong (#1-3)"); |
|
743 |
|
744 // moves the caret left |
|
745 synthesizeText( |
|
746 { "composition": |
|
747 { "string": "\u3089\u30FC\u3081", |
|
748 "clauses": |
|
749 [ |
|
750 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
751 ] |
|
752 }, |
|
753 "caret": { "start": 2, "length": 0 } |
|
754 }); |
|
755 |
|
756 if (!checkContent("\u3089\u30FC\u3081", "runCompositionTest", "#1-3-1") || |
|
757 !checkSelection(2, "", "runCompositionTest", "#1-3-1")) { |
|
758 return; |
|
759 } |
|
760 |
|
761 |
|
762 caretRect = synthesizeQueryCaretRect(2); |
|
763 if (!checkQueryContentResult(caretRect, |
|
764 "runCompositionTest: synthesizeQueryCaretRect #1-3-1")) { |
|
765 return false; |
|
766 } |
|
767 |
|
768 is(caretRect.left, caretRects[2].left, |
|
769 "runCompositionTest: caret rects are different (#1-3-1, left)"); |
|
770 is(caretRect.top, caretRects[2].top, |
|
771 "runCompositionTest: caret rects are different (#1-3-1, top)"); |
|
772 // by bug 335359, the caret width depends on the right side's character. |
|
773 is(caretRect.width, caretRects[2].width + 1, |
|
774 "runCompositionTest: caret rects are different (#1-3-1, width)"); |
|
775 is(caretRect.height, caretRects[2].height, |
|
776 "runCompositionTest: caret rects are different (#1-3-1, height)"); |
|
777 |
|
778 // moves the caret left |
|
779 synthesizeText( |
|
780 { "composition": |
|
781 { "string": "\u3089\u30FC\u3081", |
|
782 "clauses": |
|
783 [ |
|
784 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
785 ] |
|
786 }, |
|
787 "caret": { "start": 1, "length": 0 } |
|
788 }); |
|
789 |
|
790 if (!checkContent("\u3089\u30FC\u3081", "runCompositionTest", "#1-3-2") || |
|
791 !checkSelection(1, "", "runCompositionTest", "#1-3-2")) { |
|
792 return; |
|
793 } |
|
794 |
|
795 |
|
796 caretRect = synthesizeQueryCaretRect(1); |
|
797 if (!checkQueryContentResult(caretRect, |
|
798 "runCompositionTest: synthesizeQueryCaretRect #1-3-2")) { |
|
799 return false; |
|
800 } |
|
801 |
|
802 is(caretRect.left, caretRects[1].left, |
|
803 "runCompositionTest: caret rects are different (#1-3-2, left)"); |
|
804 is(caretRect.top, caretRects[1].top, |
|
805 "runCompositionTest: caret rects are different (#1-3-2, top)"); |
|
806 // by bug 335359, the caret width depends on the right side's character. |
|
807 is(caretRect.width, caretRects[1].width + 1, |
|
808 "runCompositionTest: caret rects are different (#1-3-2, width)"); |
|
809 is(caretRect.height, caretRects[1].height, |
|
810 "runCompositionTest: caret rects are different (#1-3-2, height)"); |
|
811 |
|
812 synthesizeComposition({ type: "compositionupdate", |
|
813 data: "\u3089\u30FC\u3081\u3093" }); |
|
814 synthesizeText( |
|
815 { "composition": |
|
816 { "string": "\u3089\u30FC\u3081\u3093", |
|
817 "clauses": |
|
818 [ |
|
819 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
820 ] |
|
821 }, |
|
822 "caret": { "start": 4, "length": 0 } |
|
823 }); |
|
824 |
|
825 if (!checkContent("\u3089\u30FC\u3081\u3093", "runCompositionTest", "#1-4") || |
|
826 !checkSelection(4, "", "runCompositionTest", "#1-4")) { |
|
827 return; |
|
828 } |
|
829 |
|
830 |
|
831 // backspace |
|
832 synthesizeComposition({ type: "compositionupdate", |
|
833 data: "\u3089\u30FC\u3081" }); |
|
834 synthesizeText( |
|
835 { "composition": |
|
836 { "string": "\u3089\u30FC\u3081", |
|
837 "clauses": |
|
838 [ |
|
839 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
840 ] |
|
841 }, |
|
842 "caret": { "start": 3, "length": 0 } |
|
843 }); |
|
844 |
|
845 if (!checkContent("\u3089\u30FC\u3081", "runCompositionTest", "#1-5") || |
|
846 !checkSelection(3, "", "runCompositionTest", "#1-5")) { |
|
847 return; |
|
848 } |
|
849 |
|
850 // re-input |
|
851 synthesizeComposition({ type: "compositionupdate", |
|
852 data: "\u3089\u30FC\u3081\u3093" }); |
|
853 synthesizeText( |
|
854 { "composition": |
|
855 { "string": "\u3089\u30FC\u3081\u3093", |
|
856 "clauses": |
|
857 [ |
|
858 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
859 ] |
|
860 }, |
|
861 "caret": { "start": 4, "length": 0 } |
|
862 }); |
|
863 |
|
864 if (!checkContent("\u3089\u30FC\u3081\u3093", "runCompositionTest", "#1-6") || |
|
865 !checkSelection(4, "", "runCompositionTest", "#1-6")) { |
|
866 return; |
|
867 } |
|
868 |
|
869 synthesizeComposition({ type: "compositionupdate", |
|
870 data: "\u3089\u30FC\u3081\u3093\u3055" }); |
|
871 synthesizeText( |
|
872 { "composition": |
|
873 { "string": "\u3089\u30FC\u3081\u3093\u3055", |
|
874 "clauses": |
|
875 [ |
|
876 { "length": 5, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
877 ] |
|
878 }, |
|
879 "caret": { "start": 5, "length": 0 } |
|
880 }); |
|
881 |
|
882 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055", "runCompositionTest", "#1-7") || |
|
883 !checkSelection(5, "", "runCompositionTest", "#1-7")) { |
|
884 return; |
|
885 } |
|
886 |
|
887 synthesizeComposition({ type: "compositionupdate", |
|
888 data: "\u3089\u30FC\u3081\u3093\u3055\u3044" }); |
|
889 synthesizeText( |
|
890 { "composition": |
|
891 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044", |
|
892 "clauses": |
|
893 [ |
|
894 { "length": 6, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
895 ] |
|
896 }, |
|
897 "caret": { "start": 6, "length": 0 } |
|
898 }); |
|
899 |
|
900 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044", "runCompositionTest", "#1-8") || |
|
901 !checkSelection(6, "", "runCompositionTest", "#1-8")) { |
|
902 return; |
|
903 } |
|
904 |
|
905 synthesizeComposition({ type: "compositionupdate", |
|
906 data: "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053" }); |
|
907 synthesizeText( |
|
908 { "composition": |
|
909 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", |
|
910 "clauses": |
|
911 [ |
|
912 { "length": 7, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
913 ] |
|
914 }, |
|
915 "caret": { "start": 7, "length": 0 } |
|
916 }); |
|
917 |
|
918 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", "runCompositionTest", "#1-8") || |
|
919 !checkSelection(7, "", "runCompositionTest", "#1-8")) { |
|
920 return; |
|
921 } |
|
922 |
|
923 synthesizeComposition({ type: "compositionupdate", |
|
924 data: "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046" }); |
|
925 synthesizeText( |
|
926 { "composition": |
|
927 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", |
|
928 "clauses": |
|
929 [ |
|
930 { "length": 8, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
931 ] |
|
932 }, |
|
933 "caret": { "start": 8, "length": 0 } |
|
934 }); |
|
935 |
|
936 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", |
|
937 "runCompositionTest", "#1-9") || |
|
938 !checkSelection(8, "", "runCompositionTest", "#1-9")) { |
|
939 return; |
|
940 } |
|
941 |
|
942 // convert |
|
943 synthesizeComposition({ type: "compositionupdate", |
|
944 data: "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8" }); |
|
945 synthesizeText( |
|
946 { "composition": |
|
947 { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
948 "clauses": |
|
949 [ |
|
950 { "length": 4, |
|
951 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT }, |
|
952 { "length": 2, |
|
953 "attr": COMPOSITION_ATTR_CONVERTEDTEXT } |
|
954 ] |
|
955 }, |
|
956 "caret": { "start": 4, "length": 0 } |
|
957 }); |
|
958 |
|
959 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
960 "runCompositionTest", "#1-10") || |
|
961 !checkSelection(4, "", "runCompositionTest", "#1-10")) { |
|
962 return; |
|
963 } |
|
964 |
|
965 // change the selected clause |
|
966 synthesizeText( |
|
967 { "composition": |
|
968 { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
969 "clauses": |
|
970 [ |
|
971 { "length": 4, |
|
972 "attr": COMPOSITION_ATTR_CONVERTEDTEXT }, |
|
973 { "length": 2, |
|
974 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
975 ] |
|
976 }, |
|
977 "caret": { "start": 6, "length": 0 } |
|
978 }); |
|
979 |
|
980 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
981 "runCompositionTest", "#1-11") || |
|
982 !checkSelection(6, "", "runCompositionTest", "#1-11")) { |
|
983 return; |
|
984 } |
|
985 |
|
986 // reset clauses |
|
987 synthesizeComposition({ type: "compositionupdate", |
|
988 data: "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046" }); |
|
989 synthesizeText( |
|
990 { "composition": |
|
991 { "string": "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", |
|
992 "clauses": |
|
993 [ |
|
994 { "length": 5, |
|
995 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT }, |
|
996 { "length": 3, |
|
997 "attr": COMPOSITION_ATTR_CONVERTEDTEXT } |
|
998 ] |
|
999 }, |
|
1000 "caret": { "start": 5, "length": 0 } |
|
1001 }); |
|
1002 |
|
1003 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", |
|
1004 "runCompositionTest", "#1-12") || |
|
1005 !checkSelection(5, "", "runCompositionTest", "#1-12")) { |
|
1006 return; |
|
1007 } |
|
1008 |
|
1009 |
|
1010 var textRect1 = synthesizeQueryTextRect(0, 1); |
|
1011 var textRect2 = synthesizeQueryTextRect(1, 1); |
|
1012 if (!checkQueryContentResult(textRect1, |
|
1013 "runCompositionTest: synthesizeQueryTextRect #1-12-1") || |
|
1014 !checkQueryContentResult(textRect2, |
|
1015 "runCompositionTest: synthesizeQueryTextRect #1-12-2")) { |
|
1016 return false; |
|
1017 } |
|
1018 |
|
1019 // commit the composition string |
|
1020 synthesizeText( |
|
1021 { "composition": |
|
1022 { "string": "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", |
|
1023 "clauses": |
|
1024 [ |
|
1025 { "length": 0, "attr": 0 } |
|
1026 ] |
|
1027 }, |
|
1028 "caret": { "start": 8, "length": 0 } |
|
1029 }); |
|
1030 |
|
1031 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046", |
|
1032 "runCompositionTest", "#1-13") || |
|
1033 !checkSelection(8, "", "runCompositionTest", "#1-13")) { |
|
1034 return; |
|
1035 } |
|
1036 |
|
1037 synthesizeComposition({ type: "compositionend", |
|
1038 data: "\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046" }); |
|
1039 |
|
1040 var textRect3 = synthesizeQueryTextRect(0, 1); |
|
1041 var textRect4 = synthesizeQueryTextRect(1, 1); |
|
1042 |
|
1043 if (!checkQueryContentResult(textRect3, |
|
1044 "runCompositionTest: synthesizeQueryTextRect #1-13-1") || |
|
1045 !checkQueryContentResult(textRect4, |
|
1046 "runCompositionTest: synthesizeQueryTextRect #1-13-2")) { |
|
1047 return false; |
|
1048 } |
|
1049 |
|
1050 checkRect(textRect3, textRect1, "runCompositionTest: textRect #1-13-1"); |
|
1051 checkRect(textRect4, textRect2, "runCompositionTest: textRect #1-13-2"); |
|
1052 |
|
1053 // restart composition |
|
1054 synthesizeComposition({ type: "compositionstart" }); |
|
1055 |
|
1056 // input characters |
|
1057 synthesizeComposition({ type: "compositionupdate", data: "\u3057" }); |
|
1058 synthesizeText( |
|
1059 { "composition": |
|
1060 { "string": "\u3057", |
|
1061 "clauses": |
|
1062 [ |
|
1063 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1064 ] |
|
1065 }, |
|
1066 "caret": { "start": 1, "length": 0 } |
|
1067 }); |
|
1068 |
|
1069 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046\u3057", |
|
1070 "runCompositionTest", "#2-1") || |
|
1071 !checkSelection(8 + 1, "", "runCompositionTest", "#2-1")) { |
|
1072 return; |
|
1073 } |
|
1074 |
|
1075 synthesizeComposition({ type: "compositionupdate", data: "\u3058" }); |
|
1076 synthesizeText( |
|
1077 { "composition": |
|
1078 { "string": "\u3058", |
|
1079 "clauses": |
|
1080 [ |
|
1081 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1082 ] |
|
1083 }, |
|
1084 "caret": { "start": 1, "length": 0 } |
|
1085 }); |
|
1086 |
|
1087 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046\u3058", |
|
1088 "runCompositionTest", "#2-2") || |
|
1089 !checkSelection(8 + 1, "", "runCompositionTest", "#2-2")) { |
|
1090 return; |
|
1091 } |
|
1092 |
|
1093 synthesizeComposition({ type: "compositionupdate", data: "\u3058\u3087" }); |
|
1094 synthesizeText( |
|
1095 { "composition": |
|
1096 { "string": "\u3058\u3087", |
|
1097 "clauses": |
|
1098 [ |
|
1099 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1100 ] |
|
1101 }, |
|
1102 "caret": { "start": 2, "length": 0 } |
|
1103 }); |
|
1104 |
|
1105 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046\u3058\u3087", |
|
1106 "runCompositionTest", "#2-3") || |
|
1107 !checkSelection(8 + 2, "", "runCompositionTest", "#2-3")) { |
|
1108 return; |
|
1109 } |
|
1110 |
|
1111 synthesizeComposition({ type: "compositionupdate", |
|
1112 data: "\u3058\u3087\u3046" }); |
|
1113 synthesizeText( |
|
1114 { "composition": |
|
1115 { "string": "\u3058\u3087\u3046", |
|
1116 "clauses": |
|
1117 [ |
|
1118 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1119 ] |
|
1120 }, |
|
1121 "caret": { "start": 3, "length": 0 } |
|
1122 }); |
|
1123 |
|
1124 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046\u3058\u3087\u3046", |
|
1125 "runCompositionTest", "#2-4") || |
|
1126 !checkSelection(8 + 3, "", "runCompositionTest", "#2-4")) { |
|
1127 return; |
|
1128 } |
|
1129 |
|
1130 // commit the composition string |
|
1131 synthesizeText( |
|
1132 { "composition": |
|
1133 { "string": "\u3058\u3087\u3046", |
|
1134 "clauses": |
|
1135 [ |
|
1136 { "length": 0, "attr": 0 } |
|
1137 ] |
|
1138 }, |
|
1139 "caret": { "start": 3, "length": 0 } |
|
1140 }); |
|
1141 |
|
1142 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3055\u884C\u3053\u3046\u3058\u3087\u3046", |
|
1143 "runCompositionTest", "#2-4") || |
|
1144 !checkSelection(8 + 3, "", "runCompositionTest", "#2-4")) { |
|
1145 return; |
|
1146 } |
|
1147 |
|
1148 synthesizeComposition({ type: "compositionend", data: "\u3058\u3087\u3046" }); |
|
1149 |
|
1150 // set selection |
|
1151 var selectionSetTest = synthesizeSelectionSet(4, 7, false); |
|
1152 ok(selectionSetTest, "runCompositionTest: selectionSetTest failed"); |
|
1153 |
|
1154 if (!checkSelection(4, "\u3055\u884C\u3053\u3046\u3058\u3087\u3046", "runCompositionTest", "#3-1")) { |
|
1155 return; |
|
1156 } |
|
1157 |
|
1158 // start composition with selection |
|
1159 synthesizeComposition({ type: "compositionstart" }); |
|
1160 |
|
1161 synthesizeComposition({ type: "compositionupdate", data: "\u304A" }); |
|
1162 synthesizeText( |
|
1163 { "composition": |
|
1164 { "string": "\u304A", |
|
1165 "clauses": |
|
1166 [ |
|
1167 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1168 ] |
|
1169 }, |
|
1170 "caret": { "start": 1, "length": 0 } |
|
1171 }); |
|
1172 |
|
1173 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u304A", |
|
1174 "runCompositionTest", "#3-2") || |
|
1175 !checkSelection(4 + 1, "", "runCompositionTest", "#3-2")) { |
|
1176 return; |
|
1177 } |
|
1178 |
|
1179 // remove the composition string |
|
1180 synthesizeComposition({ type: "compositionupdate", data: "" }); |
|
1181 synthesizeText( |
|
1182 { "composition": |
|
1183 { "string": "", |
|
1184 "clauses": |
|
1185 [ |
|
1186 { "length": 0, "attr": 0 } |
|
1187 ] |
|
1188 }, |
|
1189 "caret": { "start": 0, "length": 0 } |
|
1190 }); |
|
1191 |
|
1192 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1193 "runCompositionTest", "#3-3") || |
|
1194 !checkSelection(4, "", "runCompositionTest", "#3-3")) { |
|
1195 return; |
|
1196 } |
|
1197 |
|
1198 // re-input the composition string |
|
1199 synthesizeComposition({ type: "compositionupdate", data: "\u3046" }); |
|
1200 synthesizeText( |
|
1201 { "composition": |
|
1202 { "string": "\u3046", |
|
1203 "clauses": |
|
1204 [ |
|
1205 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1206 ] |
|
1207 }, |
|
1208 "caret": { "start": 1, "length": 0 } |
|
1209 }); |
|
1210 |
|
1211 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u3046", |
|
1212 "runCompositionTest", "#3-4") || |
|
1213 !checkSelection(4 + 1, "", "runCompositionTest", "#3-4")) { |
|
1214 return; |
|
1215 } |
|
1216 |
|
1217 // cancel the composition |
|
1218 synthesizeComposition({ type: "compositionupdate", data: "" }); |
|
1219 synthesizeText( |
|
1220 { "composition": |
|
1221 { "string": "", |
|
1222 "clauses": |
|
1223 [ |
|
1224 { "length": 0, "attr": 0 } |
|
1225 ] |
|
1226 }, |
|
1227 "caret": { "start": 0, "length": 0 } |
|
1228 }); |
|
1229 |
|
1230 synthesizeComposition({ type: "compositionend", data: "" }); |
|
1231 |
|
1232 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1233 "runCompositionTest", "#3-5") || |
|
1234 !checkSelection(4, "", "runCompositionTest", "#3-5")) { |
|
1235 return; |
|
1236 } |
|
1237 |
|
1238 // bug 271815, some Chinese IMEs for Linux make empty composition string |
|
1239 // and compty clause information when it lists up Chinese characters on |
|
1240 // its candidate window. |
|
1241 synthesizeComposition({ type: "compositionstart" }); |
|
1242 |
|
1243 synthesizeText( |
|
1244 { "composition": |
|
1245 { "string": "", |
|
1246 "clauses": |
|
1247 [ |
|
1248 { "length": 0, "attr": 0 } |
|
1249 ] |
|
1250 }, |
|
1251 "caret": { "start": 0, "length": 0 } |
|
1252 }); |
|
1253 |
|
1254 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1255 "runCompositionTest", "#4-1") || |
|
1256 !checkSelection(4, "", "runCompositionTest", "#4-1")) { |
|
1257 return; |
|
1258 } |
|
1259 |
|
1260 synthesizeText( |
|
1261 { "composition": |
|
1262 { "string": "", |
|
1263 "clauses": |
|
1264 [ |
|
1265 { "length": 0, "attr": 0 } |
|
1266 ] |
|
1267 }, |
|
1268 "caret": { "start": 0, "length": 0 } |
|
1269 }); |
|
1270 |
|
1271 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1272 "runCompositionTest", "#4-2") || |
|
1273 !checkSelection(4, "", "runCompositionTest", "#4-2")) { |
|
1274 return; |
|
1275 } |
|
1276 |
|
1277 synthesizeComposition({ type: "compositionupdate", data: "\u6700" }); |
|
1278 synthesizeText( |
|
1279 { "composition": |
|
1280 { "string": "\u6700", |
|
1281 "clauses": |
|
1282 [ |
|
1283 { "length": 0, "attr": 0 } |
|
1284 ] |
|
1285 }, |
|
1286 "caret": { "start": 1, "length": 0 } |
|
1287 }); |
|
1288 |
|
1289 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1290 "runCompositionTest", "#4-3") || |
|
1291 !checkSelection(5, "", "runCompositionTest", "#4-3")) { |
|
1292 return; |
|
1293 } |
|
1294 |
|
1295 synthesizeComposition({ type: "compositionend", data: "\u6700" }); |
|
1296 |
|
1297 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1298 "runCompositionTest", "#4-4") || |
|
1299 !checkSelection(5, "", "runCompositionTest", "#4-4")) { |
|
1300 return; |
|
1301 } |
|
1302 |
|
1303 // testing the canceling case |
|
1304 synthesizeComposition({ type: "compositionstart" }); |
|
1305 |
|
1306 synthesizeText( |
|
1307 { "composition": |
|
1308 { "string": "", |
|
1309 "clauses": |
|
1310 [ |
|
1311 { "length": 0, "attr": 0 } |
|
1312 ] |
|
1313 }, |
|
1314 "caret": { "start": 0, "length": 0 } |
|
1315 }); |
|
1316 |
|
1317 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1318 "runCompositionTest", "#4-5") || |
|
1319 !checkSelection(5, "", "runCompositionTest", "#4-5")) { |
|
1320 return; |
|
1321 } |
|
1322 |
|
1323 synthesizeText( |
|
1324 { "composition": |
|
1325 { "string": "", |
|
1326 "clauses": |
|
1327 [ |
|
1328 { "length": 0, "attr": 0 } |
|
1329 ] |
|
1330 }, |
|
1331 "caret": { "start": 0, "length": 0 } |
|
1332 }); |
|
1333 |
|
1334 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1335 "runCompositionTest", "#4-6") || |
|
1336 !checkSelection(5, "", "runCompositionTest", "#4-6")) { |
|
1337 return; |
|
1338 } |
|
1339 |
|
1340 synthesizeComposition({ type: "compositionend", data: "\u6700" }); |
|
1341 |
|
1342 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1343 "runCompositionTest", "#4-7") || |
|
1344 !checkSelection(5, "", "runCompositionTest", "#4-7")) { |
|
1345 return; |
|
1346 } |
|
1347 |
|
1348 // testing whether the empty composition string deletes selected string. |
|
1349 synthesizeKey("VK_LEFT", { shiftKey: true }); |
|
1350 |
|
1351 synthesizeComposition({ type: "compositionstart" }); |
|
1352 |
|
1353 synthesizeText( |
|
1354 { "composition": |
|
1355 { "string": "", |
|
1356 "clauses": |
|
1357 [ |
|
1358 { "length": 0, "attr": 0 } |
|
1359 ] |
|
1360 }, |
|
1361 "caret": { "start": 0, "length": 0 } |
|
1362 }); |
|
1363 |
|
1364 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1365 "runCompositionTest", "#4-8") || |
|
1366 !checkSelection(4, "", "runCompositionTest", "#4-8")) { |
|
1367 return; |
|
1368 } |
|
1369 |
|
1370 synthesizeComposition({ type: "compositionupdate", data: "\u9AD8" }); |
|
1371 synthesizeText( |
|
1372 { "composition": |
|
1373 { "string": "\u9AD8", |
|
1374 "clauses": |
|
1375 [ |
|
1376 { "length": 0, "attr": 0 } |
|
1377 ] |
|
1378 }, |
|
1379 "caret": { "start": 1, "length": 0 } |
|
1380 }); |
|
1381 |
|
1382 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u9AD8", |
|
1383 "runCompositionTest", "#4-9") || |
|
1384 !checkSelection(5, "", "runCompositionTest", "#4-9")) { |
|
1385 return; |
|
1386 } |
|
1387 |
|
1388 synthesizeComposition({ type: "compositionend", data: "\u9AD8" }); |
|
1389 |
|
1390 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u9AD8", |
|
1391 "runCompositionTest", "#4-10") || |
|
1392 !checkSelection(5, "", "runCompositionTest", "#4-10")) { |
|
1393 return; |
|
1394 } |
|
1395 |
|
1396 synthesizeKey("VK_BACK_SPACE", {}); |
|
1397 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1398 "runCompositionTest", "#4-11") || |
|
1399 !checkSelection(4, "", "runCompositionTest", "#4-11")) { |
|
1400 return; |
|
1401 } |
|
1402 |
|
1403 // bug 23558, ancient Japanese IMEs on Window may send empty text event |
|
1404 // twice at canceling composition. |
|
1405 synthesizeComposition({ type: "compositionstart" }); |
|
1406 |
|
1407 synthesizeComposition({ type: "compositionupdate", data: "\u6700" }); |
|
1408 synthesizeText( |
|
1409 { "composition": |
|
1410 { "string": "\u6700", |
|
1411 "clauses": |
|
1412 [ |
|
1413 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1414 ] |
|
1415 }, |
|
1416 "caret": { "start": 1, "length": 0 } |
|
1417 }); |
|
1418 |
|
1419 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1420 "runCompositionTest", "#5-1") || |
|
1421 !checkSelection(4 + 1, "", "runCompositionTest", "#5-1")) { |
|
1422 return; |
|
1423 } |
|
1424 |
|
1425 synthesizeComposition({ type: "compositionupdate", data: "" }); |
|
1426 synthesizeText( |
|
1427 { "composition": |
|
1428 { "string": "", |
|
1429 "clauses": |
|
1430 [ |
|
1431 { "length": 0, "attr": 0 } |
|
1432 ] |
|
1433 }, |
|
1434 "caret": { "start": 0, "length": 0 } |
|
1435 }); |
|
1436 |
|
1437 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1438 "runCompositionTest", "#5-2") || |
|
1439 !checkSelection(4, "", "runCompositionTest", "#5-2")) { |
|
1440 return; |
|
1441 } |
|
1442 |
|
1443 synthesizeText( |
|
1444 { "composition": |
|
1445 { "string": "", |
|
1446 "clauses": |
|
1447 [ |
|
1448 { "length": 0, "attr": 0 } |
|
1449 ] |
|
1450 }, |
|
1451 "caret": { "start": 0, "length": 0 } |
|
1452 }); |
|
1453 |
|
1454 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1455 "runCompositionTest", "#5-3") || |
|
1456 !checkSelection(4, "", "runCompositionTest", "#5-3")) { |
|
1457 return; |
|
1458 } |
|
1459 |
|
1460 synthesizeComposition({ type: "compositionend", data: "\u9AD8" }); |
|
1461 |
|
1462 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1463 "runCompositionTest", "#5-4") || |
|
1464 !checkSelection(4, "", "runCompositionTest", "#5-4")) { |
|
1465 return; |
|
1466 } |
|
1467 |
|
1468 // Undo tests for the testcases for bug 23558 and bug 271815 |
|
1469 synthesizeKey("Z", { accelKey: true }); |
|
1470 |
|
1471 // XXX this is unexpected behavior, see bug 258291 |
|
1472 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1473 "runCompositionTest", "#6-1") || |
|
1474 !checkSelection(4, "", "runCompositionTest", "#6-1")) { |
|
1475 return; |
|
1476 } |
|
1477 |
|
1478 synthesizeKey("Z", { accelKey: true }); |
|
1479 |
|
1480 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u9AD8", |
|
1481 "runCompositionTest", "#6-2") || |
|
1482 !checkSelection(5, "", "runCompositionTest", "#6-2")) { |
|
1483 return; |
|
1484 } |
|
1485 |
|
1486 synthesizeKey("Z", { accelKey: true }); |
|
1487 |
|
1488 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1489 "runCompositionTest", "#6-3") || |
|
1490 !checkSelection(4, "\u6700", "runCompositionTest", "#6-3")) { |
|
1491 return; |
|
1492 } |
|
1493 |
|
1494 synthesizeKey("Z", { accelKey: true }); |
|
1495 |
|
1496 // XXX this is unexpected behavior, see bug 258291 |
|
1497 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700", |
|
1498 "runCompositionTest", "#6-4") || |
|
1499 !checkSelection(5, "", "runCompositionTest", "#6-4")) { |
|
1500 return; |
|
1501 } |
|
1502 |
|
1503 synthesizeKey("Z", { accelKey: true }); |
|
1504 |
|
1505 if (!checkContent("\u30E9\u30FC\u30E1\u30F3", |
|
1506 "runCompositionTest", "#6-5") || |
|
1507 !checkSelection(4, "", "runCompositionTest", "#6-5")) { |
|
1508 return; |
|
1509 } |
|
1510 } |
|
1511 |
|
1512 function runCompositionEventTest() |
|
1513 { |
|
1514 const kDescription = "runCompositionEventTest: "; |
|
1515 const kEvents = ["compositionstart", "compositionupdate", "compositionend", |
|
1516 "input"]; |
|
1517 |
|
1518 input.value = ""; |
|
1519 input.focus(); |
|
1520 |
|
1521 var windowEventCounts = [], windowEventData = [], windowEventLocale = []; |
|
1522 var inputEventCounts = [], inputEventData = [], inputEventLocale = []; |
|
1523 var preventDefault = false; |
|
1524 var stopPropagation = false; |
|
1525 |
|
1526 function initResults() |
|
1527 { |
|
1528 for (var i = 0; i < kEvents.length; i++) { |
|
1529 windowEventCounts[kEvents[i]] = 0; |
|
1530 windowEventData[kEvents[i]] = ""; |
|
1531 windowEventLocale[kEvents[i]] = ""; |
|
1532 inputEventCounts[kEvents[i]] = 0; |
|
1533 inputEventData[kEvents[i]] = ""; |
|
1534 inputEventLocale[kEvents[i]] = ""; |
|
1535 } |
|
1536 } |
|
1537 |
|
1538 function compositionEventHandlerForWindow(aEvent) |
|
1539 { |
|
1540 windowEventCounts[aEvent.type]++; |
|
1541 windowEventData[aEvent.type] = aEvent.data; |
|
1542 windowEventLocale[aEvent.type] = aEvent.locale; |
|
1543 if (preventDefault) { |
|
1544 aEvent.preventDefault(); |
|
1545 } |
|
1546 if (stopPropagation) { |
|
1547 aEvent.stopPropagation(); |
|
1548 } |
|
1549 } |
|
1550 |
|
1551 function formEventHandlerForWindow(aEvent) |
|
1552 { |
|
1553 ok(aEvent.isTrusted, "input events must be trusted events"); |
|
1554 windowEventCounts[aEvent.type]++; |
|
1555 windowEventData[aEvent.type] = input.value; |
|
1556 } |
|
1557 |
|
1558 function compositionEventHandlerForInput(aEvent) |
|
1559 { |
|
1560 inputEventCounts[aEvent.type]++; |
|
1561 inputEventData[aEvent.type] = aEvent.data; |
|
1562 inputEventLocale[aEvent.type] = aEvent.locale; |
|
1563 if (preventDefault) { |
|
1564 aEvent.preventDefault(); |
|
1565 } |
|
1566 if (stopPropagation) { |
|
1567 aEvent.stopPropagation(); |
|
1568 } |
|
1569 } |
|
1570 |
|
1571 function formEventHandlerForInput(aEvent) |
|
1572 { |
|
1573 inputEventCounts[aEvent.type]++; |
|
1574 inputEventData[aEvent.type] = input.value; |
|
1575 } |
|
1576 |
|
1577 window.addEventListener("compositionstart", compositionEventHandlerForWindow, |
|
1578 true, true); |
|
1579 window.addEventListener("compositionend", compositionEventHandlerForWindow, |
|
1580 true, true); |
|
1581 window.addEventListener("compositionupdate", compositionEventHandlerForWindow, |
|
1582 true, true); |
|
1583 window.addEventListener("input", formEventHandlerForWindow, |
|
1584 true, true); |
|
1585 |
|
1586 input.addEventListener("compositionstart", compositionEventHandlerForInput, |
|
1587 true, true); |
|
1588 input.addEventListener("compositionend", compositionEventHandlerForInput, |
|
1589 true, true); |
|
1590 input.addEventListener("compositionupdate", compositionEventHandlerForInput, |
|
1591 true, true); |
|
1592 input.addEventListener("input", formEventHandlerForInput, |
|
1593 true, true); |
|
1594 |
|
1595 // test for normal case |
|
1596 initResults(); |
|
1597 |
|
1598 synthesizeComposition({ type: "compositionstart" }); |
|
1599 synthesizeComposition({ type: "compositionupdate", data: "\u3089" }); |
|
1600 synthesizeText( |
|
1601 { "composition": |
|
1602 { "string": "\u3089", |
|
1603 "clauses": |
|
1604 [ |
|
1605 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1606 ] |
|
1607 }, |
|
1608 "caret": { "start": 1, "length": 0 } |
|
1609 }); |
|
1610 |
|
1611 is(windowEventCounts["compositionstart"], 1, |
|
1612 kDescription + "compositionstart hasn't been handled by window #1"); |
|
1613 is(windowEventData["compositionstart"], "", |
|
1614 kDescription + "data of compositionstart isn't empty (window) #1"); |
|
1615 is(windowEventLocale["compositionstart"], "", |
|
1616 kDescription + "locale of compositionstart isn't empty (window) #1"); |
|
1617 is(inputEventCounts["compositionstart"], 1, |
|
1618 kDescription + "compositionstart hasn't been handled by input #1"); |
|
1619 is(inputEventData["compositionstart"], "", |
|
1620 kDescription + "data of compositionstart isn't empty (input) #1"); |
|
1621 is(inputEventLocale["compositionstart"], "", |
|
1622 kDescription + "locale of compositionstart isn't empty (input) #1"); |
|
1623 |
|
1624 is(windowEventCounts["compositionupdate"], 1, |
|
1625 kDescription + "compositionupdate hasn't been handled by window #1"); |
|
1626 is(windowEventData["compositionupdate"], "\u3089", |
|
1627 kDescription + "data of compositionupdate doesn't match (window) #1"); |
|
1628 is(windowEventLocale["compositionupdate"], "", |
|
1629 kDescription + "locale of compositionupdate isn't empty (window) #1"); |
|
1630 is(inputEventCounts["compositionupdate"], 1, |
|
1631 kDescription + "compositionupdate hasn't been handled by input #1"); |
|
1632 is(inputEventData["compositionupdate"], "\u3089", |
|
1633 kDescription + "data of compositionupdate doesn't match (input) #1"); |
|
1634 is(inputEventLocale["compositionupdate"], "", |
|
1635 kDescription + "locale of compositionupdate isn't empty (input) #1"); |
|
1636 |
|
1637 is(windowEventCounts["compositionend"], 0, |
|
1638 kDescription + "compositionend has been handled by window #1"); |
|
1639 is(inputEventCounts["compositionend"], 0, |
|
1640 kDescription + "compositionend has been handled by input #1"); |
|
1641 |
|
1642 is(windowEventCounts["input"], 1, |
|
1643 kDescription + "input hasn't been handled by window #1"); |
|
1644 is(windowEventData["input"], "\u3089", |
|
1645 kDescription + "value of input element wasn't modified (window) #1"); |
|
1646 is(inputEventCounts["input"], 1, |
|
1647 kDescription + "input hasn't been handled by input #1"); |
|
1648 is(inputEventData["input"], "\u3089", |
|
1649 kDescription + "value of input element wasn't modified (input) #1"); |
|
1650 |
|
1651 synthesizeComposition({ type: "compositionupdate", data: "\u3089\u30FC" }); |
|
1652 synthesizeText( |
|
1653 { "composition": |
|
1654 { "string": "\u3089\u30FC", |
|
1655 "clauses": |
|
1656 [ |
|
1657 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1658 ] |
|
1659 }, |
|
1660 "caret": { "start": 2, "length": 0 } |
|
1661 }); |
|
1662 |
|
1663 is(windowEventCounts["compositionstart"], 1, |
|
1664 kDescription + "compositionstart has been handled more than once by window #2"); |
|
1665 is(inputEventCounts["compositionstart"], 1, |
|
1666 kDescription + "compositionstart has been handled more than once by input #2"); |
|
1667 |
|
1668 is(windowEventCounts["compositionupdate"], 2, |
|
1669 kDescription + "compositionupdate hasn't been handled by window #2"); |
|
1670 is(windowEventData["compositionupdate"], "\u3089\u30FC", |
|
1671 kDescription + "data of compositionupdate doesn't match (window) #2"); |
|
1672 is(windowEventLocale["compositionupdate"], "", |
|
1673 kDescription + "locale of compositionupdate isn't empty (window) #2"); |
|
1674 is(inputEventCounts["compositionupdate"], 2, |
|
1675 kDescription + "compositionupdate hasn't been handled by input #2"); |
|
1676 is(inputEventData["compositionupdate"], "\u3089\u30FC", |
|
1677 kDescription + "data of compositionupdate doesn't match (input) #2"); |
|
1678 is(inputEventLocale["compositionupdate"], "", |
|
1679 kDescription + "locale of compositionupdate isn't empty (input) #2"); |
|
1680 |
|
1681 is(windowEventCounts["compositionend"], 0, |
|
1682 kDescription + "compositionend has been handled during composition by window #2"); |
|
1683 is(inputEventCounts["compositionend"], 0, |
|
1684 kDescription + "compositionend has been handled during composition by input #2"); |
|
1685 |
|
1686 is(windowEventCounts["input"], 2, |
|
1687 kDescription + "input hasn't been handled by window #2"); |
|
1688 is(windowEventData["input"], "\u3089\u30FC", |
|
1689 kDescription + "value of input element wasn't modified (window) #2"); |
|
1690 is(inputEventCounts["input"], 2, |
|
1691 kDescription + "input hasn't been handled by input #2"); |
|
1692 is(inputEventData["input"], "\u3089\u30FC", |
|
1693 kDescription + "value of input element wasn't modified (input) #2"); |
|
1694 |
|
1695 // text event shouldn't cause composition update, e.g., at committing. |
|
1696 synthesizeText( |
|
1697 { "composition": |
|
1698 { "string": "\u3089\u30FC", |
|
1699 "clauses": |
|
1700 [ |
|
1701 { "length": 0, "attr": 0 } |
|
1702 ] |
|
1703 }, |
|
1704 "caret": { "start": 2, "length": 0 } |
|
1705 }); |
|
1706 |
|
1707 synthesizeComposition({ type: "compositionend", data: "\u3089\u30FC" }); |
|
1708 |
|
1709 is(windowEventCounts["compositionstart"], 1, |
|
1710 kDescription + "compositionstart has been handled more than once by window #3"); |
|
1711 is(inputEventCounts["compositionstart"], 1, |
|
1712 kDescription + "compositionstart has been handled more than once by input #3"); |
|
1713 |
|
1714 is(windowEventCounts["compositionupdate"], 2, |
|
1715 kDescription + "compositionupdate has been fired unexpectedly on window #3"); |
|
1716 is(inputEventCounts["compositionupdate"], 2, |
|
1717 kDescription + "compositionupdate has been fired unexpectedly on input #3"); |
|
1718 |
|
1719 is(windowEventCounts["compositionend"], 1, |
|
1720 kDescription + "compositionend hasn't been handled by window #3"); |
|
1721 is(windowEventData["compositionend"], "\u3089\u30FC", |
|
1722 kDescription + "data of compositionend doesn't match (window) #3"); |
|
1723 is(windowEventLocale["compositionend"], "", |
|
1724 kDescription + "locale of compositionend isn't empty (window) #3"); |
|
1725 is(inputEventCounts["compositionend"], 1, |
|
1726 kDescription + "compositionend hasn't been handled by input #3"); |
|
1727 is(inputEventData["compositionend"], "\u3089\u30FC", |
|
1728 kDescription + "data of compositionend doesn't match (input) #3"); |
|
1729 is(inputEventLocale["compositionend"], "", |
|
1730 kDescription + "locale of compositionend isn't empty (input) #3"); |
|
1731 |
|
1732 is(windowEventCounts["input"], 3, |
|
1733 kDescription + "input hasn't been handled by window #3"); |
|
1734 is(windowEventData["input"], "\u3089\u30FC", |
|
1735 kDescription + "value of input element wasn't modified (window) #3"); |
|
1736 is(inputEventCounts["input"], 3, |
|
1737 kDescription + "input hasn't been handled by input #3"); |
|
1738 is(inputEventData["input"], "\u3089\u30FC", |
|
1739 kDescription + "value of input element wasn't modified (input) #3"); |
|
1740 |
|
1741 // select the second character, then, data of composition start should be |
|
1742 // the selected character. |
|
1743 initResults(); |
|
1744 synthesizeKey("VK_LEFT", { shiftKey: true }); |
|
1745 |
|
1746 synthesizeComposition({ type: "compositionstart" }); |
|
1747 |
|
1748 synthesizeComposition({ type: "compositionupdate", data: "\u3089" }); |
|
1749 synthesizeText( |
|
1750 { "composition": |
|
1751 { "string": "\u3089", |
|
1752 "clauses": |
|
1753 [ |
|
1754 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1755 ] |
|
1756 }, |
|
1757 "caret": { "start": 1, "length": 0 } |
|
1758 }); |
|
1759 |
|
1760 synthesizeText( |
|
1761 { "composition": |
|
1762 { "string": "\u3089", |
|
1763 "clauses": |
|
1764 [ |
|
1765 { "length": 0, "attr": 0 } |
|
1766 ] |
|
1767 }, |
|
1768 "caret": { "start": 1, "length": 0 } |
|
1769 }); |
|
1770 |
|
1771 synthesizeComposition({ type: "compositionend", data: "\u3089" }); |
|
1772 |
|
1773 is(windowEventCounts["compositionstart"], 1, |
|
1774 kDescription + "compositionstart hasn't been handled by window #4"); |
|
1775 is(windowEventData["compositionstart"], "\u30FC", |
|
1776 kDescription + "data of compositionstart is empty (window) #4"); |
|
1777 is(windowEventLocale["compositionstart"], "", |
|
1778 kDescription + "locale of compositionstart isn't empty (window) #4"); |
|
1779 is(inputEventCounts["compositionstart"], 1, |
|
1780 kDescription + "compositionstart hasn't been handled by input #4"); |
|
1781 is(inputEventData["compositionstart"], "\u30FC", |
|
1782 kDescription + "data of compositionstart is empty (input) #4"); |
|
1783 is(inputEventLocale["compositionstart"], "", |
|
1784 kDescription + "locale of compositionstart isn't empty (input) #4"); |
|
1785 |
|
1786 is(windowEventCounts["compositionupdate"], 1, |
|
1787 kDescription + "compositionupdate hasn't been handled by window #4"); |
|
1788 is(windowEventData["compositionupdate"], "\u3089", |
|
1789 kDescription + "data of compositionupdate doesn't match (window) #4"); |
|
1790 is(windowEventLocale["compositionupdate"], "", |
|
1791 kDescription + "locale of compositionupdate isn't empty (window) #4"); |
|
1792 is(inputEventCounts["compositionupdate"], 1, |
|
1793 kDescription + "compositionupdate hasn't been handled by input #4"); |
|
1794 is(inputEventData["compositionupdate"], "\u3089", |
|
1795 kDescription + "data of compositionupdate doesn't match (input) #4"); |
|
1796 is(inputEventLocale["compositionupdate"], "", |
|
1797 kDescription + "locale of compositionupdate isn't empty (input) #4"); |
|
1798 |
|
1799 is(windowEventCounts["compositionend"], 1, |
|
1800 kDescription + "compositionend hasn't been handled by window #4"); |
|
1801 is(windowEventData["compositionend"], "\u3089", |
|
1802 kDescription + "data of compositionend doesn't match (window) #4"); |
|
1803 is(windowEventLocale["compositionend"], "", |
|
1804 kDescription + "locale of compositionend isn't empty (window) #4"); |
|
1805 is(inputEventCounts["compositionend"], 1, |
|
1806 kDescription + "compositionend hasn't been handled by input #4"); |
|
1807 is(inputEventData["compositionend"], "\u3089", |
|
1808 kDescription + "data of compositionend doesn't match (input) #4"); |
|
1809 is(inputEventLocale["compositionend"], "", |
|
1810 kDescription + "locale of compositionend isn't empty (input) #4"); |
|
1811 |
|
1812 is(windowEventCounts["input"], 2, |
|
1813 kDescription + "input hasn't been handled by window #4"); |
|
1814 is(windowEventData["input"], "\u3089\u3089", |
|
1815 kDescription + "value of input element wasn't modified (window) #4"); |
|
1816 is(inputEventCounts["input"], 2, |
|
1817 kDescription + "input hasn't been handled by input #4"); |
|
1818 is(inputEventData["input"], "\u3089\u3089", |
|
1819 kDescription + "value of input element wasn't modified (input) #4"); |
|
1820 |
|
1821 // preventDefault() should effect nothing. |
|
1822 preventDefault = true; |
|
1823 |
|
1824 initResults(); |
|
1825 synthesizeKey("A", { accelKey: true }); // Select All |
|
1826 |
|
1827 synthesizeComposition({ type: "compositionstart" }); |
|
1828 |
|
1829 synthesizeComposition({ type: "compositionupdate", data: "\u306D" }); |
|
1830 synthesizeText( |
|
1831 { "composition": |
|
1832 { "string": "\u306D", |
|
1833 "clauses": |
|
1834 [ |
|
1835 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1836 ] |
|
1837 }, |
|
1838 "caret": { "start": 1, "length": 0 } |
|
1839 }); |
|
1840 |
|
1841 synthesizeText( |
|
1842 { "composition": |
|
1843 { "string": "\u306D", |
|
1844 "clauses": |
|
1845 [ |
|
1846 { "length": 0, "attr": 0 } |
|
1847 ] |
|
1848 }, |
|
1849 "caret": { "start": 1, "length": 0 } |
|
1850 }); |
|
1851 |
|
1852 synthesizeComposition({ type: "compositionend", data: "\u306D" }); |
|
1853 |
|
1854 is(windowEventCounts["compositionstart"], 1, |
|
1855 kDescription + "compositionstart hasn't been handled by window #5"); |
|
1856 is(windowEventData["compositionstart"], "\u3089\u3089", |
|
1857 kDescription + "data of compositionstart is empty (window) #5"); |
|
1858 is(windowEventLocale["compositionstart"], "", |
|
1859 kDescription + "locale of compositionstart isn't empty (window) #5"); |
|
1860 is(inputEventCounts["compositionstart"], 1, |
|
1861 kDescription + "compositionstart hasn't been handled by input #5"); |
|
1862 is(inputEventData["compositionstart"], "\u3089\u3089", |
|
1863 kDescription + "data of compositionstart is empty (input) #5"); |
|
1864 is(inputEventLocale["compositionstart"], "", |
|
1865 kDescription + "locale of compositionstart isn't empty (input) #5"); |
|
1866 |
|
1867 is(windowEventCounts["compositionupdate"], 1, |
|
1868 kDescription + "compositionupdate hasn't been handled by window #5"); |
|
1869 is(windowEventData["compositionupdate"], "\u306D", |
|
1870 kDescription + "data of compositionupdate doesn't match (window) #5"); |
|
1871 is(windowEventLocale["compositionupdate"], "", |
|
1872 kDescription + "locale of compositionupdate isn't empty (window) #5"); |
|
1873 is(inputEventCounts["compositionupdate"], 1, |
|
1874 kDescription + "compositionupdate hasn't been handled by input #5"); |
|
1875 is(inputEventData["compositionupdate"], "\u306D", |
|
1876 kDescription + "data of compositionupdate doesn't match (input) #5"); |
|
1877 is(inputEventLocale["compositionupdate"], "", |
|
1878 kDescription + "locale of compositionupdate isn't empty (input) #5"); |
|
1879 |
|
1880 is(windowEventCounts["compositionend"], 1, |
|
1881 kDescription + "compositionend hasn't been handled by window #5"); |
|
1882 is(windowEventData["compositionend"], "\u306D", |
|
1883 kDescription + "data of compositionend doesn't match (window) #5"); |
|
1884 is(windowEventLocale["compositionend"], "", |
|
1885 kDescription + "locale of compositionend isn't empty (window) #5"); |
|
1886 is(inputEventCounts["compositionend"], 1, |
|
1887 kDescription + "compositionend hasn't been handled by input #5"); |
|
1888 is(inputEventData["compositionend"], "\u306D", |
|
1889 kDescription + "data of compositionend doesn't match (input) #5"); |
|
1890 is(inputEventLocale["compositionend"], "", |
|
1891 kDescription + "locale of compositionend isn't empty (input) #5"); |
|
1892 |
|
1893 is(windowEventCounts["input"], 2, |
|
1894 kDescription + "input hasn't been handled by window #5"); |
|
1895 is(windowEventData["input"], "\u306D", |
|
1896 kDescription + "value of input element wasn't modified (window) #5"); |
|
1897 is(inputEventCounts["input"], 2, |
|
1898 kDescription + "input hasn't been handled by input #5"); |
|
1899 is(inputEventData["input"], "\u306D", |
|
1900 kDescription + "value of input element wasn't modified (input) #5"); |
|
1901 |
|
1902 prevnetDefault = false; |
|
1903 |
|
1904 // stopPropagation() should effect nothing (except event count) |
|
1905 stopPropagation = true; |
|
1906 |
|
1907 initResults(); |
|
1908 synthesizeKey("A", { accelKey: true }); // Select All |
|
1909 |
|
1910 synthesizeComposition({ type: "compositionstart" }); |
|
1911 |
|
1912 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
1913 synthesizeText( |
|
1914 { "composition": |
|
1915 { "string": "\u306E", |
|
1916 "clauses": |
|
1917 [ |
|
1918 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1919 ] |
|
1920 }, |
|
1921 "caret": { "start": 1, "length": 0 } |
|
1922 }); |
|
1923 |
|
1924 synthesizeText( |
|
1925 { "composition": |
|
1926 { "string": "\u306E", |
|
1927 "clauses": |
|
1928 [ |
|
1929 { "length": 0, "attr": 0 } |
|
1930 ] |
|
1931 }, |
|
1932 "caret": { "start": 1, "length": 0 } |
|
1933 }); |
|
1934 |
|
1935 synthesizeComposition({ type: "compositionend", data: "\u306E" }); |
|
1936 |
|
1937 is(windowEventCounts["compositionstart"], 1, |
|
1938 kDescription + "compositionstart hasn't been handled by window #6"); |
|
1939 is(windowEventData["compositionstart"], "\u306D", |
|
1940 kDescription + "data of compositionstart is empty #6"); |
|
1941 is(windowEventLocale["compositionstart"], "", |
|
1942 kDescription + "locale of compositionstart isn't empty #6"); |
|
1943 is(inputEventCounts["compositionstart"], 0, |
|
1944 kDescription + "compositionstart has been handled by input #6"); |
|
1945 |
|
1946 is(windowEventCounts["compositionupdate"], 1, |
|
1947 kDescription + "compositionupdate hasn't been handled by window #6"); |
|
1948 is(windowEventData["compositionupdate"], "\u306E", |
|
1949 kDescription + "data of compositionupdate doesn't match #6"); |
|
1950 is(windowEventLocale["compositionupdate"], "", |
|
1951 kDescription + "locale of compositionupdate isn't empty #6"); |
|
1952 is(inputEventCounts["compositionupdate"], 0, |
|
1953 kDescription + "compositionupdate has been handled by input #6"); |
|
1954 |
|
1955 is(windowEventCounts["compositionend"], 1, |
|
1956 kDescription + "compositionend hasn't been handled by window #6"); |
|
1957 is(windowEventData["compositionend"], "\u306E", |
|
1958 kDescription + "data of compositionend doesn't match #6"); |
|
1959 is(windowEventLocale["compositionend"], "", |
|
1960 kDescription + "locale of compositionend isn't empty #6"); |
|
1961 is(inputEventCounts["compositionend"], 0, |
|
1962 kDescription + "compositionend has been handled by input #6"); |
|
1963 |
|
1964 is(windowEventCounts["input"], 2, |
|
1965 kDescription + "input hasn't been handled by window #6"); |
|
1966 is(windowEventData["input"], "\u306E", |
|
1967 kDescription + "value of input element wasn't modified (window) #6"); |
|
1968 is(inputEventCounts["input"], 2, |
|
1969 kDescription + "input hasn't been handled by input #6"); |
|
1970 is(inputEventData["input"], "\u306E", |
|
1971 kDescription + "value of input element wasn't modified (input) #6"); |
|
1972 |
|
1973 stopPropagation = false; |
|
1974 |
|
1975 // create event and dispatch it. |
|
1976 initResults(); |
|
1977 |
|
1978 input.value = "value of input"; |
|
1979 synthesizeKey("A", { accelKey: true }); // Select All |
|
1980 |
|
1981 var compositionstart = document.createEvent("CompositionEvent"); |
|
1982 compositionstart.initCompositionEvent("compositionstart", |
|
1983 true, true, document.defaultView, |
|
1984 "start data", "start locale"); |
|
1985 is(compositionstart.type, "compositionstart", |
|
1986 kDescription + "type doesn't match #7"); |
|
1987 is(compositionstart.data, "start data", |
|
1988 kDescription + "data doesn't match #7"); |
|
1989 is(compositionstart.locale, "start locale", |
|
1990 kDescription + "locale doesn't match #7"); |
|
1991 is(compositionstart.detail, 0, |
|
1992 kDescription + "detail isn't 0 #7"); |
|
1993 |
|
1994 input.dispatchEvent(compositionstart); |
|
1995 |
|
1996 is(windowEventCounts["compositionstart"], 1, |
|
1997 kDescription + "compositionstart hasn't been handled by window #7"); |
|
1998 is(windowEventData["compositionstart"], "start data", |
|
1999 kDescription + "data of compositionstart was changed (window) #7"); |
|
2000 is(windowEventLocale["compositionstart"], "start locale", |
|
2001 kDescription + "locale of compositionstart was changed (window) #7"); |
|
2002 is(inputEventCounts["compositionstart"], 1, |
|
2003 kDescription + "compositionstart hasn't been handled by input #7"); |
|
2004 is(inputEventData["compositionstart"], "start data", |
|
2005 kDescription + "data of compositionstart was changed (input) #7"); |
|
2006 is(inputEventLocale["compositionstart"], "start locale", |
|
2007 kDescription + "locale of compositionstart was changed (input) #7"); |
|
2008 |
|
2009 is(input.value, "value of input", |
|
2010 kDescription + "input value was changed #7"); |
|
2011 |
|
2012 var compositionupdate1 = document.createEvent("compositionevent"); |
|
2013 compositionupdate1.initCompositionEvent("compositionupdate", |
|
2014 true, false, document.defaultView, |
|
2015 "composing string", "composing locale"); |
|
2016 is(compositionupdate1.type, "compositionupdate", |
|
2017 kDescription + "type doesn't match #8"); |
|
2018 is(compositionupdate1.data, "composing string", |
|
2019 kDescription + "data doesn't match #8"); |
|
2020 is(compositionupdate1.locale, "composing locale", |
|
2021 kDescription + "locale doesn't match #8"); |
|
2022 is(compositionupdate1.detail, 0, |
|
2023 kDescription + "detail isn't 0 #8"); |
|
2024 |
|
2025 input.dispatchEvent(compositionupdate1); |
|
2026 |
|
2027 is(windowEventCounts["compositionupdate"], 1, |
|
2028 kDescription + "compositionupdate hasn't been handled by window #8"); |
|
2029 is(windowEventData["compositionupdate"], "composing string", |
|
2030 kDescription + "data of compositionupdate was changed (window) #8"); |
|
2031 is(windowEventLocale["compositionupdate"], "composing locale", |
|
2032 kDescription + "locale of compositionupdate was changed (window) #8"); |
|
2033 is(inputEventCounts["compositionupdate"], 1, |
|
2034 kDescription + "compositionupdate hasn't been handled by input #8"); |
|
2035 is(inputEventData["compositionupdate"], "composing string", |
|
2036 kDescription + "data of compositionupdate was changed (input) #8"); |
|
2037 is(inputEventLocale["compositionupdate"], "composing locale", |
|
2038 kDescription + "locale of compositionupdate was changed (input) #8"); |
|
2039 |
|
2040 is(input.value, "value of input", |
|
2041 kDescription + "input value was changed #8"); |
|
2042 |
|
2043 var compositionupdate2 = document.createEvent("compositionEvent"); |
|
2044 compositionupdate2.initCompositionEvent("compositionupdate", |
|
2045 true, false, document.defaultView, |
|
2046 "commit string", "commit locale"); |
|
2047 is(compositionupdate2.type, "compositionupdate", |
|
2048 kDescription + "type doesn't match #9"); |
|
2049 is(compositionupdate2.data, "commit string", |
|
2050 kDescription + "data doesn't match #9"); |
|
2051 is(compositionupdate2.locale, "commit locale", |
|
2052 kDescription + "locale doesn't match #9"); |
|
2053 is(compositionupdate2.detail, 0, |
|
2054 kDescription + "detail isn't 0 #9"); |
|
2055 |
|
2056 input.dispatchEvent(compositionupdate2); |
|
2057 |
|
2058 is(windowEventCounts["compositionupdate"], 2, |
|
2059 kDescription + "compositionupdate hasn't been handled by window #9"); |
|
2060 is(windowEventData["compositionupdate"], "commit string", |
|
2061 kDescription + "data of compositionupdate was changed (window) #9"); |
|
2062 is(windowEventLocale["compositionupdate"], "commit locale", |
|
2063 kDescription + "locale of compositionupdate was changed (window) #9"); |
|
2064 is(inputEventCounts["compositionupdate"], 2, |
|
2065 kDescription + "compositionupdate hasn't been handled by input #9"); |
|
2066 is(inputEventData["compositionupdate"], "commit string", |
|
2067 kDescription + "data of compositionupdate was changed (input) #9"); |
|
2068 is(inputEventLocale["compositionupdate"], "commit locale", |
|
2069 kDescription + "locale of compositionupdate was changed (input) #9"); |
|
2070 |
|
2071 is(input.value, "value of input", |
|
2072 kDescription + "input value was changed #9"); |
|
2073 |
|
2074 var compositionend = document.createEvent("Compositionevent"); |
|
2075 compositionend.initCompositionEvent("compositionend", |
|
2076 true, false, document.defaultView, |
|
2077 "end data", "end locale"); |
|
2078 is(compositionend.type, "compositionend", |
|
2079 kDescription + "type doesn't match #10"); |
|
2080 is(compositionend.data, "end data", |
|
2081 kDescription + "data doesn't match #10"); |
|
2082 is(compositionend.locale, "end locale", |
|
2083 kDescription + "locale doesn't match #10"); |
|
2084 is(compositionend.detail, 0, |
|
2085 kDescription + "detail isn't 0 #10"); |
|
2086 |
|
2087 input.dispatchEvent(compositionend); |
|
2088 |
|
2089 is(windowEventCounts["compositionend"], 1, |
|
2090 kDescription + "compositionend hasn't been handled by window #10"); |
|
2091 is(windowEventData["compositionend"], "end data", |
|
2092 kDescription + "data of compositionend was changed (window) #10"); |
|
2093 is(windowEventLocale["compositionend"], "end locale", |
|
2094 kDescription + "locale of compositionend was changed (window) #10"); |
|
2095 is(inputEventCounts["compositionend"], 1, |
|
2096 kDescription + "compositionend hasn't been handled by input #10"); |
|
2097 is(inputEventData["compositionend"], "end data", |
|
2098 kDescription + "data of compositionend was changed (input) #10"); |
|
2099 is(inputEventLocale["compositionend"], "end locale", |
|
2100 kDescription + "locale of compositionend was changed (input) #10"); |
|
2101 |
|
2102 is(input.value, "value of input", |
|
2103 kDescription + "input value was changed #10"); |
|
2104 |
|
2105 window.removeEventListener("compositionstart", |
|
2106 compositionEventHandlerForWindow, true); |
|
2107 window.removeEventListener("compositionend", |
|
2108 compositionEventHandlerForWindow, true); |
|
2109 window.removeEventListener("compositionupdate", |
|
2110 compositionEventHandlerForWindow, true); |
|
2111 window.removeEventListener("input", |
|
2112 formEventHandlerForWindow, true); |
|
2113 |
|
2114 input.removeEventListener("compositionstart", |
|
2115 compositionEventHandlerForInput, true); |
|
2116 input.removeEventListener("compositionend", |
|
2117 compositionEventHandlerForInput, true); |
|
2118 input.removeEventListener("compositionupdate", |
|
2119 compositionEventHandlerForInput, true); |
|
2120 input.removeEventListener("input", |
|
2121 formEventHandlerForInput, true); |
|
2122 } |
|
2123 |
|
2124 function runCharAtPointTest(aFocusedEditor, aTargetName) |
|
2125 { |
|
2126 aFocusedEditor.value = "This is a test of the\nContent Events"; |
|
2127 // 012345678901234567890 12345678901234 |
|
2128 // 0 1 2 3 |
|
2129 |
|
2130 aFocusedEditor.focus(); |
|
2131 |
|
2132 const kNone = -1; |
|
2133 const kTestingOffset = [ 0, 10, 20, 21 + kLFLen, 34 + kLFLen]; |
|
2134 const kLeftSideOffset = [ kNone, 9, 19, kNone, 33 + kLFLen]; |
|
2135 const kRightSideOffset = [ 1, 11, kNone, 22 + kLFLen, kNone]; |
|
2136 |
|
2137 var editorRect = synthesizeQueryEditorRect(); |
|
2138 if (!checkQueryContentResult(editorRect, |
|
2139 "runCharAtPointTest (" + aTargetName + "): editorRect")) { |
|
2140 return; |
|
2141 } |
|
2142 |
|
2143 for (var i = 0; i < kTestingOffset.length; i++) { |
|
2144 var textRect = synthesizeQueryTextRect(kTestingOffset[i], 1); |
|
2145 if (!checkQueryContentResult(textRect, |
|
2146 "runCharAtPointTest (" + aTargetName + "): textRect: i=" + i)) { |
|
2147 continue; |
|
2148 } |
|
2149 |
|
2150 checkRectContainsRect(textRect, editorRect, |
|
2151 "runCharAtPointTest (" + aTargetName + |
|
2152 "): the text rect isn't in the editor"); |
|
2153 |
|
2154 // Test #1, getting same character rect by the point near the top-left. |
|
2155 var charAtPt1 = synthesizeCharAtPoint(textRect.left + 1, |
|
2156 textRect.top + 1); |
|
2157 if (checkQueryContentResult(charAtPt1, |
|
2158 "runCharAtPointTest (" + aTargetName + "): charAtPt1: i=" + i)) { |
|
2159 ok(!charAtPt1.notFound, |
|
2160 "runCharAtPointTest (" + aTargetName + "): charAtPt1 isn't found: i=" + i); |
|
2161 if (!charAtPt1.notFound) { |
|
2162 is(charAtPt1.offset, kTestingOffset[i], |
|
2163 "runCharAtPointTest (" + aTargetName + "): charAtPt1 offset is wrong: i=" + i); |
|
2164 checkRect(charAtPt1, textRect, "runCharAtPointTest (" + aTargetName + |
|
2165 "): charAtPt1 left is wrong: i=" + i); |
|
2166 } |
|
2167 } |
|
2168 |
|
2169 // Test #2, getting same character rect by the point near the bottom-right. |
|
2170 var charAtPt2 = synthesizeCharAtPoint(textRect.left + textRect.width - 2, |
|
2171 textRect.top + textRect.height - 2); |
|
2172 if (checkQueryContentResult(charAtPt2, |
|
2173 "runCharAtPointTest (" + aTargetName + "): charAtPt2: i=" + i)) { |
|
2174 ok(!charAtPt2.notFound, |
|
2175 "runCharAtPointTest (" + aTargetName + "): charAtPt2 isn't found: i=" + i); |
|
2176 if (!charAtPt2.notFound) { |
|
2177 is(charAtPt2.offset, kTestingOffset[i], |
|
2178 "runCharAtPointTest (" + aTargetName + "): charAtPt2 offset is wrong: i=" + i); |
|
2179 checkRect(charAtPt2, textRect, "runCharAtPointTest (" + aTargetName + |
|
2180 "): charAtPt1 left is wrong: i=" + i); |
|
2181 } |
|
2182 } |
|
2183 |
|
2184 // Test #3, getting left character offset. |
|
2185 var charAtPt3 = synthesizeCharAtPoint(textRect.left - 2, |
|
2186 textRect.top + 1); |
|
2187 if (checkQueryContentResult(charAtPt3, |
|
2188 "runCharAtPointTest (" + aTargetName + "): charAtPt3: i=" + i)) { |
|
2189 is(charAtPt3.notFound, kLeftSideOffset[i] == kNone, |
|
2190 kLeftSideOffset[i] == kNone ? |
|
2191 "runCharAtPointTest (" + aTargetName + "): charAtPt3 is found: i=" + i : |
|
2192 "runCharAtPointTest (" + aTargetName + "): charAtPt3 isn't found: i=" + i); |
|
2193 if (!charAtPt3.notFound) { |
|
2194 is(charAtPt3.offset, kLeftSideOffset[i], |
|
2195 "runCharAtPointTest (" + aTargetName + "): charAtPt3 offset is wrong: i=" + i); |
|
2196 } |
|
2197 } |
|
2198 |
|
2199 // Test #4, getting right character offset. |
|
2200 var charAtPt4 = synthesizeCharAtPoint(textRect.left + textRect.width + 1, |
|
2201 textRect.top + textRect.height - 2); |
|
2202 if (checkQueryContentResult(charAtPt4, |
|
2203 "runCharAtPointTest (" + aTargetName + "): charAtPt4: i=" + i)) { |
|
2204 is(charAtPt4.notFound, kRightSideOffset[i] == kNone, |
|
2205 kRightSideOffset[i] == kNone ? |
|
2206 "runCharAtPointTest (" + aTargetName + "): charAtPt4 is found: i=" + i : |
|
2207 "runCharAtPointTest (" + aTargetName + "): charAtPt4 isn't found: i=" + i); |
|
2208 if (!charAtPt4.notFound) { |
|
2209 is(charAtPt4.offset, kRightSideOffset[i], |
|
2210 "runCharAtPointTest (" + aTargetName + "): charAtPt4 offset is wrong: i=" + i); |
|
2211 } |
|
2212 } |
|
2213 } |
|
2214 } |
|
2215 |
|
2216 function runCharAtPointAtOutsideTest() |
|
2217 { |
|
2218 textarea.focus(); |
|
2219 textarea.value = "some text"; |
|
2220 var editorRect = synthesizeQueryEditorRect(); |
|
2221 if (!checkQueryContentResult(editorRect, |
|
2222 "runCharAtPointAtOutsideTest: editorRect")) { |
|
2223 return; |
|
2224 } |
|
2225 // Check on a text node which is at the outside of editor. |
|
2226 var charAtPt = synthesizeCharAtPoint(editorRect.left + 20, |
|
2227 editorRect.top - 10); |
|
2228 if (checkQueryContentResult(charAtPt, |
|
2229 "runCharAtPointAtOutsideTest: charAtPt")) { |
|
2230 ok(charAtPt.notFound, |
|
2231 "runCharAtPointAtOutsideTest: charAtPt is found on outside of editor"); |
|
2232 } |
|
2233 } |
|
2234 |
|
2235 function runBug722639Test() |
|
2236 { |
|
2237 textarea.focus(); |
|
2238 textarea.value = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; |
|
2239 textarea.value += textarea.value; |
|
2240 textarea.value += textarea.value; // 80 characters |
|
2241 |
|
2242 var firstLine = synthesizeQueryTextRect(0, 1); |
|
2243 if (!checkQueryContentResult(firstLine, |
|
2244 "runBug722639Test: firstLine")) { |
|
2245 return; |
|
2246 } |
|
2247 var secondLine = synthesizeQueryTextRect(kLFLen, 1); |
|
2248 if (!checkQueryContentResult(secondLine, |
|
2249 "runBug722639Test: secondLine")) { |
|
2250 return; |
|
2251 } |
|
2252 var lineHeight = secondLine.top - firstLine.top; |
|
2253 ok(lineHeight > 0, |
|
2254 "runBug722639Test: lineHeight must be positive"); |
|
2255 is(secondLine.left, firstLine.left, |
|
2256 "runBug722639Test: the left value must be always same value"); |
|
2257 var previousTop = secondLine.top; |
|
2258 for (var i = 2; i < textarea.value.length; i++) { |
|
2259 var currentLine = synthesizeQueryTextRect(kLFLen * i, 1); |
|
2260 if (!checkQueryContentResult(currentLine, |
|
2261 "runBug722639Test: " + i + "th currentLine")) { |
|
2262 return; |
|
2263 } |
|
2264 // NOTE: the top position may be 1px larger or smaller than other lines |
|
2265 // due to sub pixel positioning. |
|
2266 if (Math.abs(currentLine.top - (previousTop + lineHeight)) <= 1) { |
|
2267 ok(true, "runBug722639Test: " + i + "th line's top is expected"); |
|
2268 } else { |
|
2269 is(currentLine.top, previousTop + lineHeight, |
|
2270 "runBug722639Test: " + i + "th line's top is unexpected"); |
|
2271 } |
|
2272 is(currentLine.left, firstLine.left, |
|
2273 "runBug722639Test: " + i + "th line's left is unexpected"); |
|
2274 previousTop = currentLine.top; |
|
2275 } |
|
2276 } |
|
2277 |
|
2278 function runForceCommitTest() |
|
2279 { |
|
2280 var events; |
|
2281 function eventHandler(aEvent) |
|
2282 { |
|
2283 events.push(aEvent); |
|
2284 } |
|
2285 window.addEventListener("compositionstart", eventHandler, true); |
|
2286 window.addEventListener("compositionupdate", eventHandler, true); |
|
2287 window.addEventListener("compositionend", eventHandler, true); |
|
2288 window.addEventListener("input", eventHandler, true); |
|
2289 window.addEventListener("text", eventHandler, true); |
|
2290 |
|
2291 // Make the composition in textarea commit by click in the textarea |
|
2292 textarea.focus(); |
|
2293 textarea.value = ""; |
|
2294 |
|
2295 events = []; |
|
2296 synthesizeComposition({ type: "compositionstart" }); |
|
2297 |
|
2298 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2299 synthesizeText( |
|
2300 { "composition": |
|
2301 { "string": "\u306E", |
|
2302 "clauses": |
|
2303 [ |
|
2304 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2305 ] |
|
2306 }, |
|
2307 "caret": { "start": 1, "length": 0 } |
|
2308 }); |
|
2309 |
|
2310 is(events.length, 4, |
|
2311 "runForceCommitTest: wrong event count #1"); |
|
2312 is(events[0].type, "compositionstart", |
|
2313 "runForceCommitTest: the 1st event must be compositionstart #1"); |
|
2314 is(events[1].type, "compositionupdate", |
|
2315 "runForceCommitTest: the 2nd event must be compositionupdate #1"); |
|
2316 is(events[2].type, "text", |
|
2317 "runForceCommitTest: the 3rd event must be text #1"); |
|
2318 is(events[3].type, "input", |
|
2319 "runForceCommitTest: the 4th event must be input #1"); |
|
2320 |
|
2321 events = []; |
|
2322 synthesizeMouseAtCenter(textarea, {}); |
|
2323 |
|
2324 is(events.length, 3, |
|
2325 "runForceCommitTest: wrong event count #2"); |
|
2326 is(events[0].type, "text", |
|
2327 "runForceCommitTest: the 1st event must be text #2"); |
|
2328 is(events[1].type, "compositionend", |
|
2329 "runForceCommitTest: the 2nd event must be compositionend #2"); |
|
2330 is(events[2].type, "input", |
|
2331 "runForceCommitTest: the 3rd event must be input #2"); |
|
2332 is(events[1].data, "\u306E", |
|
2333 "runForceCommitTest: compositionend has wrong data #2"); |
|
2334 is(events[0].target, textarea, |
|
2335 "runForceCommitTest: The 1st event was fired on wrong event target #2"); |
|
2336 is(events[1].target, textarea, |
|
2337 "runForceCommitTest: The 2nd event was fired on wrong event target #2"); |
|
2338 is(events[2].target, textarea, |
|
2339 "runForceCommitTest: The 3rd event was fired on wrong event target #2"); |
|
2340 ok(!getEditorIMESupport(textarea).isComposing, |
|
2341 "runForceCommitTest: the textarea still has composition #2"); |
|
2342 is(textarea.value, "\u306E", |
|
2343 "runForceCommitTest: the textarea doesn't have the committed text #2"); |
|
2344 |
|
2345 // Make the composition in textarea commit by click in another editor (input) |
|
2346 textarea.focus(); |
|
2347 textarea.value = ""; |
|
2348 input.value = ""; |
|
2349 |
|
2350 synthesizeComposition({ type: "compositionstart" }); |
|
2351 |
|
2352 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2353 synthesizeText( |
|
2354 { "composition": |
|
2355 { "string": "\u306E", |
|
2356 "clauses": |
|
2357 [ |
|
2358 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2359 ] |
|
2360 }, |
|
2361 "caret": { "start": 1, "length": 0 } |
|
2362 }); |
|
2363 |
|
2364 events = []; |
|
2365 synthesizeMouseAtCenter(input, {}); |
|
2366 |
|
2367 is(events.length, 3, |
|
2368 "runForceCommitTest: wrong event count #3"); |
|
2369 is(events[0].type, "text", |
|
2370 "runForceCommitTest: the 1st event must be text #3"); |
|
2371 is(events[1].type, "compositionend", |
|
2372 "runForceCommitTest: the 2nd event must be compositionend #3"); |
|
2373 is(events[2].type, "input", |
|
2374 "runForceCommitTest: the 3rd event must be input #3"); |
|
2375 is(events[1].data, "\u306E", |
|
2376 "runForceCommitTest: compositionend has wrong data #3"); |
|
2377 is(events[0].target, textarea, |
|
2378 "runForceCommitTest: The 1st event was fired on wrong event target #3"); |
|
2379 is(events[1].target, textarea, |
|
2380 "runForceCommitTest: The 2nd event was fired on wrong event target #3"); |
|
2381 is(events[2].target, textarea, |
|
2382 "runForceCommitTest: The 3rd event was fired on wrong event target #3"); |
|
2383 ok(!getEditorIMESupport(textarea).isComposing, |
|
2384 "runForceCommitTest: the textarea still has composition #3"); |
|
2385 ok(!getEditorIMESupport(input).isComposing, |
|
2386 "runForceCommitTest: the input has composition #3"); |
|
2387 is(textarea.value, "\u306E", |
|
2388 "runForceCommitTest: the textarea doesn't have the committed text #3"); |
|
2389 is(input.value, "", |
|
2390 "runForceCommitTest: the input has the committed text? #3"); |
|
2391 |
|
2392 // Make the composition in textarea commit by blur() |
|
2393 textarea.focus(); |
|
2394 textarea.value = ""; |
|
2395 |
|
2396 synthesizeComposition({ type: "compositionstart" }); |
|
2397 |
|
2398 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2399 synthesizeText( |
|
2400 { "composition": |
|
2401 { "string": "\u306E", |
|
2402 "clauses": |
|
2403 [ |
|
2404 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2405 ] |
|
2406 }, |
|
2407 "caret": { "start": 1, "length": 0 } |
|
2408 }); |
|
2409 |
|
2410 events = []; |
|
2411 textarea.blur(); |
|
2412 |
|
2413 is(events.length, 3, |
|
2414 "runForceCommitTest: wrong event count #4"); |
|
2415 is(events[0].type, "text", |
|
2416 "runForceCommitTest: the 1st event must be text #4"); |
|
2417 is(events[1].type, "compositionend", |
|
2418 "runForceCommitTest: the 2nd event must be compositionend #4"); |
|
2419 is(events[2].type, "input", |
|
2420 "runForceCommitTest: the 3rd event must be input #4"); |
|
2421 is(events[1].data, "\u306E", |
|
2422 "runForceCommitTest: compositionend has wrong data #4"); |
|
2423 is(events[0].target, textarea, |
|
2424 "runForceCommitTest: The 1st event was fired on wrong event target #4"); |
|
2425 is(events[1].target, textarea, |
|
2426 "runForceCommitTest: The 2nd event was fired on wrong event target #4"); |
|
2427 is(events[2].target, textarea, |
|
2428 "runForceCommitTest: The 3rd event was fired on wrong event target #4"); |
|
2429 ok(!getEditorIMESupport(textarea).isComposing, |
|
2430 "runForceCommitTest: the textarea still has composition #4"); |
|
2431 is(textarea.value, "\u306E", |
|
2432 "runForceCommitTest: the textarea doesn't have the committed text #4"); |
|
2433 |
|
2434 // Make the composition in textarea commit by input.focus() |
|
2435 textarea.focus(); |
|
2436 textarea.value = ""; |
|
2437 input.value = ""; |
|
2438 |
|
2439 synthesizeComposition({ type: "compositionstart" }); |
|
2440 |
|
2441 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2442 synthesizeText( |
|
2443 { "composition": |
|
2444 { "string": "\u306E", |
|
2445 "clauses": |
|
2446 [ |
|
2447 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2448 ] |
|
2449 }, |
|
2450 "caret": { "start": 1, "length": 0 } |
|
2451 }); |
|
2452 |
|
2453 events = []; |
|
2454 input.focus(); |
|
2455 |
|
2456 is(events.length, 3, |
|
2457 "runForceCommitTest: wrong event count #5"); |
|
2458 is(events[0].type, "text", |
|
2459 "runForceCommitTest: the 1st event must be text #5"); |
|
2460 is(events[1].type, "compositionend", |
|
2461 "runForceCommitTest: the 2nd event must be compositionend #5"); |
|
2462 is(events[2].type, "input", |
|
2463 "runForceCommitTest: the 3rd event must be input #5"); |
|
2464 is(events[1].data, "\u306E", |
|
2465 "runForceCommitTest: compositionend has wrong data #5"); |
|
2466 is(events[0].target, textarea, |
|
2467 "runForceCommitTest: The 1st event was fired on wrong event target #5"); |
|
2468 is(events[1].target, textarea, |
|
2469 "runForceCommitTest: The 2nd event was fired on wrong event target #5"); |
|
2470 is(events[2].target, textarea, |
|
2471 "runForceCommitTest: The 3rd event was fired on wrong event target #5"); |
|
2472 ok(!getEditorIMESupport(textarea).isComposing, |
|
2473 "runForceCommitTest: the textarea still has composition #5"); |
|
2474 ok(!getEditorIMESupport(input).isComposing, |
|
2475 "runForceCommitTest: the input has composition #5"); |
|
2476 is(textarea.value, "\u306E", |
|
2477 "runForceCommitTest: the textarea doesn't have the committed text #5"); |
|
2478 is(input.value, "", |
|
2479 "runForceCommitTest: the input has the committed text? #5"); |
|
2480 |
|
2481 // Make the composition in textarea commit by click in another document's editor |
|
2482 textarea.focus(); |
|
2483 textarea.value = ""; |
|
2484 textareaInFrame.value = ""; |
|
2485 |
|
2486 synthesizeComposition({ type: "compositionstart" }); |
|
2487 |
|
2488 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2489 synthesizeText( |
|
2490 { "composition": |
|
2491 { "string": "\u306E", |
|
2492 "clauses": |
|
2493 [ |
|
2494 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2495 ] |
|
2496 }, |
|
2497 "caret": { "start": 1, "length": 0 } |
|
2498 }); |
|
2499 |
|
2500 events = []; |
|
2501 synthesizeMouseAtCenter(textareaInFrame, {}, iframe.contentWindow); |
|
2502 |
|
2503 is(events.length, 3, |
|
2504 "runForceCommitTest: wrong event count #6"); |
|
2505 is(events[0].type, "text", |
|
2506 "runForceCommitTest: the 1st event must be text #6"); |
|
2507 is(events[1].type, "compositionend", |
|
2508 "runForceCommitTest: the 2nd event must be compositionend #6"); |
|
2509 is(events[2].type, "input", |
|
2510 "runForceCommitTest: the 3rd event must be input #6"); |
|
2511 is(events[1].data, "\u306E", |
|
2512 "runForceCommitTest: compositionend has wrong data #6"); |
|
2513 is(events[0].target, textarea, |
|
2514 "runForceCommitTest: The 1st event was fired on wrong event target #6"); |
|
2515 is(events[1].target, textarea, |
|
2516 "runForceCommitTest: The 2nd event was fired on wrong event target #6"); |
|
2517 is(events[2].target, textarea, |
|
2518 "runForceCommitTest: The 3rd event was fired on wrong event target #6"); |
|
2519 ok(!getEditorIMESupport(textarea).isComposing, |
|
2520 "runForceCommitTest: the textarea still has composition #6"); |
|
2521 ok(!getEditorIMESupport(textareaInFrame).isComposing, |
|
2522 "runForceCommitTest: the textarea in frame has composition #6"); |
|
2523 is(textarea.value, "\u306E", |
|
2524 "runForceCommitTest: the textarea doesn't have the committed text #6"); |
|
2525 is(textareaInFrame.value, "", |
|
2526 "runForceCommitTest: the textarea in frame has the committed text? #6"); |
|
2527 |
|
2528 // Make the composition in textarea commit by another document's editor's focus() |
|
2529 textarea.focus(); |
|
2530 textarea.value = ""; |
|
2531 textareaInFrame.value = ""; |
|
2532 |
|
2533 synthesizeComposition({ type: "compositionstart" }); |
|
2534 |
|
2535 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2536 synthesizeText( |
|
2537 { "composition": |
|
2538 { "string": "\u306E", |
|
2539 "clauses": |
|
2540 [ |
|
2541 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2542 ] |
|
2543 }, |
|
2544 "caret": { "start": 1, "length": 0 } |
|
2545 }); |
|
2546 |
|
2547 events = []; |
|
2548 textareaInFrame.focus(); |
|
2549 |
|
2550 is(events.length, 3, |
|
2551 "runForceCommitTest: wrong event count #7"); |
|
2552 is(events[0].type, "text", |
|
2553 "runForceCommitTest: the 1st event must be text #7"); |
|
2554 is(events[1].type, "compositionend", |
|
2555 "runForceCommitTest: the 2nd event must be compositionend #7"); |
|
2556 is(events[2].type, "input", |
|
2557 "runForceCommitTest: the 3rd event must be input #7"); |
|
2558 is(events[1].data, "\u306E", |
|
2559 "runForceCommitTest: compositionend has wrong data #7"); |
|
2560 is(events[0].target, textarea, |
|
2561 "runForceCommitTest: The 1st event was fired on wrong event target #7"); |
|
2562 is(events[1].target, textarea, |
|
2563 "runForceCommitTest: The 2nd event was fired on wrong event target #7"); |
|
2564 is(events[2].target, textarea, |
|
2565 "runForceCommitTest: The 3rd event was fired on wrong event target #7"); |
|
2566 ok(!getEditorIMESupport(textarea).isComposing, |
|
2567 "runForceCommitTest: the textarea still has composition #7"); |
|
2568 ok(!getEditorIMESupport(textareaInFrame).isComposing, |
|
2569 "runForceCommitTest: the textarea in frame has composition #7"); |
|
2570 is(textarea.value, "\u306E", |
|
2571 "runForceCommitTest: the textarea doesn't have the committed text #7"); |
|
2572 is(textareaInFrame.value, "", |
|
2573 "runForceCommitTest: the textarea in frame has the committed text? #7"); |
|
2574 |
|
2575 // Make the composition in a textarea commit by click in another editable document |
|
2576 textarea.focus(); |
|
2577 textarea.value = ""; |
|
2578 iframe2.contentDocument.body.innerHTML = "Text in the Body"; |
|
2579 var iframe2BodyInnerHTML = iframe2.contentDocument.body.innerHTML; |
|
2580 |
|
2581 synthesizeComposition({ type: "compositionstart" }); |
|
2582 |
|
2583 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2584 synthesizeText( |
|
2585 { "composition": |
|
2586 { "string": "\u306E", |
|
2587 "clauses": |
|
2588 [ |
|
2589 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2590 ] |
|
2591 }, |
|
2592 "caret": { "start": 1, "length": 0 } |
|
2593 }); |
|
2594 |
|
2595 events = []; |
|
2596 synthesizeMouseAtCenter(iframe2.contentDocument.body, {}, iframe2.contentWindow); |
|
2597 |
|
2598 is(events.length, 3, |
|
2599 "runForceCommitTest: wrong event count #8"); |
|
2600 is(events[0].type, "text", |
|
2601 "runForceCommitTest: the 1st event must be text #8"); |
|
2602 is(events[1].type, "compositionend", |
|
2603 "runForceCommitTest: the 2nd event must be compositionend #8"); |
|
2604 is(events[2].type, "input", |
|
2605 "runForceCommitTest: the 3rd event must be input #8"); |
|
2606 is(events[1].data, "\u306E", |
|
2607 "runForceCommitTest: compositionend has wrong data #8"); |
|
2608 is(events[0].target, textarea, |
|
2609 "runForceCommitTest: The 1st event was fired on wrong event target #8"); |
|
2610 is(events[1].target, textarea, |
|
2611 "runForceCommitTest: The 2nd event was fired on wrong event target #8"); |
|
2612 is(events[2].target, textarea, |
|
2613 "runForceCommitTest: The 3rd event was fired on wrong event target #8"); |
|
2614 ok(!getEditorIMESupport(textarea).isComposing, |
|
2615 "runForceCommitTest: the textarea still has composition #8"); |
|
2616 ok(!getHTMLEditorIMESupport(iframe2.contentWindow).isComposing, |
|
2617 "runForceCommitTest: the editable document has composition #8"); |
|
2618 is(textarea.value, "\u306E", |
|
2619 "runForceCommitTest: the textarea doesn't have the committed text #8"); |
|
2620 is(iframe2.contentDocument.body.innerHTML, iframe2BodyInnerHTML, |
|
2621 "runForceCommitTest: the editable document has the committed text? #8"); |
|
2622 |
|
2623 // Make the composition in an editable document commit by click in it |
|
2624 iframe2.contentWindow.focus(); |
|
2625 iframe2.contentDocument.body.innerHTML = "Text in the Body"; |
|
2626 iframe2BodyInnerHTML = iframe2.contentDocument.body.innerHTML; |
|
2627 |
|
2628 synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); |
|
2629 |
|
2630 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }, iframe2.contentWindow); |
|
2631 synthesizeText( |
|
2632 { "composition": |
|
2633 { "string": "\u306E", |
|
2634 "clauses": |
|
2635 [ |
|
2636 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2637 ] |
|
2638 }, |
|
2639 "caret": { "start": 1, "length": 0 } |
|
2640 }, iframe2.contentWindow); |
|
2641 |
|
2642 events = []; |
|
2643 synthesizeMouseAtCenter(iframe2.contentDocument.body, {}, iframe2.contentWindow); |
|
2644 |
|
2645 is(events.length, 3, |
|
2646 "runForceCommitTest: wrong event count #9"); |
|
2647 is(events[0].type, "text", |
|
2648 "runForceCommitTest: the 1st event must be text #9"); |
|
2649 is(events[1].type, "compositionend", |
|
2650 "runForceCommitTest: the 2nd event must be compositionend #9"); |
|
2651 is(events[2].type, "input", |
|
2652 "runForceCommitTest: the 3rd event must be input #9"); |
|
2653 is(events[1].data, "\u306E", |
|
2654 "runForceCommitTest: compositionend has wrong data #9"); |
|
2655 is(events[0].target, iframe2.contentDocument.body, |
|
2656 "runForceCommitTest: The 1st event was fired on wrong event target #9"); |
|
2657 is(events[1].target, iframe2.contentDocument.body, |
|
2658 "runForceCommitTest: The 2nd event was fired on wrong event target #9"); |
|
2659 is(events[2].target, iframe2.contentDocument.body, |
|
2660 "runForceCommitTest: The 3rd event was fired on wrong event target #9"); |
|
2661 ok(!getHTMLEditorIMESupport(iframe2.contentWindow).isComposing, |
|
2662 "runForceCommitTest: the editable document still has composition #9"); |
|
2663 ok(iframe2.contentDocument.body.innerHTML != iframe2BodyInnerHTML && |
|
2664 iframe2.contentDocument.body.innerHTML.indexOf("\u306E") >= 0, |
|
2665 "runForceCommitTest: the editable document doesn't have the committed text #9"); |
|
2666 |
|
2667 // Make the composition in an editable document commit by click in another document's editor |
|
2668 textarea.value = ""; |
|
2669 iframe2.contentWindow.focus(); |
|
2670 iframe2.contentDocument.body.innerHTML = "Text in the Body"; |
|
2671 iframe2BodyInnerHTML = iframe2.contentDocument.body.innerHTML; |
|
2672 |
|
2673 synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); |
|
2674 |
|
2675 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }, iframe2.contentWindow); |
|
2676 synthesizeText( |
|
2677 { "composition": |
|
2678 { "string": "\u306E", |
|
2679 "clauses": |
|
2680 [ |
|
2681 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2682 ] |
|
2683 }, |
|
2684 "caret": { "start": 1, "length": 0 } |
|
2685 }, iframe2.contentWindow); |
|
2686 |
|
2687 events = []; |
|
2688 synthesizeMouseAtCenter(textarea, {}); |
|
2689 |
|
2690 is(events.length, 3, |
|
2691 "runForceCommitTest: wrong event count #10"); |
|
2692 is(events[0].type, "text", |
|
2693 "runForceCommitTest: the 1st event must be text #10"); |
|
2694 is(events[1].type, "compositionend", |
|
2695 "runForceCommitTest: the 2nd event must be compositionend #10"); |
|
2696 is(events[2].type, "input", |
|
2697 "runForceCommitTest: the 3rd event must be input #10"); |
|
2698 is(events[1].data, "\u306E", |
|
2699 "runForceCommitTest: compositionend has wrong data #10"); |
|
2700 is(events[0].target, iframe2.contentDocument.body, |
|
2701 "runForceCommitTest: The 1st event was fired on wrong event target #10"); |
|
2702 is(events[1].target, iframe2.contentDocument.body, |
|
2703 "runForceCommitTest: The 2nd event was fired on wrong event target #10"); |
|
2704 is(events[2].target, iframe2.contentDocument.body, |
|
2705 "runForceCommitTest: The 3rd event was fired on wrong event target #10"); |
|
2706 ok(!getHTMLEditorIMESupport(iframe2.contentWindow).isComposing, |
|
2707 "runForceCommitTest: the editable document still has composition #10"); |
|
2708 ok(!getEditorIMESupport(textarea).isComposing, |
|
2709 "runForceCommitTest: the textarea has composition #10"); |
|
2710 ok(iframe2.contentDocument.body.innerHTML != iframe2BodyInnerHTML && |
|
2711 iframe2.contentDocument.body.innerHTML.indexOf("\u306E") >= 0, |
|
2712 "runForceCommitTest: the editable document doesn't have the committed text #10"); |
|
2713 is(textarea.value, "", |
|
2714 "runForceCommitTest: the textarea has the committed text? #10"); |
|
2715 |
|
2716 // Make the composition in an editable document commit by click in the another editable document |
|
2717 iframe2.contentWindow.focus(); |
|
2718 iframe2.contentDocument.body.innerHTML = "Text in the Body"; |
|
2719 iframe2BodyInnerHTML = iframe2.contentDocument.body.innerHTML; |
|
2720 iframe3.contentDocument.body.innerHTML = "Text in the Body"; |
|
2721 iframe3BodyInnerHTML = iframe2.contentDocument.body.innerHTML; |
|
2722 |
|
2723 synthesizeComposition({ type: "compositionstart" }, iframe2.contentWindow); |
|
2724 |
|
2725 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }, iframe2.contentWindow); |
|
2726 synthesizeText( |
|
2727 { "composition": |
|
2728 { "string": "\u306E", |
|
2729 "clauses": |
|
2730 [ |
|
2731 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2732 ] |
|
2733 }, |
|
2734 "caret": { "start": 1, "length": 0 } |
|
2735 }, iframe2.contentWindow); |
|
2736 |
|
2737 events = []; |
|
2738 synthesizeMouseAtCenter(iframe3.contentDocument.body, {}, iframe3.contentWindow); |
|
2739 |
|
2740 is(events.length, 3, |
|
2741 "runForceCommitTest: wrong event count #11"); |
|
2742 is(events[0].type, "text", |
|
2743 "runForceCommitTest: the 1st event must be text #11"); |
|
2744 is(events[1].type, "compositionend", |
|
2745 "runForceCommitTest: the 2nd event must be compositionend #11"); |
|
2746 is(events[2].type, "input", |
|
2747 "runForceCommitTest: the 3rd event must be input #11"); |
|
2748 is(events[1].data, "\u306E", |
|
2749 "runForceCommitTest: compositionend has wrong data #11"); |
|
2750 is(events[0].target, iframe2.contentDocument.body, |
|
2751 "runForceCommitTest: The 1st event was fired on wrong event target #11"); |
|
2752 is(events[1].target, iframe2.contentDocument.body, |
|
2753 "runForceCommitTest: The 2nd event was fired on wrong event target #11"); |
|
2754 is(events[2].target, iframe2.contentDocument.body, |
|
2755 "runForceCommitTest: The 3rd event was fired on wrong event target #11"); |
|
2756 ok(!getHTMLEditorIMESupport(iframe2.contentWindow).isComposing, |
|
2757 "runForceCommitTest: the editable document still has composition #11"); |
|
2758 ok(!getHTMLEditorIMESupport(iframe3.contentWindow).isComposing, |
|
2759 "runForceCommitTest: the other editable document has composition #11"); |
|
2760 ok(iframe2.contentDocument.body.innerHTML != iframe2BodyInnerHTML && |
|
2761 iframe2.contentDocument.body.innerHTML.indexOf("\u306E") >= 0, |
|
2762 "runForceCommitTest: the editable document doesn't have the committed text #11"); |
|
2763 is(iframe3.contentDocument.body.innerHTML, iframe3BodyInnerHTML, |
|
2764 "runForceCommitTest: the other editable document has the committed text? #11"); |
|
2765 |
|
2766 window.removeEventListener("compositionstart", eventHandler, true); |
|
2767 window.removeEventListener("compositionupdate", eventHandler, true); |
|
2768 window.removeEventListener("compositionend", eventHandler, true); |
|
2769 window.removeEventListener("input", eventHandler, true); |
|
2770 window.removeEventListener("text", eventHandler, true); |
|
2771 } |
|
2772 |
|
2773 function runBug811755Test() |
|
2774 { |
|
2775 iframe2.contentDocument.body.innerHTML = "<div>content<br/></div>"; |
|
2776 iframe2.contentWindow.focus(); |
|
2777 // Query everything |
|
2778 var textContent = synthesizeQueryTextContent(0, 10); |
|
2779 if (!checkQueryContentResult(textContent, "runBug811755Test: synthesizeQueryTextContent #1")) { |
|
2780 return false; |
|
2781 } |
|
2782 // Query everything but specify exact end offset, which should be immediately after the <br> node |
|
2783 // If PreContentIterator is used, the next node after <br> is the node after </div>. |
|
2784 // If ContentIterator is used, the next node is the <div> node itself. In this case, the end |
|
2785 // node ends up being before the start node, and an empty string is returned. |
|
2786 var queryContent = synthesizeQueryTextContent(0, textContent.text.length); |
|
2787 if (!checkQueryContentResult(queryContent, "runBug811755Test: synthesizeQueryTextContent #2")) { |
|
2788 return false; |
|
2789 } |
|
2790 is(queryContent.text, textContent.text, "runBug811755Test: two queried texts don't match"); |
|
2791 return queryContent.text == textContent.text; |
|
2792 } |
|
2793 |
|
2794 function runIsComposingTest() |
|
2795 { |
|
2796 var expectedIsComposing = false; |
|
2797 var descriptionBase = "runIsComposingTest: "; |
|
2798 var description = ""; |
|
2799 |
|
2800 function eventHandler(aEvent) |
|
2801 { |
|
2802 if (aEvent.type == "keydown" || aEvent.type == "keyup") { |
|
2803 is(aEvent.isComposing, expectedIsComposing, |
|
2804 "runIsComposingTest: " + description + " (type=" + aEvent.type + ", key=" + aEvent.key + ")"); |
|
2805 } else { |
|
2806 is(aEvent.isComposing, expectedIsComposing, |
|
2807 "runIsComposingTest: " + description + " (type=" + aEvent.type + ")"); |
|
2808 } |
|
2809 } |
|
2810 |
|
2811 textarea.addEventListener("keydown", eventHandler, true); |
|
2812 textarea.addEventListener("keypress", eventHandler, true); |
|
2813 textarea.addEventListener("keyup", eventHandler, true); |
|
2814 textarea.addEventListener("input", eventHandler, true); |
|
2815 |
|
2816 textarea.focus(); |
|
2817 textarea.value = ""; |
|
2818 |
|
2819 // XXX These cases shouldn't occur in actual native key events because we |
|
2820 // don't dispatch key events while composition (bug 354358). |
|
2821 expectedIsComposing = false; |
|
2822 description = "events before dispatching compositionstart"; |
|
2823 synthesizeKey("VK_LEFT", {}); |
|
2824 |
|
2825 synthesizeKey("a", { type: "keydown" }); |
|
2826 synthesizeComposition({ type: "compositionstart" }); |
|
2827 expectedIsComposing = true; |
|
2828 description = "events after dispatching compositionstart"; |
|
2829 synthesizeComposition({ type: "compositionupdate", data: "\u3042" }); |
|
2830 synthesizeText( |
|
2831 { "composition": |
|
2832 { "string": "\u3042", |
|
2833 "clauses": |
|
2834 [ |
|
2835 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2836 ] |
|
2837 }, |
|
2838 "caret": { "start": 1, "length": 0 } |
|
2839 }); |
|
2840 synthesizeKey("a", { type: "keyup" }); |
|
2841 |
|
2842 // Although, firing keypress event during composition is a bug. |
|
2843 synthesizeKey("VK_INSERT", {}); |
|
2844 |
|
2845 description = "events for committing composition string"; |
|
2846 synthesizeKey("VK_RETURN", { type: "keydown" }); |
|
2847 synthesizeText( |
|
2848 { "composition": |
|
2849 { "string": "\u3042", |
|
2850 "clauses": |
|
2851 [ |
|
2852 { "length": 0, "attr": 0 } |
|
2853 ] |
|
2854 }, |
|
2855 "caret": { "start": 1, "length": 0 } |
|
2856 }); |
|
2857 |
|
2858 // input event will be fired by synthesizing compositionend event. |
|
2859 // Then, its isComposing should be false. |
|
2860 expectedIsComposing = false; |
|
2861 description = "events after dispatching compositionend"; |
|
2862 synthesizeComposition({ type: "compositionend" }); |
|
2863 synthesizeKey("VK_RETURN", { type: "keyup" }); |
|
2864 |
|
2865 textarea.removeEventListener("keydown", eventHandler, true); |
|
2866 textarea.removeEventListener("keypress", eventHandler, true); |
|
2867 textarea.removeEventListener("keyup", eventHandler, true); |
|
2868 textarea.removeEventListener("input", eventHandler, true); |
|
2869 |
|
2870 textarea.value = ""; |
|
2871 } |
|
2872 |
|
2873 function runRemoveContentTest(aCallback) |
|
2874 { |
|
2875 var events = []; |
|
2876 function eventHandler(aEvent) |
|
2877 { |
|
2878 events.push(aEvent); |
|
2879 } |
|
2880 textarea.addEventListener("compositionstart", eventHandler, true); |
|
2881 textarea.addEventListener("compositionupdate", eventHandler, true); |
|
2882 textarea.addEventListener("compositionend", eventHandler, true); |
|
2883 textarea.addEventListener("input", eventHandler, true); |
|
2884 textarea.addEventListener("text", eventHandler, true); |
|
2885 |
|
2886 textarea.focus(); |
|
2887 textarea.value = ""; |
|
2888 |
|
2889 synthesizeComposition({ type: "compositionstart" }); |
|
2890 |
|
2891 synthesizeComposition({ type: "compositionupdate", data: "\u306E" }); |
|
2892 synthesizeText( |
|
2893 { "composition": |
|
2894 { "string": "\u306E", |
|
2895 "clauses": |
|
2896 [ |
|
2897 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2898 ] |
|
2899 }, |
|
2900 "caret": { "start": 1, "length": 0 } |
|
2901 }); |
|
2902 |
|
2903 var nextSibling = textarea.nextSibling; |
|
2904 var parent = textarea.parentElement; |
|
2905 |
|
2906 events = []; |
|
2907 parent.removeChild(textarea); |
|
2908 |
|
2909 hitEventLoop(function () { |
|
2910 // XXX Currently, "input" event isn't fired on removed content. |
|
2911 is(events.length, 3, |
|
2912 "runRemoveContentTest: wrong event count #1"); |
|
2913 is(events[0].type, "compositionupdate", |
|
2914 "runRemoveContentTest: the 1st event must be compositionupdate #1"); |
|
2915 is(events[1].type, "text", |
|
2916 "runRemoveContentTest: the 2nd event must be text #1"); |
|
2917 is(events[2].type, "compositionend", |
|
2918 "runRemoveContentTest: the 3rd event must be compositionend #1"); |
|
2919 is(events[0].data, "", |
|
2920 "runRemoveContentTest: compositionupdate has wrong data #1"); |
|
2921 is(events[2].data, "", |
|
2922 "runRemoveContentTest: compositionend has wrong data #1"); |
|
2923 is(events[0].target, textarea, |
|
2924 "runRemoveContentTest: The 1st event was fired on wrong event target #1"); |
|
2925 is(events[1].target, textarea, |
|
2926 "runRemoveContentTest: The 2nd event was fired on wrong event target #1"); |
|
2927 is(events[2].target, textarea, |
|
2928 "runRemoveContentTest: The 3rd event was fired on wrong event target #1"); |
|
2929 ok(!getEditorIMESupport(textarea).isComposing, |
|
2930 "runRemoveContentTest: the textarea still has composition #1"); |
|
2931 todo_is(textarea.value, "", |
|
2932 "runRemoveContentTest: the textarea has the committed text? #1"); |
|
2933 |
|
2934 parent.insertBefore(textarea, nextSibling); |
|
2935 |
|
2936 textarea.focus(); |
|
2937 textarea.value = ""; |
|
2938 |
|
2939 synthesizeComposition({ type: "compositionstart" }); |
|
2940 |
|
2941 events = []; |
|
2942 parent.removeChild(textarea); |
|
2943 |
|
2944 hitEventLoop(function () { |
|
2945 // XXX Currently, "input" event isn't fired on removed content. |
|
2946 is(events.length, 1, |
|
2947 "runRemoveContentTest: wrong event count #2"); |
|
2948 is(events[0].type, "compositionend", |
|
2949 "runRemoveContentTest: the 1st event must be compositionend #2"); |
|
2950 is(events[0].data, "", |
|
2951 "runRemoveContentTest: compositionupdate has wrong data #2"); |
|
2952 is(events[0].target, textarea, |
|
2953 "runRemoveContentTest: The 1st event was fired on wrong event target #2"); |
|
2954 ok(!getEditorIMESupport(textarea).isComposing, |
|
2955 "runRemoveContentTest: the textarea still has composition #2"); |
|
2956 is(textarea.value, "", |
|
2957 "runRemoveContentTest: the textarea has the committed text? #2"); |
|
2958 |
|
2959 parent.insertBefore(textarea, nextSibling); |
|
2960 |
|
2961 textarea.removeEventListener("compositionstart", eventHandler, true); |
|
2962 textarea.removeEventListener("compositionupdate", eventHandler, true); |
|
2963 textarea.removeEventListener("compositionend", eventHandler, true); |
|
2964 textarea.removeEventListener("input", eventHandler, true); |
|
2965 textarea.removeEventListener("text", eventHandler, true); |
|
2966 |
|
2967 SimpleTest.executeSoon(aCallback); |
|
2968 }, 50); |
|
2969 }, 50); |
|
2970 } |
|
2971 |
|
2972 function runTestOnAnotherContext(aPanelOrFrame, aFocusedEditor, aTestName) |
|
2973 { |
|
2974 aFocusedEditor.value = ""; |
|
2975 |
|
2976 var editorRect = synthesizeQueryEditorRect(); |
|
2977 if (!checkQueryContentResult(editorRect, aTestName + ": editorRect")) { |
|
2978 return; |
|
2979 } |
|
2980 |
|
2981 var r = aPanelOrFrame.getBoundingClientRect(); |
|
2982 var parentRect = { "left": r.left, "top": r.top, "width": r.right - r.left, |
|
2983 "height": r.bottom - r.top }; |
|
2984 checkRectContainsRect(editorRect, parentRect, aTestName + |
|
2985 ": the editor rect coordinates are wrong"); |
|
2986 |
|
2987 // start composition |
|
2988 synthesizeComposition({ type: "compositionstart" }); |
|
2989 |
|
2990 // input characters |
|
2991 synthesizeComposition({ type: "compositionupdate", |
|
2992 data: "\u3078\u3093\u3057\u3093" }); |
|
2993 synthesizeText( |
|
2994 { "composition": |
|
2995 { "string": "\u3078\u3093\u3057\u3093", |
|
2996 "clauses": |
|
2997 [ |
|
2998 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
2999 ] |
|
3000 }, |
|
3001 "caret": { "start": 4, "length": 0 } |
|
3002 }); |
|
3003 |
|
3004 if (!checkContent("\u3078\u3093\u3057\u3093", aTestName, "#1-1") || |
|
3005 !checkSelection(4, "", aTestName, "#1-1")) { |
|
3006 return; |
|
3007 } |
|
3008 |
|
3009 // convert them #1 |
|
3010 synthesizeComposition({ type: "compositionupdate", data: "\u8FD4\u4FE1" }); |
|
3011 synthesizeText( |
|
3012 { "composition": |
|
3013 { "string": "\u8FD4\u4FE1", |
|
3014 "clauses": |
|
3015 [ |
|
3016 { "length": 2, |
|
3017 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
3018 ] |
|
3019 }, |
|
3020 "caret": { "start": 2, "length": 0 } |
|
3021 }); |
|
3022 |
|
3023 if (!checkContent("\u8FD4\u4FE1", aTestName, "#1-2") || |
|
3024 !checkSelection(2, "", aTestName, "#1-2")) { |
|
3025 return; |
|
3026 } |
|
3027 |
|
3028 // convert them #2 |
|
3029 synthesizeComposition({ type: "compositionupdate", data: "\u5909\u8EAB" }); |
|
3030 synthesizeText( |
|
3031 { "composition": |
|
3032 { "string": "\u5909\u8EAB", |
|
3033 "clauses": |
|
3034 [ |
|
3035 { "length": 2, |
|
3036 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT } |
|
3037 ] |
|
3038 }, |
|
3039 "caret": { "start": 2, "length": 0 } |
|
3040 }); |
|
3041 |
|
3042 if (!checkContent("\u5909\u8EAB", aTestName, "#1-3") || |
|
3043 !checkSelection(2, "", aTestName, "#1-3")) { |
|
3044 return; |
|
3045 } |
|
3046 |
|
3047 // commit them |
|
3048 synthesizeText( |
|
3049 { "composition": |
|
3050 { "string": "\u5909\u8EAB", |
|
3051 "clauses": |
|
3052 [ |
|
3053 { "length": 0, "attr": 0 } |
|
3054 ] |
|
3055 }, |
|
3056 "caret": { "start": 2, "length": 0 } |
|
3057 }); |
|
3058 |
|
3059 if (!checkContent("\u5909\u8EAB", aTestName, "#1-4") || |
|
3060 !checkSelection(2, "", aTestName, "#1-4")) { |
|
3061 return; |
|
3062 } |
|
3063 |
|
3064 synthesizeComposition({ type: "compositionend", data: "\u5909\u8EAB" }); |
|
3065 |
|
3066 is(aFocusedEditor.value, "\u5909\u8EAB", |
|
3067 aTestName + ": composition isn't in the focused editor"); |
|
3068 if (aFocusedEditor.value != "\u5909\u8EAB") { |
|
3069 return; |
|
3070 } |
|
3071 |
|
3072 var textRect = synthesizeQueryTextRect(0, 1); |
|
3073 var caretRect = synthesizeQueryCaretRect(2); |
|
3074 if (!checkQueryContentResult(textRect, |
|
3075 aTestName + ": synthesizeQueryTextRect") || |
|
3076 !checkQueryContentResult(caretRect, |
|
3077 aTestName + ": synthesizeQueryCaretRect")) { |
|
3078 return; |
|
3079 } |
|
3080 checkRectContainsRect(textRect, editorRect, aTestName + ":testRect"); |
|
3081 checkRectContainsRect(caretRect, editorRect, aTestName + ":caretRect"); |
|
3082 } |
|
3083 |
|
3084 function runFrameTest() |
|
3085 { |
|
3086 textareaInFrame.focus(); |
|
3087 runTestOnAnotherContext(iframe, textareaInFrame, "runFrameTest"); |
|
3088 runCharAtPointTest(textareaInFrame, "textarea in the iframe"); |
|
3089 } |
|
3090 |
|
3091 var gPanelShown = false; |
|
3092 var gPanelFocused = false; |
|
3093 function onPanelShown(aEvent) |
|
3094 { |
|
3095 gPanelShown = true; |
|
3096 textbox.focus(); |
|
3097 setTimeout(doPanelTest, 0); |
|
3098 } |
|
3099 |
|
3100 function onFocusPanelTextbox(aEvent) |
|
3101 { |
|
3102 gPanelFocused = true; |
|
3103 setTimeout(doPanelTest, 0); |
|
3104 } |
|
3105 |
|
3106 var gIsPanelHiding = false; |
|
3107 var gIsRunPanelTestInternal = false; |
|
3108 function doPanelTest() |
|
3109 { |
|
3110 if (!gPanelFocused || !gPanelShown) { |
|
3111 return; |
|
3112 } |
|
3113 if (gIsRunPanelTestInternal) { |
|
3114 return; |
|
3115 } |
|
3116 gIsRunPanelTestInternal = true; |
|
3117 runTestOnAnotherContext(panel, textbox, "runPanelTest"); |
|
3118 runCharAtPointTest(textbox, "textbox in the panel"); |
|
3119 gIsPanelHiding = true; |
|
3120 panel.hidePopup(); |
|
3121 } |
|
3122 |
|
3123 function onPanelHidden(aEvent) |
|
3124 { |
|
3125 panel.hidden = true; |
|
3126 ok(gIsPanelHiding, "runPanelTest: the panel is hidden unexpectedly"); |
|
3127 finish(); |
|
3128 } |
|
3129 |
|
3130 function runPanelTest() |
|
3131 { |
|
3132 panel.hidden = false; |
|
3133 panel.openPopupAtScreen(window.screenX + window.outerWidth, 0, false); |
|
3134 } |
|
3135 |
|
3136 function runMaxLengthTest() |
|
3137 { |
|
3138 input.maxLength = 1; |
|
3139 input.value = ""; |
|
3140 input.focus(); |
|
3141 |
|
3142 var kDesc ="runMaxLengthTest"; |
|
3143 |
|
3144 // start composition |
|
3145 synthesizeComposition({ type: "compositionstart" }); |
|
3146 |
|
3147 // input first character |
|
3148 synthesizeComposition({ type: "compositionupdate", data: "\u3089" }); |
|
3149 synthesizeText( |
|
3150 { "composition": |
|
3151 { "string": "\u3089", |
|
3152 "clauses": |
|
3153 [ |
|
3154 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3155 ] |
|
3156 }, |
|
3157 "caret": { "start": 1, "length": 0 } |
|
3158 }); |
|
3159 |
|
3160 if (!checkContent("\u3089", kDesc, "#1-1") || |
|
3161 !checkSelection(1, "", kDesc, "#1-1")) { |
|
3162 return; |
|
3163 } |
|
3164 |
|
3165 // input second character |
|
3166 synthesizeComposition({ type: "compositionupdate", data: "\u3089\u30FC" }); |
|
3167 synthesizeText( |
|
3168 { "composition": |
|
3169 { "string": "\u3089\u30FC", |
|
3170 "clauses": |
|
3171 [ |
|
3172 { "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3173 ] |
|
3174 }, |
|
3175 "caret": { "start": 2, "length": 0 } |
|
3176 }); |
|
3177 |
|
3178 if (!checkContent("\u3089\u30FC", kDesc, "#1-2") || |
|
3179 !checkSelection(2, "", kDesc, "#1-2")) { |
|
3180 return; |
|
3181 } |
|
3182 |
|
3183 // input third character |
|
3184 synthesizeComposition({ type: "compositionupdate", |
|
3185 data: "\u3089\u30FC\u3081" }); |
|
3186 synthesizeText( |
|
3187 { "composition": |
|
3188 { "string": "\u3089\u30FC\u3081", |
|
3189 "clauses": |
|
3190 [ |
|
3191 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3192 ] |
|
3193 }, |
|
3194 "caret": { "start": 3, "length": 0 } |
|
3195 }); |
|
3196 |
|
3197 if (!checkContent("\u3089\u30FC\u3081", kDesc, "#1-3") || |
|
3198 !checkSelection(3, "", kDesc, "#1-3")) { |
|
3199 return; |
|
3200 } |
|
3201 |
|
3202 // input fourth character |
|
3203 synthesizeComposition({ type: "compositionupdate", |
|
3204 data: "\u3089\u30FC\u3081\u3093" }); |
|
3205 synthesizeText( |
|
3206 { "composition": |
|
3207 { "string": "\u3089\u30FC\u3081\u3093", |
|
3208 "clauses": |
|
3209 [ |
|
3210 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3211 ] |
|
3212 }, |
|
3213 "caret": { "start": 4, "length": 0 } |
|
3214 }); |
|
3215 |
|
3216 if (!checkContent("\u3089\u30FC\u3081\u3093", kDesc, "#1-4") || |
|
3217 !checkSelection(4, "", kDesc, "#1-4")) { |
|
3218 return; |
|
3219 } |
|
3220 |
|
3221 |
|
3222 // backspace |
|
3223 synthesizeComposition({ type: "compositionupdate", |
|
3224 data: "\u3089\u30FC\u3081" }); |
|
3225 synthesizeText( |
|
3226 { "composition": |
|
3227 { "string": "\u3089\u30FC\u3081", |
|
3228 "clauses": |
|
3229 [ |
|
3230 { "length": 3, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3231 ] |
|
3232 }, |
|
3233 "caret": { "start": 3, "length": 0 } |
|
3234 }); |
|
3235 |
|
3236 if (!checkContent("\u3089\u30FC\u3081", kDesc, "#1-5") || |
|
3237 !checkSelection(3, "", kDesc, "#1-5")) { |
|
3238 return; |
|
3239 } |
|
3240 |
|
3241 // re-input |
|
3242 synthesizeComposition({ type: "compositionupdate", |
|
3243 data: "\u3089\u30FC\u3081\u3093" }); |
|
3244 synthesizeText( |
|
3245 { "composition": |
|
3246 { "string": "\u3089\u30FC\u3081\u3093", |
|
3247 "clauses": |
|
3248 [ |
|
3249 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3250 ] |
|
3251 }, |
|
3252 "caret": { "start": 4, "length": 0 } |
|
3253 }); |
|
3254 |
|
3255 if (!checkContent("\u3089\u30FC\u3081\u3093", kDesc, "#1-6") || |
|
3256 !checkSelection(4, "", kDesc, "#1-6")) { |
|
3257 return; |
|
3258 } |
|
3259 |
|
3260 synthesizeComposition({ type: "compositionupdate", |
|
3261 data: "\u3089\u30FC\u3081\u3093\u3055" }); |
|
3262 synthesizeText( |
|
3263 { "composition": |
|
3264 { "string": "\u3089\u30FC\u3081\u3093\u3055", |
|
3265 "clauses": |
|
3266 [ |
|
3267 { "length": 5, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3268 ] |
|
3269 }, |
|
3270 "caret": { "start": 5, "length": 0 } |
|
3271 }); |
|
3272 |
|
3273 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055", kDesc, "#1-7") || |
|
3274 !checkSelection(5, "", kDesc, "#1-7")) { |
|
3275 return; |
|
3276 } |
|
3277 |
|
3278 synthesizeComposition({ type: "compositionupdate", |
|
3279 data: "\u3089\u30FC\u3081\u3093\u3055\u3044" }); |
|
3280 synthesizeText( |
|
3281 { "composition": |
|
3282 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044", |
|
3283 "clauses": |
|
3284 [ |
|
3285 { "length": 6, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3286 ] |
|
3287 }, |
|
3288 "caret": { "start": 6, "length": 0 } |
|
3289 }); |
|
3290 |
|
3291 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044", kDesc, "#1-8") || |
|
3292 !checkSelection(6, "", kDesc, "#1-8")) { |
|
3293 return; |
|
3294 } |
|
3295 |
|
3296 synthesizeComposition({ type: "compositionupdate", |
|
3297 data: "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053" }); |
|
3298 synthesizeText( |
|
3299 { "composition": |
|
3300 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", |
|
3301 "clauses": |
|
3302 [ |
|
3303 { "length": 7, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3304 ] |
|
3305 }, |
|
3306 "caret": { "start": 7, "length": 0 } |
|
3307 }); |
|
3308 |
|
3309 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044\u3053", |
|
3310 kDesc, "#1-8") || |
|
3311 !checkSelection(7, "", kDesc, "#1-8")) { |
|
3312 return; |
|
3313 } |
|
3314 |
|
3315 synthesizeComposition({ type: "compositionupdate", |
|
3316 data: "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046" }); |
|
3317 synthesizeText( |
|
3318 { "composition": |
|
3319 { "string": "\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", |
|
3320 "clauses": |
|
3321 [ |
|
3322 { "length": 8, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3323 ] |
|
3324 }, |
|
3325 "caret": { "start": 8, "length": 0 } |
|
3326 }); |
|
3327 |
|
3328 if (!checkContent("\u3089\u30FC\u3081\u3093\u3055\u3044\u3053\u3046", |
|
3329 kDesc, "#1-9") || |
|
3330 !checkSelection(8, "", kDesc, "#1-9")) { |
|
3331 return; |
|
3332 } |
|
3333 |
|
3334 // convert |
|
3335 synthesizeComposition({ type: "compositionupdate", |
|
3336 data: "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8" }); |
|
3337 synthesizeText( |
|
3338 { "composition": |
|
3339 { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
3340 "clauses": |
|
3341 [ |
|
3342 { "length": 4, |
|
3343 "attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT }, |
|
3344 { "length": 2, |
|
3345 "attr": COMPOSITION_ATTR_CONVERTEDTEXT } |
|
3346 ] |
|
3347 }, |
|
3348 "caret": { "start": 4, "length": 0 } |
|
3349 }); |
|
3350 |
|
3351 if (!checkContent("\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", kDesc, "#1-10") || |
|
3352 !checkSelection(4, "", kDesc, "#1-10")) { |
|
3353 return; |
|
3354 } |
|
3355 |
|
3356 // commit the composition string |
|
3357 synthesizeText( |
|
3358 { "composition": |
|
3359 { "string": "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8", |
|
3360 "clauses": |
|
3361 [ |
|
3362 { "length": 0, "attr": 0 } |
|
3363 ] |
|
3364 }, |
|
3365 "caret": { "start": 6, "length": 0 } |
|
3366 }); |
|
3367 |
|
3368 if (!checkContent("\u30E9", kDesc, "#1-11") || |
|
3369 !checkSelection(1, "", kDesc, "#1-11")) { |
|
3370 return; |
|
3371 } |
|
3372 |
|
3373 synthesizeComposition({ type: "compositionend", |
|
3374 data: "\u30E9\u30FC\u30E1\u30F3\u6700\u9AD8" }); |
|
3375 |
|
3376 // restart composition |
|
3377 synthesizeComposition({ type: "compositionstart" }); |
|
3378 |
|
3379 // input characters |
|
3380 synthesizeComposition({ type: "compositionupdate", data: "\u3057" }); |
|
3381 synthesizeText( |
|
3382 { "composition": |
|
3383 { "string": "\u3057", |
|
3384 "clauses": |
|
3385 [ |
|
3386 { "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
3387 ] |
|
3388 }, |
|
3389 "caret": { "start": 1, "length": 0 } |
|
3390 }); |
|
3391 |
|
3392 if (!checkContent("\u30E9\u3057", kDesc, "#2-1") || |
|
3393 !checkSelection(1 + 1, "", kDesc, "#2-1")) { |
|
3394 return; |
|
3395 } |
|
3396 |
|
3397 // commit the composition string |
|
3398 synthesizeComposition({ type: "compositionupdate", data: "\u3058" }); |
|
3399 synthesizeText( |
|
3400 { "composition": |
|
3401 { "string": "\u3058", |
|
3402 "clauses": |
|
3403 [ |
|
3404 { "length": 0, "attr": 0 } |
|
3405 ] |
|
3406 }, |
|
3407 "caret": { "start": 1, "length": 0 } |
|
3408 }); |
|
3409 |
|
3410 if (!checkContent("\u30E9", kDesc, "#2-2") || |
|
3411 !checkSelection(1 + 0, "", kDesc, "#2-2")) { |
|
3412 return; |
|
3413 } |
|
3414 |
|
3415 synthesizeComposition({ type: "compositionend", data: "\u3058" }); |
|
3416 |
|
3417 // Undo |
|
3418 synthesizeKey("Z", {accelKey: true}); |
|
3419 |
|
3420 // XXX this is unexpected behavior, see bug 258291 |
|
3421 if (!checkContent("\u30E9", kDesc, "#3-1") || |
|
3422 !checkSelection(1 + 0, "", kDesc, "#3-1")) { |
|
3423 return; |
|
3424 } |
|
3425 |
|
3426 // Undo |
|
3427 synthesizeKey("Z", {accelKey: true}); |
|
3428 if (!checkContent("", kDesc, "#3-2") || |
|
3429 !checkSelection(0, "", kDesc, "#3-2")) { |
|
3430 return; |
|
3431 } |
|
3432 |
|
3433 // Redo |
|
3434 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
3435 if (!checkContent("\u30E9", kDesc, "#3-3") || |
|
3436 !checkSelection(1, "", kDesc, "#3-3")) { |
|
3437 return; |
|
3438 } |
|
3439 |
|
3440 // Redo |
|
3441 synthesizeKey("Z", {accelKey: true, shiftKey: true}); |
|
3442 if (!checkContent("\u30E9", kDesc, "#3-4") || |
|
3443 !checkSelection(1 + 0, "", kDesc, "#3-4")) { |
|
3444 return; |
|
3445 } |
|
3446 } |
|
3447 |
|
3448 function runTest() |
|
3449 { |
|
3450 textareaInFrame = iframe.contentDocument.getElementById("textarea"); |
|
3451 |
|
3452 runUndoRedoTest(); |
|
3453 runCompositionTest(); |
|
3454 runCompositionEventTest(); |
|
3455 runCharAtPointTest(textarea, "textarea in the document"); |
|
3456 runCharAtPointAtOutsideTest(); |
|
3457 runBug722639Test(); |
|
3458 runForceCommitTest(); |
|
3459 runBug811755Test(); |
|
3460 runIsComposingTest(); |
|
3461 runRemoveContentTest(function () { |
|
3462 runFrameTest(); |
|
3463 runPanelTest(); |
|
3464 runMaxLengthTest(); |
|
3465 }); |
|
3466 } |
|
3467 |
|
3468 ]]> |
|
3469 </script> |
|
3470 |
|
3471 </window> |