Skip to content
This repository was archived by the owner on May 15, 2025. It is now read-only.

Commit b09c4cb

Browse files
committed
fix: speed up code for filling in form
1 parent 8aff87f commit b09c4cb

File tree

1 file changed

+28
-71
lines changed

1 file changed

+28
-71
lines changed

windows-rdp/devolutions-patch.js

Lines changed: 28 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ const formFieldEntries = {
7474
};
7575

7676
/**
77-
* Handles typing in the values for the input form, dispatching each character
78-
* as an event. This function assumes that all characters in the input will be
79-
* UTF-8.
77+
* Handles typing in the values for the input form. All values are written
78+
* immediately, even though that would be physically impossible with a real
79+
* keyboard.
8080
*
8181
* Note: this code will never break, but you might get warnings in the console
8282
* from Angular about unexpected value changes. Angular patches over a lot of
@@ -94,75 +94,32 @@ const formFieldEntries = {
9494
* @returns {Promise<void>}
9595
*/
9696
function setInputValue(inputField, inputText) {
97-
const continueEventName = "coder-patch--continue";
98-
99-
const keyboardInputPromise = /** @type {Promise<void>} */ (
100-
new Promise((resolve, reject) => {
101-
if (inputText === "") {
102-
resolve();
103-
return;
104-
}
105-
106-
// -1 indicates a "pre-write" for clearing out the input before trying to
107-
// write new text to it
108-
let i = -1;
109-
110-
// requestAnimationFrame is not capable of giving back values of 0 for its
111-
// task IDs. Good default value to ensure that we don't need if statements
112-
// when trying to cancel anything
113-
let currentAnimationId = 0;
114-
115-
// Super easy to pool the same event objects, because the events don't
116-
// have any custom, context-specific values on them, and they're
117-
// restricted to this one callback.
118-
const continueEvent = new CustomEvent(continueEventName);
119-
const inputEvent = new Event("input", {
120-
bubbles: true,
121-
cancelable: true,
122-
});
123-
124-
/** @returns {void} */
125-
const handleNextCharIndex = () => {
126-
if (i === inputText.length) {
127-
resolve();
128-
return;
129-
}
130-
131-
const currentChar = inputText[i];
132-
if (i !== -1 && currentChar === undefined) {
133-
throw new Error("Went out of bounds");
134-
}
135-
136-
try {
137-
inputField.addEventListener(
138-
continueEventName,
139-
() => {
140-
i++;
141-
currentAnimationId =
142-
window.requestAnimationFrame(handleNextCharIndex);
143-
},
144-
{ once: true },
145-
);
146-
147-
if (i === -1) {
148-
inputField.value = "";
149-
} else {
150-
inputField.value = inputField.value + currentChar;
151-
}
152-
153-
inputField.dispatchEvent(inputEvent);
154-
inputField.dispatchEvent(continueEvent);
155-
} catch (err) {
156-
cancelAnimationFrame(currentAnimationId);
157-
reject(err);
158-
}
159-
};
160-
161-
currentAnimationId = window.requestAnimationFrame(handleNextCharIndex);
162-
})
163-
);
97+
return new Promise((resolve, reject) => {
98+
// Adding timeout for input event, even though we'll be dispatching it
99+
// immediately, just in the off chance that something in the Angular app
100+
// intercepts it or stops it from propagating properly
101+
const timeoutId = window.setTimeout(() => {
102+
reject(new Error("Input event did not get processed correctly in time."));
103+
}, 3_000);
104+
105+
const handleSuccessfulDispatch = () => {
106+
resolve();
107+
window.clearTimeout(timeoutId);
108+
inputField.removeEventListener("input", handleSuccessfulDispatch);
109+
};
110+
111+
inputField.addEventListener("input", handleSuccessfulDispatch);
112+
113+
// Code assumes that Angular will have an event handler in place to handle
114+
// the new event
115+
const inputEvent = new Event("input", {
116+
bubbles: true,
117+
cancelable: true,
118+
});
164119

165-
return keyboardInputPromise;
120+
inputField.value = inputText;
121+
inputField.dispatchEvent(inputEvent);
122+
});
166123
}
167124

168125
/**

0 commit comments

Comments
 (0)