1import "./index.d"
2import "tocca"
3
4// Pointer Events
5// --------------
6// Thanks to https://github.com/mpizenberg/elm-pep/
7
8let enteredElement
9
10
11tocca({
12 dbltapThreshold: 400,
13 tapThreshold: 250
14})
15
16
17function mousePointerEvent(eventType, mouseEvent) {
18 const pointerEvent: any = new MouseEvent(eventType, mouseEvent)
19 pointerEvent.pointerId = 1
20 pointerEvent.isPrimary = true
21 pointerEvent.pointerType = "mouse"
22 pointerEvent.width = 1
23 pointerEvent.height = 1
24 pointerEvent.tiltX = 0
25 pointerEvent.tiltY = 0
26
27 "buttons" in mouseEvent && mouseEvent.buttons !== 0
28 ? (pointerEvent.pressure = 0.5)
29 : (pointerEvent.pressure = 0)
30
31 return pointerEvent
32}
33
34
35function touchPointerEvent(eventType, touchEvent, touch) {
36 const pointerEvent: any = new CustomEvent(eventType, {
37 bubbles: true,
38 cancelable: true
39 })
40
41 pointerEvent.ctrlKey = touchEvent.ctrlKey
42 pointerEvent.shiftKey = touchEvent.shiftKey
43 pointerEvent.altKey = touchEvent.altKey
44 pointerEvent.metaKey = touchEvent.metaKey
45
46 pointerEvent.clientX = touch.clientX
47 pointerEvent.clientY = touch.clientY
48 pointerEvent.screenX = touch.screenX
49 pointerEvent.screenY = touch.screenY
50 pointerEvent.pageX = touch.pageX
51 pointerEvent.pageY = touch.pageY
52
53 const rect = touch.target.getBoundingClientRect()
54 pointerEvent.offsetX = touch.clientX - rect.left
55 pointerEvent.offsetY = touch.clientY - rect.top
56 pointerEvent.pointerId = 1 + touch.identifier
57
58 pointerEvent.button = 0
59 pointerEvent.buttons = 1
60 pointerEvent.movementX = 0
61 pointerEvent.movementY = 0
62 pointerEvent.region = null
63 pointerEvent.relatedTarget = null
64 pointerEvent.x = pointerEvent.clientX
65 pointerEvent.y = pointerEvent.clientY
66
67 pointerEvent.pointerType = "touch"
68 pointerEvent.width = 1
69 pointerEvent.height = 1
70 pointerEvent.tiltX = 0
71 pointerEvent.tiltY = 0
72 pointerEvent.pressure = 1
73 pointerEvent.isPrimary = true
74
75 return pointerEvent
76}
77
78
79// Simulate `pointerenter` and `pointerleave` event for non-touch devices
80if (!self.PointerEvent) {
81 document.addEventListener("mouseover", event => {
82 const section = document.body.querySelector("section")
83 const isDragging = section && section.classList.contains("dragging-something")
84 const node = isDragging && document.elementFromPoint(event.clientX, event.clientY)
85
86 if (node && node != enteredElement) {
87 enteredElement && enteredElement.dispatchEvent(mousePointerEvent("pointerleave", event))
88 node.dispatchEvent(mousePointerEvent("pointerenter", event))
89 enteredElement = node
90 }
91 })
92}
93
94
95// Simulate `pointerenter` and `pointerleave` event for touch devices
96document.body.addEventListener("touchmove", event => {
97 const section = document.body.querySelector("section")
98 const isDragging = section && section.classList.contains("dragging-something")
99 const touch = event.touches[0]
100
101 let node
102
103 if (isDragging && touch) {
104 node = document.elementFromPoint(touch.clientX, touch.clientY)
105 }
106
107 if (node && node != enteredElement) {
108 enteredElement && enteredElement.dispatchEvent(touchPointerEvent("pointerleave", event, touch))
109 node.dispatchEvent(touchPointerEvent("pointerenter", event, touch))
110 enteredElement = node
111 }
112
113 if (isDragging) {
114 event.stopPropagation()
115 }
116})