]> git.proxmox.com Git - mirror_novnc.git/blame - core/util/events.js
feat: add French localization strings
[mirror_novnc.git] / core / util / events.js
CommitLineData
6d6f0db0
SR
1/*
2 * noVNC: HTML5 VNC client
84586c0f 3 * Copyright (C) 2018 The noVNC Authors
6d6f0db0
SR
4 * Licensed under MPL 2.0 (see LICENSE.txt)
5 *
6 * See README.md for usage and integration instructions.
7 */
8
9/*
10 * Cross-browser event and position routines
11 */
12
2c5491e1 13export function getPointerEvent(e) {
6d6f0db0 14 return e.changedTouches ? e.changedTouches[0] : e.touches ? e.touches[0] : e;
8727f598 15}
6d6f0db0 16
2c5491e1 17export function stopEvent(e) {
6d6f0db0
SR
18 e.stopPropagation();
19 e.preventDefault();
8727f598 20}
6d6f0db0
SR
21
22// Emulate Element.setCapture() when not supported
2b5f94fa 23let _captureRecursion = false;
7a96fc37 24let _elementForUnflushedEvents = null;
0c4b3e80 25document.captureElement = null;
858ea4a7 26function _captureProxy(e) {
6d6f0db0
SR
27 // Recursion protection as we'll see our own event
28 if (_captureRecursion) return;
29
30 // Clone the event as we cannot dispatch an already dispatched event
2b5f94fa 31 const newEv = new e.constructor(e.type, e);
6d6f0db0
SR
32
33 _captureRecursion = true;
0c4b3e80
SM
34 if (document.captureElement) {
35 document.captureElement.dispatchEvent(newEv);
7a96fc37
SM
36 } else {
37 _elementForUnflushedEvents.dispatchEvent(newEv);
38 }
6d6f0db0
SR
39 _captureRecursion = false;
40
41 // Avoid double events
42 e.stopPropagation();
43
44 // Respect the wishes of the redirected event handlers
45 if (newEv.defaultPrevented) {
46 e.preventDefault();
47 }
48
49 // Implicitly release the capture on button release
333ad45c 50 if (e.type === "mouseup") {
6d6f0db0
SR
51 releaseCapture();
52 }
8727f598 53}
6d6f0db0
SR
54
55// Follow cursor style of target element
fcd99d04
SM
56function _capturedElemChanged() {
57 const proxyElem = document.getElementById("noVNC_mouse_capture_elem");
0c4b3e80 58 proxyElem.style.cursor = window.getComputedStyle(document.captureElement).cursor;
8727f598 59}
6d6f0db0 60
fcd99d04 61const _captureObserver = new MutationObserver(_capturedElemChanged);
2b5f94fa 62
fcd99d04
SM
63export function setCapture(target) {
64 if (target.setCapture) {
6d6f0db0 65
fcd99d04 66 target.setCapture();
0c4b3e80 67 document.captureElement = target;
6d6f0db0
SR
68 } else {
69 // Release any existing capture in case this method is
70 // called multiple times without coordination
71 releaseCapture();
72
fcd99d04 73 let proxyElem = document.getElementById("noVNC_mouse_capture_elem");
6d6f0db0 74
fcd99d04
SM
75 if (proxyElem === null) {
76 proxyElem = document.createElement("div");
77 proxyElem.id = "noVNC_mouse_capture_elem";
78 proxyElem.style.position = "fixed";
79 proxyElem.style.top = "0px";
80 proxyElem.style.left = "0px";
81 proxyElem.style.width = "100%";
82 proxyElem.style.height = "100%";
83 proxyElem.style.zIndex = 10000;
84 proxyElem.style.display = "none";
85 document.body.appendChild(proxyElem);
6d6f0db0
SR
86
87 // This is to make sure callers don't get confused by having
88 // our blocking element as the target
fcd99d04 89 proxyElem.addEventListener('contextmenu', _captureProxy);
6d6f0db0 90
fcd99d04
SM
91 proxyElem.addEventListener('mousemove', _captureProxy);
92 proxyElem.addEventListener('mouseup', _captureProxy);
6d6f0db0
SR
93 }
94
0c4b3e80 95 document.captureElement = target;
6d6f0db0
SR
96
97 // Track cursor and get initial cursor
fcd99d04
SM
98 _captureObserver.observe(target, {attributes: true});
99 _capturedElemChanged();
6d6f0db0 100
fcd99d04 101 proxyElem.style.display = "";
6d6f0db0
SR
102
103 // We listen to events on window in order to keep tracking if it
104 // happens to leave the viewport
105 window.addEventListener('mousemove', _captureProxy);
106 window.addEventListener('mouseup', _captureProxy);
6d6f0db0 107 }
8727f598 108}
6d6f0db0 109
2c5491e1 110export function releaseCapture() {
6d6f0db0
SR
111 if (document.releaseCapture) {
112
113 document.releaseCapture();
0c4b3e80 114 document.captureElement = null;
6d6f0db0
SR
115
116 } else {
0c4b3e80 117 if (!document.captureElement) {
6d6f0db0
SR
118 return;
119 }
120
7a96fc37
SM
121 // There might be events already queued. The event proxy needs
122 // access to the captured element for these queued events.
123 // E.g. contextmenu (right-click) in Microsoft Edge
124 //
125 // Before removing the capturedElem pointer we save it to a
126 // temporary variable that the unflushed events can use.
0c4b3e80
SM
127 _elementForUnflushedEvents = document.captureElement;
128 document.captureElement = null;
6d6f0db0
SR
129
130 _captureObserver.disconnect();
131
fcd99d04
SM
132 const proxyElem = document.getElementById("noVNC_mouse_capture_elem");
133 proxyElem.style.display = "none";
6d6f0db0
SR
134
135 window.removeEventListener('mousemove', _captureProxy);
136 window.removeEventListener('mouseup', _captureProxy);
6d6f0db0 137 }
8727f598 138}