|
1 <html style="ime-mode: disabled;"> |
|
2 <head> |
|
3 <title>Test for IME state controling</title> |
|
4 <script type="text/javascript" |
|
5 src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> |
|
6 <script type="text/javascript" |
|
7 src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script> |
|
8 <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js"></script> |
|
9 <link rel="stylesheet" type="text/css" |
|
10 href="chrome://mochikit/content/tests/SimpleTest/test.css" /> |
|
11 </head> |
|
12 <body onload="setTimeout(runTests, 0);" style="ime-mode: disabled;"> |
|
13 <div id="display" style="ime-mode: disabled;"> |
|
14 <!-- input elements --> |
|
15 <input type="text" id="text"/><br/> |
|
16 <input type="text" id="text_readonly" readonly="readonly"/><br/> |
|
17 <input type="password" id="password"/><br/> |
|
18 <input type="password" id="password_readonly" readonly="readonly"/><br/> |
|
19 <input type="checkbox" id="checkbox"/><br/> |
|
20 <input type="radio" id="radio"/><br/> |
|
21 <input type="submit" id="submit"/><br/> |
|
22 <input type="reset" id="reset"/><br/> |
|
23 <input type="file" id="file"/><br/> |
|
24 <input type="button" id="ibutton"/><br/> |
|
25 <input type="image" id="image" alt="image"/><br/> |
|
26 |
|
27 <!-- html5 input elements --> |
|
28 <input type="url" id="url"/><br/> |
|
29 <input type="email" id="email"/><br/> |
|
30 <input type="search" id="search"/><br/> |
|
31 <input type="tel" id="tel"/><br/> |
|
32 <input type="number" id="number"/><br/> |
|
33 |
|
34 <!-- form controls --> |
|
35 <button id="button">button</button><br/> |
|
36 <textarea id="textarea">textarea</textarea><br/> |
|
37 <textarea id="textarea_readonly" readonly="readonly">textarea[readonly]</textarea><br/> |
|
38 <select id="select"> |
|
39 <option value="option" selected="selected"/> |
|
40 </select><br/> |
|
41 <select id="select_multiple" multiple="multiple"> |
|
42 <option value="option" selected="selected"/> |
|
43 </select><br/> |
|
44 <isindex id="isindex" prompt="isindex"/><br/> |
|
45 |
|
46 <!-- a element --> |
|
47 <a id="a_href" href="about:blank">a[href]</a><br/> |
|
48 |
|
49 <!-- ime-mode test --> |
|
50 <input type="text" id="ime_mode_auto" style="ime-mode: auto;"/><br/> |
|
51 <input type="text" id="ime_mode_normal" style="ime-mode: normal;"/><br/> |
|
52 <input type="text" id="ime_mode_active" style="ime-mode: active;"/><br/> |
|
53 <input type="text" id="ime_mode_inactive" style="ime-mode: inactive;"/><br/> |
|
54 <input type="text" id="ime_mode_disabled" style="ime-mode: disabled;"/><br/> |
|
55 |
|
56 <input type="text" id="ime_mode_auto_url" style="ime-mode: auto;"/><br/> |
|
57 <input type="text" id="ime_mode_normal_url" style="ime-mode: normal;"/><br/> |
|
58 <input type="text" id="ime_mode_active_url" style="ime-mode: active;"/><br/> |
|
59 <input type="text" id="ime_mode_inactive_url" style="ime-mode: inactive;"/><br/> |
|
60 <input type="text" id="ime_mode_disabled_url" style="ime-mode: disabled;"/><br/> |
|
61 |
|
62 <input type="text" id="ime_mode_auto_email" style="ime-mode: auto;"/><br/> |
|
63 <input type="text" id="ime_mode_normal_email" style="ime-mode: normal;"/><br/> |
|
64 <input type="text" id="ime_mode_active_email" style="ime-mode: active;"/><br/> |
|
65 <input type="text" id="ime_mode_inactive_email" style="ime-mode: inactive;"/><br/> |
|
66 <input type="text" id="ime_mode_disabled_email" style="ime-mode: disabled;"/><br/> |
|
67 |
|
68 <input type="text" id="ime_mode_auto_search" style="ime-mode: auto;"/><br/> |
|
69 <input type="text" id="ime_mode_normal_search" style="ime-mode: normal;"/><br/> |
|
70 <input type="text" id="ime_mode_active_search" style="ime-mode: active;"/><br/> |
|
71 <input type="text" id="ime_mode_inactive_search" style="ime-mode: inactive;"/><br/> |
|
72 <input type="text" id="ime_mode_disabled_search" style="ime-mode: disabled;"/><br/> |
|
73 |
|
74 <input type="text" id="ime_mode_auto_tel" style="ime-mode: auto;"/><br/> |
|
75 <input type="text" id="ime_mode_normal_tel" style="ime-mode: normal;"/><br/> |
|
76 <input type="text" id="ime_mode_active_tel" style="ime-mode: active;"/><br/> |
|
77 <input type="text" id="ime_mode_inactive_tel" style="ime-mode: inactive;"/><br/> |
|
78 <input type="text" id="ime_mode_disabled_tel" style="ime-mode: disabled;"/><br/> |
|
79 |
|
80 <input type="text" id="ime_mode_auto_number" style="ime-mode: auto;"/><br/> |
|
81 <input type="text" id="ime_mode_normal_number" style="ime-mode: normal;"/><br/> |
|
82 <input type="text" id="ime_mode_active_number" style="ime-mode: active;"/><br/> |
|
83 <input type="text" id="ime_mode_inactive_number" style="ime-mode: inactive;"/><br/> |
|
84 <input type="text" id="ime_mode_disabled_number" style="ime-mode: disabled;"/><br/> |
|
85 |
|
86 <input type="password" id="ime_mode_auto_p" style="ime-mode: auto;"/><br/> |
|
87 <input type="password" id="ime_mode_normal_p" style="ime-mode: normal;"/><br/> |
|
88 <input type="password" id="ime_mode_active_p" style="ime-mode: active;"/><br/> |
|
89 <input type="password" id="ime_mode_inactive_p" style="ime-mode: inactive;"/><br/> |
|
90 <input type="password" id="ime_mode_disabled_p" style="ime-mode: disabled;"/><br/> |
|
91 <textarea id="ime_mode_auto_t" style="ime-mode: auto;">textarea</textarea><br/> |
|
92 <textarea id="ime_mode_normal_t" style="ime-mode: normal;">textarea</textarea><br/> |
|
93 <textarea id="ime_mode_active_t" style="ime-mode: active;">textarea</textarea><br/> |
|
94 <textarea id="ime_mode_inactive_t" style="ime-mode: inactive;">textarea</textarea><br/> |
|
95 <textarea id="ime_mode_disabled_t" style="ime-mode: disabled;">textarea</textarea><br/> |
|
96 |
|
97 <!-- plugin --> |
|
98 <object type="application/x-test" id="plugin"></object><br/> |
|
99 |
|
100 <!-- contenteditable editor --> |
|
101 <div id="contenteditableEditor" contenteditable="true"></div> |
|
102 |
|
103 <!-- designMode editor --> |
|
104 <iframe id="designModeEditor" |
|
105 onload="document.getElementById('designModeEditor').contentDocument.designMode = 'on';" |
|
106 src="data:text/html,<html><body></body></html>"></iframe><br/> |
|
107 </div> |
|
108 <div id="content" style="display: none"> |
|
109 |
|
110 </div> |
|
111 <pre id="test"> |
|
112 </pre> |
|
113 |
|
114 <script class="testbody" type="application/javascript"> |
|
115 |
|
116 SimpleTest.waitForExplicitFinish(); |
|
117 |
|
118 function hitEventLoop(aFunc, aTimes) |
|
119 { |
|
120 if (--aTimes) { |
|
121 setTimeout(hitEventLoop, 0, aFunc, aTimes); |
|
122 } else { |
|
123 setTimeout(aFunc, 20); |
|
124 } |
|
125 } |
|
126 |
|
127 var gUtils = window. |
|
128 QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
129 getInterface(Components.interfaces.nsIDOMWindowUtils); |
|
130 var gFM = Components.classes["@mozilla.org/focus-manager;1"]. |
|
131 getService(Components.interfaces.nsIFocusManager); |
|
132 const kIMEEnabledSupported = navigator.platform.indexOf("Mac") == 0 || |
|
133 navigator.platform.indexOf("Win") == 0 || |
|
134 navigator.platform.indexOf("Linux") == 0; |
|
135 |
|
136 // We support to control IME open state on Windows and Mac actually. However, |
|
137 // we cannot test it on Mac if the current keyboard layout is not CJK. And also |
|
138 // we cannot test it on Win32 if the system didn't be installed IME. So, |
|
139 // currently we should not run the open state testing. |
|
140 const kIMEOpenSupported = false; |
|
141 |
|
142 function runBasicTest(aIsEditable, aInDesignMode, aDescription) |
|
143 { |
|
144 function test(aTest) |
|
145 { |
|
146 function moveFocus(aTest, aFocusEventHandler) |
|
147 { |
|
148 if (aInDesignMode) { |
|
149 if (document.activeElement) { |
|
150 document.activeElement.blur(); |
|
151 } |
|
152 } else if (aIsEditable) { |
|
153 document.getElementById("display").focus(); |
|
154 } else if (aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED) { |
|
155 document.getElementById("password").focus(); |
|
156 } else { |
|
157 document.getElementById("text").focus(); |
|
158 } |
|
159 var previousFocusedElement = gFM.focusedElement; |
|
160 var element = document.getElementById(aTest.id); |
|
161 var focusEventTarget = element; |
|
162 var subDocument = null; |
|
163 if (element.contentDocument) { |
|
164 focusEventTarget = element.contentDocument; |
|
165 subDocument = element.contentDocument; |
|
166 element = element.contentDocument.documentElement; |
|
167 } |
|
168 |
|
169 focusEventTarget.addEventListener("focus", aFocusEventHandler, true); |
|
170 document.addEventListener("MozIMEFocusIn", aFocusEventHandler, true); |
|
171 document.addEventListener("MozIMEFocusOut", aFocusEventHandler, true); |
|
172 if (subDocument) { |
|
173 subDocument.addEventListener("MozIMEFocusIn", aFocusEventHandler, true); |
|
174 subDocument.addEventListener("MozIMEFocusOut", aFocusEventHandler, true); |
|
175 } |
|
176 |
|
177 element.focus(); |
|
178 |
|
179 focusEventTarget.removeEventListener("focus", aFocusEventHandler, true); |
|
180 document.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true); |
|
181 document.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true); |
|
182 if (element.contentDocument) { |
|
183 subDocument.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true); |
|
184 subDocument.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true); |
|
185 } |
|
186 |
|
187 var focusedElement = gFM.focusedElement; |
|
188 if (focusedElement) { |
|
189 var bindingParent = document.getBindingParent(focusedElement); |
|
190 if (bindingParent) { |
|
191 focusedElement = bindingParent; |
|
192 } |
|
193 } |
|
194 if (aTest.focusable) { |
|
195 is(focusedElement, element, |
|
196 aDescription + ": " + aTest.description + ", focus didn't move"); |
|
197 return (element == focusedElement); |
|
198 } |
|
199 is(focusedElement, previousFocusedElement, |
|
200 aDescription + ": " + aTest.description + ", focus moved as unexpected"); |
|
201 return (previousFocusedElement == focusedElement); |
|
202 } |
|
203 |
|
204 function testOpened(aTest, aOpened) |
|
205 { |
|
206 document.getElementById("text").focus(); |
|
207 gUtils.IMEIsOpen = aOpened; |
|
208 if (!moveFocus(aTest)) { |
|
209 return; |
|
210 } |
|
211 var message = aDescription + ": " + aTest.description + |
|
212 ", wrong opened state"; |
|
213 is(gUtils.IMEIsOpen, |
|
214 aTest.changeOpened ? aTest.expectedOpened : aOpened, message); |
|
215 } |
|
216 |
|
217 // IME Enabled state testing |
|
218 var enabled = gUtils.IME_STATUS_ENABLED; |
|
219 if (kIMEEnabledSupported) { |
|
220 var focusEventCount = 0; |
|
221 var mozIMEFocusInCount = 0; |
|
222 var mozIMEFocusOutCount = 0; |
|
223 var IMEHasFocus = false; |
|
224 |
|
225 function onFocus(aEvent) |
|
226 { |
|
227 switch (aEvent.type) { |
|
228 case "focus": |
|
229 focusEventCount++; |
|
230 is(gUtils.IMEStatus, aTest.expectedEnabled, |
|
231 aDescription + ": " + aTest.description + ", wrong enabled state at focus event"); |
|
232 break; |
|
233 case "MozIMEFocusIn": |
|
234 mozIMEFocusInCount++; |
|
235 IMEHasFocus = true; |
|
236 is(gUtils.IMEStatus, aTest.expectedEnabled, |
|
237 aDescription + ": " + aTest.description + |
|
238 ", MozIMEFocusIn event must be fired after IME state is updated"); |
|
239 break; |
|
240 case "MozIMEFocusOut": |
|
241 mozIMEFocusOutCount++; |
|
242 IMEHasFocus = false; |
|
243 var changingStatus = !(aIsEditable && aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED); |
|
244 if (aTest.toDesignModeEditor) { |
|
245 is(gUtils.IME_STATUS_ENABLED, aTest.expectedEnabled, |
|
246 aDescription + ": " + aTest.description + |
|
247 ", MozIMEFocusOut event must be fired after IME state is updated"); |
|
248 } else if (changingStatus) { |
|
249 isnot(gUtils.IMEStatus, aTest.expectedEnabled, |
|
250 aDescription + ": " + aTest.description + |
|
251 ", MozIMEFocusOut event must be fired before IME state is updated"); |
|
252 } else { |
|
253 is(gUtils.IMEStatus, aTest.expectedEnabled, |
|
254 aDescription + ": " + aTest.description + |
|
255 ", MozIMEFocusOut event must be fired with expected IME state if the state isn't being changed"); |
|
256 } |
|
257 break; |
|
258 } |
|
259 } |
|
260 |
|
261 if (!moveFocus(aTest, onFocus)) { |
|
262 return; |
|
263 } |
|
264 |
|
265 if (aTest.focusable) { |
|
266 if (!aTest.focusEventNotFired) { |
|
267 ok(focusEventCount > 0, |
|
268 aDescription + ": " + aTest.description + ", focus event is never fired"); |
|
269 if (aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED || aTest.expectedEnabled == gUtils.IME_STATUS_PASSWORD) { |
|
270 ok(mozIMEFocusInCount > 0, |
|
271 aDescription + ": " + aTest.description + ", MozIMEFocusIn event should be fired"); |
|
272 if (aInDesignMode && !aTest.toDesignModeEditor) { |
|
273 is(mozIMEFocusOutCount, 0, |
|
274 aDescription + ": " + aTest.description + |
|
275 ", MozIMEFocusOut event shouldn't be fired in designMode since focus isn't moved from another editor"); |
|
276 } else { |
|
277 ok(mozIMEFocusOutCount > 0, |
|
278 aDescription + ": " + aTest.description + |
|
279 ", MozIMEFocusOut event should be fired for the previous focused editor"); |
|
280 } |
|
281 ok(IMEHasFocus, |
|
282 aDescription + ": " + aTest.description + |
|
283 ", The latest MozIMEFocus* event must be MozIMEFocusIn"); |
|
284 } else { |
|
285 is(mozIMEFocusInCount, 0, |
|
286 aDescription + ": " + aTest.description + |
|
287 ", MozIMEFocusIn event shouldn't be fired"); |
|
288 ok(mozIMEFocusOutCount > 0, |
|
289 aDescription + ": " + aTest.description + |
|
290 ", MozIMEFocusOut event should be fired"); |
|
291 ok(!IMEHasFocus, |
|
292 aDescription + ": " + aTest.description + |
|
293 ", The latest MozIMEFocus* event must be MozIMEFocusOut"); |
|
294 } |
|
295 } else { |
|
296 todo(focusEventCount > 0, |
|
297 aDescription + ": " + aTest.description + ", focus event should be fired"); |
|
298 } |
|
299 } else { |
|
300 is(mozIMEFocusInCount, 0, |
|
301 aDescription + ": " + aTest.description + |
|
302 ", MozIMEFocusIn event shouldn't be fired at testing non-focusable element"); |
|
303 is(mozIMEFocusOutCount, 0, |
|
304 aDescription + ": " + aTest.description + |
|
305 ", MozIMEFocusOut event shouldn't be fired at testing non-focusable element"); |
|
306 } |
|
307 |
|
308 enabled = gUtils.IMEStatus; |
|
309 inputtype = gUtils.focusedInputType; |
|
310 is(enabled, aTest.expectedEnabled, |
|
311 aDescription + ": " + aTest.description + ", wrong enabled state"); |
|
312 if (aTest.expectedType && !aInDesignMode) { |
|
313 is(inputtype, aTest.expectedType, |
|
314 aDescription + ": " + aTest.description + ", wrong input type"); |
|
315 } else if (aInDesignMode) { |
|
316 is(inputtype, "", |
|
317 aDescription + ": " + aTest.description + ", wrong input type") |
|
318 } |
|
319 } |
|
320 |
|
321 if (!kIMEOpenSupported || enabled != gUtils.IME_STATUS_ENABLED || |
|
322 aTest.expectedEnabled != gUtils.IME_STATUS_ENABLED) { |
|
323 return; |
|
324 } |
|
325 |
|
326 // IME Open state testing |
|
327 testOpened(aTest, false); |
|
328 testOpened(aTest, true); |
|
329 } |
|
330 |
|
331 if (kIMEEnabledSupported) { |
|
332 // make sure there is an active element |
|
333 document.getElementById("text").focus(); |
|
334 document.activeElement.blur(); |
|
335 is(gUtils.IMEStatus, |
|
336 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_DISABLED, |
|
337 aDescription + ": unexpected enabled state when no element has focus"); |
|
338 } |
|
339 |
|
340 // Form controls except text editable elements are "disable" in normal |
|
341 // condition, however, if they are editable, they are "enabled". |
|
342 // XXX Probably there are some bugs: If the form controls editable, they |
|
343 // shouldn't be focusable. |
|
344 const kEnabledStateOnNonEditableElement = |
|
345 (aInDesignMode || aIsEditable) ? gUtils.IME_STATUS_ENABLED : |
|
346 gUtils.IME_STATUS_DISABLED; |
|
347 const kEnabledStateOnPasswordField = |
|
348 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_PASSWORD; |
|
349 const kEnabledStateOnReadonlyField = |
|
350 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_DISABLED; |
|
351 const kTests = [ |
|
352 { id: "text", |
|
353 description: "input[type=text]", |
|
354 focusable: !aInDesignMode, |
|
355 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
356 expectedType: "text" }, |
|
357 { id: "text_readonly", |
|
358 description: "input[type=text][readonly]", |
|
359 focusable: !aInDesignMode, |
|
360 expectedEnabled: kEnabledStateOnReadonlyField }, |
|
361 { id: "password", |
|
362 description: "input[type=password]", |
|
363 focusable: !aInDesignMode, |
|
364 expectedEnabled: kEnabledStateOnPasswordField, |
|
365 expectedType: "password" }, |
|
366 { id: "password_readonly", |
|
367 description: "input[type=password][readonly]", |
|
368 focusable: !aInDesignMode, |
|
369 expectedEnabled: kEnabledStateOnReadonlyField }, |
|
370 { id: "checkbox", |
|
371 description: "input[type=checkbox]", |
|
372 focusable: !aInDesignMode, |
|
373 focusEventNotFired: aIsEditable && !aInDesignMode, |
|
374 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
375 { id: "radio", |
|
376 description: "input[type=radio]", |
|
377 focusable: !aInDesignMode, |
|
378 focusEventNotFired: aIsEditable && !aInDesignMode, |
|
379 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
380 { id: "submit", |
|
381 description: "input[type=submit]", |
|
382 focusable: !aInDesignMode, |
|
383 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
384 { id: "reset", |
|
385 description: "input[type=reset]", |
|
386 focusable: !aInDesignMode, |
|
387 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
388 { id: "file", |
|
389 description: "input[type=file]", |
|
390 focusable: !aInDesignMode, |
|
391 focusEventNotFired: aIsEditable && !aInDesignMode, |
|
392 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
393 { id: "button", |
|
394 description: "input[type=button]", |
|
395 focusable: !aInDesignMode, |
|
396 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
397 { id: "image", |
|
398 description: "input[type=image]", |
|
399 focusable: !aInDesignMode, |
|
400 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
401 { id: "url", |
|
402 description: "input[type=url]", |
|
403 focusable: !aInDesignMode, |
|
404 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
405 expectedType: "url" }, |
|
406 { id: "email", |
|
407 description: "input[type=email]", |
|
408 focusable: !aInDesignMode, |
|
409 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
410 expectedType: "email" }, |
|
411 { id: "search", |
|
412 description: "input[type=search]", |
|
413 focusable: !aInDesignMode, |
|
414 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
415 expectedType: "search" }, |
|
416 { id: "tel", |
|
417 description: "input[type=tel]", |
|
418 focusable: !aInDesignMode, |
|
419 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
420 expectedType: "tel" }, |
|
421 { id: "number", |
|
422 description: "input[type=number]", |
|
423 focusable: !aInDesignMode, |
|
424 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
425 expectedType: "number" }, |
|
426 |
|
427 // form controls |
|
428 { id: "button", |
|
429 description: "button", |
|
430 focusable: !aInDesignMode, |
|
431 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
432 { id: "textarea", |
|
433 description: "textarea", |
|
434 focusable: !aInDesignMode, |
|
435 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
436 { id: "textarea_readonly", |
|
437 description: "textarea[readonly]", |
|
438 focusable: !aInDesignMode, |
|
439 expectedEnabled: kEnabledStateOnReadonlyField }, |
|
440 { id: "select", |
|
441 description: "select (dropdown list)", |
|
442 focusable: !aInDesignMode, |
|
443 focusEventNotFired: aIsEditable && !aInDesignMode, |
|
444 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
445 { id: "select_multiple", |
|
446 description: "select (list box)", |
|
447 focusable: !aInDesignMode, |
|
448 focusEventNotFired: aIsEditable && !aInDesignMode, |
|
449 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
450 |
|
451 // a element |
|
452 { id: "a_href", |
|
453 description: "a[href]", |
|
454 focusable: !aIsEditable && !aInDesignMode, |
|
455 expectedEnabled: kEnabledStateOnNonEditableElement }, |
|
456 |
|
457 // ime-mode |
|
458 { id: "ime_mode_auto", |
|
459 description: "input[type=text][style=\"ime-mode: auto;\"]", |
|
460 focusable: !aInDesignMode, |
|
461 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
462 { id: "ime_mode_normal", |
|
463 description: "input[type=text][style=\"ime-mode: normal;\"]", |
|
464 focusable: !aInDesignMode, |
|
465 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
466 { id: "ime_mode_active", |
|
467 description: "input[type=text][style=\"ime-mode: active;\"]", |
|
468 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
469 focusable: !aInDesignMode, |
|
470 changeOpened: true, expectedOpened: true }, |
|
471 { id: "ime_mode_inactive", |
|
472 description: "input[type=text][style=\"ime-mode: inactive;\"]", |
|
473 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
474 focusable: !aInDesignMode, |
|
475 changeOpened: true, expectedOpened: false }, |
|
476 { id: "ime_mode_disabled", |
|
477 description: "input[type=text][style=\"ime-mode: disabled;\"]", |
|
478 focusable: !aInDesignMode, |
|
479 expectedEnabled: kEnabledStateOnPasswordField }, |
|
480 |
|
481 { id: "ime_mode_auto_url", |
|
482 description: "input[type=url][style=\"ime-mode: auto;\"]", |
|
483 focusable: !aInDesignMode, |
|
484 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
485 { id: "ime_mode_normal_url", |
|
486 description: "input[type=url][style=\"ime-mode: normal;\"]", |
|
487 focusable: !aInDesignMode, |
|
488 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
489 { id: "ime_mode_active_url", |
|
490 description: "input[type=url][style=\"ime-mode: active;\"]", |
|
491 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
492 focusable: !aInDesignMode, |
|
493 changeOpened: true, expectedOpened: true }, |
|
494 { id: "ime_mode_inactive_url", |
|
495 description: "input[type=url][style=\"ime-mode: inactive;\"]", |
|
496 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
497 focusable: !aInDesignMode, |
|
498 changeOpened: true, expectedOpened: false }, |
|
499 { id: "ime_mode_disabled_url", |
|
500 description: "input[type=url][style=\"ime-mode: disabled;\"]", |
|
501 focusable: !aInDesignMode, |
|
502 expectedEnabled: kEnabledStateOnPasswordField }, |
|
503 |
|
504 { id: "ime_mode_auto_email", |
|
505 description: "input[type=email][style=\"ime-mode: auto;\"]", |
|
506 focusable: !aInDesignMode, |
|
507 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
508 { id: "ime_mode_normal_email", |
|
509 description: "input[type=email][style=\"ime-mode: normal;\"]", |
|
510 focusable: !aInDesignMode, |
|
511 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
512 { id: "ime_mode_active_email", |
|
513 description: "input[type=email][style=\"ime-mode: active;\"]", |
|
514 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
515 focusable: !aInDesignMode, |
|
516 changeOpened: true, expectedOpened: true }, |
|
517 { id: "ime_mode_inactive_email", |
|
518 description: "input[type=email][style=\"ime-mode: inactive;\"]", |
|
519 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
520 focusable: !aInDesignMode, |
|
521 changeOpened: true, expectedOpened: false }, |
|
522 { id: "ime_mode_disabled_email", |
|
523 description: "input[type=email][style=\"ime-mode: disabled;\"]", |
|
524 focusable: !aInDesignMode, |
|
525 expectedEnabled: kEnabledStateOnPasswordField }, |
|
526 |
|
527 { id: "ime_mode_auto_search", |
|
528 description: "input[type=search][style=\"ime-mode: auto;\"]", |
|
529 focusable: !aInDesignMode, |
|
530 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
531 { id: "ime_mode_normal_search", |
|
532 description: "input[type=search][style=\"ime-mode: normal;\"]", |
|
533 focusable: !aInDesignMode, |
|
534 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
535 { id: "ime_mode_active_search", |
|
536 description: "input[type=search][style=\"ime-mode: active;\"]", |
|
537 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
538 focusable: !aInDesignMode, |
|
539 changeOpened: true, expectedOpened: true }, |
|
540 { id: "ime_mode_inactive_search", |
|
541 description: "input[type=search][style=\"ime-mode: inactive;\"]", |
|
542 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
543 focusable: !aInDesignMode, |
|
544 changeOpened: true, expectedOpened: false }, |
|
545 { id: "ime_mode_disabled_search", |
|
546 description: "input[type=search][style=\"ime-mode: disabled;\"]", |
|
547 focusable: !aInDesignMode, |
|
548 expectedEnabled: kEnabledStateOnPasswordField }, |
|
549 |
|
550 { id: "ime_mode_auto_tel", |
|
551 description: "input[type=tel][style=\"ime-mode: auto;\"]", |
|
552 focusable: !aInDesignMode, |
|
553 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
554 { id: "ime_mode_normal_tel", |
|
555 description: "input[type=tel][style=\"ime-mode: normal;\"]", |
|
556 focusable: !aInDesignMode, |
|
557 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
558 { id: "ime_mode_active_tel", |
|
559 description: "input[type=tel][style=\"ime-mode: active;\"]", |
|
560 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
561 focusable: !aInDesignMode, |
|
562 changeOpened: true, expectedOpened: true }, |
|
563 { id: "ime_mode_inactive_tel", |
|
564 description: "input[type=tel][style=\"ime-mode: inactive;\"]", |
|
565 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
566 focusable: !aInDesignMode, |
|
567 changeOpened: true, expectedOpened: false }, |
|
568 { id: "ime_mode_disabled_tel", |
|
569 description: "input[type=tel][style=\"ime-mode: disabled;\"]", |
|
570 focusable: !aInDesignMode, |
|
571 expectedEnabled: kEnabledStateOnPasswordField }, |
|
572 |
|
573 { id: "ime_mode_auto_number", |
|
574 description: "input[type=number][style=\"ime-mode: auto;\"]", |
|
575 focusable: !aInDesignMode, |
|
576 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
577 { id: "ime_mode_normal_number", |
|
578 description: "input[type=number][style=\"ime-mode: normal;\"]", |
|
579 focusable: !aInDesignMode, |
|
580 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
581 { id: "ime_mode_active_number", |
|
582 description: "input[type=number][style=\"ime-mode: active;\"]", |
|
583 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
584 focusable: !aInDesignMode, |
|
585 changeOpened: true, expectedOpened: true }, |
|
586 { id: "ime_mode_inactive_number", |
|
587 description: "input[type=number][style=\"ime-mode: inactive;\"]", |
|
588 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
589 focusable: !aInDesignMode, |
|
590 changeOpened: true, expectedOpened: false }, |
|
591 { id: "ime_mode_disabled_number", |
|
592 description: "input[type=number][style=\"ime-mode: disabled;\"]", |
|
593 focusable: !aInDesignMode, |
|
594 expectedEnabled: kEnabledStateOnPasswordField }, |
|
595 |
|
596 { id: "ime_mode_auto_p", |
|
597 description: "input[type=password][style=\"ime-mode: auto;\"]", |
|
598 focusable: !aInDesignMode, |
|
599 expectedEnabled: kEnabledStateOnPasswordField }, |
|
600 { id: "ime_mode_normal_p", |
|
601 description: "input[type=password][style=\"ime-mode: normal;\"]", |
|
602 focusable: !aInDesignMode, |
|
603 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
604 { id: "ime_mode_active_p", |
|
605 description: "input[type=password][style=\"ime-mode: active;\"]", |
|
606 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
607 focusable: !aInDesignMode, |
|
608 changeOpened: true, expectedOpened: true }, |
|
609 { id: "ime_mode_inactive_p", |
|
610 description: "input[type=password][style=\"ime-mode: inactive;\"]", |
|
611 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
612 focusable: !aInDesignMode, |
|
613 changeOpened: true, expectedOpened: false }, |
|
614 { id: "ime_mode_disabled_p", |
|
615 description: "input[type=password][style=\"ime-mode: disabled;\"]", |
|
616 focusable: !aInDesignMode, |
|
617 expectedEnabled: kEnabledStateOnPasswordField }, |
|
618 { id: "ime_mode_auto", |
|
619 description: "textarea[style=\"ime-mode: auto;\"]", |
|
620 focusable: !aInDesignMode, |
|
621 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
622 { id: "ime_mode_normal", |
|
623 description: "textarea[style=\"ime-mode: normal;\"]", |
|
624 focusable: !aInDesignMode, |
|
625 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
626 { id: "ime_mode_active", |
|
627 description: "textarea[style=\"ime-mode: active;\"]", |
|
628 focusable: !aInDesignMode, |
|
629 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
630 changeOpened: true, expectedOpened: true }, |
|
631 { id: "ime_mode_inactive", |
|
632 description: "textarea[style=\"ime-mode: inactive;\"]", |
|
633 focusable: !aInDesignMode, |
|
634 expectedEnabled: gUtils.IME_STATUS_ENABLED, |
|
635 changeOpened: true, expectedOpened: false }, |
|
636 { id: "ime_mode_disabled", |
|
637 description: "textarea[style=\"ime-mode: disabled;\"]", |
|
638 focusable: !aInDesignMode, |
|
639 expectedEnabled: kEnabledStateOnPasswordField }, |
|
640 |
|
641 // HTML editors |
|
642 { id: "contenteditableEditor", |
|
643 description: "div[contenteditable=\"true\"]", |
|
644 focusable: !aIsEditable && !aInDesignMode, |
|
645 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
646 { id: "designModeEditor", |
|
647 description: "designMode editor", |
|
648 focusable: true, |
|
649 toDesignModeEditor: true, |
|
650 expectedEnabled: gUtils.IME_STATUS_ENABLED }, |
|
651 ]; |
|
652 |
|
653 for (var i = 0; i < kTests.length; i++) { |
|
654 test(kTests[i]); |
|
655 } |
|
656 } |
|
657 |
|
658 function runPluginTest() |
|
659 { |
|
660 if (!kIMEEnabledSupported) { |
|
661 return; |
|
662 } |
|
663 |
|
664 if (navigator.platform.indexOf("Mac") == 0) { |
|
665 // XXX on mac, currently, this test isn't passed because it doesn't return |
|
666 // IME_STATUS_PLUGIN by its bug. |
|
667 return; |
|
668 } |
|
669 |
|
670 var plugin = document.getElementById("plugin"); |
|
671 |
|
672 document.activeElement.blur(); |
|
673 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
674 "runPluginTest: unexpected enabled state when no element has focus"); |
|
675 |
|
676 plugin.focus(); |
|
677 is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN, |
|
678 "runPluginTest: unexpected enabled state when plugin has focus"); |
|
679 |
|
680 plugin.blur(); |
|
681 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
682 "runPluginTest: unexpected enabled state when plugin has focus"); |
|
683 |
|
684 plugin.focus(); |
|
685 is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN, |
|
686 "runPluginTest: unexpected enabled state when plugin has focus #2"); |
|
687 |
|
688 var parent = plugin.parentNode; |
|
689 parent.removeChild(plugin); |
|
690 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
691 "runPluginTest: unexpected enabled state when plugin is removed from tree"); |
|
692 |
|
693 document.getElementById("text").focus(); |
|
694 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
695 "runPluginTest: unexpected enabled state when input[type=text] has focus"); |
|
696 } |
|
697 |
|
698 function runTypeChangingTest() |
|
699 { |
|
700 if (!kIMEEnabledSupported) |
|
701 return; |
|
702 |
|
703 const kInputControls = [ |
|
704 { id: "text", |
|
705 type: "text", expected: gUtils.IME_STATUS_ENABLED, |
|
706 description: "[type=\"text\"]" }, |
|
707 { id: "text_readonly", |
|
708 type: "text", expected: gUtils.IME_STATUS_DISABLED, isReadonly: true, |
|
709 description: "[type=\"text\"][readonly]" }, |
|
710 { id: "password", |
|
711 type: "password", expected: gUtils.IME_STATUS_PASSWORD, |
|
712 description: "[type=\"password\"]" }, |
|
713 { id: "password_readonly", |
|
714 type: "password", expected: gUtils.IME_STATUS_DISABLED, isReadonly: true, |
|
715 description: "[type=\"password\"][readonly]" }, |
|
716 { id: "checkbox", |
|
717 type: "checkbox", expected: gUtils.IME_STATUS_DISABLED, |
|
718 description: "[type=\"checkbox\"]" }, |
|
719 { id: "radio", |
|
720 type: "radio", expected: gUtils.IME_STATUS_DISABLED, |
|
721 description: "[type=\"radio\"]" }, |
|
722 { id: "submit", |
|
723 type: "submit", expected: gUtils.IME_STATUS_DISABLED, |
|
724 description: "[type=\"submit\"]" }, |
|
725 { id: "reset", |
|
726 type: "reset", expected: gUtils.IME_STATUS_DISABLED, |
|
727 description: "[type=\"reset\"]" }, |
|
728 { id: "file", |
|
729 type: "file", expected: gUtils.IME_STATUS_DISABLED, |
|
730 description: "[type=\"file\"]" }, |
|
731 { id: "ibutton", |
|
732 type: "button", expected: gUtils.IME_STATUS_DISABLED, |
|
733 description: "[type=\"button\"]" }, |
|
734 { id: "image", |
|
735 type: "image", expected: gUtils.IME_STATUS_DISABLED, |
|
736 description: "[type=\"image\"]" }, |
|
737 { id: "url", |
|
738 type: "url", expected: gUtils.IME_STATUS_ENABLED, |
|
739 description: "[type=\"url\"]" }, |
|
740 { id: "email", |
|
741 type: "email", expected: gUtils.IME_STATUS_ENABLED, |
|
742 description: "[type=\"email\"]" }, |
|
743 { id: "search", |
|
744 type: "search", expected: gUtils.IME_STATUS_ENABLED, |
|
745 description: "[type=\"search\"]" }, |
|
746 { id: "tel", |
|
747 type: "tel", expected: gUtils.IME_STATUS_ENABLED, |
|
748 description: "[type=\"tel\"]" }, |
|
749 { id: "number", |
|
750 type: "number", expected: gUtils.IME_STATUS_ENABLED, |
|
751 description: "[type=\"number\"]" }, |
|
752 { id: "ime_mode_auto", |
|
753 type: "text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
754 description: "[type=\"text\"][ime-mode: auto;]" }, |
|
755 { id: "ime_mode_normal", |
|
756 type: "text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
757 description: "[type=\"text\"][ime-mode: normal;]" }, |
|
758 { id: "ime_mode_active", |
|
759 type: "text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
760 description: "[type=\"text\"][ime-mode: active;]" }, |
|
761 { id: "ime_mode_inactive", |
|
762 type: "text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
763 description: "[type=\"text\"][ime-mode: inactive;]" }, |
|
764 { id: "ime_mode_disabled", |
|
765 type: "text", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
766 description: "[type=\"text\"][ime-mode: disabled;]" }, |
|
767 |
|
768 { id: "ime_mode_auto_url", |
|
769 type: "url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
770 description: "[type=\"url\"][ime-mode: auto;]" }, |
|
771 { id: "ime_mode_normal_url", |
|
772 type: "url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
773 description: "[type=\"url\"][ime-mode: normal;]" }, |
|
774 { id: "ime_mode_active_url", |
|
775 type: "url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
776 description: "[type=\"url\"][ime-mode: active;]" }, |
|
777 { id: "ime_mode_inactive_url", |
|
778 type: "url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
779 description: "[type=\"url\"][ime-mode: inactive;]" }, |
|
780 { id: "ime_mode_disabled_url", |
|
781 type: "url", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
782 description: "[type=\"url\"][ime-mode: disabled;]" }, |
|
783 |
|
784 { id: "ime_mode_auto_email", |
|
785 type: "email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
786 description: "[type=\"email\"][ime-mode: auto;]" }, |
|
787 { id: "ime_mode_normal_email", |
|
788 type: "email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
789 description: "[type=\"email\"][ime-mode: normal;]" }, |
|
790 { id: "ime_mode_active_email", |
|
791 type: "email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
792 description: "[type=\"email\"][ime-mode: active;]" }, |
|
793 { id: "ime_mode_inactive_email", |
|
794 type: "email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
795 description: "[type=\"email\"][ime-mode: inactive;]" }, |
|
796 { id: "ime_mode_disabled_email", |
|
797 type: "email", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
798 description: "[type=\"email\"][ime-mode: disabled;]" }, |
|
799 |
|
800 { id: "ime_mode_auto_search", |
|
801 type: "search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
802 description: "[type=\"search\"][ime-mode: auto;]" }, |
|
803 { id: "ime_mode_normal_search", |
|
804 type: "search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
805 description: "[type=\"search\"][ime-mode: normal;]" }, |
|
806 { id: "ime_mode_active_search", |
|
807 type: "search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
808 description: "[type=\"search\"][ime-mode: active;]" }, |
|
809 { id: "ime_mode_inactive_search", |
|
810 type: "search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
811 description: "[type=\"search\"][ime-mode: inactive;]" }, |
|
812 { id: "ime_mode_disabled_search", |
|
813 type: "search", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
814 description: "[type=\"search\"][ime-mode: disabled;]" }, |
|
815 |
|
816 { id: "ime_mode_auto_tel", |
|
817 type: "tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
818 description: "[type=\"tel\"][ime-mode: auto;]" }, |
|
819 { id: "ime_mode_normal_tel", |
|
820 type: "tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
821 description: "[type=\"tel\"][ime-mode: normal;]" }, |
|
822 { id: "ime_mode_active_tel", |
|
823 type: "tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
824 description: "[type=\"tel\"][ime-mode: active;]" }, |
|
825 { id: "ime_mode_inactive_tel", |
|
826 type: "tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
827 description: "[type=\"tel\"][ime-mode: inactive;]" }, |
|
828 { id: "ime_mode_disabled_tel", |
|
829 type: "tel", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
830 description: "[type=\"tel\"][ime-mode: disabled;]" }, |
|
831 |
|
832 { id: "ime_mode_auto_number", |
|
833 type: "number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
834 description: "[type=\"number\"][ime-mode: auto;]" }, |
|
835 { id: "ime_mode_normal_number", |
|
836 type: "number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
837 description: "[type=\"number\"][ime-mode: normal;]" }, |
|
838 { id: "ime_mode_active_number", |
|
839 type: "number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
840 description: "[type=\"number\"][ime-mode: active;]" }, |
|
841 { id: "ime_mode_inactive_number", |
|
842 type: "number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
843 description: "[type=\"number\"][ime-mode: inactive;]" }, |
|
844 { id: "ime_mode_disabled_number", |
|
845 type: "number", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
846 description: "[type=\"number\"][ime-mode: disabled;]" }, |
|
847 |
|
848 { id: "ime_mode_auto_p", |
|
849 type: "password", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
850 description: "[type=\"password\"][ime-mode: auto;]" }, |
|
851 { id: "ime_mode_normal_p", |
|
852 type: "password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
853 description: "[type=\"password\"][ime-mode: normal;]" }, |
|
854 { id: "ime_mode_active_p", |
|
855 type: "password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
856 description: "[type=\"password\"][ime-mode: active;]" }, |
|
857 { id: "ime_mode_inactive_p", |
|
858 type: "password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true, |
|
859 description: "[type=\"password\"][ime-mode: inactive;]" }, |
|
860 { id: "ime_mode_disabled_p", |
|
861 type: "password", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true, |
|
862 description: "[type=\"password\"][ime-mode: disabled;]" } |
|
863 ]; |
|
864 |
|
865 const kInputTypes = [ |
|
866 { type: "", expected: gUtils.IME_STATUS_ENABLED }, |
|
867 { type: "text", expected: gUtils.IME_STATUS_ENABLED }, |
|
868 { type: "password", expected: gUtils.IME_STATUS_PASSWORD }, |
|
869 { type: "checkbox", expected: gUtils.IME_STATUS_DISABLED }, |
|
870 { type: "radio", expected: gUtils.IME_STATUS_DISABLED }, |
|
871 { type: "submit", expected: gUtils.IME_STATUS_DISABLED }, |
|
872 { type: "reset", expected: gUtils.IME_STATUS_DISABLED }, |
|
873 { type: "file", expected: gUtils.IME_STATUS_DISABLED }, |
|
874 { type: "button", expected: gUtils.IME_STATUS_DISABLED }, |
|
875 { type: "image", expected: gUtils.IME_STATUS_DISABLED }, |
|
876 { type: "url", expected: gUtils.IME_STATUS_ENABLED }, |
|
877 { type: "email", expected: gUtils.IME_STATUS_ENABLED }, |
|
878 { type: "search", expected: gUtils.IME_STATUS_ENABLED }, |
|
879 { type: "tel", expected: gUtils.IME_STATUS_ENABLED }, |
|
880 { type: "number", expected: gUtils.IME_STATUS_ENABLED } |
|
881 ]; |
|
882 |
|
883 function getExpectedIMEEnabled(aNewType, aInputControl) |
|
884 { |
|
885 if (aNewType.expected == gUtils.IME_STATUS_DISABLED || |
|
886 aInputControl.isReadonly) |
|
887 return gUtils.IME_STATUS_DISABLED; |
|
888 return aInputControl.imeMode ? aInputControl.expected : aNewType.expected; |
|
889 } |
|
890 |
|
891 const kOpenedState = [ true, false ]; |
|
892 |
|
893 for (var i = 0; i < kOpenedState.length; i++) { |
|
894 const kOpened = kOpenedState[i]; |
|
895 for (var j = 0; j < kInputControls.length; j++) { |
|
896 const kInput = kInputControls[j]; |
|
897 var e = document.getElementById(kInput.id); |
|
898 e.focus(); |
|
899 for (var k = 0; k < kInputTypes.length; k++) { |
|
900 const kType = kInputTypes[k]; |
|
901 var typeChangingDescription = |
|
902 "\"" + e.getAttribute("type") + "\" to \"" + kInput.type + "\""; |
|
903 e.setAttribute("type", kInput.type); |
|
904 is(gUtils.IMEStatus, kInput.expected, |
|
905 "type attr changing test (IMEStatus): " + typeChangingDescription + |
|
906 " (" + kInput.description + ")"); |
|
907 is(gUtils.focusedInputType, kInput.type, |
|
908 "type attr changing test (type): " + typeChangingDescription + |
|
909 " (" + kInput.description + ")"); |
|
910 |
|
911 const kTestOpenState = kIMEOpenSupported && |
|
912 gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED && |
|
913 getExpectedIMEEnabled(kType, kInput) == gUtils.IME_STATUS_ENABLED; |
|
914 if (kTestOpenState) { |
|
915 gUtils.IMEIsOpen = kOpened; |
|
916 } |
|
917 |
|
918 typeChangingDescription = |
|
919 "\"" + e.getAttribute("type") + "\" to \"" + kType.type + "\""; |
|
920 if (kType.type != "") |
|
921 e.setAttribute("type", kType.type); |
|
922 else |
|
923 e.removeAttribute("type"); |
|
924 |
|
925 is(gUtils.IMEStatus, getExpectedIMEEnabled(kType, kInput), |
|
926 "type attr changing test (IMEStatus): " + typeChangingDescription + |
|
927 " (" + kInput.description + ")"); |
|
928 is(gUtils.focusedInputType, kType.type, |
|
929 "type attr changing test (type): " + typeChangingDescription + |
|
930 " (" + kInput.description + ")"); |
|
931 if (kTestOpenState && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) { |
|
932 is(gUtils.IMEIsOpen, kOpened, |
|
933 "type attr changing test (open state is changed): " + |
|
934 typeChangingDescription + " (" + kInput.description + ")"); |
|
935 } |
|
936 } |
|
937 // reset the type to default |
|
938 e.setAttribute("type", kInput.type); |
|
939 } |
|
940 if (!kIMEOpenSupported) |
|
941 break; |
|
942 } |
|
943 } |
|
944 |
|
945 function runReadonlyChangingTest() |
|
946 { |
|
947 if (!kIMEEnabledSupported) |
|
948 return; |
|
949 |
|
950 const kInputControls = [ |
|
951 { id: "text", |
|
952 type: "text", expected: gUtils.IME_STATUS_ENABLED }, |
|
953 { id: "password", |
|
954 type: "password", expected: gUtils.IME_STATUS_PASSWORD }, |
|
955 { id: "url", |
|
956 type: "url", expected: gUtils.IME_STATUS_ENABLED }, |
|
957 { id: "email", |
|
958 type: "email", expected: gUtils.IME_STATUS_ENABLED }, |
|
959 { id: "search", |
|
960 type: "search", expected: gUtils.IME_STATUS_ENABLED }, |
|
961 { id: "tel", |
|
962 type: "tel", expected: gUtils.IME_STATUS_ENABLED }, |
|
963 { id: "number", |
|
964 type: "number", expected: gUtils.IME_STATUS_ENABLED }, |
|
965 { id: "textarea", |
|
966 type: "textarea", expected: gUtils.IME_STATUS_ENABLED } |
|
967 ]; |
|
968 const kOpenedState = [ true, false ]; |
|
969 |
|
970 for (var i = 0; i < kOpenedState.length; i++) { |
|
971 const kOpened = kOpenedState[i]; |
|
972 for (var j = 0; j < kInputControls.length; j++) { |
|
973 const kInput = kInputControls[j]; |
|
974 var e = document.getElementById(kInput.id); |
|
975 e.focus(); |
|
976 if (kIMEOpenSupported && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) { |
|
977 gUtils.IMEIsOpen = kOpened; |
|
978 } |
|
979 e.setAttribute("readonly", "readonly"); |
|
980 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
981 "readonly attr setting test: type=" + kInput.type); |
|
982 e.removeAttribute("readonly"); |
|
983 is(gUtils.IMEStatus, kInput.expected, |
|
984 "readonly attr removing test: type=" + kInput.type); |
|
985 if (kIMEOpenSupported && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) { |
|
986 is(gUtils.IMEIsOpen, kOpened, |
|
987 "readonly attr removing test (open state is changed): type=" + |
|
988 kInput.type); |
|
989 } |
|
990 } |
|
991 if (!kIMEOpenSupported) |
|
992 break; |
|
993 } |
|
994 } |
|
995 |
|
996 function runComplexContenteditableTests() |
|
997 { |
|
998 if (!kIMEEnabledSupported) { |
|
999 return; |
|
1000 } |
|
1001 |
|
1002 var description = "runReadonlyChangingOnContenteditable: "; |
|
1003 |
|
1004 var container = document.getElementById("display"); |
|
1005 var button = document.getElementById("button"); |
|
1006 |
|
1007 // the editor has focus directly. |
|
1008 container.setAttribute("contenteditable", "true"); |
|
1009 container.focus(); |
|
1010 |
|
1011 is(gFM.focusedElement, container, |
|
1012 description + "The editor doesn't get focus"); |
|
1013 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1014 description + "IME isn't enabled on HTML editor"); |
|
1015 const kReadonly = |
|
1016 Components.interfaces.nsIPlaintextEditor.eEditorReadonlyMask; |
|
1017 var editor = |
|
1018 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1019 getInterface(Components.interfaces.nsIWebNavigation). |
|
1020 QueryInterface(Components.interfaces.nsIDocShell).editor; |
|
1021 var flags = editor.flags; |
|
1022 editor.flags = flags | kReadonly; |
|
1023 is(gFM.focusedElement, container, |
|
1024 description + "The editor loses focus by flag change"); |
|
1025 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
1026 description + "IME is still enabled on readonly HTML editor"); |
|
1027 editor.flags = flags; |
|
1028 is(gFM.focusedElement, container, |
|
1029 description + "The editor loses focus by flag change #2"); |
|
1030 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1031 description + "IME is still disabled, the editor isn't readonly now"); |
|
1032 container.removeAttribute("contenteditable"); |
|
1033 todo_is(gFM.focusedElement, null, |
|
1034 description + "The container still has focus, the editor has been no editable"); |
|
1035 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
1036 description + "IME is still enabled on the editor, the editor has been no editable"); |
|
1037 |
|
1038 // a button which is in the editor has focus |
|
1039 button.focus(); |
|
1040 is(gFM.focusedElement, button, |
|
1041 description + "The button doesn't get focus"); |
|
1042 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
1043 description + "IME is enabled on the button"); |
|
1044 container.setAttribute("contenteditable", "true"); |
|
1045 is(gFM.focusedElement, button, |
|
1046 description + "The button loses focus, the container is editable now"); |
|
1047 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1048 description + "IME is still disabled on the button, the container is editable now"); |
|
1049 editor = |
|
1050 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1051 getInterface(Components.interfaces.nsIWebNavigation). |
|
1052 QueryInterface(Components.interfaces.nsIDocShell).editor; |
|
1053 flags = editor.flags; |
|
1054 editor.flags = flags | kReadonly; |
|
1055 is(gFM.focusedElement, button, |
|
1056 description + "The button loses focus by changing editor flags"); |
|
1057 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
1058 description + "IME is still enabled on the button, the container is readonly now"); |
|
1059 editor.flags = flags; |
|
1060 is(gFM.focusedElement, button, |
|
1061 description + "The button loses focus by changing editor flags #2"); |
|
1062 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1063 description + "IME is still disabled on the button, the container isn't readonly now"); |
|
1064 container.removeAttribute("contenteditable"); |
|
1065 is(gFM.focusedElement, button, |
|
1066 description + "The button loses focus, the container has been no editable"); |
|
1067 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED, |
|
1068 description + "IME is still enabled on the button, the container has been no editable"); |
|
1069 |
|
1070 description = "testOnIndependentEditor: "; |
|
1071 function testOnIndependentEditor(aEditor, aEditorDescription) |
|
1072 { |
|
1073 var isReadonly = aEditor.readOnly; |
|
1074 var expectedState = |
|
1075 aEditor.readOnly ? gUtils.IME_STATUS_DISABLED : gUtils.IME_STATUS_ENABLED; |
|
1076 var unexpectedStateDescription = |
|
1077 expectedState != gUtils.IME_STATUS_ENABLED ? "enabled" : "disabled"; |
|
1078 aEditor.focus(); |
|
1079 is(gFM.focusedElement, aEditor, |
|
1080 description + "The " + aEditorDescription + " doesn't get focus"); |
|
1081 is(gUtils.IMEStatus, expectedState, |
|
1082 description + "IME is " + unexpectedStateDescription + |
|
1083 " on the " + aEditorDescription); |
|
1084 container.setAttribute("contenteditable", "true"); |
|
1085 is(gFM.focusedElement, aEditor, |
|
1086 description + "The " + aEditorDescription + |
|
1087 " loses focus, the container is editable now"); |
|
1088 is(gUtils.IMEStatus, expectedState, |
|
1089 description + "IME becomes " + unexpectedStateDescription + |
|
1090 " on the " + aEditorDescription + ", the container is editable now"); |
|
1091 editor = |
|
1092 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1093 getInterface(Components.interfaces.nsIWebNavigation). |
|
1094 QueryInterface(Components.interfaces.nsIDocShell).editor; |
|
1095 flags = editor.flags; |
|
1096 editor.flags = flags | kReadonly; |
|
1097 is(gFM.focusedElement, aEditor, |
|
1098 description + "The " + aEditorDescription + |
|
1099 " loses focus by changing editor flags"); |
|
1100 is(gUtils.IMEStatus, expectedState, |
|
1101 description + "IME becomes " + unexpectedStateDescription + " on the " + |
|
1102 aEditorDescription + ", the container is readonly now"); |
|
1103 editor.flags = flags; |
|
1104 is(gFM.focusedElement, aEditor, |
|
1105 description + "The " + aEditorDescription + |
|
1106 " loses focus by changing editor flags #2"); |
|
1107 is(gUtils.IMEStatus, expectedState, |
|
1108 description + "IME becomes " + unexpectedStateDescription + " on the " + |
|
1109 aEditorDescription + ", the container isn't readonly now"); |
|
1110 container.removeAttribute("contenteditable"); |
|
1111 is(gFM.focusedElement, aEditor, |
|
1112 description + "The " + aEditorDescription + |
|
1113 " loses focus, the container has been no editable"); |
|
1114 is(gUtils.IMEStatus, expectedState, |
|
1115 description + "IME becomes " + unexpectedStateDescription + " on the " + |
|
1116 aEditorDescription + ", the container has been no editable"); |
|
1117 } |
|
1118 |
|
1119 // a textarea which is in the editor has focus |
|
1120 testOnIndependentEditor(document.getElementById("textarea"), |
|
1121 "textarea"); |
|
1122 // a readonly textarea which is in the editor has focus |
|
1123 testOnIndependentEditor(document.getElementById("textarea_readonly"), |
|
1124 "textarea[readonly]"); |
|
1125 // an input field which is in the editor has focus |
|
1126 testOnIndependentEditor(document.getElementById("text"), |
|
1127 "input[type=\"text\"]"); |
|
1128 // a readonly input field which is in the editor has focus |
|
1129 testOnIndependentEditor(document.getElementById("text_readonly"), |
|
1130 "input[type=\"text\"][readonly]"); |
|
1131 |
|
1132 description = "testOnOutsideOfEditor: "; |
|
1133 function testOnOutsideOfEditor(aFocusNode, aFocusNodeDescription, aEditor) |
|
1134 { |
|
1135 if (aFocusNode) { |
|
1136 aFocusNode.focus(); |
|
1137 is(gFM.focusedElement, aFocusNode, |
|
1138 description + "The " + aFocusNodeDescription + " doesn't get focus"); |
|
1139 } else { |
|
1140 if (document.activeElement) { |
|
1141 document.activeElement.blur(); |
|
1142 } |
|
1143 is(gFM.focusedElement, null, |
|
1144 description + "Unexpected element has focus"); |
|
1145 } |
|
1146 var expectedState = |
|
1147 aFocusNode ? gUtils.IMEStatus : gUtils.IME_STATUS_DISABLED; |
|
1148 var unexpectedStateDescription = |
|
1149 expectedState != gUtils.IME_STATUS_ENABLED ? "enabled" : "disabled"; |
|
1150 |
|
1151 aEditor.setAttribute("contenteditable", "true"); |
|
1152 is(gFM.focusedElement, aFocusNode, |
|
1153 description + "The " + aFocusNodeDescription + |
|
1154 " loses focus, a HTML editor is editable now"); |
|
1155 is(gUtils.IMEStatus, expectedState, |
|
1156 description + "IME becomes " + unexpectedStateDescription + |
|
1157 " on the " + aFocusNodeDescription + |
|
1158 ", the HTML editor is editable now"); |
|
1159 editor = |
|
1160 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1161 getInterface(Components.interfaces.nsIWebNavigation). |
|
1162 QueryInterface(Components.interfaces.nsIDocShell).editor; |
|
1163 flags = editor.flags; |
|
1164 editor.flags = flags | kReadonly; |
|
1165 is(gFM.focusedElement, aFocusNode, |
|
1166 description + aFocusNodeDescription + |
|
1167 " loses focus by changing HTML editor flags"); |
|
1168 is(gUtils.IMEStatus, expectedState, |
|
1169 description + "IME becomes " + unexpectedStateDescription + " on " + |
|
1170 aFocusNodeDescription + ", the HTML editor is readonly now"); |
|
1171 editor.flags = flags; |
|
1172 is(gFM.focusedElement, aFocusNode, |
|
1173 description + aFocusNodeDescription + |
|
1174 " loses focus by changing HTML editor flags #2"); |
|
1175 is(gUtils.IMEStatus, expectedState, |
|
1176 description + "IME becomes " + unexpectedStateDescription + " on " + |
|
1177 aFocusNodeDescription + ", the HTML editor isn't readonly now"); |
|
1178 container.removeAttribute("contenteditable"); |
|
1179 is(gFM.focusedElement, aFocusNode, |
|
1180 description + aFocusNodeDescription + |
|
1181 " loses focus, the HTML editor has been no editable"); |
|
1182 is(gUtils.IMEStatus, expectedState, |
|
1183 description + "IME becomes " + unexpectedStateDescription + " on " + |
|
1184 aFocusNodeDescription + ", the HTML editor has been no editable"); |
|
1185 } |
|
1186 |
|
1187 var div = document.getElementById("contenteditableEditor"); |
|
1188 // a textarea which is outside of the editor has focus |
|
1189 testOnOutsideOfEditor(document.getElementById("textarea"), "textarea", div); |
|
1190 // a readonly textarea which is outside of the editor has focus |
|
1191 testOnOutsideOfEditor(document.getElementById("textarea_readonly"), |
|
1192 "textarea[readonly]", div); |
|
1193 // an input field which is outside of the editor has focus |
|
1194 testOnOutsideOfEditor(document.getElementById("text"), |
|
1195 "input[type=\"text\"]", div); |
|
1196 // a readonly input field which outside of the editor has focus |
|
1197 testOnOutsideOfEditor(document.getElementById("text_readonly"), |
|
1198 "input[type=\"text\"][readonly]", div); |
|
1199 // a readonly input field which outside of the editor has focus |
|
1200 testOnOutsideOfEditor(document.getElementById("button"), "button", div); |
|
1201 // nobody has focus. |
|
1202 testOnOutsideOfEditor(null, "nobody", div); |
|
1203 } |
|
1204 |
|
1205 function runEditorFlagChangeTests() |
|
1206 { |
|
1207 if (!kIMEEnabledSupported) { |
|
1208 return; |
|
1209 } |
|
1210 |
|
1211 var description = "runEditorFlagChangeTests: "; |
|
1212 |
|
1213 var container = document.getElementById("display"); |
|
1214 |
|
1215 // the editor has focus directly. |
|
1216 container.setAttribute("contenteditable", "true"); |
|
1217 container.focus(); |
|
1218 |
|
1219 is(gFM.focusedElement, container, |
|
1220 description + "The editor doesn't get focus"); |
|
1221 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1222 description + "IME isn't enabled on HTML editor"); |
|
1223 const kIMEStateChangeFlags = |
|
1224 Components.interfaces.nsIPlaintextEditor.eEditorPasswordMask | |
|
1225 Components.interfaces.nsIPlaintextEditor.eEditorReadonlyMask | |
|
1226 Components.interfaces.nsIPlaintextEditor.eEditorDisabledMask; |
|
1227 var editor = |
|
1228 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1229 getInterface(Components.interfaces.nsIWebNavigation). |
|
1230 QueryInterface(Components.interfaces.nsIDocShell).editor; |
|
1231 var editorIMESupport = |
|
1232 editor.QueryInterface(Components.interfaces.nsIEditorIMESupport); |
|
1233 var flags = editor.flags; |
|
1234 |
|
1235 // start composition |
|
1236 synthesizeComposition({ type: "compositionstart" }); |
|
1237 |
|
1238 // input characters |
|
1239 synthesizeComposition({ type: "compositionupdate", |
|
1240 data: "\u3078\u3093\u3057\u3093" }); |
|
1241 synthesizeText( |
|
1242 { "composition": |
|
1243 { "string": "\u3078\u3093\u3057\u3093", |
|
1244 "clauses": |
|
1245 [ |
|
1246 { "length": 4, "attr": COMPOSITION_ATTR_RAWINPUT } |
|
1247 ] |
|
1248 }, |
|
1249 "caret": { "start": 4, "length": 0 } |
|
1250 }); |
|
1251 |
|
1252 editor.flags &= ~kIMEStateChangeFlags; |
|
1253 ok(editorIMESupport.composing, |
|
1254 description + "#1 IME composition was committed unexpectedly"); |
|
1255 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1256 description + "#1 IME isn't enabled on HTML editor"); |
|
1257 |
|
1258 editor.flags |= ~kIMEStateChangeFlags; |
|
1259 ok(editorIMESupport.composing, |
|
1260 description + "#2 IME composition was committed unexpectedly"); |
|
1261 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1262 description + "#2 IME isn't enabled on HTML editor"); |
|
1263 |
|
1264 editor.flags = flags; |
|
1265 ok(editorIMESupport.composing, |
|
1266 description + "#3 IME composition was committed unexpectedly"); |
|
1267 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED, |
|
1268 description + "#3 IME isn't enabled on HTML editor"); |
|
1269 |
|
1270 // cancel the composition |
|
1271 synthesizeComposition({ type: "compositionupdate", data: "" }); |
|
1272 synthesizeText( |
|
1273 { "composition": |
|
1274 { "string": "", |
|
1275 "clauses": |
|
1276 [ |
|
1277 { "length": 0, "attr": 0 } |
|
1278 ] |
|
1279 }, |
|
1280 "caret": { "start": 0, "length": 0 } |
|
1281 }); |
|
1282 |
|
1283 synthesizeComposition({ type: "compositionend", data: "" }); |
|
1284 |
|
1285 container.removeAttribute("contenteditable"); |
|
1286 } |
|
1287 |
|
1288 function runEditableSubframeTests() |
|
1289 { |
|
1290 window.open("window_imestate_iframes.html", "_blank", |
|
1291 "width=600,height=600"); |
|
1292 } |
|
1293 |
|
1294 function runTestPasswordFieldOnDialog() |
|
1295 { |
|
1296 if (!kIMEEnabledSupported) { |
|
1297 return; |
|
1298 } |
|
1299 |
|
1300 if (document.activeElement) { |
|
1301 document.activeElement.blur(); |
|
1302 } |
|
1303 |
|
1304 var dialog; |
|
1305 |
|
1306 function WindowObserver() |
|
1307 { |
|
1308 Components.classes["@mozilla.org/observer-service;1"]. |
|
1309 getService(Components.interfaces.nsIObserverService). |
|
1310 addObserver(this, "domwindowopened", false); |
|
1311 } |
|
1312 |
|
1313 WindowObserver.prototype = { |
|
1314 QueryInterface: function (iid) |
|
1315 { |
|
1316 if (iid.equals(Components.interfaces.nsIObserver) || |
|
1317 iid.equals(Components.interfaces.nsISupports)) { |
|
1318 return this; |
|
1319 } |
|
1320 }, |
|
1321 |
|
1322 observe: function (subject, topic, data) |
|
1323 { |
|
1324 if (topic === "domwindowopened") { |
|
1325 ok(true, "dialog window is created"); |
|
1326 dialog = subject.QueryInterface(Components.interfaces.nsIDOMWindow); |
|
1327 dialog.addEventListener("load", onPasswordDialogLoad, false); |
|
1328 } |
|
1329 } |
|
1330 }; |
|
1331 |
|
1332 var observer = new WindowObserver(); |
|
1333 var arg1 = new Object(), arg2 = new Object(); |
|
1334 Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. |
|
1335 getService(Components.interfaces.nsIPromptService). |
|
1336 promptPassword(window, "title", "text", arg1, "msg", arg2); |
|
1337 |
|
1338 ok(true, "password dialog was closed"); |
|
1339 |
|
1340 Components.classes["@mozilla.org/observer-service;1"]. |
|
1341 getService(Components.interfaces.nsIObserverService). |
|
1342 removeObserver(observer, "domwindowopened"); |
|
1343 |
|
1344 var passwordField; |
|
1345 |
|
1346 function onPasswordDialogLoad() |
|
1347 { |
|
1348 ok(true, "onPasswordDialogLoad is called"); |
|
1349 dialog.removeEventListener("load", onPasswordDialogLoad, false); |
|
1350 passwordField = dialog.document.getElementById("password1Textbox"); |
|
1351 passwordField.addEventListener("focus", onPasswordFieldFocus, false); |
|
1352 } |
|
1353 |
|
1354 function onPasswordFieldFocus() |
|
1355 { |
|
1356 ok(true, "onPasswordFieldFocus is called"); |
|
1357 passwordField.removeEventListener("focus", onPasswordFieldFocus, false); |
|
1358 var utils = dialog. |
|
1359 QueryInterface(Components.interfaces.nsIInterfaceRequestor). |
|
1360 getInterface(Components.interfaces.nsIDOMWindowUtils); |
|
1361 is(utils.IMEStatus, utils.IME_STATUS_PASSWORD, |
|
1362 "IME isn't disabled on a password field of password dialog"); |
|
1363 synthesizeKey("VK_ESCAPE", { }, dialog); |
|
1364 } |
|
1365 } |
|
1366 |
|
1367 // Bug 580388 and bug 808287 |
|
1368 function runEditorReframeTests(aCallback) |
|
1369 { |
|
1370 if (document.activeElement) { |
|
1371 document.activeElement.blur(); |
|
1372 } |
|
1373 |
|
1374 var input = document.getElementById("text"); |
|
1375 input.focus(); |
|
1376 input.style.overflow = "visible"; |
|
1377 |
|
1378 var mozIMEFocusIn = 0; |
|
1379 var mozIMEFocusOut = 0; |
|
1380 var IMEHasFocus = false; |
|
1381 |
|
1382 var handler = function (aEvent) { |
|
1383 switch (aEvent.type) { |
|
1384 case "MozIMEFocusIn": |
|
1385 mozIMEFocusIn++; |
|
1386 IMEHasFocus = true; |
|
1387 break; |
|
1388 case "MozIMEFocusOut": |
|
1389 mozIMEFocusOut++; |
|
1390 IMEHasFocus = false; |
|
1391 break; |
|
1392 } |
|
1393 }; |
|
1394 |
|
1395 var onInput = function (aEvent) { |
|
1396 aEvent.target.style.overflow = "hidden"; |
|
1397 } |
|
1398 |
|
1399 document.addEventListener("MozIMEFocusIn", handler, true); |
|
1400 document.addEventListener("MozIMEFocusOut", handler, true); |
|
1401 input.addEventListener("input", onInput, true); |
|
1402 |
|
1403 sendChar("a"); |
|
1404 |
|
1405 hitEventLoop(function () { |
|
1406 ok(mozIMEFocusOut > 0, "runEditorReframeTests(): IME focus must be lost at reframing"); |
|
1407 ok(mozIMEFocusIn > 0, "runEditorReframeTests(): IME focus must be restored after reframing"); |
|
1408 ok(IMEHasFocus, "runEditorReframeTests(): IME must have focus after reframing"); |
|
1409 |
|
1410 var focusQueryHandler = function(aEvent) { |
|
1411 // Perform a style change and query during focus to trigger reframing |
|
1412 input.style.overflow = "visible"; |
|
1413 synthesizeQuerySelectedText(); |
|
1414 } |
|
1415 document.addEventListener("MozIMEFocusIn", focusQueryHandler, true); |
|
1416 mozIMEFocusIn = mozIMEFocusOut = 0; |
|
1417 |
|
1418 input.blur(); |
|
1419 input.focus(); |
|
1420 sendChar("a"); |
|
1421 |
|
1422 hitEventLoop(function() { |
|
1423 ok(IMEHasFocus, "runEditorReframeTests(): IME must have focus after reframing during focus"); |
|
1424 ok(mozIMEFocusOut == mozIMEFocusIn, "runEditorReframeTests(): IME focus/blur (" + mozIMEFocusIn + "/" + mozIMEFocusOut + ") must match after reframing during focus"); |
|
1425 |
|
1426 document.removeEventListener("MozIMEFocusIn", focusQueryHandler, true); |
|
1427 document.removeEventListener("MozIMEFocusIn", handler, true); |
|
1428 document.removeEventListener("MozIMEFocusOut", handler, true); |
|
1429 input.removeEventListener("input", onInput, true); |
|
1430 |
|
1431 input.style.overflow = "visible"; |
|
1432 input.value = ""; |
|
1433 |
|
1434 hitEventLoop(aCallback, 20); |
|
1435 }, 20); |
|
1436 }, 20); |
|
1437 } |
|
1438 |
|
1439 function runTests() |
|
1440 { |
|
1441 if (!kIMEEnabledSupported && !kIMEOpenSupported) |
|
1442 return; |
|
1443 |
|
1444 SpecialPowers.setBoolPref("test.IME", true); |
|
1445 |
|
1446 // test for normal contents. |
|
1447 runBasicTest(false, false, "Testing of normal contents"); |
|
1448 |
|
1449 // test for plugin contents |
|
1450 runPluginTest(); |
|
1451 |
|
1452 var container = document.getElementById("display"); |
|
1453 // test for contentEditable="true" |
|
1454 container.setAttribute("contenteditable", "true"); |
|
1455 runBasicTest(true, false, "Testing [contentEditable=\"true\"]"); |
|
1456 |
|
1457 // test for contentEditable="false" |
|
1458 container.setAttribute("contenteditable", "false"); |
|
1459 runBasicTest(false, false, "Testing [contentEditable=\"false\"]"); |
|
1460 |
|
1461 // test for removing contentEditable |
|
1462 container.setAttribute("contenteditable", "true"); |
|
1463 container.removeAttribute("contenteditable"); |
|
1464 runBasicTest(false, false, "Testing after contentEditable to be removed"); |
|
1465 |
|
1466 // test designMode |
|
1467 document.designMode = "on"; |
|
1468 runBasicTest(true, true, "Testing designMode=\"on\""); |
|
1469 document.designMode = "off"; |
|
1470 document.getElementById("text").focus(); |
|
1471 runBasicTest(false, false, "Testing designMode=\"off\""); |
|
1472 |
|
1473 // changing input[type] values |
|
1474 // XXX currently, type attribute changing doesn't work fine. bug 559728. |
|
1475 // runTypeChangingTest(); |
|
1476 |
|
1477 // changing readonly attribute |
|
1478 runReadonlyChangingTest(); |
|
1479 |
|
1480 // complex contenteditable editor's tests |
|
1481 runComplexContenteditableTests(); |
|
1482 |
|
1483 // test whether the IME state and composition are not changed unexpectedly |
|
1484 runEditorFlagChangeTests(); |
|
1485 |
|
1486 // test password field on dialog |
|
1487 // XXX temporary disable against failure |
|
1488 //runTestPasswordFieldOnDialog(); |
|
1489 |
|
1490 // Asynchronous tests |
|
1491 runEditorReframeTests(function () { |
|
1492 // This will call onFinish(), so, this test must be the last. |
|
1493 runEditableSubframeTests(); |
|
1494 }); |
|
1495 } |
|
1496 |
|
1497 function onFinish() |
|
1498 { |
|
1499 SpecialPowers.clearUserPref("test.IME"); |
|
1500 SimpleTest.finish(); |
|
1501 } |
|
1502 |
|
1503 </script> |
|
1504 </body> |
|
1505 |
|
1506 </html> |