diff options
author | Samuel Mannehed <samuel@cendio.se> | 2017-02-14 16:20:18 +0100 |
---|---|---|
committer | Samuel Mannehed <samuel@cendio.se> | 2017-02-16 13:59:22 +0100 |
commit | 1658466579ee638aa29aaa7adfc18bb64348737c (patch) | |
tree | 12f29ad56857336e7868b2c32c2c920bbd4ca785 | |
parent | 0ee5ca6ebe3ff8fbb8112cd7e235fdbc98ff32bb (diff) | |
download | novnc-1658466579ee638aa29aaa7adfc18bb64348737c.tar.gz |
Improve setCapture polyfill
Fix some corner cases.
Fixes issue #773
-rw-r--r-- | core/util.js | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/core/util.js b/core/util.js index e73eb9d..30f75e1 100644 --- a/core/util.js +++ b/core/util.js @@ -531,6 +531,14 @@ Util._captureProxy = function (e) { Util._captureElem.dispatchEvent(newEv); Util._captureRecursion = false; + // Avoid double events + e.stopPropagation(); + + // Respect the wishes of the redirected event handlers + if (newEv.defaultPrevented) { + e.preventDefault(); + } + // Implicitly release the capture on button release if ((e.type === "mouseup") || (e.type === "touchend")) { Util.releaseCapture(); @@ -547,6 +555,10 @@ Util.setCapture = function (elem) { elem.addEventListener('touchend', Util.releaseCapture); } else { + // Release any existing capture in case this method is + // called multiple times without coordination + Util.releaseCapture(); + // Safari on iOS 9 has a broken constructor for TouchEvent. // We are fine in this case however, since Safari seems to // have some sort of implicit setCapture magic anyway. @@ -572,6 +584,10 @@ Util.setCapture = function (elem) { captureElem.style.display = "none"; document.body.appendChild(captureElem); + // This is to make sure callers don't get confused by having + // our blocking element as the target + captureElem.addEventListener('contextmenu', Util._captureProxy); + captureElem.addEventListener('mousemove', Util._captureProxy); captureElem.addEventListener('mouseup', Util._captureProxy); @@ -598,8 +614,17 @@ Util.releaseCapture = function () { document.releaseCapture(); } else { + if (!Util._captureElem) { + return; + } + + // There might be events already queued, so we need to wait for + // them to flush. E.g. contextmenu in Microsoft Edge + // + // FIXME: What happens if setCapture is called before this fires? + window.setTimeout(function() { Util._captureElem = null; }); + var captureElem = document.getElementById("noVNC_mouse_capture_elem"); - Util._captureElem = null; captureElem.style.display = "none"; window.removeEventListener('mousemove', Util._captureProxy); |