Bug 1917491 - Part 3: Introduce call-like syntax for resource disposal in DisposableS...
[gecko.git] / widget / tests / test_ime_state_on_editable_state_change_in_parent.html
bloba1acbe2e6ed2ffb2044393848fe8a71e8fde70f5
1 <!doctype html>
2 <html>
3 <head>
4 <meta charset="utf-8">
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">
9 </head>
10 <body>
11 <div></div>
12 <script>
13 "use strict";
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() {
22 return new Promise(
23 resolve => requestAnimationFrame(
24 () => requestAnimationFrame(resolve)
29 function resetIMEStateWithFocusMove() {
30 const input = document.createElement("input");
31 document.body.appendChild(input);
32 input.focus();
33 input.remove();
34 return waitForIMEContentObserverSendingNotifications();
37 await (async function test_setting_contenteditable_of_focused_div() {
38 const div = document.querySelector("div");
39 div.setAttribute("tabindex", "0");
40 div.focus();
41 is(
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));
54 is(
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"
59 ok(
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();
65 is(
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"
70 ok(
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");
75 })();
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);
86 div.focus();
87 await waitForIMEContentObserverSendingNotifications();
88 div.removeAttribute("contenteditable");
89 await waitForIMEContentObserverSendingNotifications();
90 is(
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"
95 ok(
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");
101 })();
103 await resetIMEStateWithFocusMove();
105 await (async function test_setting_designMode() {
106 window.focus();
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"'
129 })();
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);
139 divInShadow.focus();
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(${
145 aMode
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.
153 todo_is(
154 window.windowUtils.IMEStatus,
155 Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
156 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${
157 aMode
158 }): IME should be enabled when the <body> becomes editable`
160 todo(
161 tipWrapper.IMEHasFocus,
162 `test_setting_content_editable_of_body_when_shadow_DOM_has_focus(${
163 aMode
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)${
172 aMode
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)${
178 aMode
179 }): IME should not have focus when the <body> becomes not editable`
181 div.remove();
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);
191 divInShadow.focus();
192 await waitForIMEContentObserverSendingNotifications();
194 window.windowUtils.IMEStatus,
195 Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED,
196 `test_setting_designMode_when_shadow_DOM_has_focus(${
197 aMode
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(${
206 aMode
207 }): IME should stay disabled when designMode is set`
210 !tipWrapper.IMEHasFocus,
211 `test_setting_designMode_when_shadow_DOM_has_focus(${
212 aMode
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(${
221 aMode
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(${
227 aMode
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(${
236 aMode
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(${
242 aMode
243 }): IME should keep having focus when designMode is unset but an editable element in the shadow DOM has focus`
245 div.remove();
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();
256 SimpleTest.finish();
258 </script>
259 </body>
260 </html>