react-native-gesture-handler 2.15.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/RNGestureHandler.podspec +2 -23
  2. package/android/build.gradle +1 -1
  3. package/android/noreanimated/src/main/java/com/swmansion/gesturehandler/ReanimatedEventDispatcher.kt +2 -0
  4. package/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerDelegate.java +9 -0
  5. package/android/paper/src/main/java/com/facebook/react/viewmanagers/RNGestureHandlerButtonManagerInterface.java +3 -0
  6. package/android/src/main/java/com/swmansion/gesturehandler/RNGestureHandlerPackage.kt +11 -6
  7. package/android/src/main/java/com/swmansion/gesturehandler/core/DiagonalDirections.kt +8 -0
  8. package/android/src/main/java/com/swmansion/gesturehandler/core/FlingGestureHandler.kt +65 -24
  9. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandler.kt +86 -22
  10. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureHandlerOrchestrator.kt +54 -29
  11. package/android/src/main/java/com/swmansion/gesturehandler/core/GestureUtils.kt +3 -0
  12. package/android/src/main/java/com/swmansion/gesturehandler/core/LongPressGestureHandler.kt +5 -1
  13. package/android/src/main/java/com/swmansion/gesturehandler/core/PanGestureHandler.kt +5 -1
  14. package/android/src/main/java/com/swmansion/gesturehandler/core/TapGestureHandler.kt +7 -3
  15. package/android/src/main/java/com/swmansion/gesturehandler/core/Vector.kt +66 -0
  16. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerButtonViewManager.kt +119 -19
  17. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEnabledRootView.kt +2 -2
  18. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerEvent.kt +1 -4
  19. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerModule.kt +8 -5
  20. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootHelper.kt +7 -4
  21. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerRootView.kt +1 -1
  22. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerStateChangeEvent.kt +1 -4
  23. package/android/src/main/java/com/swmansion/gesturehandler/react/RNGestureHandlerTouchEvent.kt +4 -7
  24. package/android/src/main/java/com/swmansion/gesturehandler/react/eventbuilders/GestureHandlerEventDataBuilder.kt +3 -0
  25. package/android/src/main/jni/cpp-adapter.cpp +18 -22
  26. package/apple/Handlers/RNFlingHandler.m +5 -4
  27. package/apple/Handlers/RNForceTouchHandler.m +3 -1
  28. package/apple/Handlers/RNHoverHandler.m +2 -1
  29. package/apple/Handlers/RNLongPressHandler.m +8 -14
  30. package/apple/Handlers/RNManualHandler.m +1 -0
  31. package/apple/Handlers/RNNativeViewHandler.mm +9 -7
  32. package/apple/Handlers/RNPanHandler.m +7 -2
  33. package/apple/Handlers/RNPinchHandler.m +50 -26
  34. package/apple/Handlers/RNRotationHandler.m +43 -29
  35. package/apple/Handlers/RNTapHandler.m +6 -4
  36. package/apple/RNGestureHandler.h +9 -0
  37. package/apple/RNGestureHandler.m +41 -4
  38. package/apple/RNGestureHandlerEvents.h +18 -9
  39. package/apple/RNGestureHandlerEvents.m +29 -11
  40. package/apple/RNGestureHandlerManager.h +5 -0
  41. package/apple/RNGestureHandlerManager.mm +32 -6
  42. package/apple/RNGestureHandlerModule.h +5 -3
  43. package/apple/RNGestureHandlerModule.mm +33 -19
  44. package/apple/RNGestureHandlerPointerType.h +8 -0
  45. package/lib/commonjs/Directions.js +19 -6
  46. package/lib/commonjs/Directions.js.map +1 -1
  47. package/lib/commonjs/PointerType.js +16 -0
  48. package/lib/commonjs/PointerType.js.map +1 -0
  49. package/lib/commonjs/RNGestureHandlerModule.web.js +7 -61
  50. package/lib/commonjs/RNGestureHandlerModule.web.js.map +1 -1
  51. package/lib/commonjs/components/DrawerLayout.js.map +1 -1
  52. package/lib/commonjs/components/GestureHandlerRootView.android.js +17 -2
  53. package/lib/commonjs/components/GestureHandlerRootView.android.js.map +1 -1
  54. package/lib/commonjs/components/GestureHandlerRootView.js +15 -2
  55. package/lib/commonjs/components/GestureHandlerRootView.js.map +1 -1
  56. package/lib/commonjs/components/GestureHandlerRootView.web.js +15 -2
  57. package/lib/commonjs/components/GestureHandlerRootView.web.js.map +1 -1
  58. package/lib/commonjs/components/Swipeable.js +3 -1
  59. package/lib/commonjs/components/Swipeable.js.map +1 -1
  60. package/lib/commonjs/components/touchables/GenericTouchable.js +1 -0
  61. package/lib/commonjs/components/touchables/GenericTouchable.js.map +1 -1
  62. package/lib/commonjs/getShadowNodeFromRef.js +19 -2
  63. package/lib/commonjs/getShadowNodeFromRef.js.map +1 -1
  64. package/lib/commonjs/handlers/createHandler.js +5 -0
  65. package/lib/commonjs/handlers/createHandler.js.map +1 -1
  66. package/lib/commonjs/handlers/customDirectEventTypes.js +14 -0
  67. package/lib/commonjs/handlers/customDirectEventTypes.js.map +1 -0
  68. package/lib/commonjs/handlers/customDirectEventTypes.web.js +11 -0
  69. package/lib/commonjs/handlers/customDirectEventTypes.web.js.map +1 -0
  70. package/lib/commonjs/handlers/gestureHandlerCommon.js +13 -2
  71. package/lib/commonjs/handlers/gestureHandlerCommon.js.map +1 -1
  72. package/lib/commonjs/handlers/gestures/GestureDetector.js +10 -0
  73. package/lib/commonjs/handlers/gestures/GestureDetector.js.map +1 -1
  74. package/lib/commonjs/handlers/gestures/gesture.js.map +1 -1
  75. package/lib/commonjs/index.js +11 -3
  76. package/lib/commonjs/index.js.map +1 -1
  77. package/lib/commonjs/mocks.js +2 -0
  78. package/lib/commonjs/mocks.js.map +1 -1
  79. package/lib/commonjs/specs/NativeRNGestureHandlerModule.js.map +1 -1
  80. package/lib/commonjs/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  81. package/lib/commonjs/web/Gestures.js +66 -0
  82. package/lib/commonjs/web/Gestures.js.map +1 -0
  83. package/lib/commonjs/web/constants.js +3 -8
  84. package/lib/commonjs/web/constants.js.map +1 -1
  85. package/lib/commonjs/web/handlers/FlingGestureHandler.js +36 -12
  86. package/lib/commonjs/web/handlers/FlingGestureHandler.js.map +1 -1
  87. package/lib/commonjs/web/handlers/GestureHandler.js +10 -5
  88. package/lib/commonjs/web/handlers/GestureHandler.js.map +1 -1
  89. package/lib/commonjs/web/handlers/IGestureHandler.js +2 -0
  90. package/lib/commonjs/web/handlers/IGestureHandler.js.map +1 -0
  91. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js +5 -6
  92. package/lib/commonjs/web/handlers/NativeViewGestureHandler.js.map +1 -1
  93. package/lib/commonjs/web/interfaces.js +1 -23
  94. package/lib/commonjs/web/interfaces.js.map +1 -1
  95. package/lib/commonjs/web/tools/EventManager.js.map +1 -1
  96. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js +117 -118
  97. package/lib/commonjs/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  98. package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js +10 -5
  99. package/lib/commonjs/web/tools/GestureHandlerWebDelegate.js.map +1 -1
  100. package/lib/commonjs/web/tools/InteractionManager.js +12 -3
  101. package/lib/commonjs/web/tools/InteractionManager.js.map +1 -1
  102. package/lib/commonjs/web/tools/NodeManager.js.map +1 -1
  103. package/lib/commonjs/web/tools/PointerEventManager.js +77 -27
  104. package/lib/commonjs/web/tools/PointerEventManager.js.map +1 -1
  105. package/lib/commonjs/web/tools/TouchEventManager.js +29 -6
  106. package/lib/commonjs/web/tools/TouchEventManager.js.map +1 -1
  107. package/lib/commonjs/web/tools/Vector.js +58 -0
  108. package/lib/commonjs/web/tools/Vector.js.map +1 -0
  109. package/lib/commonjs/web/utils.js +14 -0
  110. package/lib/commonjs/web/utils.js.map +1 -1
  111. package/lib/commonjs/web_hammer/NodeManager.js.map +1 -1
  112. package/lib/module/Directions.js +16 -4
  113. package/lib/module/Directions.js.map +1 -1
  114. package/lib/module/PointerType.js +9 -0
  115. package/lib/module/PointerType.js.map +1 -0
  116. package/lib/module/RNGestureHandlerModule.web.js +2 -39
  117. package/lib/module/RNGestureHandlerModule.web.js.map +1 -1
  118. package/lib/module/components/DrawerLayout.js.map +1 -1
  119. package/lib/module/components/GestureHandlerRootView.android.js +15 -2
  120. package/lib/module/components/GestureHandlerRootView.android.js.map +1 -1
  121. package/lib/module/components/GestureHandlerRootView.js +15 -3
  122. package/lib/module/components/GestureHandlerRootView.js.map +1 -1
  123. package/lib/module/components/GestureHandlerRootView.web.js +15 -3
  124. package/lib/module/components/GestureHandlerRootView.web.js.map +1 -1
  125. package/lib/module/components/Swipeable.js +3 -1
  126. package/lib/module/components/Swipeable.js.map +1 -1
  127. package/lib/module/components/touchables/GenericTouchable.js +1 -0
  128. package/lib/module/components/touchables/GenericTouchable.js.map +1 -1
  129. package/lib/module/getShadowNodeFromRef.js +19 -2
  130. package/lib/module/getShadowNodeFromRef.js.map +1 -1
  131. package/lib/module/handlers/createHandler.js +5 -1
  132. package/lib/module/handlers/createHandler.js.map +1 -1
  133. package/lib/module/handlers/customDirectEventTypes.js +3 -0
  134. package/lib/module/handlers/customDirectEventTypes.js.map +1 -0
  135. package/lib/module/handlers/customDirectEventTypes.web.js +5 -0
  136. package/lib/module/handlers/customDirectEventTypes.web.js.map +1 -0
  137. package/lib/module/handlers/gestureHandlerCommon.js +11 -1
  138. package/lib/module/handlers/gestureHandlerCommon.js.map +1 -1
  139. package/lib/module/handlers/gestures/GestureDetector.js +10 -0
  140. package/lib/module/handlers/gestures/GestureDetector.js.map +1 -1
  141. package/lib/module/handlers/gestures/gesture.js.map +1 -1
  142. package/lib/module/index.js +2 -1
  143. package/lib/module/index.js.map +1 -1
  144. package/lib/module/mocks.js +2 -0
  145. package/lib/module/mocks.js.map +1 -1
  146. package/lib/module/specs/NativeRNGestureHandlerModule.js.map +1 -1
  147. package/lib/module/specs/RNGestureHandlerButtonNativeComponent.js.map +1 -1
  148. package/lib/module/web/Gestures.js +39 -0
  149. package/lib/module/web/Gestures.js.map +1 -0
  150. package/lib/module/web/constants.js +1 -6
  151. package/lib/module/web/constants.js.map +1 -1
  152. package/lib/module/web/handlers/FlingGestureHandler.js +34 -12
  153. package/lib/module/web/handlers/FlingGestureHandler.js.map +1 -1
  154. package/lib/module/web/handlers/GestureHandler.js +7 -4
  155. package/lib/module/web/handlers/GestureHandler.js.map +1 -1
  156. package/lib/module/web/handlers/IGestureHandler.js +2 -0
  157. package/lib/module/web/handlers/IGestureHandler.js.map +1 -0
  158. package/lib/module/web/handlers/NativeViewGestureHandler.js +5 -6
  159. package/lib/module/web/handlers/NativeViewGestureHandler.js.map +1 -1
  160. package/lib/module/web/interfaces.js +0 -20
  161. package/lib/module/web/interfaces.js.map +1 -1
  162. package/lib/module/web/tools/EventManager.js.map +1 -1
  163. package/lib/module/web/tools/GestureHandlerOrchestrator.js +116 -117
  164. package/lib/module/web/tools/GestureHandlerOrchestrator.js.map +1 -1
  165. package/lib/module/web/tools/GestureHandlerWebDelegate.js +9 -4
  166. package/lib/module/web/tools/GestureHandlerWebDelegate.js.map +1 -1
  167. package/lib/module/web/tools/InteractionManager.js +9 -3
  168. package/lib/module/web/tools/InteractionManager.js.map +1 -1
  169. package/lib/module/web/tools/NodeManager.js.map +1 -1
  170. package/lib/module/web/tools/PointerEventManager.js +75 -27
  171. package/lib/module/web/tools/PointerEventManager.js.map +1 -1
  172. package/lib/module/web/tools/TouchEventManager.js +28 -6
  173. package/lib/module/web/tools/TouchEventManager.js.map +1 -1
  174. package/lib/module/web/tools/Vector.js +47 -0
  175. package/lib/module/web/tools/Vector.js.map +1 -0
  176. package/lib/module/web/utils.js +4 -0
  177. package/lib/module/web/utils.js.map +1 -1
  178. package/lib/module/web_hammer/NodeManager.js.map +1 -1
  179. package/lib/typescript/Directions.d.ts +7 -0
  180. package/lib/typescript/PointerType.d.ts +6 -0
  181. package/lib/typescript/RNGestureHandlerModule.web.d.ts +4 -39
  182. package/lib/typescript/components/DrawerLayout.d.ts +1 -2
  183. package/lib/typescript/components/GestureHandlerRootView.android.d.ts +1 -1
  184. package/lib/typescript/components/GestureHandlerRootView.d.ts +1 -1
  185. package/lib/typescript/components/GestureHandlerRootView.web.d.ts +1 -1
  186. package/lib/typescript/components/touchables/GenericTouchable.d.ts +2 -1
  187. package/lib/typescript/getShadowNodeFromRef.d.ts +1 -1
  188. package/lib/typescript/handlers/NativeViewGestureHandler.d.ts +1 -1
  189. package/lib/typescript/handlers/customDirectEventTypes.d.ts +1 -0
  190. package/lib/typescript/handlers/customDirectEventTypes.web.d.ts +2 -0
  191. package/lib/typescript/handlers/gestureHandlerCommon.d.ts +13 -2
  192. package/lib/typescript/handlers/gestures/GestureDetector.d.ts +2 -1
  193. package/lib/typescript/handlers/gestures/gesture.d.ts +1 -2
  194. package/lib/typescript/index.d.ts +2 -1
  195. package/lib/typescript/mocks.d.ts +1 -0
  196. package/lib/typescript/specs/NativeRNGestureHandlerModule.d.ts +6 -6
  197. package/lib/typescript/specs/RNGestureHandlerButtonNativeComponent.d.ts +4 -1
  198. package/lib/typescript/web/Gestures.d.ts +36 -0
  199. package/lib/typescript/web/constants.d.ts +1 -6
  200. package/lib/typescript/web/handlers/FlingGestureHandler.d.ts +3 -3
  201. package/lib/typescript/web/handlers/GestureHandler.d.ts +12 -9
  202. package/lib/typescript/web/handlers/IGestureHandler.d.ts +38 -0
  203. package/lib/typescript/web/handlers/NativeViewGestureHandler.d.ts +1 -0
  204. package/lib/typescript/web/interfaces.d.ts +9 -16
  205. package/lib/typescript/web/tools/EventManager.d.ts +15 -12
  206. package/lib/typescript/web/tools/GestureHandlerDelegate.d.ts +3 -4
  207. package/lib/typescript/web/tools/GestureHandlerOrchestrator.d.ts +7 -5
  208. package/lib/typescript/web/tools/GestureHandlerWebDelegate.d.ts +3 -3
  209. package/lib/typescript/web/tools/InteractionManager.d.ts +6 -6
  210. package/lib/typescript/web/tools/NodeManager.d.ts +4 -3
  211. package/lib/typescript/web/tools/PointerEventManager.d.ts +11 -2
  212. package/lib/typescript/web/tools/TouchEventManager.d.ts +6 -1
  213. package/lib/typescript/web/tools/Vector.d.ts +15 -0
  214. package/lib/typescript/web/utils.d.ts +6 -4
  215. package/lib/typescript/web_hammer/NodeManager.d.ts +1 -1
  216. package/package.json +2 -1
  217. package/src/Directions.ts +21 -4
  218. package/src/PointerType.ts +6 -0
  219. package/src/RNGestureHandlerModule.web.ts +3 -44
  220. package/src/components/DrawerLayout.tsx +1 -1
  221. package/src/components/GestureHandlerRootView.android.tsx +13 -5
  222. package/src/components/GestureHandlerRootView.tsx +10 -5
  223. package/src/components/GestureHandlerRootView.web.tsx +10 -5
  224. package/src/components/Swipeable.tsx +2 -0
  225. package/src/components/touchables/GenericTouchable.tsx +3 -0
  226. package/src/getShadowNodeFromRef.ts +28 -6
  227. package/src/handlers/createHandler.tsx +14 -2
  228. package/src/handlers/customDirectEventTypes.ts +2 -0
  229. package/src/handlers/customDirectEventTypes.web.ts +5 -0
  230. package/src/handlers/gestureHandlerCommon.ts +30 -1
  231. package/src/handlers/gestures/GestureDetector.tsx +15 -0
  232. package/src/handlers/gestures/gesture.ts +1 -1
  233. package/src/index.ts +2 -1
  234. package/src/mocks.ts +2 -0
  235. package/src/specs/NativeRNGestureHandlerModule.ts +8 -8
  236. package/src/specs/RNGestureHandlerButtonNativeComponent.ts +4 -0
  237. package/src/web/Gestures.ts +41 -0
  238. package/src/web/constants.ts +1 -7
  239. package/src/web/handlers/FlingGestureHandler.ts +54 -24
  240. package/src/web/handlers/GestureHandler.ts +17 -12
  241. package/src/web/handlers/IGestureHandler.ts +50 -0
  242. package/src/web/handlers/NativeViewGestureHandler.ts +5 -6
  243. package/src/web/interfaces.ts +15 -17
  244. package/src/web/tools/EventManager.ts +16 -14
  245. package/src/web/tools/GestureHandlerDelegate.ts +3 -4
  246. package/src/web/tools/GestureHandlerOrchestrator.ts +162 -147
  247. package/src/web/tools/GestureHandlerWebDelegate.ts +14 -9
  248. package/src/web/tools/InteractionManager.ts +18 -12
  249. package/src/web/tools/NodeManager.ts +4 -3
  250. package/src/web/tools/PointerEventManager.ts +189 -154
  251. package/src/web/tools/TouchEventManager.ts +128 -120
  252. package/src/web/tools/Vector.ts +60 -0
  253. package/src/web/utils.ts +16 -4
  254. package/src/web_hammer/NodeManager.ts +1 -1
