GUACAMOLE-352: Allow additional elements to be added to a single Guacamole.Keyboard.

This commit is contained in:
Michael Jumper
2017-12-18 10:58:50 -08:00
parent 05822907b4
commit 2d26d24dda

View File

@@ -25,9 +25,12 @@ var Guacamole = Guacamole || {};
* which represent keys as their corresponding X11 keysym. * which represent keys as their corresponding X11 keysym.
* *
* @constructor * @constructor
* @param {Element} element The Element to use to provide keyboard events. * @param {Element} [element]
* The Element to use to provide keyboard events. If omitted, at least one
* Element must be manually provided through the listenTo() function for
* the Guacamole.Keyboard instance to have any effect.
*/ */
Guacamole.Keyboard = function(element) { Guacamole.Keyboard = function Keyboard(element) {
/** /**
* Reference to this Guacamole.Keyboard. * Reference to this Guacamole.Keyboard.
@@ -35,6 +38,25 @@ Guacamole.Keyboard = function(element) {
*/ */
var guac_keyboard = this; var guac_keyboard = this;
/**
* An integer value which uniquely identifies this Guacamole.Keyboard
* instance with respect to other Guacamole.Keyboard instances.
*
* @private
* @type {Number}
*/
var guacKeyboardID = Guacamole.Keyboard._nextID++;
/**
* The name of the property which is added to event objects via markEvent()
* to note that they have already been handled by this Guacamole.Keyboard.
*
* @private
* @constant
* @type {String}
*/
var EVENT_MARKER = '_GUAC_KEYBOARD_HANDLED_BY_' + guacKeyboardID;
/** /**
* Fired whenever the user presses a key with the element associated * Fired whenever the user presses a key with the element associated
* with this Guacamole.Keyboard in focus. * with this Guacamole.Keyboard in focus.
@@ -1134,12 +1156,51 @@ Guacamole.Keyboard = function(element) {
}; };
/**
* Attempts to mark the given Event as having been handled by this
* Guacamole.Keyboard. If the Event has already been marked as handled,
* false is returned.
*
* @param {Event} e
* The Event to mark.
*
* @returns {Boolean}
* true if the given Event was successfully marked, false if the given
* Event was already marked.
*/
var markEvent = function markEvent(e) {
// Fail if event is already marked
if (e[EVENT_MARKER])
return false;
// Mark event otherwise
e[EVENT_MARKER] = true;
return true;
};
/**
* Attaches event listeners to the given Element, automatically translating
* received key, input, and composition events into simple keydown/keyup
* events signalled through this Guacamole.Keyboard's onkeydown and
* onkeyup handlers.
*
* @param {Element} element
* The Element to attach event listeners to for the sake of handling
* key or input events.
*/
this.listenTo = function listenTo(element) {
// When key pressed // When key pressed
element.addEventListener("keydown", function(e) { element.addEventListener("keydown", function(e) {
// Only intercept if handler set // Only intercept if handler set
if (!guac_keyboard.onkeydown) return; if (!guac_keyboard.onkeydown) return;
// Ignore events which have already been handled
if (!markEvent(e)) return;
var keyCode; var keyCode;
if (window.event) keyCode = window.event.keyCode; if (window.event) keyCode = window.event.keyCode;
else if (e.which) keyCode = e.which; else if (e.which) keyCode = e.which;
@@ -1168,6 +1229,9 @@ Guacamole.Keyboard = function(element) {
// Only intercept if handler set // Only intercept if handler set
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return; if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
// Ignore events which have already been handled
if (!markEvent(e)) return;
var charCode; var charCode;
if (window.event) charCode = window.event.keyCode; if (window.event) charCode = window.event.keyCode;
else if (e.which) charCode = e.which; else if (e.which) charCode = e.which;
@@ -1191,6 +1255,9 @@ Guacamole.Keyboard = function(element) {
// Only intercept if handler set // Only intercept if handler set
if (!guac_keyboard.onkeyup) return; if (!guac_keyboard.onkeyup) return;
// Ignore events which have already been handled
if (!markEvent(e)) return;
e.preventDefault(); e.preventDefault();
var keyCode; var keyCode;
@@ -1221,9 +1288,12 @@ Guacamole.Keyboard = function(element) {
// Only intercept if handler set // Only intercept if handler set
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return; if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
// Ignore events which have already been handled
if (!markEvent(e)) return;
// Type all content written // Type all content written
if (e.data && !e.isComposing) { if (e.data && !e.isComposing) {
element.removeEventListener("compositionend", handleComposition, false); element.removeEventListener("compositionend", handleComposition, true);
guac_keyboard.type(e.data); guac_keyboard.type(e.data);
} }
@@ -1244,20 +1314,38 @@ Guacamole.Keyboard = function(element) {
// Only intercept if handler set // Only intercept if handler set
if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return; if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
// Ignore events which have already been handled
if (!markEvent(e)) return;
// Type all content written // Type all content written
if (e.data) { if (e.data) {
element.removeEventListener("input", handleInput, false); element.removeEventListener("input", handleInput, true);
guac_keyboard.type(e.data); guac_keyboard.type(e.data);
} }
}; };
// Automatically type text entered into the wrapped element // Automatically type text entered into the wrapped field
element.addEventListener("input", handleInput, false); element.addEventListener("input", handleInput, true);
element.addEventListener("compositionend", handleComposition, false); element.addEventListener("compositionend", handleComposition, true);
};
// Listen to given element, if any
if (element)
guac_keyboard.listenTo(element);
}; };
/**
* The unique numerical identifier to assign to the next Guacamole.Keyboard
* instance.
*
* @private
* @type {Number}
*/
Guacamole.Keyboard._nextID = 0;
/** /**
* The state of all supported keyboard modifiers. * The state of all supported keyboard modifiers.
* @constructor * @constructor