1 <html style=
"ime-mode: disabled;">
3 <title>Test for IME state controling
</title>
4 <script type=
"text/javascript"
5 src=
"chrome://mochikit/content/MochiKit/packed.js"></script>
6 <script type=
"text/javascript"
7 src=
"chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
8 <script type=
"text/javascript"
9 src=
"chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
10 <link rel=
"stylesheet" type=
"text/css"
11 href=
"chrome://mochikit/content/tests/SimpleTest/test.css" />
13 <body onload=
"setTimeout(runTests, 0);" style=
"ime-mode: disabled;">
14 <div id=
"display" style=
"ime-mode: disabled;">
15 <!-- input elements -->
16 <input type=
"text" id=
"text"/><br/>
17 <input type=
"text" id=
"text_readonly" readonly=
"readonly"/><br/>
18 <input type=
"password" id=
"password"/><br/>
19 <input type=
"password" id=
"password_readonly" readonly=
"readonly"/><br/>
20 <input type=
"checkbox" id=
"checkbox"/><br/>
21 <input type=
"radio" id=
"radio"/><br/>
22 <input type=
"submit" id=
"submit"/><br/>
23 <input type=
"reset" id=
"reset"/><br/>
24 <input type=
"file" id=
"file"/><br/>
25 <input type=
"button" id=
"ibutton"/><br/>
26 <input type=
"image" id=
"image" alt=
"image"/><br/>
28 <!-- html5 input elements -->
29 <input type=
"url" id=
"url"/><br/>
30 <input type=
"email" id=
"email"/><br/>
31 <input type=
"search" id=
"search"/><br/>
32 <input type=
"tel" id=
"tel"/><br/>
33 <input type=
"number" id=
"number"/><br/>
35 <!-- form controls -->
36 <button id=
"button">button
</button><br/>
37 <textarea id=
"textarea">textarea
</textarea><br/>
38 <textarea id=
"textarea_readonly" readonly=
"readonly">textarea[readonly]
</textarea><br/>
40 <option value=
"option" selected=
"selected"/>
42 <select id=
"select_multiple" multiple=
"multiple">
43 <option value=
"option" selected=
"selected"/>
45 <isindex id=
"isindex" prompt=
"isindex"/><br/>
48 <a id=
"a_href" href=
"about:blank">a[href]
</a><br/>
50 <!-- ime-mode test -->
51 <input type=
"text" id=
"ime_mode_auto" style=
"ime-mode: auto;"/><br/>
52 <input type=
"text" id=
"ime_mode_normal" style=
"ime-mode: normal;"/><br/>
53 <input type=
"text" id=
"ime_mode_active" style=
"ime-mode: active;"/><br/>
54 <input type=
"text" id=
"ime_mode_inactive" style=
"ime-mode: inactive;"/><br/>
55 <input type=
"text" id=
"ime_mode_disabled" style=
"ime-mode: disabled;"/><br/>
57 <input type=
"text" id=
"ime_mode_auto_url" style=
"ime-mode: auto;"/><br/>
58 <input type=
"text" id=
"ime_mode_normal_url" style=
"ime-mode: normal;"/><br/>
59 <input type=
"text" id=
"ime_mode_active_url" style=
"ime-mode: active;"/><br/>
60 <input type=
"text" id=
"ime_mode_inactive_url" style=
"ime-mode: inactive;"/><br/>
61 <input type=
"text" id=
"ime_mode_disabled_url" style=
"ime-mode: disabled;"/><br/>
63 <input type=
"text" id=
"ime_mode_auto_email" style=
"ime-mode: auto;"/><br/>
64 <input type=
"text" id=
"ime_mode_normal_email" style=
"ime-mode: normal;"/><br/>
65 <input type=
"text" id=
"ime_mode_active_email" style=
"ime-mode: active;"/><br/>
66 <input type=
"text" id=
"ime_mode_inactive_email" style=
"ime-mode: inactive;"/><br/>
67 <input type=
"text" id=
"ime_mode_disabled_email" style=
"ime-mode: disabled;"/><br/>
69 <input type=
"text" id=
"ime_mode_auto_search" style=
"ime-mode: auto;"/><br/>
70 <input type=
"text" id=
"ime_mode_normal_search" style=
"ime-mode: normal;"/><br/>
71 <input type=
"text" id=
"ime_mode_active_search" style=
"ime-mode: active;"/><br/>
72 <input type=
"text" id=
"ime_mode_inactive_search" style=
"ime-mode: inactive;"/><br/>
73 <input type=
"text" id=
"ime_mode_disabled_search" style=
"ime-mode: disabled;"/><br/>
75 <input type=
"text" id=
"ime_mode_auto_tel" style=
"ime-mode: auto;"/><br/>
76 <input type=
"text" id=
"ime_mode_normal_tel" style=
"ime-mode: normal;"/><br/>
77 <input type=
"text" id=
"ime_mode_active_tel" style=
"ime-mode: active;"/><br/>
78 <input type=
"text" id=
"ime_mode_inactive_tel" style=
"ime-mode: inactive;"/><br/>
79 <input type=
"text" id=
"ime_mode_disabled_tel" style=
"ime-mode: disabled;"/><br/>
81 <input type=
"text" id=
"ime_mode_auto_number" style=
"ime-mode: auto;"/><br/>
82 <input type=
"text" id=
"ime_mode_normal_number" style=
"ime-mode: normal;"/><br/>
83 <input type=
"text" id=
"ime_mode_active_number" style=
"ime-mode: active;"/><br/>
84 <input type=
"text" id=
"ime_mode_inactive_number" style=
"ime-mode: inactive;"/><br/>
85 <input type=
"text" id=
"ime_mode_disabled_number" style=
"ime-mode: disabled;"/><br/>
87 <input type=
"password" id=
"ime_mode_auto_p" style=
"ime-mode: auto;"/><br/>
88 <input type=
"password" id=
"ime_mode_normal_p" style=
"ime-mode: normal;"/><br/>
89 <input type=
"password" id=
"ime_mode_active_p" style=
"ime-mode: active;"/><br/>
90 <input type=
"password" id=
"ime_mode_inactive_p" style=
"ime-mode: inactive;"/><br/>
91 <input type=
"password" id=
"ime_mode_disabled_p" style=
"ime-mode: disabled;"/><br/>
92 <textarea id=
"ime_mode_auto_t" style=
"ime-mode: auto;">textarea
</textarea><br/>
93 <textarea id=
"ime_mode_normal_t" style=
"ime-mode: normal;">textarea
</textarea><br/>
94 <textarea id=
"ime_mode_active_t" style=
"ime-mode: active;">textarea
</textarea><br/>
95 <textarea id=
"ime_mode_inactive_t" style=
"ime-mode: inactive;">textarea
</textarea><br/>
96 <textarea id=
"ime_mode_disabled_t" style=
"ime-mode: disabled;">textarea
</textarea><br/>
99 <object type=
"application/x-test" id=
"plugin"></object><br/>
101 <!-- contenteditable editor -->
102 <div id=
"contenteditableEditor" contenteditable=
"true"></div>
104 <!-- designMode editor -->
105 <iframe id=
"designModeEditor"
106 onload=
"document.getElementById('designModeEditor').contentDocument.designMode = 'on';"
107 src=
"data:text/html,<html><body></body></html>"></iframe><br/>
109 <div id=
"content" style=
"display: none">
115 <script class=
"testbody" type=
"application/javascript">
117 SimpleTest.waitForExplicitFinish();
120 QueryInterface(Components.interfaces.nsIInterfaceRequestor).
121 getInterface(Components.interfaces.nsIDOMWindowUtils);
122 var gUtils2 = gUtils.QueryInterface(Components.interfaces.nsIDOMWindowUtils_MOZILLA_2_0_BRANCH);
124 var gUtils2 = window.
125 QueryInterface(Components.interfaces.nsIInterfaceRequestor).
126 getInterface(Components.interfaces.nsIDOMWindowUtils_MOZILLA_2_0_BRANCH);
128 var gFM = Components.classes[
"@mozilla.org/focus-manager;1"].
129 getService(Components.interfaces.nsIFocusManager);
130 const kIMEEnabledSupported = navigator.platform.indexOf(
"Mac") ==
0 ||
131 navigator.platform.indexOf(
"Win") ==
0 ||
132 navigator.platform.indexOf(
"Linux") ==
0;
134 // We support to control IME open state on Windows and Mac actually. However,
135 // we cannot test it on Mac if the current keyboard layout is not CJK. And also
136 // we cannot test it on Win32 if the system didn't be installed IME. So,
137 // currently we should not run the open state testing.
138 const kIMEOpenSupported = false;
140 function runBasicTest(aIsEditable, aInDesignMode, aDescription)
144 function moveFocus(aTest)
147 if (document.activeElement) {
148 document.activeElement.blur();
150 } else if (aIsEditable) {
151 document.getElementById(
"display").focus();
152 } else if (aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED) {
153 document.getElementById(
"password").focus();
155 document.getElementById(
"text").focus();
157 var previousFocusedElement = gFM.focusedElement;
158 var element = document.getElementById(aTest.id);
159 if (element.contentDocument) {
160 element = element.contentDocument.documentElement;
163 var focusedElement = gFM.focusedElement;
164 if (focusedElement) {
165 var bindingParent = document.getBindingParent(focusedElement);
167 focusedElement = bindingParent;
170 if (aTest.focusable) {
171 is(focusedElement, element,
172 aDescription +
": " + aTest.description +
", focus didn't move");
173 return (element == focusedElement);
175 is(focusedElement, previousFocusedElement,
176 aDescription +
": " + aTest.description +
", focus moved as unexpected");
177 return (previousFocusedElement == focusedElement);
180 function testOpened(aTest, aOpened)
182 document.getElementById(
"text").focus();
183 gUtils.IMEIsOpen = aOpened;
184 if (!moveFocus(aTest)) {
187 var message = aDescription +
": " + aTest.description +
188 ", wrong opened state";
190 aTest.changeOpened ? aTest.expectedOpened : aOpened, message);
193 // IME Enabled state testing
194 var enabled = gUtils.IME_STATUS_ENABLED;
195 if (kIMEEnabledSupported) {
196 if (!moveFocus(aTest)) {
199 enabled = gUtils.IMEStatus;
200 inputtype = gUtils2.focusedInputType;
201 is(enabled, aTest.expectedEnabled,
202 aDescription +
": " + aTest.description +
", wrong enabled state");
203 if (aTest.expectedType && !aInDesignMode) {
204 is(inputtype, aTest.expectedType,
205 aDescription +
": " + aTest.description +
", wrong input type");
206 } else if (aInDesignMode) {
208 aDescription +
": " + aTest.description +
", wrong input type")
212 if (!kIMEOpenSupported || enabled != gUtils.IME_STATUS_ENABLED ||
213 aTest.expectedEnabled != gUtils.IME_STATUS_ENABLED) {
217 // IME Open state testing
218 testOpened(aTest, false);
219 testOpened(aTest, true);
222 if (kIMEEnabledSupported) {
223 // make sure there is an active element
224 document.getElementById(
"text").focus();
225 document.activeElement.blur();
227 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_DISABLED,
228 aDescription +
": unexpected enabled state when no element has focus");
231 // Form controls except text editable elements are
"disable" in normal
232 // condition, however, if they are editable, they are
"enabled".
233 // XXX Probably there are some bugs: If the form controls editable, they
234 // shouldn't be focusable.
235 const kEnabledStateOnNonEditableElement =
236 (aInDesignMode || aIsEditable) ? gUtils.IME_STATUS_ENABLED :
237 gUtils.IME_STATUS_DISABLED;
238 const kEnabledStateOnPasswordField =
239 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_PASSWORD;
240 const kEnabledStateOnReadonlyField =
241 aInDesignMode ? gUtils.IME_STATUS_ENABLED : gUtils.IME_STATUS_DISABLED;
244 description:
"input[type=text]",
245 focusable: !aInDesignMode,
246 expectedEnabled: gUtils.IME_STATUS_ENABLED,
247 expectedType:
"text" },
248 { id:
"text_readonly",
249 description:
"input[type=text][readonly]",
250 focusable: !aInDesignMode,
251 expectedEnabled: kEnabledStateOnReadonlyField },
253 description:
"input[type=password]",
254 focusable: !aInDesignMode,
255 expectedEnabled: kEnabledStateOnPasswordField,
256 expectedType:
"password" },
257 { id:
"password_readonly",
258 description:
"input[type=password][readonly]",
259 focusable: !aInDesignMode,
260 expectedEnabled: kEnabledStateOnReadonlyField },
262 description:
"input[type=checkbox]",
263 focusable: !aInDesignMode,
264 expectedEnabled: kEnabledStateOnNonEditableElement },
266 description:
"input[type=radio]",
267 focusable: !aInDesignMode,
268 expectedEnabled: kEnabledStateOnNonEditableElement },
270 description:
"input[type=submit]",
271 focusable: !aInDesignMode,
272 expectedEnabled: kEnabledStateOnNonEditableElement },
274 description:
"input[type=reset]",
275 focusable: !aInDesignMode,
276 expectedEnabled: kEnabledStateOnNonEditableElement },
278 description:
"input[type=file]",
279 focusable: !aInDesignMode,
280 expectedEnabled: kEnabledStateOnNonEditableElement },
282 description:
"input[type=button]",
283 focusable: !aInDesignMode,
284 expectedEnabled: kEnabledStateOnNonEditableElement },
286 description:
"input[type=image]",
287 focusable: !aInDesignMode,
288 expectedEnabled: kEnabledStateOnNonEditableElement },
290 description:
"input[type=url]",
291 focusable: !aInDesignMode,
292 expectedEnabled: gUtils.IME_STATUS_ENABLED,
293 expectedType:
"url" },
295 description:
"input[type=email]",
296 focusable: !aInDesignMode,
297 expectedEnabled: gUtils.IME_STATUS_ENABLED,
298 expectedType:
"email" },
300 description:
"input[type=search]",
301 focusable: !aInDesignMode,
302 expectedEnabled: gUtils.IME_STATUS_ENABLED,
303 expectedType:
"search" },
305 description:
"input[type=tel]",
306 focusable: !aInDesignMode,
307 expectedEnabled: gUtils.IME_STATUS_ENABLED,
308 expectedType:
"tel" },
310 description:
"input[type=number]",
311 focusable: !aInDesignMode,
312 expectedEnabled: gUtils.IME_STATUS_ENABLED,
313 expectedType:
"number" },
317 description:
"button",
318 focusable: !aInDesignMode,
319 expectedEnabled: kEnabledStateOnNonEditableElement },
321 description:
"textarea",
322 focusable: !aInDesignMode,
323 expectedEnabled: gUtils.IME_STATUS_ENABLED },
324 { id:
"textarea_readonly",
325 description:
"textarea[readonly]",
326 focusable: !aInDesignMode,
327 expectedEnabled: kEnabledStateOnReadonlyField },
329 description:
"select (dropdown list)",
330 focusable: !aInDesignMode,
331 expectedEnabled: kEnabledStateOnNonEditableElement },
332 { id:
"select_multiple",
333 description:
"select (list box)",
334 focusable: !aInDesignMode,
335 expectedEnabled: kEnabledStateOnNonEditableElement },
339 description:
"a[href]",
340 focusable: !aIsEditable && !aInDesignMode,
341 expectedEnabled: kEnabledStateOnNonEditableElement },
344 { id:
"ime_mode_auto",
345 description:
"input[type=text][style=\"ime-mode: auto;\
"]",
346 focusable: !aInDesignMode,
347 expectedEnabled: gUtils.IME_STATUS_ENABLED },
348 { id:
"ime_mode_normal",
349 description:
"input[type=text][style=\"ime-mode: normal;\
"]",
350 focusable: !aInDesignMode,
351 expectedEnabled: gUtils.IME_STATUS_ENABLED },
352 { id:
"ime_mode_active",
353 description:
"input[type=text][style=\"ime-mode: active;\
"]",
354 expectedEnabled: gUtils.IME_STATUS_ENABLED,
355 focusable: !aInDesignMode,
356 changeOpened: true, expectedOpened: true },
357 { id:
"ime_mode_inactive",
358 description:
"input[type=text][style=\"ime-mode: inactive;\
"]",
359 expectedEnabled: gUtils.IME_STATUS_ENABLED,
360 focusable: !aInDesignMode,
361 changeOpened: true, expectedOpened: false },
362 { id:
"ime_mode_disabled",
363 description:
"input[type=text][style=\"ime-mode: disabled;\
"]",
364 focusable: !aInDesignMode,
365 expectedEnabled: kEnabledStateOnPasswordField },
367 { id:
"ime_mode_auto_url",
368 description:
"input[type=url][style=\"ime-mode: auto;\
"]",
369 focusable: !aInDesignMode,
370 expectedEnabled: gUtils.IME_STATUS_ENABLED },
371 { id:
"ime_mode_normal_url",
372 description:
"input[type=url][style=\"ime-mode: normal;\
"]",
373 focusable: !aInDesignMode,
374 expectedEnabled: gUtils.IME_STATUS_ENABLED },
375 { id:
"ime_mode_active_url",
376 description:
"input[type=url][style=\"ime-mode: active;\
"]",
377 expectedEnabled: gUtils.IME_STATUS_ENABLED,
378 focusable: !aInDesignMode,
379 changeOpened: true, expectedOpened: true },
380 { id:
"ime_mode_inactive_url",
381 description:
"input[type=url][style=\"ime-mode: inactive;\
"]",
382 expectedEnabled: gUtils.IME_STATUS_ENABLED,
383 focusable: !aInDesignMode,
384 changeOpened: true, expectedOpened: false },
385 { id:
"ime_mode_disabled_url",
386 description:
"input[type=url][style=\"ime-mode: disabled;\
"]",
387 focusable: !aInDesignMode,
388 expectedEnabled: kEnabledStateOnPasswordField },
390 { id:
"ime_mode_auto_email",
391 description:
"input[type=email][style=\"ime-mode: auto;\
"]",
392 focusable: !aInDesignMode,
393 expectedEnabled: gUtils.IME_STATUS_ENABLED },
394 { id:
"ime_mode_normal_email",
395 description:
"input[type=email][style=\"ime-mode: normal;\
"]",
396 focusable: !aInDesignMode,
397 expectedEnabled: gUtils.IME_STATUS_ENABLED },
398 { id:
"ime_mode_active_email",
399 description:
"input[type=email][style=\"ime-mode: active;\
"]",
400 expectedEnabled: gUtils.IME_STATUS_ENABLED,
401 focusable: !aInDesignMode,
402 changeOpened: true, expectedOpened: true },
403 { id:
"ime_mode_inactive_email",
404 description:
"input[type=email][style=\"ime-mode: inactive;\
"]",
405 expectedEnabled: gUtils.IME_STATUS_ENABLED,
406 focusable: !aInDesignMode,
407 changeOpened: true, expectedOpened: false },
408 { id:
"ime_mode_disabled_email",
409 description:
"input[type=email][style=\"ime-mode: disabled;\
"]",
410 focusable: !aInDesignMode,
411 expectedEnabled: kEnabledStateOnPasswordField },
413 { id:
"ime_mode_auto_search",
414 description:
"input[type=search][style=\"ime-mode: auto;\
"]",
415 focusable: !aInDesignMode,
416 expectedEnabled: gUtils.IME_STATUS_ENABLED },
417 { id:
"ime_mode_normal_search",
418 description:
"input[type=search][style=\"ime-mode: normal;\
"]",
419 focusable: !aInDesignMode,
420 expectedEnabled: gUtils.IME_STATUS_ENABLED },
421 { id:
"ime_mode_active_search",
422 description:
"input[type=search][style=\"ime-mode: active;\
"]",
423 expectedEnabled: gUtils.IME_STATUS_ENABLED,
424 focusable: !aInDesignMode,
425 changeOpened: true, expectedOpened: true },
426 { id:
"ime_mode_inactive_search",
427 description:
"input[type=search][style=\"ime-mode: inactive;\
"]",
428 expectedEnabled: gUtils.IME_STATUS_ENABLED,
429 focusable: !aInDesignMode,
430 changeOpened: true, expectedOpened: false },
431 { id:
"ime_mode_disabled_search",
432 description:
"input[type=search][style=\"ime-mode: disabled;\
"]",
433 focusable: !aInDesignMode,
434 expectedEnabled: kEnabledStateOnPasswordField },
436 { id:
"ime_mode_auto_tel",
437 description:
"input[type=tel][style=\"ime-mode: auto;\
"]",
438 focusable: !aInDesignMode,
439 expectedEnabled: gUtils.IME_STATUS_ENABLED },
440 { id:
"ime_mode_normal_tel",
441 description:
"input[type=tel][style=\"ime-mode: normal;\
"]",
442 focusable: !aInDesignMode,
443 expectedEnabled: gUtils.IME_STATUS_ENABLED },
444 { id:
"ime_mode_active_tel",
445 description:
"input[type=tel][style=\"ime-mode: active;\
"]",
446 expectedEnabled: gUtils.IME_STATUS_ENABLED,
447 focusable: !aInDesignMode,
448 changeOpened: true, expectedOpened: true },
449 { id:
"ime_mode_inactive_tel",
450 description:
"input[type=tel][style=\"ime-mode: inactive;\
"]",
451 expectedEnabled: gUtils.IME_STATUS_ENABLED,
452 focusable: !aInDesignMode,
453 changeOpened: true, expectedOpened: false },
454 { id:
"ime_mode_disabled_tel",
455 description:
"input[type=tel][style=\"ime-mode: disabled;\
"]",
456 focusable: !aInDesignMode,
457 expectedEnabled: kEnabledStateOnPasswordField },
459 { id:
"ime_mode_auto_number",
460 description:
"input[type=number][style=\"ime-mode: auto;\
"]",
461 focusable: !aInDesignMode,
462 expectedEnabled: gUtils.IME_STATUS_ENABLED },
463 { id:
"ime_mode_normal_number",
464 description:
"input[type=number][style=\"ime-mode: normal;\
"]",
465 focusable: !aInDesignMode,
466 expectedEnabled: gUtils.IME_STATUS_ENABLED },
467 { id:
"ime_mode_active_number",
468 description:
"input[type=number][style=\"ime-mode: active;\
"]",
469 expectedEnabled: gUtils.IME_STATUS_ENABLED,
470 focusable: !aInDesignMode,
471 changeOpened: true, expectedOpened: true },
472 { id:
"ime_mode_inactive_number",
473 description:
"input[type=number][style=\"ime-mode: inactive;\
"]",
474 expectedEnabled: gUtils.IME_STATUS_ENABLED,
475 focusable: !aInDesignMode,
476 changeOpened: true, expectedOpened: false },
477 { id:
"ime_mode_disabled_number",
478 description:
"input[type=number][style=\"ime-mode: disabled;\
"]",
479 focusable: !aInDesignMode,
480 expectedEnabled: kEnabledStateOnPasswordField },
482 { id:
"ime_mode_auto_p",
483 description:
"input[type=password][style=\"ime-mode: auto;\
"]",
484 focusable: !aInDesignMode,
485 expectedEnabled: kEnabledStateOnPasswordField },
486 { id:
"ime_mode_normal_p",
487 description:
"input[type=password][style=\"ime-mode: normal;\
"]",
488 focusable: !aInDesignMode,
489 expectedEnabled: gUtils.IME_STATUS_ENABLED },
490 { id:
"ime_mode_active_p",
491 description:
"input[type=password][style=\"ime-mode: active;\
"]",
492 expectedEnabled: gUtils.IME_STATUS_ENABLED,
493 focusable: !aInDesignMode,
494 changeOpened: true, expectedOpened: true },
495 { id:
"ime_mode_inactive_p",
496 description:
"input[type=password][style=\"ime-mode: inactive;\
"]",
497 expectedEnabled: gUtils.IME_STATUS_ENABLED,
498 focusable: !aInDesignMode,
499 changeOpened: true, expectedOpened: false },
500 { id:
"ime_mode_disabled_p",
501 description:
"input[type=password][style=\"ime-mode: disabled;\
"]",
502 focusable: !aInDesignMode,
503 expectedEnabled: kEnabledStateOnPasswordField },
504 { id:
"ime_mode_auto",
505 description:
"textarea[style=\"ime-mode: auto;\
"]",
506 focusable: !aInDesignMode,
507 expectedEnabled: gUtils.IME_STATUS_ENABLED },
508 { id:
"ime_mode_normal",
509 description:
"textarea[style=\"ime-mode: normal;\
"]",
510 focusable: !aInDesignMode,
511 expectedEnabled: gUtils.IME_STATUS_ENABLED },
512 { id:
"ime_mode_active",
513 description:
"textarea[style=\"ime-mode: active;\
"]",
514 focusable: !aInDesignMode,
515 expectedEnabled: gUtils.IME_STATUS_ENABLED,
516 changeOpened: true, expectedOpened: true },
517 { id:
"ime_mode_inactive",
518 description:
"textarea[style=\"ime-mode: inactive;\
"]",
519 focusable: !aInDesignMode,
520 expectedEnabled: gUtils.IME_STATUS_ENABLED,
521 changeOpened: true, expectedOpened: false },
522 { id:
"ime_mode_disabled",
523 description:
"textarea[style=\"ime-mode: disabled;\
"]",
524 focusable: !aInDesignMode,
525 expectedEnabled: kEnabledStateOnPasswordField },
528 { id:
"contenteditableEditor",
529 description:
"div[contenteditable=\"true\
"]",
530 focusable: !aIsEditable && !aInDesignMode,
531 expectedEnabled: gUtils.IME_STATUS_ENABLED },
532 { id:
"designModeEditor",
533 description:
"designMode editor",
535 expectedEnabled: gUtils.IME_STATUS_ENABLED },
538 for (var i =
0; i < kTests.length; i++) {
543 function runPluginTest()
545 if (!kIMEEnabledSupported) {
549 if (navigator.platform.indexOf(
"Mac") ==
0) {
550 // XXX on mac, currently, this test isn't passed because it doesn't return
551 // IME_STATUS_PLUGIN by its bug.
555 var plugin = document.getElementById(
"plugin");
557 document.activeElement.blur();
558 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
559 "runPluginTest: unexpected enabled state when no element has focus");
562 is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN,
563 "runPluginTest: unexpected enabled state when plugin has focus");
566 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
567 "runPluginTest: unexpected enabled state when plugin has focus");
570 is(gUtils.IMEStatus, gUtils.IME_STATUS_PLUGIN,
571 "runPluginTest: unexpected enabled state when plugin has focus #2");
573 var parent = plugin.parentNode;
574 parent.removeChild(plugin);
575 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
576 "runPluginTest: unexpected enabled state when plugin is removed from tree");
578 document.getElementById(
"text").focus();
579 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
580 "runPluginTest: unexpected enabled state when input[type=text] has focus");
583 function runTypeChangingTest()
585 if (!kIMEEnabledSupported)
588 const kInputControls = [
590 type:
"text", expected: gUtils.IME_STATUS_ENABLED,
591 description:
"[type=\"text\
"]" },
592 { id:
"text_readonly",
593 type:
"text", expected: gUtils.IME_STATUS_DISABLED, isReadonly: true,
594 description:
"[type=\"text\
"][readonly]" },
596 type:
"password", expected: gUtils.IME_STATUS_PASSWORD,
597 description:
"[type=\"password\
"]" },
598 { id:
"password_readonly",
599 type:
"password", expected: gUtils.IME_STATUS_DISABLED, isReadonly: true,
600 description:
"[type=\"password\
"][readonly]" },
602 type:
"checkbox", expected: gUtils.IME_STATUS_DISABLED,
603 description:
"[type=\"checkbox\
"]" },
605 type:
"radio", expected: gUtils.IME_STATUS_DISABLED,
606 description:
"[type=\"radio\
"]" },
608 type:
"submit", expected: gUtils.IME_STATUS_DISABLED,
609 description:
"[type=\"submit\
"]" },
611 type:
"reset", expected: gUtils.IME_STATUS_DISABLED,
612 description:
"[type=\"reset\
"]" },
614 type:
"file", expected: gUtils.IME_STATUS_DISABLED,
615 description:
"[type=\"file\
"]" },
617 type:
"button", expected: gUtils.IME_STATUS_DISABLED,
618 description:
"[type=\"button\
"]" },
620 type:
"image", expected: gUtils.IME_STATUS_DISABLED,
621 description:
"[type=\"image\
"]" },
623 type:
"url", expected: gUtils.IME_STATUS_ENABLED,
624 description:
"[type=\"url\
"]" },
626 type:
"email", expected: gUtils.IME_STATUS_ENABLED,
627 description:
"[type=\"email\
"]" },
629 type:
"search", expected: gUtils.IME_STATUS_ENABLED,
630 description:
"[type=\"search\
"]" },
632 type:
"tel", expected: gUtils.IME_STATUS_ENABLED,
633 description:
"[type=\"tel\
"]" },
635 type:
"number", expected: gUtils.IME_STATUS_ENABLED,
636 description:
"[type=\"number\
"]" },
637 { id:
"ime_mode_auto",
638 type:
"text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
639 description:
"[type=\"text\
"][ime-mode: auto;]" },
640 { id:
"ime_mode_normal",
641 type:
"text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
642 description:
"[type=\"text\
"][ime-mode: normal;]" },
643 { id:
"ime_mode_active",
644 type:
"text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
645 description:
"[type=\"text\
"][ime-mode: active;]" },
646 { id:
"ime_mode_inactive",
647 type:
"text", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
648 description:
"[type=\"text\
"][ime-mode: inactive;]" },
649 { id:
"ime_mode_disabled",
650 type:
"text", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
651 description:
"[type=\"text\
"][ime-mode: disabled;]" },
653 { id:
"ime_mode_auto_url",
654 type:
"url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
655 description:
"[type=\"url\
"][ime-mode: auto;]" },
656 { id:
"ime_mode_normal_url",
657 type:
"url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
658 description:
"[type=\"url\
"][ime-mode: normal;]" },
659 { id:
"ime_mode_active_url",
660 type:
"url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
661 description:
"[type=\"url\
"][ime-mode: active;]" },
662 { id:
"ime_mode_inactive_url",
663 type:
"url", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
664 description:
"[type=\"url\
"][ime-mode: inactive;]" },
665 { id:
"ime_mode_disabled_url",
666 type:
"url", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
667 description:
"[type=\"url\
"][ime-mode: disabled;]" },
669 { id:
"ime_mode_auto_email",
670 type:
"email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
671 description:
"[type=\"email\
"][ime-mode: auto;]" },
672 { id:
"ime_mode_normal_email",
673 type:
"email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
674 description:
"[type=\"email\
"][ime-mode: normal;]" },
675 { id:
"ime_mode_active_email",
676 type:
"email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
677 description:
"[type=\"email\
"][ime-mode: active;]" },
678 { id:
"ime_mode_inactive_email",
679 type:
"email", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
680 description:
"[type=\"email\
"][ime-mode: inactive;]" },
681 { id:
"ime_mode_disabled_email",
682 type:
"email", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
683 description:
"[type=\"email\
"][ime-mode: disabled;]" },
685 { id:
"ime_mode_auto_search",
686 type:
"search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
687 description:
"[type=\"search\
"][ime-mode: auto;]" },
688 { id:
"ime_mode_normal_search",
689 type:
"search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
690 description:
"[type=\"search\
"][ime-mode: normal;]" },
691 { id:
"ime_mode_active_search",
692 type:
"search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
693 description:
"[type=\"search\
"][ime-mode: active;]" },
694 { id:
"ime_mode_inactive_search",
695 type:
"search", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
696 description:
"[type=\"search\
"][ime-mode: inactive;]" },
697 { id:
"ime_mode_disabled_search",
698 type:
"search", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
699 description:
"[type=\"search\
"][ime-mode: disabled;]" },
701 { id:
"ime_mode_auto_tel",
702 type:
"tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
703 description:
"[type=\"tel\
"][ime-mode: auto;]" },
704 { id:
"ime_mode_normal_tel",
705 type:
"tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
706 description:
"[type=\"tel\
"][ime-mode: normal;]" },
707 { id:
"ime_mode_active_tel",
708 type:
"tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
709 description:
"[type=\"tel\
"][ime-mode: active;]" },
710 { id:
"ime_mode_inactive_tel",
711 type:
"tel", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
712 description:
"[type=\"tel\
"][ime-mode: inactive;]" },
713 { id:
"ime_mode_disabled_tel",
714 type:
"tel", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
715 description:
"[type=\"tel\
"][ime-mode: disabled;]" },
717 { id:
"ime_mode_auto_number",
718 type:
"number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
719 description:
"[type=\"number\
"][ime-mode: auto;]" },
720 { id:
"ime_mode_normal_number",
721 type:
"number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
722 description:
"[type=\"number\
"][ime-mode: normal;]" },
723 { id:
"ime_mode_active_number",
724 type:
"number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
725 description:
"[type=\"number\
"][ime-mode: active;]" },
726 { id:
"ime_mode_inactive_number",
727 type:
"number", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
728 description:
"[type=\"number\
"][ime-mode: inactive;]" },
729 { id:
"ime_mode_disabled_number",
730 type:
"number", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
731 description:
"[type=\"number\
"][ime-mode: disabled;]" },
733 { id:
"ime_mode_auto_p",
734 type:
"password", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
735 description:
"[type=\"password\
"][ime-mode: auto;]" },
736 { id:
"ime_mode_normal_p",
737 type:
"password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
738 description:
"[type=\"password\
"][ime-mode: normal;]" },
739 { id:
"ime_mode_active_p",
740 type:
"password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
741 description:
"[type=\"password\
"][ime-mode: active;]" },
742 { id:
"ime_mode_inactive_p",
743 type:
"password", expected: gUtils.IME_STATUS_ENABLED, imeMode: true,
744 description:
"[type=\"password\
"][ime-mode: inactive;]" },
745 { id:
"ime_mode_disabled_p",
746 type:
"password", expected: gUtils.IME_STATUS_PASSWORD, imeMode: true,
747 description:
"[type=\"password\
"][ime-mode: disabled;]" }
750 const kInputTypes = [
751 { type:
"", expected: gUtils.IME_STATUS_ENABLED },
752 { type:
"text", expected: gUtils.IME_STATUS_ENABLED },
753 { type:
"password", expected: gUtils.IME_STATUS_PASSWORD },
754 { type:
"checkbox", expected: gUtils.IME_STATUS_DISABLED },
755 { type:
"radio", expected: gUtils.IME_STATUS_DISABLED },
756 { type:
"submit", expected: gUtils.IME_STATUS_DISABLED },
757 { type:
"reset", expected: gUtils.IME_STATUS_DISABLED },
758 { type:
"file", expected: gUtils.IME_STATUS_DISABLED },
759 { type:
"button", expected: gUtils.IME_STATUS_DISABLED },
760 { type:
"image", expected: gUtils.IME_STATUS_DISABLED },
761 { type:
"url", expected: gUtils.IME_STATUS_ENABLED },
762 { type:
"email", expected: gUtils.IME_STATUS_ENABLED },
763 { type:
"search", expected: gUtils.IME_STATUS_ENABLED },
764 { type:
"tel", expected: gUtils.IME_STATUS_ENABLED },
765 { type:
"number", expected: gUtils.IME_STATUS_ENABLED }
768 function getExpectedIMEEnabled(aNewType, aInputControl)
770 if (aNewType.expected == gUtils.IME_STATUS_DISABLED ||
771 aInputControl.isReadonly)
772 return gUtils.IME_STATUS_DISABLED;
773 return aInputControl.imeMode ? aInputControl.expected : aNewType.expected;
776 const kOpenedState = [ true, false ];
778 for (var i =
0; i < kOpenedState.length; i++) {
779 const kOpened = kOpenedState[i];
780 for (var j =
0; j < kInputControls.length; j++) {
781 const kInput = kInputControls[j];
782 var e = document.getElementById(kInput.id);
784 for (var k =
0; k < kInputTypes.length; k++) {
785 const kType = kInputTypes[k];
786 var typeChangingDescription =
787 "\"" + e.getAttribute("type
") + "\
" to \"" + kInput.type + "\
"";
788 e.setAttribute(
"type", kInput.type);
789 is(gUtils.IMEStatus, kInput.expected,
790 "type attr changing test (IMEStatus): " + typeChangingDescription +
791 " (" + kInput.description +
")");
792 is(gUtils2.focusedInputType, kInput.type,
793 "type attr changing test (type): " + typeChangingDescription +
794 " (" + kInput.description +
")");
796 const kTestOpenState = kIMEOpenSupported &&
797 gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED &&
798 getExpectedIMEEnabled(kType, kInput) == gUtils.IME_STATUS_ENABLED;
799 if (kTestOpenState) {
800 gUtils.IMEIsOpen = kOpened;
803 typeChangingDescription =
804 "\"" + e.getAttribute("type
") + "\
" to \"" + kType.type + "\
"";
805 if (kType.type !=
"")
806 e.setAttribute(
"type", kType.type);
808 e.removeAttribute(
"type");
810 is(gUtils.IMEStatus, getExpectedIMEEnabled(kType, kInput),
811 "type attr changing test (IMEStatus): " + typeChangingDescription +
812 " (" + kInput.description +
")");
813 is(gUtils2.focusedInputType, kType.type,
814 "type attr changing test (type): " + typeChangingDescription +
815 " (" + kInput.description +
")");
816 if (kTestOpenState && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) {
817 is(gUtils.IMEIsOpen, kOpened,
818 "type attr changing test (open state is changed): " +
819 typeChangingDescription +
" (" + kInput.description +
")");
822 // reset the type to default
823 e.setAttribute(
"type", kInput.type);
825 if (!kIMEOpenSupported)
830 function runReadonlyChangingTest()
832 if (!kIMEEnabledSupported)
835 const kInputControls = [
837 type:
"text", expected: gUtils.IME_STATUS_ENABLED },
839 type:
"password", expected: gUtils.IME_STATUS_PASSWORD },
841 type:
"url", expected: gUtils.IME_STATUS_ENABLED },
843 type:
"email", expected: gUtils.IME_STATUS_ENABLED },
845 type:
"search", expected: gUtils.IME_STATUS_ENABLED },
847 type:
"tel", expected: gUtils.IME_STATUS_ENABLED },
849 type:
"number", expected: gUtils.IME_STATUS_ENABLED },
851 type:
"textarea", expected: gUtils.IME_STATUS_ENABLED }
853 const kOpenedState = [ true, false ];
855 for (var i =
0; i < kOpenedState.length; i++) {
856 const kOpened = kOpenedState[i];
857 for (var j =
0; j < kInputControls.length; j++) {
858 const kInput = kInputControls[j];
859 var e = document.getElementById(kInput.id);
861 if (kIMEOpenSupported && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) {
862 gUtils.IMEIsOpen = kOpened;
864 e.setAttribute(
"readonly",
"readonly");
865 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
866 "readonly attr setting test: type=" + kInput.type);
867 e.removeAttribute(
"readonly");
868 is(gUtils.IMEStatus, kInput.expected,
869 "readonly attr removing test: type=" + kInput.type);
870 if (kIMEOpenSupported && gUtils.IMEStatus == gUtils.IME_STATUS_ENABLED) {
871 is(gUtils.IMEIsOpen, kOpened,
872 "readonly attr removing test (open state is changed): type=" +
876 if (!kIMEOpenSupported)
881 function runComplexContenteditableTests()
883 if (!kIMEEnabledSupported) {
887 var description =
"runReadonlyChangingOnContenteditable: ";
889 var container = document.getElementById(
"display");
890 var button = document.getElementById(
"button");
892 // the editor has focus directly.
893 container.setAttribute(
"contenteditable",
"true");
896 is(gFM.focusedElement, container,
897 description +
"The editor doesn't get focus");
898 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
899 description +
"IME isn't enabled on HTML editor");
901 Components.interfaces.nsIPlaintextEditor.eEditorReadonlyMask;
903 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
904 getInterface(Components.interfaces.nsIWebNavigation).
905 QueryInterface(Components.interfaces.nsIEditorDocShell).editor;
906 var flags = editor.flags;
907 editor.flags = flags | kReadonly;
908 is(gFM.focusedElement, container,
909 description +
"The editor loses focus by flag change");
910 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
911 description +
"IME is still enabled on readonly HTML editor");
912 editor.flags = flags;
913 is(gFM.focusedElement, container,
914 description +
"The editor loses focus by flag change #2");
915 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
916 description +
"IME is still disabled, the editor isn't readonly now");
917 container.removeAttribute(
"contenteditable");
918 todo_is(gFM.focusedElement, null,
919 description +
"The container still has focus, the editor has been no editable");
920 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
921 description +
"IME is still enabled on the editor, the editor has been no editable");
923 // a button which is in the editor has focus
925 is(gFM.focusedElement, button,
926 description +
"The button doesn't get focus");
927 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
928 description +
"IME is enabled on the button");
929 container.setAttribute(
"contenteditable",
"true");
930 is(gFM.focusedElement, button,
931 description +
"The button loses focus, the container is editable now");
932 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
933 description +
"IME is still disabled on the button, the container is editable now");
935 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
936 getInterface(Components.interfaces.nsIWebNavigation).
937 QueryInterface(Components.interfaces.nsIEditorDocShell).editor;
938 flags = editor.flags;
939 editor.flags = flags | kReadonly;
940 is(gFM.focusedElement, button,
941 description +
"The button loses focus by changing editor flags");
942 is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
943 description +
"IME is still enabled on the button, the container is readonly now");
944 editor.flags = flags;
945 is(gFM.focusedElement, button,
946 description +
"The button loses focus by changing editor flags #2");
947 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
948 description +
"IME is still disabled on the button, the container isn't readonly now");
949 container.removeAttribute(
"contenteditable");
950 is(gFM.focusedElement, button,
951 description +
"The button loses focus, the container has been no editable");
952 todo_is(gUtils.IMEStatus, gUtils.IME_STATUS_DISABLED,
953 description +
"IME is still enabled on the button, the container has been no editable");
955 description =
"testOnIndependentEditor: ";
956 function testOnIndependentEditor(aEditor, aEditorDescription)
958 var isReadonly = aEditor.readOnly;
960 aEditor.readOnly ? gUtils.IME_STATUS_DISABLED : gUtils.IME_STATUS_ENABLED;
961 var unexpectedStateDescription =
962 expectedState != gUtils.IME_STATUS_ENABLED ?
"enabled" :
"disabled";
964 is(gFM.focusedElement, aEditor,
965 description +
"The " + aEditorDescription +
" doesn't get focus");
966 is(gUtils.IMEStatus, expectedState,
967 description +
"IME is " + unexpectedStateDescription +
968 " on the " + aEditorDescription);
969 container.setAttribute(
"contenteditable",
"true");
970 is(gFM.focusedElement, aEditor,
971 description +
"The " + aEditorDescription +
972 " loses focus, the container is editable now");
973 is(gUtils.IMEStatus, expectedState,
974 description +
"IME becomes " + unexpectedStateDescription +
975 " on the " + aEditorDescription +
", the container is editable now");
977 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
978 getInterface(Components.interfaces.nsIWebNavigation).
979 QueryInterface(Components.interfaces.nsIEditorDocShell).editor;
980 flags = editor.flags;
981 editor.flags = flags | kReadonly;
982 is(gFM.focusedElement, aEditor,
983 description +
"The " + aEditorDescription +
984 " loses focus by changing editor flags");
985 is(gUtils.IMEStatus, expectedState,
986 description +
"IME becomes " + unexpectedStateDescription +
" on the " +
987 aEditorDescription +
", the container is readonly now");
988 editor.flags = flags;
989 is(gFM.focusedElement, aEditor,
990 description +
"The " + aEditorDescription +
991 " loses focus by changing editor flags #2");
992 is(gUtils.IMEStatus, expectedState,
993 description +
"IME becomes " + unexpectedStateDescription +
" on the " +
994 aEditorDescription +
", the container isn't readonly now");
995 container.removeAttribute(
"contenteditable");
996 is(gFM.focusedElement, aEditor,
997 description +
"The " + aEditorDescription +
998 " loses focus, the container has been no editable");
999 is(gUtils.IMEStatus, expectedState,
1000 description +
"IME becomes " + unexpectedStateDescription +
" on the " +
1001 aEditorDescription +
", the container has been no editable");
1004 // a textarea which is in the editor has focus
1005 testOnIndependentEditor(document.getElementById(
"textarea"),
1007 // a readonly textarea which is in the editor has focus
1008 testOnIndependentEditor(document.getElementById(
"textarea_readonly"),
1009 "textarea[readonly]");
1010 // an input field which is in the editor has focus
1011 testOnIndependentEditor(document.getElementById(
"text"),
1012 "input[type=\"text\
"]");
1013 // a readonly input field which is in the editor has focus
1014 testOnIndependentEditor(document.getElementById(
"text_readonly"),
1015 "input[type=\"text\
"][readonly]");
1017 description =
"testOnOutsideOfEditor: ";
1018 function testOnOutsideOfEditor(aFocusNode, aFocusNodeDescription, aEditor)
1022 is(gFM.focusedElement, aFocusNode,
1023 description +
"The " + aFocusNodeDescription +
" doesn't get focus");
1025 if (document.activeElement) {
1026 document.activeElement.blur();
1028 is(gFM.focusedElement, null,
1029 description +
"Unexpected element has focus");
1032 aFocusNode ? gUtils.IMEStatus : gUtils.IME_STATUS_DISABLED;
1033 var unexpectedStateDescription =
1034 expectedState != gUtils.IME_STATUS_ENABLED ?
"enabled" :
"disabled";
1036 aEditor.setAttribute(
"contenteditable",
"true");
1037 is(gFM.focusedElement, aFocusNode,
1038 description +
"The " + aFocusNodeDescription +
1039 " loses focus, a HTML editor is editable now");
1040 is(gUtils.IMEStatus, expectedState,
1041 description +
"IME becomes " + unexpectedStateDescription +
1042 " on the " + aFocusNodeDescription +
1043 ", the HTML editor is editable now");
1045 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
1046 getInterface(Components.interfaces.nsIWebNavigation).
1047 QueryInterface(Components.interfaces.nsIEditorDocShell).editor;
1048 flags = editor.flags;
1049 editor.flags = flags | kReadonly;
1050 is(gFM.focusedElement, aFocusNode,
1051 description + aFocusNodeDescription +
1052 " loses focus by changing HTML editor flags");
1053 is(gUtils.IMEStatus, expectedState,
1054 description +
"IME becomes " + unexpectedStateDescription +
" on " +
1055 aFocusNodeDescription +
", the HTML editor is readonly now");
1056 editor.flags = flags;
1057 is(gFM.focusedElement, aFocusNode,
1058 description + aFocusNodeDescription +
1059 " loses focus by changing HTML editor flags #2");
1060 is(gUtils.IMEStatus, expectedState,
1061 description +
"IME becomes " + unexpectedStateDescription +
" on " +
1062 aFocusNodeDescription +
", the HTML editor isn't readonly now");
1063 container.removeAttribute(
"contenteditable");
1064 is(gFM.focusedElement, aFocusNode,
1065 description + aFocusNodeDescription +
1066 " loses focus, the HTML editor has been no editable");
1067 is(gUtils.IMEStatus, expectedState,
1068 description +
"IME becomes " + unexpectedStateDescription +
" on " +
1069 aFocusNodeDescription +
", the HTML editor has been no editable");
1072 var div = document.getElementById(
"contenteditableEditor");
1073 // a textarea which is outside of the editor has focus
1074 testOnOutsideOfEditor(document.getElementById(
"textarea"),
"textarea", div);
1075 // a readonly textarea which is outside of the editor has focus
1076 testOnOutsideOfEditor(document.getElementById(
"textarea_readonly"),
1077 "textarea[readonly]", div);
1078 // an input field which is outside of the editor has focus
1079 testOnOutsideOfEditor(document.getElementById(
"text"),
1080 "input[type=\"text\
"]", div);
1081 // a readonly input field which outside of the editor has focus
1082 testOnOutsideOfEditor(document.getElementById(
"text_readonly"),
1083 "input[type=\"text\
"][readonly]", div);
1084 // a readonly input field which outside of the editor has focus
1085 testOnOutsideOfEditor(document.getElementById(
"button"),
"button", div);
1086 // nobody has focus.
1087 testOnOutsideOfEditor(null,
"nobody", div);
1090 function runEditorFlagChangeTests()
1092 if (!kIMEEnabledSupported) {
1096 var description =
"runEditorFlagChangeTests: ";
1098 var container = document.getElementById(
"display");
1100 // the editor has focus directly.
1101 container.setAttribute(
"contenteditable",
"true");
1104 is(gFM.focusedElement, container,
1105 description +
"The editor doesn't get focus");
1106 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
1107 description +
"IME isn't enabled on HTML editor");
1108 const kIMEStateChangeFlags =
1109 Components.interfaces.nsIPlaintextEditor.eEditorPasswordMask |
1110 Components.interfaces.nsIPlaintextEditor.eEditorReadonlyMask |
1111 Components.interfaces.nsIPlaintextEditor.eEditorDisabledMask;
1113 window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
1114 getInterface(Components.interfaces.nsIWebNavigation).
1115 QueryInterface(Components.interfaces.nsIEditorDocShell).editor;
1116 var editorIMESupport =
1117 editor.QueryInterface(Components.interfaces.nsIEditorIMESupport);
1118 var flags = editor.flags;
1120 // start composition
1121 synthesizeComposition(true);
1126 {
"string":
"\u3078\u3093\u3057\u3093",
1129 {
"length":
4,
"attr": gUtils.COMPOSITION_ATTR_RAWINPUT }
1132 "caret": {
"start":
4,
"length":
0 }
1135 editor.flags &= ~kIMEStateChangeFlags;
1136 ok(editorIMESupport.composing,
1137 description +
"#1 IME composition was committed unexpectedly");
1138 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
1139 description +
"#1 IME isn't enabled on HTML editor");
1141 editor.flags |= ~kIMEStateChangeFlags;
1142 ok(editorIMESupport.composing,
1143 description +
"#2 IME composition was committed unexpectedly");
1144 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
1145 description +
"#2 IME isn't enabled on HTML editor");
1147 editor.flags = flags;
1148 ok(editorIMESupport.composing,
1149 description +
"#3 IME composition was committed unexpectedly");
1150 is(gUtils.IMEStatus, gUtils.IME_STATUS_ENABLED,
1151 description +
"#3 IME isn't enabled on HTML editor");
1153 // cancel the composition
1159 {
"length":
0,
"attr":
0 }
1162 "caret": {
"start":
0,
"length":
0 }
1165 synthesizeComposition(false);
1167 container.removeAttribute(
"contenteditable");
1170 function runEditableSubframeTests()
1172 window.open(
"window_imestate_iframes.html",
"_blank",
1173 "width=600,height=600");
1176 function runTestPasswordFieldOnDialog()
1178 if (!kIMEEnabledSupported) {
1182 if (document.activeElement) {
1183 document.activeElement.blur();
1188 function WindowObserver()
1190 Components.classes[
"@mozilla.org/observer-service;1"].
1191 getService(Components.interfaces.nsIObserverService).
1192 addObserver(this,
"domwindowopened", false);
1195 WindowObserver.prototype = {
1196 QueryInterface: function (iid)
1198 if (iid.equals(Components.interfaces.nsIObserver) ||
1199 iid.equals(Components.interfaces.nsISupports)) {
1204 observe: function (subject, topic, data)
1206 if (topic ===
"domwindowopened") {
1207 ok(true,
"dialog window is created");
1208 dialog = subject.QueryInterface(Components.interfaces.nsIDOMWindow);
1209 dialog.addEventListener(
"load", onPasswordDialogLoad, false);
1214 var observer = new WindowObserver();
1215 var arg1 = new Object(), arg2 = new Object();
1216 Components.classes[
"@mozilla.org/embedcomp/prompt-service;1"].
1217 getService(Components.interfaces.nsIPromptService).
1218 promptPassword(window,
"title",
"text", arg1,
"msg", arg2);
1220 ok(true,
"password dialog was closed");
1222 Components.classes[
"@mozilla.org/observer-service;1"].
1223 getService(Components.interfaces.nsIObserverService).
1224 removeObserver(observer,
"domwindowopened");
1228 function onPasswordDialogLoad()
1230 ok(true,
"onPasswordDialogLoad is called");
1231 dialog.removeEventListener(
"load", onPasswordDialogLoad, false);
1232 passwordField = dialog.document.getElementById(
"password1Textbox");
1233 passwordField.addEventListener(
"focus", onPasswordFieldFocus, false);
1236 function onPasswordFieldFocus()
1238 ok(true,
"onPasswordFieldFocus is called");
1239 passwordField.removeEventListener(
"focus", onPasswordFieldFocus, false);
1241 QueryInterface(Components.interfaces.nsIInterfaceRequestor).
1242 getInterface(Components.interfaces.nsIDOMWindowUtils);
1243 is(utils.IMEStatus, utils.IME_STATUS_PASSWORD,
1244 "IME isn't disabled on a password field of password dialog");
1245 synthesizeKey(
"VK_ESCAPE", { }, dialog);
1251 if (!kIMEEnabledSupported && !kIMEOpenSupported)
1254 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
1256 // test for normal contents.
1257 runBasicTest(false, false,
"Testing of normal contents");
1259 // test for plugin contents
1262 var container = document.getElementById(
"display");
1263 // test for
contentEditable=
"true"
1264 container.setAttribute(
"contenteditable",
"true");
1265 runBasicTest(true, false,
"Testing [contentEditable=\"true\
"]");
1267 // test for
contentEditable=
"false"
1268 container.setAttribute(
"contenteditable",
"false");
1269 runBasicTest(false, false,
"Testing [contentEditable=\"false\
"]");
1271 // test for removing contentEditable
1272 container.setAttribute(
"contenteditable",
"true");
1273 container.removeAttribute(
"contenteditable");
1274 runBasicTest(false, false,
"Testing after contentEditable to be removed");
1277 document.designMode =
"on";
1278 runBasicTest(true, true,
"Testing designMode=\"on\
"");
1279 document.designMode =
"off";
1280 document.getElementById(
"text").focus();
1281 runBasicTest(false, false,
"Testing designMode=\"off\
"");
1283 // changing input[type] values
1284 // XXX currently, type attribute changing doesn't work fine. bug
559728.
1285 // runTypeChangingTest();
1287 // changing readonly attribute
1288 runReadonlyChangingTest();
1290 // complex contenteditable editor's tests
1291 runComplexContenteditableTests();
1293 // test whether the IME state and composition are not changed unexpectedly
1294 runEditorFlagChangeTests();
1296 // test password field on dialog
1297 // XXX temporary disable against failure
1298 //runTestPasswordFieldOnDialog();
1303 function runASyncTests()
1305 // The tests must call onFinish() method.
1306 runEditableSubframeTests();
1311 SimpleTest.finish();