@@ -1,17 +1,19 @@
1
- import {
2
- AdaptedEvent,
3
- EventTypes,
4
- MouseButton,
5
- PointerType,
6
- } from '../interfaces';
7
1
  import EventManager from './EventManager';
8
- import { isPointerInBounds } from '../utils';
2
+ import { MouseButton } from '../../handlers/gestureHandlerCommon';
3
+ import { AdaptedEvent, EventTypes, Point } from '../interfaces';
4
+ import { PointerTypeMapping, isPointerInBounds } from '../utils';
5
+ import { PointerType } from '../../PointerType';
9
6
 
10
7
  const POINTER_CAPTURE_EXCLUDE_LIST = new Set<string>(['SELECT', 'INPUT']);
8
+ const PointerTypes = {
9
+ Touch: 'touch',
10
+ Stylus: 'pen',
11
+ };
11
12
 
12
13
  export default class PointerEventManager extends EventManager<HTMLElement> {
13
14
  private trackedPointers = new Set<number>();
14
15
  private readonly mouseButtonsMapper = new Map<number, MouseButton>();
16
+ private lastPosition: Point;
15
17
 
16
18
  constructor(view: HTMLElement) {
17
19
  super(view);
@@ -21,181 +23,213 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
21
23
  this.mouseButtonsMapper.set(2, MouseButton.RIGHT);
22
24
  this.mouseButtonsMapper.set(3, MouseButton.BUTTON_4);
23
25
  this.mouseButtonsMapper.set(4, MouseButton.BUTTON_5);
26
+
27
+ this.lastPosition = {
28
+ x: -Infinity,
29
+ y: -Infinity,
30
+ };
24
31
  }
25
32
 
26
- public setListeners(): void {
27
- this.view.addEventListener('pointerdown', (event: PointerEvent): void => {
28
- if (event.pointerType === PointerType.TOUCH) {
29
- return;
30
- }
31
- if (
32
- !isPointerInBounds(this.view, { x: event.clientX, y: event.clientY })
33
- ) {
34
- return;
35
- }
33
+ private pointerDownCallback = (event: PointerEvent) => {
34
+ if (event.pointerType === PointerTypes.Touch) {
35
+ return;
36
+ }
37
+ if (!isPointerInBounds(this.view, { x: event.clientX, y: event.clientY })) {
38
+ return;
39
+ }
40
+
41
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.DOWN);
42
+ const target = event.target as HTMLElement;
43
+
44
+ if (!POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)) {
45
+ target.setPointerCapture(adaptedEvent.pointerId);
46
+ }
47
+
48
+ this.markAsInBounds(adaptedEvent.pointerId);
49
+ this.trackedPointers.add(adaptedEvent.pointerId);
50
+
51
+ if (++this.activePointersCounter > 1) {
52
+ adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_DOWN;
53
+ this.onPointerAdd(adaptedEvent);
54
+ } else {
55
+ this.onPointerDown(adaptedEvent);
56
+ }
57
+ };
58
+
59
+ private pointerUpCallback = (event: PointerEvent) => {
60
+ if (event.pointerType === PointerTypes.Touch) {
61
+ return;
62
+ }
63
+
64
+ // When we call reset on gesture handlers, it also resets their event managers
65
+ // In some handlers (like RotationGestureHandler) reset is called before all pointers leave view
66
+ // This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view
67
+ // Removing them will end in activePointersCounter going below 0, therefore handlers won't behave properly
68
+ if (this.activePointersCounter === 0) {
69
+ return;
70
+ }
71
+
72
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.UP);
73
+ const target = event.target as HTMLElement;
74
+
75
+ if (!POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)) {
76
+ target.releasePointerCapture(adaptedEvent.pointerId);
77
+ }
78
+
79
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
80
+ this.trackedPointers.delete(adaptedEvent.pointerId);
81
+
82
+ if (--this.activePointersCounter > 0) {
83
+ adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_UP;
84
+ this.onPointerRemove(adaptedEvent);
85
+ } else {
86
+ this.onPointerUp(adaptedEvent);
87
+ }
88
+ };
89
+
90
+ private pointerMoveCallback = (event: PointerEvent) => {
91
+ if (event.pointerType === PointerTypes.Touch) {
92
+ return;
93
+ }
94
+
95
+ // Stylus triggers `pointermove` event when it detects changes in pressure. Since it is very sensitive to those changes,
96
+ // it constantly sends events, even though there was no change in position. To fix that we check whether
97
+ // pointer has actually moved and if not, we do not send event.
98
+ if (
99
+ event.pointerType === PointerTypes.Stylus &&
100
+ event.x === this.lastPosition.x &&
101
+ event.y === this.lastPosition.y
102
+ ) {
103
+ return;
104
+ }
105
+
106
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.MOVE);
107
+ const target = event.target as HTMLElement;
108
+
109
+ // You may be wondering why are we setting pointer capture here, when we
110
+ // already set it in `pointerdown` handler. Well, that's a great question,
111
+ // for which I don't have an answer. Specification (https://www.w3.org/TR/pointerevents2/#dom-element-setpointercapture)
112
+ // says that the requirement for `setPointerCapture` to work is that pointer
113
+ // must be in 'active buttons state`, otherwise it will fail silently, which
114
+ // is lovely. Obviously, when `pointerdown` is fired, one of the buttons
115
+ // (when using mouse) is pressed, but that doesn't mean that `setPointerCapture`
116
+ // will succeed, for some reason. Since it fails silently, we don't actually know
117
+ // if it worked or not (there's `gotpointercapture` event, but the complexity of
118
+ // incorporating it here seems stupid), so we just call it again here, every time
119
+ // pointer moves until it succeeds.
120
+ // God, I do love web development.
121
+ if (
122
+ !target.hasPointerCapture(event.pointerId) &&
123
+ !POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)
124
+ ) {
125
+ target.setPointerCapture(event.pointerId);
126
+ }
127
+
128
+ const inBounds: boolean = isPointerInBounds(this.view, {
129
+ x: adaptedEvent.x,
130
+ y: adaptedEvent.y,
131
+ });
36
132
 
