You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@guacamole.apache.org by vn...@apache.org on 2018/01/16 18:41:56 UTC
[10/23] guacamole-client git commit: GUACAMOLE-352: Allow additional
elements to be added to a single Guacamole.Keyboard.
GUACAMOLE-352: Allow additional elements to be added to a single Guacamole.Keyboard.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/2d26d24d
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/2d26d24d
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/2d26d24d
Branch: refs/heads/master
Commit: 2d26d24dda30ba3679c3259e920487fdf28865bf
Parents: 0582290
Author: Michael Jumper <mj...@apache.org>
Authored: Mon Dec 18 10:58:50 2017 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 16 10:20:41 2018 -0800
----------------------------------------------------------------------
.../src/main/webapp/modules/Keyboard.js | 272 ++++++++++++-------
1 file changed, 180 insertions(+), 92 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/2d26d24d/guacamole-common-js/src/main/webapp/modules/Keyboard.js
----------------------------------------------------------------------
diff --git a/guacamole-common-js/src/main/webapp/modules/Keyboard.js b/guacamole-common-js/src/main/webapp/modules/Keyboard.js
index 3cc28f8..c25a1fd 100644
--- a/guacamole-common-js/src/main/webapp/modules/Keyboard.js
+++ b/guacamole-common-js/src/main/webapp/modules/Keyboard.js
@@ -25,9 +25,12 @@ var Guacamole = Guacamole || {};
* which represent keys as their corresponding X11 keysym.
*
* @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.
@@ -36,6 +39,25 @@ Guacamole.Keyboard = function(element) {
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
* with this Guacamole.Keyboard in focus.
*
@@ -1134,131 +1156,197 @@ Guacamole.Keyboard = function(element) {
};
- // When key pressed
- element.addEventListener("keydown", function(e) {
+ /**
+ * 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
+ element.addEventListener("keydown", function(e) {
- // Only intercept if handler set
- if (!guac_keyboard.onkeydown) return;
+ // Only intercept if handler set
+ if (!guac_keyboard.onkeydown) return;
- var keyCode;
- if (window.event) keyCode = window.event.keyCode;
- else if (e.which) keyCode = e.which;
+ // Ignore events which have already been handled
+ if (!markEvent(e)) return;
- // Fix modifier states
- syncModifierStates(e);
+ var keyCode;
+ if (window.event) keyCode = window.event.keyCode;
+ else if (e.which) keyCode = e.which;
- // Ignore (but do not prevent) the "composition" keycode sent by some
- // browsers when an IME is in use (see: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
- if (keyCode === 229)
- return;
+ // Fix modifier states
+ syncModifierStates(e);
- // Log event
- var keydownEvent = new KeydownEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
- eventLog.push(keydownEvent);
+ // Ignore (but do not prevent) the "composition" keycode sent by some
+ // browsers when an IME is in use (see: http://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
+ if (keyCode === 229)
+ return;
- // Interpret as many events as possible, prevent default if indicated
- if (interpret_events())
- e.preventDefault();
+ // Log event
+ var keydownEvent = new KeydownEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
+ eventLog.push(keydownEvent);
- }, true);
+ // Interpret as many events as possible, prevent default if indicated
+ if (interpret_events())
+ e.preventDefault();
+
+ }, true);
+
+ // When key pressed
+ element.addEventListener("keypress", function(e) {
+
+ // Only intercept if handler set
+ if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
+
+ // Ignore events which have already been handled
+ if (!markEvent(e)) return;
- // When key pressed
- element.addEventListener("keypress", function(e) {
+ var charCode;
+ if (window.event) charCode = window.event.keyCode;
+ else if (e.which) charCode = e.which;
- // Only intercept if handler set
- if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
+ // Fix modifier states
+ syncModifierStates(e);
- var charCode;
- if (window.event) charCode = window.event.keyCode;
- else if (e.which) charCode = e.which;
+ // Log event
+ var keypressEvent = new KeypressEvent(charCode);
+ eventLog.push(keypressEvent);
- // Fix modifier states
- syncModifierStates(e);
+ // Interpret as many events as possible, prevent default if indicated
+ if (interpret_events())
+ e.preventDefault();
- // Log event
- var keypressEvent = new KeypressEvent(charCode);
- eventLog.push(keypressEvent);
+ }, true);
+
+ // When key released
+ element.addEventListener("keyup", function(e) {
+
+ // Only intercept if handler set
+ if (!guac_keyboard.onkeyup) return;
+
+ // Ignore events which have already been handled
+ if (!markEvent(e)) return;
- // Interpret as many events as possible, prevent default if indicated
- if (interpret_events())
e.preventDefault();
- }, true);
+ var keyCode;
+ if (window.event) keyCode = window.event.keyCode;
+ else if (e.which) keyCode = e.which;
- // When key released
- element.addEventListener("keyup", function(e) {
+ // Fix modifier states
+ syncModifierStates(e);
- // Only intercept if handler set
- if (!guac_keyboard.onkeyup) return;
+ // Log event, call for interpretation
+ var keyupEvent = new KeyupEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
+ eventLog.push(keyupEvent);
+ interpret_events();
- e.preventDefault();
+ }, true);
- var keyCode;
- if (window.event) keyCode = window.event.keyCode;
- else if (e.which) keyCode = e.which;
-
- // Fix modifier states
- syncModifierStates(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) {
- // Log event, call for interpretation
- var keyupEvent = new KeyupEvent(keyCode, e.keyIdentifier, e.key, getEventLocation(e));
- eventLog.push(keyupEvent);
- interpret_events();
+ // Only intercept if handler set
+ if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
- }, true);
+ // Ignore events which have already been handled
+ if (!markEvent(e)) return;
- /**
- * 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) {
+ // Type all content written
+ if (e.data && !e.isComposing) {
+ element.removeEventListener("compositionend", handleComposition, true);
+ guac_keyboard.type(e.data);
+ }
- // Only intercept if handler set
- if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
+ };
- // Type all content written
- if (e.data && !e.isComposing) {
- element.removeEventListener("compositionend", handleComposition, false);
- guac_keyboard.type(e.data);
- }
+ /**
+ * 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;
- /**
- * 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) {
+ // Ignore events which have already been handled
+ if (!markEvent(e)) return;
- // Only intercept if handler set
- if (!guac_keyboard.onkeydown && !guac_keyboard.onkeyup) return;
+ // Type all content written
+ if (e.data) {
+ element.removeEventListener("input", handleInput, true);
+ guac_keyboard.type(e.data);
+ }
- // Type all content written
- if (e.data) {
- element.removeEventListener("input", handleInput, false);
- guac_keyboard.type(e.data);
- }
+ };
+
+ // Automatically type text entered into the wrapped field
+ element.addEventListener("input", handleInput, true);
+ element.addEventListener("compositionend", handleComposition, true);
};
- // Automatically type text entered into the wrapped element
- element.addEventListener("input", handleInput, false);
- element.addEventListener("compositionend", handleComposition, false);
+ // 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.
* @constructor
*/