Fix jsdoc, add missing documentation.
[guacamole-common-js.git] / src / main / resources / mouse.js
index b954fd3..9dc2f22 100644 (file)
  *
  * ***** END LICENSE BLOCK ***** */
 
-// Guacamole namespace
+/**
+ * Namespace for all Guacamole JavaScript objects.
+ * @namespace
+ */
 var Guacamole = Guacamole || {};
 
 /**
@@ -56,6 +59,12 @@ Guacamole.Mouse = function(element) {
     var guac_mouse = this;
 
     /**
+     * The number of mousemove events to require before re-enabling mouse
+     * event handling after receiving a touch event.
+     */
+    this.touchMouseThreshold = 3;
+
+    /**
      * The current mouse state. The properties of this state are updated when
      * mouse events fire. This state object is also passed in as a parameter to
      * the handler of any mouse events.
@@ -95,37 +104,11 @@ Guacamole.Mouse = function(element) {
        this.onmousemove = null;
 
     /**
-     * Zero-delay timeout set when mouse events are fired, and canceled when
-     * touch events are detected, in order to prevent touch events registering
-     * as mouse events (some browsers will do this).
-     */
-    var deferred_mouse_event = null;
-
-    /**
-     * Flag which, when set to true, will cause all mouse events to be
-     * ignored. Used to temporarily ignore events when generated by
-     * touch events, and not by a mouse.
-     */
-    var ignore_mouse = false;
-
-    /**
-     * Forces all mouse events to be ignored until the event queue is flushed.
+     * Counter of mouse events to ignore. This decremented by mousemove, and
+     * while non-zero, mouse events will have no effect.
+     * @private
      */
-    function ignorePendingMouseEvents() {
-
-        // Cancel deferred event
-        if (deferred_mouse_event) {
-            window.clearTimeout(deferred_mouse_event);
-            deferred_mouse_event = null;
-        }
-
-        // Ignore all other events until end of event loop
-        ignore_mouse = true;
-        window.setTimeout(function() {
-            ignore_mouse = false;
-        }, 0);
-
-    }
+    var ignore_mouse = 0;
 
     function cancelEvent(e) {
         e.stopPropagation();
@@ -142,20 +125,16 @@ Guacamole.Mouse = function(element) {
 
         cancelEvent(e);
 
-        // If artificial event detected, ignore currently pending events
-        if (deferred_mouse_event)
-            ignorePendingMouseEvents();
-
-        if (ignore_mouse)
+        // If ignoring events, decrement counter
+        if (ignore_mouse) {
+            ignore_mouse--;
             return;
+        }
 
         guac_mouse.currentState.fromClientPosition(element, e.clientX, e.clientY);
 
         if (guac_mouse.onmousemove)
-            deferred_mouse_event = window.setTimeout(function() {
-                guac_mouse.onmousemove(guac_mouse.currentState);
-                deferred_mouse_event = null;
-            }, 0);
+            guac_mouse.onmousemove(guac_mouse.currentState);
 
     }, false);
 
@@ -163,10 +142,7 @@ Guacamole.Mouse = function(element) {
 
         cancelEvent(e);
 
-        // If artificial event detected, ignore currently pending events
-        if (deferred_mouse_event)
-            ignorePendingMouseEvents();
-
+        // Do not handle if ignoring events
         if (ignore_mouse)
             return;
 
@@ -183,10 +159,7 @@ Guacamole.Mouse = function(element) {
         }
 
         if (guac_mouse.onmousedown)
-            deferred_mouse_event = window.setTimeout(function() {
-                guac_mouse.onmousedown(guac_mouse.currentState);
-                deferred_mouse_event = null;
-            }, 0);
+            guac_mouse.onmousedown(guac_mouse.currentState);
 
     }, false);
 
@@ -194,10 +167,7 @@ Guacamole.Mouse = function(element) {
 
         cancelEvent(e);
 
-        // If artificial event detected, ignore currently pending events
-        if (deferred_mouse_event)
-            ignorePendingMouseEvents();
-
+        // Do not handle if ignoring events
         if (ignore_mouse)
             return;
 
@@ -214,10 +184,7 @@ Guacamole.Mouse = function(element) {
         }
 
         if (guac_mouse.onmouseup)
-            deferred_mouse_event = window.setTimeout(function() {
-                guac_mouse.onmouseup(guac_mouse.currentState);
-                deferred_mouse_event = null;
-            }, 0);
+            guac_mouse.onmouseup(guac_mouse.currentState);
 
     }, false);
 
@@ -256,8 +223,9 @@ Guacamole.Mouse = function(element) {
         cancelEvent(e);
     }, false);
 
-
     // Ignore all pending mouse events when touch events are the apparent source
+    function ignorePendingMouseEvents() { ignore_mouse = guac_mouse.touchMouseThreshold; }
+
     element.addEventListener("touchmove",  ignorePendingMouseEvents, false);
     element.addEventListener("touchstart", ignorePendingMouseEvents, false);
     element.addEventListener("touchend",   ignorePendingMouseEvents, false);
@@ -801,12 +769,15 @@ Guacamole.Mouse.State = function(x, y, left, middle, right, up, down) {
             parent = parent.offsetParent;
         }
 
-        // Offset by document scroll amount
-        var documentScrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
-        var documentScrollTop = document.body.scrollTop || document.documentElement.scrollTop;
+        // Element ultimately depends on positioning within document body,
+        // take document scroll into account. 
+        if (parent) {
+            var documentScrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
+            var documentScrollTop = document.body.scrollTop || document.documentElement.scrollTop;
 
-        guac_state.x -= parent.offsetLeft - documentScrollLeft;
-        guac_state.y -= parent.offsetTop  - documentScrollTop;
+            guac_state.x -= parent.offsetLeft - documentScrollLeft;
+            guac_state.y -= parent.offsetTop  - documentScrollTop;
+        }
 
     };