5 <title>Test for IME state management at changing editable state
</title>
6 <script src=
"chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
7 <script src=
"file_ime_state_test_helper.js"></script>
8 <link rel=
"stylesheet" href=
"chrome://mochikit/content/tests/SimpleTest/test.css">
15 /* import-globals-from file_ime_state_test_helper.js */
17 SimpleTest
.waitForExplicitFinish();
18 SimpleTest
.waitForFocus(async () => {
19 const tipWrapper
= new TIPWrapper(window
);
21 function waitForIMEContentObserverSendingNotifications() {
23 resolve
=> requestAnimationFrame(
24 () => requestAnimationFrame(resolve
)
29 function resetIMEStateWithFocusMove() {
30 const input
= document
.createElement("input");
31 document
.body
.appendChild(input
);
34 return waitForIMEContentObserverSendingNotifications();
37 await (async
function test_setting_contenteditable_of_focused_div() {
38 const div
= document
.querySelector("div");
39 div
.setAttribute("tabindex", "0");
42 window
.windowUtils
.IMEStatus
,
43 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
44 "test_setting_contenteditable_of_focused_div: IME should be disabled when non-editable <div> has focus"
46 div
.setAttribute("contenteditable", "");
47 await
waitForIMEContentObserverSendingNotifications();
48 // Sometimes, it's not enough waiting only 2 animation frames here to wait
49 // for IME focus, perhaps, it may be related to HTMLEditor initialization.
50 // Let's wait one more animation frame here.
51 if (!tipWrapper
.IMEHasFocus
) {
52 await
new Promise(resolve
=> requestAnimationFrame(resolve
));
55 window
.windowUtils
.IMEStatus
,
56 Ci
.nsIDOMWindowUtils
.IME_STATUS_ENABLED
,
57 "test_setting_contenteditable_of_focused_div: IME should be enabled when contenteditable of focused <div> is set"
60 tipWrapper
.IMEHasFocus
,
61 "test_setting_contenteditable_of_focused_div: IME should have focus when contenteditable of focused <div> is set"
63 div
.removeAttribute("contenteditable");
64 await
waitForIMEContentObserverSendingNotifications();
66 window
.windowUtils
.IMEStatus
,
67 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
68 "test_setting_contenteditable_of_focused_div: IME should be disabled when contenteditable of focused <div> is removed"
71 !tipWrapper
.IMEHasFocus
,
72 "test_setting_contenteditable_of_focused_div: IME should not have focus when contenteditable of focused <div> is removed"
74 div
.removeAttribute("tabindex");
77 await
resetIMEStateWithFocusMove();
79 await (async
function test_removing_contenteditable_of_non_last_editable_div() {
80 const div
= document
.querySelector("div");
81 div
.setAttribute("tabindex", "0");
82 div
.setAttribute("contenteditable", "");
83 const anotherEditableDiv
= document
.createElement("div");
84 anotherEditableDiv
.setAttribute("contenteditable", "");
85 div
.parentElement
.appendChild(anotherEditableDiv
);
87 await
waitForIMEContentObserverSendingNotifications();
88 div
.removeAttribute("contenteditable");
89 await
waitForIMEContentObserverSendingNotifications();
91 window
.windowUtils
.IMEStatus
,
92 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
93 "test_removing_contenteditable_of_non_last_editable_div: IME should be disabled when contenteditable of focused <div> is removed"
96 !tipWrapper
.IMEHasFocus
,
97 "test_removing_contenteditable_of_non_last_editable_div: IME should not have focus when contenteditable of focused <div> is removed"
99 anotherEditableDiv
.remove();
100 div
.removeAttribute("tabindex");
103 await
resetIMEStateWithFocusMove();
105 await (async
function test_setting_designMode() {
107 document
.designMode
= "on";
108 await
waitForIMEContentObserverSendingNotifications();
110 window
.windowUtils
.IMEStatus
,
111 Ci
.nsIDOMWindowUtils
.IME_STATUS_ENABLED
,
112 'test_setting_designMode: IME should be enabled when designMode is set to "on"'
115 tipWrapper
.IMEHasFocus
,
116 'test_setting_designMode: IME should have focus when designMode is set to "on"'
118 document
.designMode
= "off";
119 await
waitForIMEContentObserverSendingNotifications();
121 window
.windowUtils
.IMEStatus
,
122 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
123 'test_setting_designMode: IME should be disabled when designMode is set to "off"'
126 !tipWrapper
.IMEHasFocus
,
127 'test_setting_designMode: IME should not have focus when designMode is set to "off"'
131 await
resetIMEStateWithFocusMove();
133 async
function test_setting_content_editable_of_body_when_shadow_DOM_has_focus(aMode
) {
134 const div
= document
.querySelector("div");
135 const shadow
= div
.attachShadow({mode
: aMode
});
136 const divInShadow
= document
.createElement("div");
137 divInShadow
.setAttribute("tabindex", "0");
138 shadow
.appendChild(divInShadow
);
140 await
waitForIMEContentObserverSendingNotifications();
142 window
.windowUtils
.IMEStatus
,
143 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
144 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${
146 }): IME should be disabled when non-editable <div> in a shadow DOM has focus`
148 document
.body
.setAttribute("contenteditable", "");
149 await
waitForIMEContentObserverSendingNotifications();
150 // todo_is because of bug 1807597. Gecko does not update focus when focused
151 // element becomes an editable child. Therefore, cannot initialize
152 // HTMLEditor with the new editing host.
154 window
.windowUtils
.IMEStatus
,
155 Ci
.nsIDOMWindowUtils
.IME_STATUS_ENABLED
,
156 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${
158 }): IME should be enabled when the <body> becomes editable`
161 tipWrapper
.IMEHasFocus
,
162 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${
164 }): IME should have focus when the <body> becomes editable`
166 document
.body
.removeAttribute("contenteditable");
167 await
waitForIMEContentObserverSendingNotifications();
169 window
.windowUtils
.IMEStatus
,
170 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
171 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus)${
173 }): IME should be disabled when the <body> becomes not editable`
176 !tipWrapper
.IMEHasFocus
,
177 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus)${
179 }): IME should not have focus when the <body> becomes not editable`
182 document
.body
.appendChild(document
.createElement("div"));
185 async
function test_setting_designMode_when_shadow_DOM_has_focus(aMode
) {
186 const div
= document
.querySelector("div");
187 const shadow
= div
.attachShadow({mode
: aMode
});
188 const divInShadow
= document
.createElement("div");
189 divInShadow
.setAttribute("tabindex", "0");
190 shadow
.appendChild(divInShadow
);
192 await
waitForIMEContentObserverSendingNotifications();
194 window
.windowUtils
.IMEStatus
,
195 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
196 `test_setting_designMode_when_shadow_DOM_has_focus(${
198 }): IME should be disabled when non-editable <div> in a shadow DOM has focus`
200 document
.designMode
= "on";
201 await
waitForIMEContentObserverSendingNotifications();
203 window
.windowUtils
.IMEStatus
,
204 Ci
.nsIDOMWindowUtils
.IME_STATUS_DISABLED
,
205 `test_setting_designMode_when_shadow_DOM_has_focus(${
207 }): IME should stay disabled when designMode is set`
210 !tipWrapper
.IMEHasFocus
,
211 `test_setting_designMode_when_shadow_DOM_has_focus(${
213 }): IME should not have focus when designMode is set`
215 divInShadow
.setAttribute("contenteditable", "");
216 await
waitForIMEContentObserverSendingNotifications();
218 window
.windowUtils
.IMEStatus
,
219 Ci
.nsIDOMWindowUtils
.IME_STATUS_ENABLED
,
220 `test_setting_designMode_when_shadow_DOM_has_focus(${
222 }): IME should be enabled when focused <div> in a shadow DOM becomes editable`
225 tipWrapper
.IMEHasFocus
,
226 `test_setting_designMode_when_shadow_DOM_has_focus(${
228 }): IME should have focus when focused <div> in a shadow DOM becomes editable`
230 document
.designMode
= "off";
231 await
waitForIMEContentObserverSendingNotifications();
233 window
.windowUtils
.IMEStatus
,
234 Ci
.nsIDOMWindowUtils
.IME_STATUS_ENABLED
,
235 `test_setting_designMode_when_shadow_DOM_has_focus(${
237 }): IME should keep being enabled when designMode is unset but an editable element in the shadow DOM has focus`
240 tipWrapper
.IMEHasFocus
,
241 `test_setting_designMode_when_shadow_DOM_has_focus(${
243 }): IME should keep having focus when designMode is unset but an editable element in the shadow DOM has focus`
246 document
.body
.appendChild(document
.createElement("div"));
249 for (const mode
of ["open", "closed"]) {
250 await
test_setting_content_editable_of_body_when_shadow_DOM_has_focus(mode
);
251 await
resetIMEStateWithFocusMove();
252 await
test_setting_designMode_when_shadow_DOM_has_focus(mode
);
253 await
resetIMEStateWithFocusMove();