Handle "input" / "compositionend" events in a mutually-exclusive manner, as they may conflict.
@@ -1207,29 +1207,54 @@ Guacamole.Keyboard = function(element) {
}, true);
- // Automatically type text entered into the wrapped element
- element.addEventListener("input", function(e) {
+ /**
+ * Handles the given "input" event, typing the data within the input text.
+ * If the event is complete (text is provided), handling of "compositionend"
+ * events is suspended, as such events may conflict with input events.
+ *
+ * @private
+ * @param {InputEvent} e
+ * The "input" event to handle.
+ */
+ var handleInput = function handleInput(e) {
// Only intercept if handler set
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
// Type all content written
- if (e.data)
+ if (e.data) {
+ element.removeEventListener("compositionend", handleComposition, false);
guac_keyboard.type(e.data);
+ }
- }, false);
+ };
- // Automatically type the result of composed characters/text
- element.addEventListener("compositionend", function(e) {
+ /**
+ * Handles the given "compositionend" event, typing the data within the
+ * composed text. If the event is complete (composed text is provided),
+ * handling of "input" events is suspended, as such events may conflict
+ * with composition events.
+ *
+ * @private
+ * @param {CompositionEvent} e
+ * The "compositionend" event to handle.
+ */
+ var handleComposition = function handleComposition(e) {
// Only intercept if handler set
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
// Type all content written
- if (e.data)
+ if (e.data) {
+ element.removeEventListener("input", handleInput, false);
guac_keyboard.type(e.data);
+ }
- }, false);
+ };
+
+ // Automatically type text entered into the wrapped element
+ element.addEventListener("input", handleInput, false);
+ element.addEventListener("compositionend", handleComposition, false);
};
