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:53 UTC
[07/23] guacamole-client git commit: GUACAMOLE-352: Add
Guacamole.Keyboard.InputSink object to serve as a reliable default
destination for input events.
GUACAMOLE-352: Add Guacamole.Keyboard.InputSink object to serve as a reliable default destination for input events.
Project: http://git-wip-us.apache.org/repos/asf/guacamole-client/repo
Commit: http://git-wip-us.apache.org/repos/asf/guacamole-client/commit/f9a639d2
Tree: http://git-wip-us.apache.org/repos/asf/guacamole-client/tree/f9a639d2
Diff: http://git-wip-us.apache.org/repos/asf/guacamole-client/diff/f9a639d2
Branch: refs/heads/master
Commit: f9a639d2014815c8e68bdebb17dd78283d31ee68
Parents: 3d6a3aa
Author: Michael Jumper <mj...@apache.org>
Authored: Sun Dec 17 22:38:10 2017 -0800
Committer: Michael Jumper <mj...@apache.org>
Committed: Tue Jan 16 09:50:54 2018 -0800
----------------------------------------------------------------------
.../src/main/webapp/modules/Keyboard.js | 88 ++++++++++++++++++++
1 file changed, 88 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/guacamole-client/blob/f9a639d2/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 a11050f..ea7128b 100644
--- a/guacamole-common-js/src/main/webapp/modules/Keyboard.js
+++ b/guacamole-common-js/src/main/webapp/modules/Keyboard.js
@@ -1324,3 +1324,91 @@ Guacamole.Keyboard.ModifierState.fromKeyboardEvent = function(e) {
return state;
};
+
+/**
+ * A hidden input field which attempts to keep itself focused at all times,
+ * except when another input field has been intentionally focused, whether
+ * programatically or by the user. The actual underlying input field, returned
+ * by getElement(), may be used as a reliable source of keyboard-related events,
+ * particularly composition and input events which may require a focused input
+ * field to be dispatched at all.
+ *
+ * @constructor
+ */
+Guacamole.Keyboard.InputSink = function InputSink() {
+
+ /**
+ * Reference to this instance of Guacamole.Keyboard.InputSink.
+ *
+ * @private
+ * @type {Guacamole.Keyboard.InputSink}
+ */
+ var sink = this;
+
+ /**
+ * The underlying input field, styled to be invisible.
+ *
+ * @private
+ * @type {Element}
+ */
+ var field = document.createElement('textarea');
+ field.setAttribute('autofocus', 'autofocus');
+ field.style.position = 'fixed';
+ field.style.border = 'none';
+ field.style.width = '10px';
+ field.style.height = '10px';
+ field.style.left = '-10px';
+ field.style.top = '-10px';
+
+ /**
+ * Clears the contents of the underlying field. The actual clearing of the
+ * field is deferred, occurring asynchronously after the call completes.
+ *
+ * @private
+ */
+ var clear = function clear() {
+ window.setTimeout(function deferClear() {
+ field.value = '';
+ }, 0);
+ };
+
+ // Keep internal field contents clear
+ field.addEventListener("change", clear, false);
+ field.addEventListener("input", clear, false);
+
+ /**
+ * Attempts to focus the underlying input field. The focus attempt occurs
+ * asynchronously, and may silently fail depending on browser restrictions.
+ */
+ this.focus = function focus() {
+ window.setTimeout(function deferRefocus() {
+ field.focus(); // Focus must be deferred to work reliably across browsers
+ }, 0);
+ };
+
+ /**
+ * Returns the underlying input field. This input field MUST be manually
+ * added to the DOM for the Guacamole.Keyboard.InputSink to have any
+ * effect.
+ *
+ * @returns {Element}
+ */
+ this.getElement = function getElement() {
+ return field;
+ };
+
+ // Automatically refocus input sink if part of DOM
+ document.addEventListener("click", function refocusSink(e) {
+
+ // Do not refocus if focus is on an input field
+ var focused = document.activeElement;
+ if (focused && focused !== document.body)
+ return;
+
+ // Refocus input sink instead of handling click
+ sink.focus();
+ e.preventDefault();
+
+ }, true);
+
+};