37
- const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.DOWN);
38
- const target = event.target as HTMLElement;
133
+ const pointerIndex: number = this.pointersInBounds.indexOf(
134
+ adaptedEvent.pointerId
135
+ );
39
136
 
40
- if (!POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)) {
41
- target.setPointerCapture(adaptedEvent.pointerId);
137
+ if (inBounds) {
138
+ if (pointerIndex < 0) {
139
+ adaptedEvent.eventType = EventTypes.ENTER;
140
+ this.onPointerEnter(adaptedEvent);
141
+ this.markAsInBounds(adaptedEvent.pointerId);
142
+ } else {
143
+ this.onPointerMove(adaptedEvent);
42
144
  }
43
-
44
- this.markAsInBounds(adaptedEvent.pointerId);
45
- this.trackedPointers.add(adaptedEvent.pointerId);
46
-
47
- if (++this.activePointersCounter > 1) {
48
- adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_DOWN;
49
- this.onPointerAdd(adaptedEvent);
145
+ } else {
146
+ if (pointerIndex >= 0) {
147
+ adaptedEvent.eventType = EventTypes.LEAVE;
148
+ this.onPointerLeave(adaptedEvent);
149
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
50
150
  } else {
51
- this.onPointerDown(adaptedEvent);
151
+ this.onPointerOutOfBounds(adaptedEvent);
52
152
  }
53
- });
153
+ }
54
154
 
