]>
git.proxmox.com Git - mirror_novnc.git/blob - core/util/events.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2012 Joel Martin
4 * Licensed under MPL 2.0 (see LICENSE.txt)
6 * See README.md for usage and integration instructions.
10 * Cross-browser event and position routines
13 export function getPointerEvent (e
) {
14 return e
.changedTouches
? e
.changedTouches
[0] : e
.touches
? e
.touches
[0] : e
;
17 export function stopEvent (e
) {
22 // Emulate Element.setCapture() when not supported
23 let _captureRecursion
= false;
24 let _captureElem
= null;
25 function _captureProxy(e
) {
26 // Recursion protection as we'll see our own event
27 if (_captureRecursion
) return;
29 // Clone the event as we cannot dispatch an already dispatched event
30 const newEv
= new e
.constructor(e
.type
, e
);
32 _captureRecursion
= true;
33 _captureElem
.dispatchEvent(newEv
);
34 _captureRecursion
= false;
36 // Avoid double events
39 // Respect the wishes of the redirected event handlers
40 if (newEv
.defaultPrevented
) {
44 // Implicitly release the capture on button release
45 if (e
.type
=== "mouseup") {
50 // Follow cursor style of target element
51 function _captureElemChanged() {
52 const captureElem
= document
.getElementById("noVNC_mouse_capture_elem");
53 captureElem
.style
.cursor
= window
.getComputedStyle(_captureElem
).cursor
;
56 const _captureObserver
= new MutationObserver(_captureElemChanged
);
58 let _captureIndex
= 0;
60 export function setCapture (elem
) {
61 if (elem
.setCapture
) {
65 // IE releases capture on 'click' events which might not trigger
66 elem
.addEventListener('mouseup', releaseCapture
);
69 // Release any existing capture in case this method is
70 // called multiple times without coordination
73 let captureElem
= document
.getElementById("noVNC_mouse_capture_elem");
75 if (captureElem
=== null) {
76 captureElem
= document
.createElement("div");
77 captureElem
.id
= "noVNC_mouse_capture_elem";
78 captureElem
.style
.position
= "fixed";
79 captureElem
.style
.top
= "0px";
80 captureElem
.style
.left
= "0px";
81 captureElem
.style
.width
= "100%";
82 captureElem
.style
.height
= "100%";
83 captureElem
.style
.zIndex
= 10000;
84 captureElem
.style
.display
= "none";
85 document
.body
.appendChild(captureElem
);
87 // This is to make sure callers don't get confused by having
88 // our blocking element as the target
89 captureElem
.addEventListener('contextmenu', _captureProxy
);
91 captureElem
.addEventListener('mousemove', _captureProxy
);
92 captureElem
.addEventListener('mouseup', _captureProxy
);
98 // Track cursor and get initial cursor
99 _captureObserver
.observe(elem
, {attributes
:true});
100 _captureElemChanged();
102 captureElem
.style
.display
= "";
104 // We listen to events on window in order to keep tracking if it
105 // happens to leave the viewport
106 window
.addEventListener('mousemove', _captureProxy
);
107 window
.addEventListener('mouseup', _captureProxy
);
111 export function releaseCapture () {
112 if (document
.releaseCapture
) {
114 document
.releaseCapture();
121 // There might be events already queued, so we need to wait for
122 // them to flush. E.g. contextmenu in Microsoft Edge
123 window
.setTimeout((expected
) => {
124 // Only clear it if it's the expected grab (i.e. no one
125 // else has initiated a new grab)
126 if (_captureIndex
=== expected
) {
129 }, 0, _captureIndex
);
131 _captureObserver
.disconnect();
133 const captureElem
= document
.getElementById("noVNC_mouse_capture_elem");
134 captureElem
.style
.display
= "none";
136 window
.removeEventListener('mousemove', _captureProxy
);
137 window
.removeEventListener('mouseup', _captureProxy
);