mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUACAMOLE-352: Refactor Guacamole.Keyboard.InputSink to Guacamole.InputSink.
This commit is contained in:
		
							
								
								
									
										128
									
								
								guacamole-common-js/src/main/webapp/modules/InputSink.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								guacamole-common-js/src/main/webapp/modules/InputSink.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | ||||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one | ||||
|  * or more contributor license agreements.  See the NOTICE file | ||||
|  * distributed with this work for additional information | ||||
|  * regarding copyright ownership.  The ASF licenses this file | ||||
|  * to you under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance | ||||
|  * with the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, | ||||
|  * software distributed under the License is distributed on an | ||||
|  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
|  * KIND, either express or implied.  See the License for the | ||||
|  * specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  */ | ||||
|  | ||||
| var Guacamole = Guacamole || {}; | ||||
|  | ||||
| /** | ||||
|  * 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.InputSink = function InputSink() { | ||||
|  | ||||
|     /** | ||||
|      * Reference to this instance of Guacamole.InputSink. | ||||
|      * | ||||
|      * @private | ||||
|      * @type {Guacamole.InputSink} | ||||
|      */ | ||||
|     var sink = this; | ||||
|  | ||||
|     /** | ||||
|      * The underlying input field, styled to be invisible. | ||||
|      * | ||||
|      * @private | ||||
|      * @type {Element} | ||||
|      */ | ||||
|     var field = document.createElement('textarea'); | ||||
|     field.style.position   = 'fixed'; | ||||
|     field.style.outline    = 'none'; | ||||
|     field.style.border     = 'none'; | ||||
|     field.style.margin     = '0'; | ||||
|     field.style.padding    = '0'; | ||||
|     field.style.height     = '0'; | ||||
|     field.style.width      = '0'; | ||||
|     field.style.left       = '0'; | ||||
|     field.style.bottom     = '0'; | ||||
|     field.style.resize     = 'none'; | ||||
|     field.style.background = 'transparent'; | ||||
|     field.style.color      = 'transparent'; | ||||
|  | ||||
|     // Keep field clear when modified via normal keypresses | ||||
|     field.addEventListener("keypress", function clearKeypress(e) { | ||||
|         field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Keep field clear when modofied via composition events | ||||
|     field.addEventListener("compositionend", function clearCompletedComposition(e) { | ||||
|         if (e.data) | ||||
|             field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Keep field clear when modofied via input events | ||||
|     field.addEventListener("input", function clearCompletedInput(e) { | ||||
|         if (e.data && !e.isComposing) | ||||
|             field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Whenever focus is gained, automatically click to ensure cursor is | ||||
|     // actually placed within the field (the field may simply be highlighted or | ||||
|     // outlined otherwise) | ||||
|     field.addEventListener("focus", function focusReceived() { | ||||
|         window.setTimeout(function deferRefocus() { | ||||
|             field.click(); | ||||
|             field.select(); | ||||
|         }, 0); | ||||
|     }, true); | ||||
|  | ||||
|     /** | ||||
|      * 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.InputSink to have any effect. | ||||
|      * | ||||
|      * @returns {Element} | ||||
|      */ | ||||
|     this.getElement = function getElement() { | ||||
|         return field; | ||||
|     }; | ||||
|  | ||||
|     // Automatically refocus input sink if part of DOM | ||||
|     document.addEventListener("keydown", function refocusSink(e) { | ||||
|  | ||||
|         // Do not refocus if focus is on an input field | ||||
|         var focused = document.activeElement; | ||||
|         if (focused && focused !== document.body) { | ||||
|  | ||||
|             // Only consider focused input fields which are actually visible | ||||
|             var rect = focused.getBoundingClientRect(); | ||||
|             if (rect.left + rect.width > 0 && rect.top + rect.height > 0) | ||||
|                 return; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Refocus input sink instead of handling click | ||||
|         sink.focus(); | ||||
|  | ||||
|     }, true); | ||||
|  | ||||
| }; | ||||
| @@ -1412,112 +1412,3 @@ 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.style.position   = 'fixed'; | ||||
|     field.style.outline    = 'none'; | ||||
|     field.style.border     = 'none'; | ||||
|     field.style.margin     = '0'; | ||||
|     field.style.padding    = '0'; | ||||
|     field.style.height     = '0'; | ||||
|     field.style.width      = '0'; | ||||
|     field.style.left       = '0'; | ||||
|     field.style.bottom     = '0'; | ||||
|     field.style.resize     = 'none'; | ||||
|     field.style.background = 'transparent'; | ||||
|     field.style.color      = 'transparent'; | ||||
|  | ||||
|     // Keep field clear when modified via normal keypresses | ||||
|     field.addEventListener("keypress", function clearKeypress(e) { | ||||
|         field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Keep field clear when modofied via composition events | ||||
|     field.addEventListener("compositionend", function clearCompletedComposition(e) { | ||||
|         if (e.data) | ||||
|             field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Keep field clear when modofied via input events | ||||
|     field.addEventListener("input", function clearCompletedInput(e) { | ||||
|         if (e.data && !e.isComposing) | ||||
|             field.value = ''; | ||||
|     }, false); | ||||
|  | ||||
|     // Whenever focus is gained, automatically click to ensure cursor is | ||||
|     // actually placed within the field (the field may simply be highlighted or | ||||
|     // outlined otherwise) | ||||
|     field.addEventListener("focus", function focusReceived() { | ||||
|         window.setTimeout(function deferRefocus() { | ||||
|             field.click(); | ||||
|             field.select(); | ||||
|         }, 0); | ||||
|     }, true); | ||||
|  | ||||
|     /** | ||||
|      * 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("keydown", function refocusSink(e) { | ||||
|  | ||||
|         // Do not refocus if focus is on an input field | ||||
|         var focused = document.activeElement; | ||||
|         if (focused && focused !== document.body) { | ||||
|  | ||||
|             // Only consider focused input fields which are actually visible | ||||
|             var rect = focused.getBoundingClientRect(); | ||||
|             if (rect.left + rect.width > 0 && rect.top + rect.height > 0) | ||||
|                 return; | ||||
|  | ||||
|         } | ||||
|  | ||||
|         // Refocus input sink instead of handling click | ||||
|         sink.focus(); | ||||
|  | ||||
|     }, true); | ||||
|  | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user