Bug 1906125 - [devtools] Implement memory panel odd background in CSS instead of...
[gecko.git] / widget / tests / file_test_ime_state_in_text_control_on_reframe.js
blob719022b889778a8d3c9b2e96ef27c38c15791e2e
1 /* Any copyright is dedicated to the Public Domain.
2    http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
6 /* import-globals-from file_ime_state_test_helper.js */
8 // Bug 580388 and bug 808287
9 class IMEStateInTextControlOnReframeTester {
10   static #sTextControls = [
11     {
12       tag: "input",
13       type: "text",
14     },
15     {
16       tag: "input",
17       type: "password",
18     },
19     {
20       tag: "textarea",
21     },
22   ];
24   static get numberOfTextControlTypes() {
25     return IMEStateInTextControlOnReframeTester.#sTextControls.length;
26   }
28   #createElement() {
29     const textControl = this.#mDocument.createElement(this.#mTextControl.tag);
30     if (this.#mTextControl.type !== undefined) {
31       textControl.setAttribute("type", this.#mTextControl.type);
32     }
33     return textControl;
34   }
36   #getDescription() {
37     return `<${this.#mTextControl.tag}${
38       this.#mTextControl.type !== undefined
39         ? ` type=${this.#mTextControl.type}`
40         : ""
41     }>`;
42   }
44   #getExpectedIMEState() {
45     return this.#mTextControl.type == "password"
46       ? SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_PASSWORD
47       : SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_ENABLED;
48   }
50   #flushPendingIMENotifications() {
51     return new Promise(resolve =>
52       this.#mWindow.requestAnimationFrame(() =>
53         this.#mWindow.requestAnimationFrame(resolve)
54       )
55     );
56   }
58   // Runner only fields.
59   #mTextControl;
60   #mTextControlElement;
61   #mWindow;
62   #mDocument;
64   // Checker only fields.
65   #mWindowUtils;
66   #mTIPWrapper;
68   clear() {
69     this.#mTIPWrapper?.clearFocusBlurNotifications();
70     this.#mTIPWrapper = null;
71   }
73   /**
74    * @param {number} aIndex Index of the test.
75    * @param {Element} aDocument The document to run the test.
76    * @param {Window} aWindow [optional] The DOM window for aDocument.
77    * @returns {object} Expected result of initial state.
78    */
79   async prepareToRun(aIndex, aDocument, aWindow = window) {
80     this.#mWindow = aWindow;
81     this.#mDocument = aDocument;
82     this.#mDocument.activeElement?.blur();
83     this.#mTextControlElement?.remove();
84     await this.#flushPendingIMENotifications();
85     this.#mTextControl =
86       IMEStateInTextControlOnReframeTester.#sTextControls[aIndex];
87     this.#mTextControlElement = this.#createElement();
88     this.#mDocument.body.appendChild(this.#mTextControlElement);
89     this.#mTextControlElement.focus();
90     this.#mTextControlElement.style.overflow = "visible";
91     this.#mTextControlElement.addEventListener(
92       "input",
93       aEvent => {
94         aEvent.target.style.overflow = "hidden";
95       },
96       {
97         capture: true,
98       }
99     );
100     await this.#flushPendingIMENotifications();
101     const expectedIMEState = this.#getExpectedIMEState();
102     return {
103       description: `when ${this.#getDescription()} has focus`,
104       expectedIMEState,
105       expectedIMEFocus:
106         expectedIMEState !=
107         SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED,
108       expectedNumberOfFocusNotifications: 1,
109     };
110   }
112   #checkResult(aExpectedResult) {
113     const description = "IMEStateInTextControlOnReframeTester";
114     is(
115       this.#mWindowUtils.IMEStatus,
116       aExpectedResult.expectedIMEState,
117       `${description}: IME state should be proper one for the text control ${aExpectedResult.description}`
118     );
119     is(
120       this.#mTIPWrapper.IMEHasFocus,
121       aExpectedResult.expectedIMEFocus,
122       `${description}: IME should ${
123         aExpectedResult.expectedIMEFocus ? "" : "not "
124       }have focus ${aExpectedResult.description}`
125     );
126     if (aExpectedResult.numberOfFocusNotifications !== undefined) {
127       is(
128         this.#mTIPWrapper.numberOfFocusNotifications,
129         aExpectedResult.numberOfFocusNotifications,
130         `${description}: focus notifications should've been received ${
131           this.#mTIPWrapper.numberOfFocusNotifications
132         } times ${aExpectedResult.description}`
133       );
134     }
135     if (aExpectedResult.numberOfBlurNotifications !== undefined) {
136       is(
137         this.#mTIPWrapper.numberOfBlurNotifications,
138         aExpectedResult.numberOfBlurNotifications,
139         `${description}: blur notifications should've been received ${
140           this.#mTIPWrapper.numberOfBlurNotifications
141         } times ${aExpectedResult.description}`
142       );
143     }
144   }
146   /**
147    * @param {object} aExpectedResult The expected result returned by prepareToRun().
148    * @param {Window} aWindow The window whose IME state should be checked.
149    * @param {TIPWrapper} aTIPWrapper The TIP wrapper of aWindow.
150    */
151   checkResultAfterTypingA(aExpectedResult, aWindow, aTIPWrapper) {
152     this.#mWindowUtils = SpecialPowers.wrap(aWindow).windowUtils;
153     this.#mTIPWrapper = aTIPWrapper;
154     this.#checkResult(aExpectedResult);
156     this.#mTIPWrapper.clearFocusBlurNotifications();
157   }
159   async prepareToRun2() {
160     this.#mTextControlElement.addEventListener("focus", aEvent => {
161       // Perform a style change and flush it to trigger reframing.
162       aEvent.target.style.overflow = "visible";
163       aEvent.target.getBoundingClientRect();
164     });
165     this.#mTextControlElement.blur();
166     this.#mTextControlElement.focus();
168     await this.#flushPendingIMENotifications();
170     const expectedIMEState = this.#getExpectedIMEState();
171     return {
172       description: `when ${this.#getDescription()} is reframed by focus event listener`,
173       expectedIMEState,
174       expectedIMEFocus:
175         expectedIMEState !=
176         SpecialPowers.Ci.nsIDOMWindowUtils.IME_STATUS_DISABLED,
177       expectedNumberOfFocusNotifications: 1,
178       expectedNumberOfBlurNotifications: 1,
179     };
180   }
182   /**
183    * @param {object} aExpectedResult The expected result returned by prepareToRun().
184    */
185   checkResultAfterTypingA2(aExpectedResult) {
186     this.#checkResult(aExpectedResult);
188     this.#mTIPWrapper.clearFocusBlurNotifications();
189   }