55
- this.view.addEventListener('pointerup', (event: PointerEvent): void => {
56
- if (event.pointerType === PointerType.TOUCH) {
57
- return;
58
- }
155
+ this.lastPosition.x = event.x;
156
+ this.lastPosition.y = event.y;
157
+ };
59
158
 
60
- // When we call reset on gesture handlers, it also resets their event managers
61
- // In some handlers (like RotationGestureHandler) reset is called before all pointers leave view
62
- // This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view
63
- // Removing them will end in activePointersCounter going below 0, therefore handlers won't behave properly
64
- if (this.activePointersCounter === 0) {
65
- return;
66
- }
159
+ private pointerCancelCallback = (event: PointerEvent) => {
160
+ if (event.pointerType === PointerTypes.Touch) {
161
+ return;
162
+ }
67
163
 
68
- const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.UP);
69
- const target = event.target as HTMLElement;
164
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.CANCEL);
70
165
 
71
- if (!POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)) {
72
- target.releasePointerCapture(adaptedEvent.pointerId);
73
- }
166
+ this.onPointerCancel(adaptedEvent);
167
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
168
+ this.activePointersCounter = 0;
169
+ this.trackedPointers.clear();
170
+ };
74
171
 
75
- this.markAsOutOfBounds(adaptedEvent.pointerId);
76
- this.trackedPointers.delete(adaptedEvent.pointerId);
172
+ private pointerEnterCallback = (event: PointerEvent) => {
173
+ if (event.pointerType === PointerTypes.Touch) {
174
+ return;
175
+ }
77
176
 
78
- if (--this.activePointersCounter > 0) {
79
- adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_UP;
80
- this.onPointerRemove(adaptedEvent);
81
- } else {
82
- this.onPointerUp(adaptedEvent);
83
- }
84
- });
177
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.ENTER);
85
178
 
