1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
6 /* import-globals-from file_ime_state_test_helper.js */
8 class IMEStateOnReadonlyChangeTester {
9 static #sTextControlTypes = [
11 description: "<input>",
12 createElement: aDoc => aDoc.createElement("input"),
13 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
16 description: `<input type="text">`,
17 createElement: aDoc => {
18 const input = aDoc.createElement("input");
19 input.setAttribute("type", "text");
22 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
25 description: `<input type="password">`,
26 createElement: aDoc => {
27 const input = aDoc.createElement("input");
28 input.setAttribute("type", "password");
31 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_PASSWORD,
34 description: `<input type="url">`,
35 createElement: aDoc => {
36 const input = aDoc.createElement("input");
37 input.setAttribute("type", "url");
40 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
43 description: `<input type="email">`,
44 createElement: aDoc => {
45 const input = aDoc.createElement("input");
46 input.setAttribute("type", "email");
49 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
52 description: `<input type="search">`,
53 createElement: aDoc => {
54 const input = aDoc.createElement("input");
55 input.setAttribute("type", "search");
58 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
61 description: `<input type="tel">`,
62 createElement: aDoc => {
63 const input = aDoc.createElement("input");
64 input.setAttribute("type", "tel");
67 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
70 description: `<input type="number">`,
71 createElement: aDoc => {
72 const input = aDoc.createElement("input");
73 input.setAttribute("type", "number");
76 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
79 description: `<textarea></textarea>`,
80 createElement: aDoc => aDoc.createElement("textarea"),
81 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED,
85 static get numberOfTextControlTypes() {
86 return IMEStateOnReadonlyChangeTester.#sTextControlTypes.length;
94 // Only checker fields
99 this.#mTextControlElement?.remove();
100 this.#mTIPWrapper?.clearFocusBlurNotifications();
101 this.#mTIPWrapper = null;
104 #flushPendingIMENotifications() {
105 return new Promise(resolve =>
106 this.#mWindow.requestAnimationFrame(() =>
107 this.#mWindow.requestAnimationFrame(resolve)
113 * @param {number} aIndex The index of text control types.
114 * @param {Window} aWindow The window running tests.
115 * @param {Element} aContainer The element which should have new <input> or <textarea>.
116 * @returns {object} Expected data before running tests.
118 async prepareToRun(aIndex, aWindow, aContainer) {
119 this.#mWindow = aWindow;
121 IMEStateOnReadonlyChangeTester.#sTextControlTypes[aIndex];
123 if (aContainer.ownerDocument.activeElement) {
124 aContainer.ownerDocument.activeElement.blur();
125 await this.#flushPendingIMENotifications();
127 if (this.#mTextControlElement?.isConnected) {
128 this.#mTextControlElement.remove();
130 this.#mTextControlElement = this.#mTextControl.createElement(
131 aContainer.ownerDocument
134 const waitForFocus = new Promise(resolve =>
135 this.#mTextControlElement.addEventListener("focus", resolve, {
139 aContainer.appendChild(this.#mTextControlElement);
140 this.#mTextControlElement.focus();
143 await this.#flushPendingIMENotifications();
146 description: this.#mTextControl.description,
147 expectedIMEState: this.#mTextControl.expectedIMEState,
148 expectedIMEFocus: true,
153 * @param {object} aExpectedData The expected data which was returned by prepareToRun().
154 * @param {TIPWrapper} aTIPWrapper TIP wrapper in aWindow.
155 * @param {Window} aWindow [optional] The window object of which you want to check IME state.
157 checkBeforeRun(aExpectedData, aTIPWrapper, aWindow = window) {
158 this.#mWindowUtils = SpecialPowers.wrap(aWindow).windowUtils;
159 this.#mTIPWrapper = aTIPWrapper;
160 const description = `IMEStateOnReadonlyChangeTester(${aExpectedData.description})`;
162 this.#mWindowUtils.IMEStatus,
163 aExpectedData.expectedIMEState,
164 `${description}: IME state should be set to expected value before setting readonly attribute`
167 this.#mTIPWrapper.IMEHasFocus,
168 aExpectedData.expectedIMEFocus,
169 `${description}: IME state should ${
170 aExpectedData.expectedIMEFocus ? "" : "not"
171 } have focus before setting readonly attribute`
176 * @returns {object} Expected result.
178 async runToMakeTextControlReadonly() {
179 this.#mTextControlElement.setAttribute("readonly", "");
181 await this.#flushPendingIMENotifications();
184 description: this.#mTextControl.description,
185 expectedIMEState: SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED,
186 expectedIMEFocus: false,
191 * @param {object} aExpectedData Expected result which is returned by runToMakeTextControlReadonly().
193 checkResultOfMakingTextControlReadonly(aExpectedData) {
194 const description = `IMEStateOnReadonlyChangeTester(${aExpectedData.description})`;
196 this.#mWindowUtils.IMEStatus,
197 aExpectedData.expectedIMEState,
198 `${description}: IME state should be set to expected value after setting readonly attribute`
201 this.#mTIPWrapper.IMEHasFocus,
202 aExpectedData.expectedIMEFocus,
203 `${description}: IME state should ${
204 aExpectedData.expectedIMEFocus ? "" : "not"
205 } have focus after setting readonly attribute`
210 * @returns {object} Expected result.
212 async runToMakeTextControlEditable() {
213 this.#mTextControlElement.removeAttribute("readonly");
215 await this.#flushPendingIMENotifications();
218 description: this.#mTextControl.description,
219 expectedIMEState: this.#mTextControl.expectedIMEState,
220 expectedIMEFocus: true,
225 * @param {object} aExpectedData Expected result which is returned by runToMakeTextControlEditable().
227 checkResultOfMakingTextControlEditable(aExpectedData) {
228 const description = `IMEStateOnReadonlyChangeTester(${aExpectedData.description})`;
230 this.#mWindowUtils.IMEStatus,
231 aExpectedData.expectedIMEState,
232 `${description}: IME state should be set to expected value after removing readonly attribute`
235 this.#mTIPWrapper.IMEHasFocus,
236 aExpectedData.expectedIMEFocus,
237 `${description}: IME state should ${
238 aExpectedData.expectedIMEFocus ? "" : "not"
239 } have focus after removing readonly attribute`