Support Pointer Events (#12507)
* Support Pointer Events * Add Pointer Events DOM Fixture
Philipp Spieß committed
May 16, 2018 at 15:34 UTC
49979bbf521102d0fb55c77323bcec6fd6871a03
13 files changed
+373
-17
fixtures/dom/src/components/Header.js
+1
@@ -64,6 +64,7 @@ class Header extends React.Component {
64
<option value="/event-pooling">Event Pooling</option>
65
<option value="/custom-elements">Custom Elements</option>
66
<option value="/media-events">Media Events</option>
67
+ <option value="/pointer-events">Pointer Events</option>
68
</select>
69
</label>
70
<label htmlFor="react_version">
fixtures/dom/src/components/fixtures/index.js
+3
@@ -11,6 +11,7 @@ import ErrorHandling from './error-handling';
11
import EventPooling from './event-pooling';
12
import CustomElementFixtures from './custom-elements';
13
import MediaEventsFixtures from './media-events';
14
+import PointerEventsFixtures from './pointer-events';
15
16
const React = window.React;
17
@@ -46,6 +47,8 @@ function FixturesPage() {
47
return <CustomElementFixtures />;
48
case '/media-events':
49
return <MediaEventsFixtures />;
50
+ case '/pointer-events':
51
+ return <PointerEventsFixtures />;
52
default:
53
return <p>Please select a test fixture.</p>;
54
}
fixtures/dom/src/components/fixtures/pointer-events/drag-box.js
new
+90
@@ -0,0 +1,90 @@
1
+const React = window.React;
2
+
3
+const CIRCLE_SIZE = 80;
4
+
5
+class DragBox extends React.Component {
6
+ state = {
7
+ hasCapture: false,
8
+ circleLeft: 80,
9
+ circleTop: 80,
10
+ };
11
+ isDragging = false;
12
+ previousLeft = 0;
13
+ previousTop = 0;
14
+
15
+ onDown = event => {
16
+ this.isDragging = true;
17
+ event.target.setPointerCapture(event.pointerId);
18
+
19
+ // We store the initial coordinates to be able to calculate the changes
20
+ // later on.
21
+ this.extractPositionDelta(event);
22
+ };
23
+
24
+ onMove = event => {
25
+ if (!this.isDragging) {
26
+ return;
27
+ }
28
+ const {left, top} = this.extractPositionDelta(event);
29
+
30
+ this.setState(({circleLeft, circleTop}) => ({
31
+ circleLeft: circleLeft + left,
32
+ circleTop: circleTop + top,
33
+ }));
34
+ };
35
+
36
+ onUp = event => (this.isDragging = false);
37
+ onGotCapture = event => this.setState({hasCapture: true});
38
+ onLostCapture = event => this.setState({hasCapture: false});
39
+
40
+ extractPositionDelta = event => {
41
+ const left = event.pageX;
42
+ const top = event.pageY;
43
+ const delta = {
44
+ left: left - this.previousLeft,
45
+ top: top - this.previousTop,
46
+ };
47
+ this.previousLeft = left;
48
+ this.previousTop = top;
49
+ return delta;
50
+ };
51
+
52
+ render() {
53
+ const {hasCapture, circleLeft, circleTop} = this.state;
54
+
55
+ const boxStyle = {
56
+ border: '1px solid #d9d9d9',
57
+ margin: '10px 0 20px',
58
+ minHeight: 400,
59
+ width: '100%',
60
+ position: 'relative',
61
+ };
62
+
63
+ const circleStyle = {
64
+ width: CIRCLE_SIZE,
65
+ height: CIRCLE_SIZE,
66
+ borderRadius: CIRCLE_SIZE / 2,
67
+ position: 'absolute',
68
+ left: circleLeft,
69
+ top: circleTop,
70
+ backgroundColor: hasCapture ? 'blue' : 'green',
71
+ touchAction: 'none',
72
+ };
73
+
74
+ return (
75
+ <div style={boxStyle}>
76
+ <div
77
+ style={circleStyle}
78
+ onPointerDown={this.onDown}
79
+ onPointerMove={this.onMove}
80
+ onPointerUp={this.onUp}
81
+ onPointerCancel={this.onUp}
82
+ onGotPointerCapture={this.onGotCapture}
83
+ onLostPointerCapture={this.onLostCapture}
84
+ />
85
+ </div>
86
+ );
87
+ }
88
+}
89
+
90
+export default DragBox;
fixtures/dom/src/components/fixtures/pointer-events/drag.js
new
+25
@@ -0,0 +1,25 @@
1
+import TestCase from '../../TestCase';
2
+import DragBox from './drag-box';
3
+
4
+const React = window.React;
5
+
6
+class Drag extends React.Component {
7
+ render() {
8
+ return (
9
+ <TestCase title="Drag" description="">
10
+ <TestCase.Steps>
11
+ <li>Drag the circle below with any pointer tool</li>
12
+ </TestCase.Steps>
13
+
14
+ <TestCase.ExpectedResult>
15
+ While dragging, the circle must have turn blue to indicate that a
16
+ pointer capture was received.
17
+ </TestCase.ExpectedResult>
18
+
19
+ <DragBox />
20
+ </TestCase>
21
+ );
22
+ }
23
+}
24
+
25
+export default Drag;
fixtures/dom/src/components/fixtures/pointer-events/hover-box.js
new
+34
@@ -0,0 +1,34 @@
1
+const React = window.React;
2
+
3
+class DrawBox extends React.Component {
4
+ render() {
5
+ const boxStyle = {
6
+ border: '1px solid #d9d9d9',
7
+ margin: '10px 0 20px',
8
+ padding: '20px 20px',
9
+ touchAction: 'none',
10
+ };
11
+
12
+ const obstacleStyle = {
13
+ border: '1px solid #d9d9d9',
14
+ width: '25%',
15
+ height: '200px',
16
+ margin: '12.5%',
17
+ display: 'inline-block',
18
+ };
19
+
20
+ return (
21
+ <div
22
+ style={boxStyle}
23
+ onPointerOver={this.props.onOver}
24
+ onPointerOut={this.props.onOut}
25
+ onPointerEnter={this.props.onEnter}
26
+ onPointerLeave={this.props.onLeave}>
27
+ <div style={obstacleStyle} />
28
+ <div style={obstacleStyle} />
29
+ </div>
30
+ );
31
+ }
32
+}
33
+
34
+export default DrawBox;
fixtures/dom/src/components/fixtures/pointer-events/hover.js
new
+51
@@ -0,0 +1,51 @@
1
+import TestCase from '../../TestCase';
2
+import HoverBox from './hover-box';
3
+
4
+const React = window.React;
5
+
6
+class Hover extends React.Component {
7
+ state = {
8
+ overs: 0,
9
+ outs: 0,
10
+ enters: 0,
11
+ leaves: 0,
12
+ };
13
+
14
+ onOver = () => this.setState({overs: this.state.overs + 1});
15
+ onOut = () => this.setState({outs: this.state.outs + 1});
16
+ onEnter = () => this.setState({enters: this.state.enters + 1});
17
+ onLeave = () => this.setState({leaves: this.state.leaves + 1});
18
+
19
+ render() {
20
+ const {overs, outs, enters, leaves} = this.state;
21
+
22
+ return (
23
+ <TestCase title="Hover" description="">
24
+ <TestCase.Steps>
25
+ <li>Hover over the above box and the obstacles</li>
26
+ </TestCase.Steps>
27
+
28
+ <TestCase.ExpectedResult>
29
+ Overs and outs should increase when moving over the obstacles but
30
+ enters and leaves should not.
31
+ </TestCase.ExpectedResult>
32
+
33
+ <HoverBox
34
+ onOver={this.onOver}
35
+ onOut={this.onOut}
36
+ onEnter={this.onEnter}
37
+ onLeave={this.onLeave}
38
+ />
39
+
40
+ <p>
41
+ Pointer Overs: <b>{overs}</b> <br />
42
+ Pointer Outs: <b>{outs}</b> <br />
43
+ Pointer Enters: <b>{enters}</b> <br />
44
+ Pointer Leaves: <b>{leaves}</b> <br />
45
+ </p>
46
+ </TestCase>
47
+ );
48
+ }
49
+}
50
+
51
+export default Hover;
fixtures/dom/src/components/fixtures/pointer-events/index.js
new
+20
@@ -0,0 +1,20 @@
1
+import FixtureSet from '../../FixtureSet';
2
+import Drag from './drag';
3
+import Hover from './hover';
4
+
5
+const React = window.React;
6
+
7
+class PointerEvents extends React.Component {
8
+ render() {
9
+ return (
10
+ <FixtureSet
11
+ title="Pointer Events"
12
+ description="Pointer Events are not supported in every browser. The examples below might not work in every browser. To test pointer events, make sure to use Google Chrome, Firefox, Internet Explorer, or Edge.">
13
+ <Drag />
14
+ <Hover />
15
+ </FixtureSet>
16
+ );
17
+ }
18
+}
19
+
20
+export default PointerEvents;
packages/react-dom/src/__tests__/__snapshots__/ReactTestUtils-test.js.snap
+10
@@ -35,6 +35,7 @@ Array [
35
"ended",
36
"error",
37
"focus",
38
+ "gotPointerCapture",
39
"input",
40
"invalid",
41
"keyDown",
@@ -44,6 +45,7 @@ Array [
45
"loadStart",
46
"loadedData",
47
"loadedMetadata",
48
+ "lostPointerCapture",
49
"mouseDown",
50
"mouseEnter",
51
"mouseLeave",
@@ -55,6 +57,14 @@ Array [
57
"pause",
58
"play",
59
"playing",
60
+ "pointerCancel",
61
+ "pointerDown",
62
+ "pointerEnter",
63
+ "pointerLeave",
64
+ "pointerMove",
65
+ "pointerOut",
66
+ "pointerOver",
67
+ "pointerUp",
68
"progress",
69
"rateChange",
70
"reset",
packages/react-dom/src/events/DOMTopLevelEventTypes.js
+26
@@ -72,6 +72,9 @@ export const TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
72
export const TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
73
export const TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
74
export const TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
75
+export const TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType(
76
+ 'gotpointercapture',
77
+);
78
export const TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
79
export const TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
80
export const TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
@@ -83,6 +86,9 @@ export const TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
86
export const TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType(
87
'loadedmetadata',
88
);
89
+export const TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType(
90
+ 'lostpointercapture',
91
+);
92
export const TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
93
export const TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
94
export const TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
@@ -92,6 +98,26 @@ export const TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
98
export const TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
99
export const TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
100
export const TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
101
+export const TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType(
102
+ 'pointercancel',
103
+);
104
+export const TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType(
105
+ 'pointerdown',
106
+);
107
+export const TOP_POINTER_ENTER = unsafeCastStringToDOMTopLevelType(
108
+ 'pointerenter',
109
+);
110
+export const TOP_POINTER_LEAVE = unsafeCastStringToDOMTopLevelType(
111
+ 'pointerleave',
112
+);
113
+export const TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType(
114
+ 'pointermove',
115
+);
116
+export const TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
117
+export const TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType(
118
+ 'pointerover',
119
+);
120
+export const TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
121
export const TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
122
export const TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
123
export const TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
packages/react-dom/src/events/EnterLeaveEventPlugin.js
+48
-14
@@ -7,8 +7,14 @@
7
8
import {accumulateEnterLeaveDispatches} from 'events/EventPropagators';
9
10
-import {TOP_MOUSE_OUT, TOP_MOUSE_OVER} from './DOMTopLevelEventTypes';
10
+import {
11
+ TOP_MOUSE_OUT,
12
+ TOP_MOUSE_OVER,
13
+ TOP_POINTER_OUT,
14
+ TOP_POINTER_OVER,
15
+} from './DOMTopLevelEventTypes';
16
import SyntheticMouseEvent from './SyntheticMouseEvent';
17
+import SyntheticPointerEvent from './SyntheticPointerEvent';
18
import {
19
getClosestInstanceFromNode,
20
getNodeFromInstance,
@@ -23,6 +29,14 @@ const eventTypes = {
29
registrationName: 'onMouseLeave',
30
dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER],
31
},
32
+ pointerEnter: {
33
+ registrationName: 'onPointerEnter',
34
+ dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER],
35
+ },
36
+ pointerLeave: {
37
+ registrationName: 'onPointerLeave',
38
+ dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER],
39
+ },
40
};
41
42
const EnterLeaveEventPlugin = {
@@ -41,14 +55,17 @@ const EnterLeaveEventPlugin = {
55
nativeEvent,
56
nativeEventTarget,
57
) {
44
- if (
45
- topLevelType === TOP_MOUSE_OVER &&
46
- (nativeEvent.relatedTarget || nativeEvent.fromElement)
47
- ) {
58
+ const isOverEvent =
59
+ topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
60
+ const isOutEvent =
61
+ topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
62
+
63
+ if (isOverEvent && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
64
return null;
65
}
50
- if (topLevelType !== TOP_MOUSE_OUT && topLevelType !== TOP_MOUSE_OVER) {
51
- // Must not be a mouse in or mouse out - ignoring.
66
+
67
+ if (!isOutEvent && !isOverEvent) {
68
+ // Must not be a mouse or pointer in or out - ignoring.
69
return null;
70
}
71
@@ -68,7 +85,7 @@ const EnterLeaveEventPlugin = {
85
86
let from;
87
let to;
71
- if (topLevelType === TOP_MOUSE_OUT) {
88
+ if (isOutEvent) {
89
from = targetInst;
90
const related = nativeEvent.relatedTarget || nativeEvent.toElement;
91
to = related ? getClosestInstanceFromNode(related) : null;
@@ -83,26 +100,43 @@ const EnterLeaveEventPlugin = {
100
return null;
101
}
102
103
+ let eventInterface, leaveEventType, enterEventType, eventTypePrefix;
104
+
105
+ if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
106
+ eventInterface = SyntheticMouseEvent;
107
+ leaveEventType = eventTypes.mouseLeave;
108
+ enterEventType = eventTypes.mouseEnter;
109
+ eventTypePrefix = 'mouse';
110
+ } else if (
111
+ topLevelType === TOP_POINTER_OUT ||
112
+ topLevelType === TOP_POINTER_OVER
113
+ ) {
114
+ eventInterface = SyntheticPointerEvent;
115
+ leaveEventType = eventTypes.pointerLeave;
116
+ enterEventType = eventTypes.pointerEnter;
117
+ eventTypePrefix = 'pointer';
118
+ }
119
+
120
const fromNode = from == null ? win : getNodeFromInstance(from);
121
const toNode = to == null ? win : getNodeFromInstance(to);
122
89
- const leave = SyntheticMouseEvent.getPooled(
90
- eventTypes.mouseLeave,
123
+ const leave = eventInterface.getPooled(
124
+ leaveEventType,
125
from,
126
nativeEvent,
127
nativeEventTarget,
128
);
95
- leave.type = 'mouseleave';
129
+ leave.type = eventTypePrefix + 'leave';
130
leave.target = fromNode;
131
leave.relatedTarget = toNode;
132
99
- const enter = SyntheticMouseEvent.getPooled(
100
- eventTypes.mouseEnter,
133
+ const enter = eventInterface.getPooled(
134
+ enterEventType,
135
to,
136
nativeEvent,
137
nativeEventTarget,
138
);
105
- enter.type = 'mouseenter';
139
+ enter.type = eventTypePrefix + 'enter';
140
enter.target = toNode;
141
enter.relatedTarget = fromNode;
142
packages/react-dom/src/events/SimpleEventPlugin.js
+19
@@ -29,6 +29,7 @@ import SyntheticClipboardEvent from './SyntheticClipboardEvent';
29
import SyntheticFocusEvent from './SyntheticFocusEvent';
30
import SyntheticKeyboardEvent from './SyntheticKeyboardEvent';
31
import SyntheticMouseEvent from './SyntheticMouseEvent';
32
+import SyntheticPointerEvent from './SyntheticPointerEvent';
33
import SyntheticDragEvent from './SyntheticDragEvent';
34
import SyntheticTouchEvent from './SyntheticTouchEvent';
35
import SyntheticTransitionEvent from './SyntheticTransitionEvent';
@@ -78,6 +79,9 @@ const interactiveEventTypeNames: Array<EventTuple> = [
79
[DOMTopLevelEventTypes.TOP_PASTE, 'paste'],
80
[DOMTopLevelEventTypes.TOP_PAUSE, 'pause'],
81
[DOMTopLevelEventTypes.TOP_PLAY, 'play'],
82
+ [DOMTopLevelEventTypes.TOP_POINTER_CANCEL, 'pointerCancel'],
83
+ [DOMTopLevelEventTypes.TOP_POINTER_DOWN, 'pointerDown'],
84
+ [DOMTopLevelEventTypes.TOP_POINTER_UP, 'pointerUp'],
85
[DOMTopLevelEventTypes.TOP_RATE_CHANGE, 'rateChange'],
86
[DOMTopLevelEventTypes.TOP_RESET, 'reset'],
87
[DOMTopLevelEventTypes.TOP_SEEKED, 'seeked'],
@@ -104,14 +108,19 @@ const nonInteractiveEventTypeNames: Array<EventTuple> = [
108
[DOMTopLevelEventTypes.TOP_ENCRYPTED, 'encrypted'],
109
[DOMTopLevelEventTypes.TOP_ENDED, 'ended'],
110
[DOMTopLevelEventTypes.TOP_ERROR, 'error'],
111
+ [DOMTopLevelEventTypes.TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture'],
112
[DOMTopLevelEventTypes.TOP_LOAD, 'load'],
113
[DOMTopLevelEventTypes.TOP_LOADED_DATA, 'loadedData'],
114
[DOMTopLevelEventTypes.TOP_LOADED_METADATA, 'loadedMetadata'],
115
[DOMTopLevelEventTypes.TOP_LOAD_START, 'loadStart'],
116
+ [DOMTopLevelEventTypes.TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture'],
117
[DOMTopLevelEventTypes.TOP_MOUSE_MOVE, 'mouseMove'],
118
[DOMTopLevelEventTypes.TOP_MOUSE_OUT, 'mouseOut'],
119
[DOMTopLevelEventTypes.TOP_MOUSE_OVER, 'mouseOver'],
120
[DOMTopLevelEventTypes.TOP_PLAYING, 'playing'],
121
+ [DOMTopLevelEventTypes.TOP_POINTER_MOVE, 'pointerMove'],
122
+ [DOMTopLevelEventTypes.TOP_POINTER_OUT, 'pointerOut'],
123
+ [DOMTopLevelEventTypes.TOP_POINTER_OVER, 'pointerOver'],
124
[DOMTopLevelEventTypes.TOP_PROGRESS, 'progress'],
125
[DOMTopLevelEventTypes.TOP_SCROLL, 'scroll'],
126
[DOMTopLevelEventTypes.TOP_SEEKING, 'seeking'],
@@ -282,6 +291,16 @@ const SimpleEventPlugin: PluginModule<MouseEvent> & {
291
case DOMTopLevelEventTypes.TOP_PASTE:
292
EventConstructor = SyntheticClipboardEvent;
293
break;
294
+ case DOMTopLevelEventTypes.TOP_GOT_POINTER_CAPTURE:
295
+ case DOMTopLevelEventTypes.TOP_LOST_POINTER_CAPTURE:
296
+ case DOMTopLevelEventTypes.TOP_POINTER_CANCEL:
297
+ case DOMTopLevelEventTypes.TOP_POINTER_DOWN:
298
+ case DOMTopLevelEventTypes.TOP_POINTER_MOVE:
299
+ case DOMTopLevelEventTypes.TOP_POINTER_OUT:
300
+ case DOMTopLevelEventTypes.TOP_POINTER_OVER:
301
+ case DOMTopLevelEventTypes.TOP_POINTER_UP:
302
+ EventConstructor = SyntheticPointerEvent;
303
+ break;
304
default:
305
if (__DEV__) {
306
if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
packages/react-dom/src/events/SyntheticPointerEvent.js
new
+25
@@ -0,0 +1,25 @@
1
+/**
2
+ * Copyright (c) 2013-present, Facebook, Inc.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+import SyntheticMouseEvent from './SyntheticMouseEvent';
9
+
10
+/**
11
+ * @interface PointerEvent
12
+ * @see http://www.w3.org/TR/pointerevents/
13
+ */
14
+const SyntheticPointerEvent = SyntheticMouseEvent.extend({
15
+ pointerId: null,
16
+ width: null,
17
+ height: null,
18
+ pressure: null,
19
+ tiltX: null,
20
+ tiltY: null,
21
+ pointerType: null,
22
+ isPrimary: null,
23
+});
24
+
25
+export default SyntheticPointerEvent;
packages/react-dom/src/events/TapEventPlugin.js
+21
-3
@@ -15,6 +15,10 @@ import {
15
TOP_MOUSE_DOWN,
16
TOP_MOUSE_MOVE,
17
TOP_MOUSE_UP,
18
+ TOP_POINTER_CANCEL,
19
+ TOP_POINTER_DOWN,
20
+ TOP_POINTER_UP,
21
+ TOP_POINTER_MOVE,
22
TOP_TOUCH_CANCEL,
23
TOP_TOUCH_END,
24
TOP_TOUCH_MOVE,
@@ -23,14 +27,20 @@ import {
27
import SyntheticUIEvent from './SyntheticUIEvent';
28
29
function isStartish(topLevelType) {
26
- return topLevelType === TOP_MOUSE_DOWN || topLevelType === TOP_TOUCH_START;
30
+ return (
31
+ topLevelType === TOP_MOUSE_DOWN ||
32
+ topLevelType === TOP_TOUCH_START ||
33
+ topLevelType === TOP_POINTER_DOWN
34
+ );
35
}
36
37
function isEndish(topLevelType) {
38
return (
39
topLevelType === TOP_MOUSE_UP ||
32
- topLevelType === TOP_TOUCH_END ||
33
- topLevelType === TOP_TOUCH_CANCEL
40
+ topLevelType === TOP_POINTER_CANCEL ||
41
+ topLevelType === TOP_POINTER_UP ||
42
+ topLevelType === TOP_TOUCH_CANCEL ||
43
+ topLevelType === TOP_TOUCH_END
44
);
45
}
46
@@ -102,8 +112,16 @@ const touchEvents = [
112
TOP_TOUCH_MOVE,
113
];
114
115
+const pointerEvents = [
116
+ TOP_POINTER_CANCEL,
117
+ TOP_POINTER_DOWN,
118
+ TOP_POINTER_MOVE,
119
+ TOP_POINTER_UP,
120
+];
121
+
122
const dependencies = [TOP_MOUSE_DOWN, TOP_MOUSE_MOVE, TOP_MOUSE_UP].concat(
123
touchEvents,
124
+ pointerEvents,
125
);
126
127
const eventTypes = {