86
- this.view.addEventListener('pointermove', (event: PointerEvent): void => {
87
- if (event.pointerType === PointerType.TOUCH) {
88
- return;
89
- }
179
+ this.onPointerMoveOver(adaptedEvent);
180
+ };
90
181
 
91
- const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.MOVE);
92
- const target = event.target as HTMLElement;
93
-
94
- // You may be wondering why are we setting pointer capture here, when we
95
- // already set it in `pointerdown` handler. Well, that's a great question,
96
- // for which I don't have an answer. Specification (https://www.w3.org/TR/pointerevents2/#dom-element-setpointercapture)
97
- // says that the requirement for `setPointerCapture` to work is that pointer
98
- // must be in 'active buttons state`, otherwise it will fail silently, which
99
- // is lovely. Obviously, when `pointerdown` is fired, one of the buttons
100
- // (when using mouse) is pressed, but that doesn't mean that `setPointerCapture`
101
- // will succeed, for some reason. Since it fails silently, we don't actually know
102
- // if it worked or not (there's `gotpointercapture` event, but the complexity of
103
- // incorporating it here seems stupid), so we just call it again here, every time
104
- // pointer moves until it succeeds.
105
- // God, I do love web development.
106
- if (
107
- !target.hasPointerCapture(event.pointerId) &&
108
- !POINTER_CAPTURE_EXCLUDE_LIST.has(target.tagName)
109
- ) {
110
- target.setPointerCapture(event.pointerId);
111
- }
182
+ private pointerLeaveCallback = (event: PointerEvent) => {
183
+ if (event.pointerType === PointerTypes.Touch) {
184
+ return;
185
+ }
112
186
 
113
- const inBounds: boolean = isPointerInBounds(this.view, {
114
- x: adaptedEvent.x,
115
- y: adaptedEvent.y,
116
- });
117
-
118
- const pointerIndex: number = this.pointersInBounds.indexOf(
119
- adaptedEvent.pointerId
120
- );
121
-
122
- if (inBounds) {
123
- if (pointerIndex < 0) {
124
- adaptedEvent.eventType = EventTypes.ENTER;
125
- this.onPointerEnter(adaptedEvent);
126
- this.markAsInBounds(adaptedEvent.pointerId);
127
- } else {
128
- this.onPointerMove(adaptedEvent);
129
- }
130
- } else {
131
- if (pointerIndex >= 0) {
132
- adaptedEvent.eventType = EventTypes.LEAVE;
133
- this.onPointerLeave(adaptedEvent);
134
- this.markAsOutOfBounds(adaptedEvent.pointerId);
135
- } else {
136
- this.onPointerOutOfBounds(adaptedEvent);
137
- }
138
- }
139
- });
187
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.LEAVE);
140
188
 
141
- this.view.addEventListener('pointercancel', (event: PointerEvent): void => {
142
- if (event.pointerType === PointerType.TOUCH) {
143
- return;
144
- }
189
+ this.onPointerMoveOut(adaptedEvent);
190
+ };
145
191
 
146
- const adaptedEvent: AdaptedEvent = this.mapEvent(
147
- event,
148
- EventTypes.CANCEL
149
- );
192
+ private lostPointerCaptureCallback = (event: PointerEvent) => {
193
+ const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.CANCEL);
150
194
 
195
+ if (this.trackedPointers.has(adaptedEvent.pointerId)) {
196
+ // in some cases the `pointerup` event is not fired, but `lostpointercapture` is
197
+ // we simulate the `pointercancel` event here to make sure the gesture handler stops tracking it
151
198
  this.onPointerCancel(adaptedEvent);
152
- this.markAsOutOfBounds(adaptedEvent.pointerId);
199
+
153
200
  this.activePointersCounter = 0;
154
201
  this.trackedPointers.clear();
155
- });
202
+ }
203
+ };
204
+
205
+ public registerListeners(): void {
206
+ this.view.addEventListener('pointerdown', this.pointerDownCallback);
207
+ this.view.addEventListener('pointerup', this.pointerUpCallback);
208
+ this.view.addEventListener('pointermove', this.pointerMoveCallback);
209
+ this.view.addEventListener('pointercancel', this.pointerCancelCallback);
156
210
 
157
211
  // onPointerEnter and onPointerLeave are triggered by a custom logic responsible for
158
212
  // handling shouldCancelWhenOutside flag, and are unreliable unless the pointer is down.
159
213
  // We therefore use pointerenter and pointerleave events to handle the hover gesture,
160
214
  // mapping them to onPointerMoveOver and onPointerMoveOut respectively.
161
-
162
- this.view.addEventListener('pointerenter', (event: PointerEvent): void => {
163
- if (event.pointerType === PointerType.TOUCH) {
164
- return;
165
- }
166
-
167
- const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.ENTER);
168
-
169
- this.onPointerMoveOver(adaptedEvent);
170
- });
171
-
172
- this.view.addEventListener('pointerleave', (event: PointerEvent): void => {
173
- if (event.pointerType === PointerType.TOUCH) {
174
- return;
175
- }
176
-
177
- const adaptedEvent: AdaptedEvent = this.mapEvent(event, EventTypes.LEAVE);
178
-
179
- this.onPointerMoveOut(adaptedEvent);
180
- });
181
-
215
+ this.view.addEventListener('pointerenter', this.pointerEnterCallback);
216
+ this.view.addEventListener('pointerleave', this.pointerLeaveCallback);
182
217
  this.view.addEventListener(
183
218
  'lostpointercapture',
184
- (event: PointerEvent): void => {
185
- const adaptedEvent: AdaptedEvent = this.mapEvent(
186
- event,
187
- EventTypes.CANCEL
188
- );
189
-
190
- if (this.trackedPointers.has(adaptedEvent.pointerId)) {
191
- // in some cases the `pointerup` event is not fired, but `lostpointercapture` is
192
- // we simulate the `pointercancel` event here to make sure the gesture handler stops tracking it
193
- this.onPointerCancel(adaptedEvent);
194
-
195
- this.activePointersCounter = 0;
196
- this.trackedPointers.clear();
197
- }
198
- }
219
+ this.lostPointerCaptureCallback
220
+ );
221
+ }
222
+
223
+ public unregisterListeners(): void {
224
+ this.view.removeEventListener('pointerdown', this.pointerDownCallback);
225
+ this.view.removeEventListener('pointerup', this.pointerUpCallback);
226
+ this.view.removeEventListener('pointermove', this.pointerMoveCallback);
227
+ this.view.removeEventListener('pointercancel', this.pointerCancelCallback);
228
+ this.view.removeEventListener('pointerenter', this.pointerEnterCallback);
229
+ this.view.removeEventListener('pointerleave', this.pointerLeaveCallback);
230
+ this.view.removeEventListener(
231
+ 'lostpointercapture',
232
+ this.lostPointerCaptureCallback
199
233
  );
200
234
  }
201
235
 
@@ -207,7 +241,8 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
207
241
  offsetY: event.offsetY,
208
242
  pointerId: event.pointerId,
209
243
  eventType: eventType,
210
- pointerType: event.pointerType as PointerType,
244
+ pointerType:
245
+ PointerTypeMapping.get(event.pointerType) ?? PointerType.OTHER,
211
246
  button: this.mouseButtonsMapper.get(event.button),
212
247
  time: event.timeStamp,
213
248
  };
@@ -1,141 +1,149 @@
1
- import {
2
- AdaptedEvent,
3
- EventTypes,
4
- PointerType,
5
- TouchEventType,
6
- } from '../interfaces';
1
+ import { AdaptedEvent, EventTypes, TouchEventType } from '../interfaces';
7
2
  import EventManager from './EventManager';
8
3
  import { isPointerInBounds } from '../utils';
4
+ import { PointerType } from '../../PointerType';
9
5
 
10
6
  export default class TouchEventManager extends EventManager<HTMLElement> {
11
- public setListeners(): void {
12
- this.view.addEventListener('touchstart', (event: TouchEvent) => {
13
- for (let i = 0; i < event.changedTouches.length; ++i) {
14
- const adaptedEvent: AdaptedEvent = this.mapEvent(
15
- event,
16
- EventTypes.DOWN,
17
- i,
18
- TouchEventType.DOWN
19
- );
20
-
21
- // Here we skip stylus, because in case of anything different than touch we want to handle it by using PointerEvents
22
- // If we leave stylus to send touch events, handlers will receive every action twice
23
- if (
24
- !isPointerInBounds(this.view, {
25
- x: adaptedEvent.x,
26
- y: adaptedEvent.y,
27
- }) ||
28
- //@ts-ignore touchType field does exist
29
- event.changedTouches[i].touchType === 'stylus'
30
- ) {
31
- continue;
32
- }
33
-
34
- this.markAsInBounds(adaptedEvent.pointerId);
35
-
36
- if (++this.activePointersCounter > 1) {
37
- adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_DOWN;
38
- this.onPointerAdd(adaptedEvent);
39
- } else {
40
- this.onPointerDown(adaptedEvent);
41
- }
42
- }
43
- });
44
-
45
- this.view.addEventListener('touchmove', (event: TouchEvent) => {
46
- for (let i = 0; i < event.changedTouches.length; ++i) {
47
- const adaptedEvent: AdaptedEvent = this.mapEvent(
48
- event,
49
- EventTypes.MOVE,
50
- i,
51
- TouchEventType.MOVE
52
- );
53
- //@ts-ignore touchType field does exist
54
- if (event.changedTouches[i].touchType === 'stylus') {
55
- continue;
56
- }
57
-
58
- const inBounds: boolean = isPointerInBounds(this.view, {
7
+ private touchStartCallback = (event: TouchEvent): void => {
8
+ for (let i = 0; i < event.changedTouches.length; ++i) {
9
+ const adaptedEvent: AdaptedEvent = this.mapEvent(
10
+ event,
11
+ EventTypes.DOWN,
12
+ i,
13
+ TouchEventType.DOWN
14
+ );
15
+
16
+ // Here we skip stylus, because in case of anything different than touch we want to handle it by using PointerEvents
17
+ // If we leave stylus to send touch events, handlers will receive every action twice
18
+ if (
19
+ !isPointerInBounds(this.view, {
59
20
  x: adaptedEvent.x,
60
21
  y: adaptedEvent.y,
61
- });
62
-
63
- const pointerIndex: number = this.pointersInBounds.indexOf(
64
- adaptedEvent.pointerId
65
- );
66
-
67
- if (inBounds) {
68
- if (pointerIndex < 0) {
69
- adaptedEvent.eventType = EventTypes.ENTER;
70
- this.onPointerEnter(adaptedEvent);
71
- this.markAsInBounds(adaptedEvent.pointerId);
72
- } else {
73
- this.onPointerMove(adaptedEvent);
74
- }
75
- } else {
76
- if (pointerIndex >= 0) {
77
- adaptedEvent.eventType = EventTypes.LEAVE;
78
- this.onPointerLeave(adaptedEvent);
79
- this.markAsOutOfBounds(adaptedEvent.pointerId);
80
- } else {
81
- this.onPointerOutOfBounds(adaptedEvent);
82
- }
83
- }
22
+ }) ||
23
+ //@ts-ignore touchType field does exist
24
+ event.changedTouches[i].touchType === 'stylus'
25
+ ) {
26
+ continue;
84
27
  }
85
- });
86
-
87
- this.view.addEventListener('touchend', (event: TouchEvent) => {
88
- for (let i = 0; i < event.changedTouches.length; ++i) {
89
- // When we call reset on gesture handlers, it also resets their event managers
90
- // In some handlers (like RotationGestureHandler) reset is called before all pointers leave view
91
- // This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view
92
- // Removing them will end in activePointersCounter going below 0, therefore handlers won't behave properly
93
- if (this.activePointersCounter === 0) {
94
- break;
95
- }
96
28
 
97
- //@ts-ignore touchType field does exist
98
- if (event.changedTouches[i].touchType === 'stylus') {
99
- continue;
100
- }
29
+ this.markAsInBounds(adaptedEvent.pointerId);
101
30
 
102
- const adaptedEvent: AdaptedEvent = this.mapEvent(
103
- event,
104
- EventTypes.UP,
105
- i,
106
- TouchEventType.UP
107
- );
31
+ if (++this.activePointersCounter > 1) {
32
+ adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_DOWN;
33
+ this.onPointerAdd(adaptedEvent);
34
+ } else {
35
+ this.onPointerDown(adaptedEvent);
36
+ }
37
+ }
38
+ };
39
+
40
+ private touchMoveCallback = (event: TouchEvent): void => {
41
+ for (let i = 0; i < event.changedTouches.length; ++i) {
42
+ const adaptedEvent: AdaptedEvent = this.mapEvent(
43
+ event,
44
+ EventTypes.MOVE,
45
+ i,
46
+ TouchEventType.MOVE
47
+ );
48
+ //@ts-ignore touchType field does exist
49
+ if (event.changedTouches[i].touchType === 'stylus') {
50
+ continue;
51
+ }
108
52
 
109
- this.markAsOutOfBounds(adaptedEvent.pointerId);
53
+ const inBounds: boolean = isPointerInBounds(this.view, {
54
+ x: adaptedEvent.x,
55
+ y: adaptedEvent.y,
56
+ });
110
57
 
111
- if (--this.activePointersCounter > 0) {
112
- adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_UP;
113
- this.onPointerRemove(adaptedEvent);
58
+ const pointerIndex: number = this.pointersInBounds.indexOf(
59
+ adaptedEvent.pointerId
60
+ );
61
+
62
+ if (inBounds) {
63
+ if (pointerIndex < 0) {
64
+ adaptedEvent.eventType = EventTypes.ENTER;
65
+ this.onPointerEnter(adaptedEvent);
66
+ this.markAsInBounds(adaptedEvent.pointerId);
114
67
  } else {
115
- this.onPointerUp(adaptedEvent);
68
+ this.onPointerMove(adaptedEvent);
116
69
  }
70
+ } else {
71
+ if (pointerIndex >= 0) {
72
+ adaptedEvent.eventType = EventTypes.LEAVE;
73
+ this.onPointerLeave(adaptedEvent);
74
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
75
+ } else {
76
+ this.onPointerOutOfBounds(adaptedEvent);
77
+ }
78
+ }
79
+ }
80
+ };
81
+
82
+ private touchEndCallback = (event: TouchEvent): void => {
83
+ for (let i = 0; i < event.changedTouches.length; ++i) {
84
+ // When we call reset on gesture handlers, it also resets their event managers
85
+ // In some handlers (like RotationGestureHandler) reset is called before all pointers leave view
86
+ // This means, that activePointersCounter will be set to 0, while there are still remaining pointers on view
87
+ // Removing them will end in activePointersCounter going below 0, therefore handlers won't behave properly
88
+ if (this.activePointersCounter === 0) {
89
+ break;
90
+ }
91
+
92
+ //@ts-ignore touchType field does exist
93
+ if (event.changedTouches[i].touchType === 'stylus') {
94
+ continue;
117
95
  }
118
- });
119
96
 
120
- this.view.addEventListener('touchcancel', (event: TouchEvent) => {
121
- for (let i = 0; i < event.changedTouches.length; ++i) {
122
- const adaptedEvent: AdaptedEvent = this.mapEvent(
123
- event,
124
- EventTypes.CANCEL,
125
- i,
126
- TouchEventType.CANCELLED
127
- );
97
+ const adaptedEvent: AdaptedEvent = this.mapEvent(
98
+ event,
99
+ EventTypes.UP,
100
+ i,
101
+ TouchEventType.UP
102
+ );
128
103
 
129
- //@ts-ignore touchType field does exist
130
- if (event.changedTouches[i].touchType === 'stylus') {
131
- continue;
132
- }
104
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
133
105
 
134
- this.onPointerCancel(adaptedEvent);
135
- this.markAsOutOfBounds(adaptedEvent.pointerId);
136
- this.activePointersCounter = 0;
106
+ if (--this.activePointersCounter > 0) {
107
+ adaptedEvent.eventType = EventTypes.ADDITIONAL_POINTER_UP;
108
+ this.onPointerRemove(adaptedEvent);
109
+ } else {
110
+ this.onPointerUp(adaptedEvent);
111
+ }
112
+ }
113
+ };
114
+
115
+ private touchCancelCallback = (event: TouchEvent): void => {
116
+ for (let i = 0; i < event.changedTouches.length; ++i) {
117
+ const adaptedEvent: AdaptedEvent = this.mapEvent(
118
+ event,
119
+ EventTypes.CANCEL,
120
+ i,
121
+ TouchEventType.CANCELLED
122
+ );
123
+
124
+ //@ts-ignore touchType field does exist
125
+ if (event.changedTouches[i].touchType === 'stylus') {
126
+ continue;
137
127
  }
138
- });
128
+
129
+ this.onPointerCancel(adaptedEvent);
130
+ this.markAsOutOfBounds(adaptedEvent.pointerId);
131
+ this.activePointersCounter = 0;
132
+ }
133
+ };
134
+
135
+ public registerListeners(): void {
136
+ this.view.addEventListener('touchstart', this.touchStartCallback);
137
+ this.view.addEventListener('touchmove', this.touchMoveCallback);
138
+ this.view.addEventListener('touchend', this.touchEndCallback);
139
+ this.view.addEventListener('touchcancel', this.touchCancelCallback);
140
+ }
141
+
142
+ public unregisterListeners(): void {
143
+ this.view.removeEventListener('touchstart', this.touchStartCallback);
144
+ this.view.removeEventListener('touchmove', this.touchMoveCallback);
145
+ this.view.removeEventListener('touchend', this.touchEndCallback);
146
+ this.view.removeEventListener('touchcancel', this.touchCancelCallback);
139
147
  }
140
148
 
141
149
  protected mapEvent(