Ensure touch events are properly handled for pageX and pageY (#15587)
Dominic Gannaway committed
May 8, 2019 at 19:08 UTC
8abf243b86e062cf54110d4b3bf629cd5d071dd8
2 files changed
+563
-181
packages/react-events/src/Press.js
+36
-10
@@ -190,14 +190,13 @@ function dispatchLongPressChangeEvent(
190
191
function activate(event, context, props, state) {
192
const nativeEvent: any = event.nativeEvent;
193
- const pageX = nativeEvent.pageX;
194
- const pageY = nativeEvent.pageY;
193
+ const {x, y} = getEventPageCoords(nativeEvent);
194
const wasActivePressed = state.isActivePressed;
195
state.isActivePressed = true;
197
- if (pageX != null && pageY != null) {
196
+ if (x !== null && y !== null) {
197
state.activationPosition = {
199
- pageX: nativeEvent.pageX,
200
- pageY: nativeEvent.pageY,
198
+ pageX: x,
199
+ pageY: y,
200
};
201
}
202
@@ -402,12 +401,39 @@ function calculateResponderRegion(target: Element, props: PressProps) {
401
};
402
}
403
404
+function isTouchEvent(nativeEvent: Event): boolean {
405
+ return Array.isArray((nativeEvent: any).changedTouches);
406
+}
407
+
408
+function getTouchFromPressEvent(nativeEvent: TouchEvent): Touch {
409
+ const {changedTouches, touches} = nativeEvent;
410
+ return changedTouches.length > 0
411
+ ? changedTouches[0]
412
+ : touches.length > 0
413
+ ? touches[0]
414
+ : (nativeEvent: any);
415
+}
416
+
417
+function getEventPageCoords(
418
+ nativeEvent: Event,
419
+): {x: null | number, y: null | number} {
420
+ let eventObject = (nativeEvent: any);
421
+ if (isTouchEvent(eventObject)) {
422
+ eventObject = getTouchFromPressEvent(eventObject);
423
+ }
424
+ const pageX = eventObject.pageX;
425
+ const pageY = eventObject.pageY;
426
+ return {
427
+ x: pageX != null ? pageX : null,
428
+ y: pageY != null ? pageY : null,
429
+ };
430
+}
431
+
432
function isPressWithinResponderRegion(
433
nativeEvent: $PropertyType<ReactResponderEvent, 'nativeEvent'>,
434
state: PressState,
435
): boolean {
436
const {responderRegionOnActivation, responderRegionOnDeactivation} = state;
410
- const event = (nativeEvent: any);
437
let left, top, right, bottom;
438
439
if (responderRegionOnActivation != null) {
@@ -423,16 +449,16 @@ function isPressWithinResponderRegion(
449
bottom = Math.max(bottom, responderRegionOnDeactivation.bottom);
450
}
451
}
452
+ const {x, y} = getEventPageCoords(((nativeEvent: any): Event));
453
454
return (
455
left != null &&
456
right != null &&
457
top != null &&
458
bottom != null &&
432
- (event.pageX >= left &&
433
- event.pageX <= right &&
434
- event.pageY >= top &&
435
- event.pageY <= bottom)
459
+ x !== null &&
460
+ y !== null &&
461
+ (x >= left && x <= right && y >= top && y <= bottom)
462
);
463
}
464
packages/react-events/src/__tests__/Press-test.internal.js
+527
-171
@@ -16,7 +16,7 @@ let Press;
16
17
const DEFAULT_LONG_PRESS_DELAY = 500;
18
19
-const createPointerEvent = (type, data) => {
19
+const createEvent = (type, data) => {
20
const event = document.createEvent('CustomEvent');
21
event.initCustomEvent(type, true, true);
22
if (data != null) {
@@ -77,8 +77,8 @@ describe('Event responder: Press', () => {
77
});
78
79
it('prevents custom events being dispatched', () => {
80
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
81
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
80
+ ref.current.dispatchEvent(createEvent('pointerdown'));
81
+ ref.current.dispatchEvent(createEvent('pointerup'));
82
expect(onPressStart).not.toBeCalled();
83
expect(onPress).not.toBeCalled();
84
expect(onPressEnd).not.toBeCalled();
@@ -101,7 +101,7 @@ describe('Event responder: Press', () => {
101
102
it('is called after "pointerdown" event', () => {
103
ref.current.dispatchEvent(
104
- createPointerEvent('pointerdown', {pointerType: 'pen'}),
104
+ createEvent('pointerdown', {pointerType: 'pen'}),
105
);
106
expect(onPressStart).toHaveBeenCalledTimes(1);
107
expect(onPressStart).toHaveBeenCalledWith(
@@ -110,16 +110,16 @@ describe('Event responder: Press', () => {
110
});
111
112
it('ignores browser emulated events', () => {
113
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
114
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
115
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
113
+ ref.current.dispatchEvent(createEvent('pointerdown'));
114
+ ref.current.dispatchEvent(createEvent('touchstart'));
115
+ ref.current.dispatchEvent(createEvent('mousedown'));
116
expect(onPressStart).toHaveBeenCalledTimes(1);
117
});
118
119
it('ignores any events not caused by left-click or touch/pen contact', () => {
120
- ref.current.dispatchEvent(createPointerEvent('pointerdown', {button: 1}));
121
- ref.current.dispatchEvent(createPointerEvent('pointerdown', {button: 5}));
122
- ref.current.dispatchEvent(createPointerEvent('mousedown', {button: 2}));
120
+ ref.current.dispatchEvent(createEvent('pointerdown', {button: 1}));
121
+ ref.current.dispatchEvent(createEvent('pointerdown', {button: 5}));
122
+ ref.current.dispatchEvent(createEvent('mousedown', {button: 2}));
123
expect(onPressStart).toHaveBeenCalledTimes(0);
124
});
125
@@ -151,14 +151,14 @@ describe('Event responder: Press', () => {
151
152
// No PointerEvent fallbacks
153
it('is called after "mousedown" event', () => {
154
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
154
+ ref.current.dispatchEvent(createEvent('mousedown'));
155
expect(onPressStart).toHaveBeenCalledTimes(1);
156
expect(onPressStart).toHaveBeenCalledWith(
157
expect.objectContaining({pointerType: 'mouse', type: 'pressstart'}),
158
);
159
});
160
it('is called after "touchstart" event', () => {
161
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
161
+ ref.current.dispatchEvent(createEvent('touchstart'));
162
expect(onPressStart).toHaveBeenCalledTimes(1);
163
expect(onPressStart).toHaveBeenCalledWith(
164
expect.objectContaining({pointerType: 'touch', type: 'pressstart'}),
@@ -174,7 +174,7 @@ describe('Event responder: Press', () => {
174
);
175
ReactDOM.render(element, container);
176
177
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
177
+ ref.current.dispatchEvent(createEvent('pointerdown'));
178
jest.advanceTimersByTime(1999);
179
expect(onPressStart).not.toBeCalled();
180
jest.advanceTimersByTime(1);
@@ -196,11 +196,11 @@ describe('Event responder: Press', () => {
196
right: 500,
197
});
198
199
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
199
+ ref.current.dispatchEvent(createEvent('pointerdown'));
200
jest.advanceTimersByTime(499);
201
expect(onPressStart).toHaveBeenCalledTimes(0);
202
ref.current.dispatchEvent(
203
- createPointerEvent('pointerup', {
203
+ createEvent('pointerup', {
204
pageX: 55,
205
pageY: 55,
206
}),
@@ -218,7 +218,7 @@ describe('Event responder: Press', () => {
218
);
219
ReactDOM.render(element, container);
220
221
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
221
+ ref.current.dispatchEvent(createEvent('pointerdown'));
222
expect(onPressStart).toHaveBeenCalledTimes(1);
223
});
224
});
@@ -235,9 +235,9 @@ describe('Event responder: Press', () => {
235
);
236
ReactDOM.render(element, container);
237
238
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
239
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
240
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
238
+ ref.current.dispatchEvent(createEvent('pointerdown'));
239
+ ref.current.dispatchEvent(createEvent('pointerup'));
240
+ ref.current.dispatchEvent(createEvent('pointerdown'));
241
expect(onPressStart).toHaveBeenCalledTimes(2);
242
});
243
});
@@ -259,9 +259,9 @@ describe('Event responder: Press', () => {
259
260
it('is called after "pointerup" event', () => {
261
ref.current.dispatchEvent(
262
- createPointerEvent('pointerdown', {pointerType: 'pen'}),
262
+ createEvent('pointerdown', {pointerType: 'pen'}),
263
);
264
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
264
+ ref.current.dispatchEvent(createEvent('pointerup'));
265
expect(onPressEnd).toHaveBeenCalledTimes(1);
266
expect(onPressEnd).toHaveBeenCalledWith(
267
expect.objectContaining({pointerType: 'pen', type: 'pressend'}),
@@ -270,13 +270,13 @@ describe('Event responder: Press', () => {
270
271
it('ignores browser emulated events', () => {
272
ref.current.dispatchEvent(
273
- createPointerEvent('pointerdown', {pointerType: 'touch'}),
273
+ createEvent('pointerdown', {pointerType: 'touch'}),
274
);
275
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
276
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
277
- ref.current.dispatchEvent(createPointerEvent('touchend'));
278
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
279
- ref.current.dispatchEvent(createPointerEvent('mouseup'));
275
+ ref.current.dispatchEvent(createEvent('touchstart'));
276
+ ref.current.dispatchEvent(createEvent('pointerup'));
277
+ ref.current.dispatchEvent(createEvent('touchend'));
278
+ ref.current.dispatchEvent(createEvent('mousedown'));
279
+ ref.current.dispatchEvent(createEvent('mouseup'));
280
expect(onPressEnd).toHaveBeenCalledTimes(1);
281
expect(onPressEnd).toHaveBeenCalledWith(
282
expect.objectContaining({pointerType: 'touch', type: 'pressend'}),
@@ -309,16 +309,16 @@ describe('Event responder: Press', () => {
309
310
// No PointerEvent fallbacks
311
it('is called after "mouseup" event', () => {
312
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
313
- ref.current.dispatchEvent(createPointerEvent('mouseup'));
312
+ ref.current.dispatchEvent(createEvent('mousedown'));
313
+ ref.current.dispatchEvent(createEvent('mouseup'));
314
expect(onPressEnd).toHaveBeenCalledTimes(1);
315
expect(onPressEnd).toHaveBeenCalledWith(
316
expect.objectContaining({pointerType: 'mouse', type: 'pressend'}),
317
);
318
});
319
it('is called after "touchend" event', () => {
320
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
321
- ref.current.dispatchEvent(createPointerEvent('touchend'));
320
+ ref.current.dispatchEvent(createEvent('touchstart'));
321
+ ref.current.dispatchEvent(createEvent('touchend'));
322
expect(onPressEnd).toHaveBeenCalledTimes(1);
323
expect(onPressEnd).toHaveBeenCalledWith(
324
expect.objectContaining({pointerType: 'touch', type: 'pressend'}),
@@ -334,8 +334,8 @@ describe('Event responder: Press', () => {
334
);
335
ReactDOM.render(element, container);
336
337
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
338
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
337
+ ref.current.dispatchEvent(createEvent('pointerdown'));
338
+ ref.current.dispatchEvent(createEvent('pointerup'));
339
jest.advanceTimersByTime(1999);
340
expect(onPressEnd).not.toBeCalled();
341
jest.advanceTimersByTime(1);
@@ -350,13 +350,13 @@ describe('Event responder: Press', () => {
350
);
351
ReactDOM.render(element, container);
352
353
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
354
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
353
+ ref.current.dispatchEvent(createEvent('pointerdown'));
354
+ ref.current.dispatchEvent(createEvent('pointerup'));
355
jest.advanceTimersByTime(499);
356
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
356
+ ref.current.dispatchEvent(createEvent('pointerdown'));
357
jest.advanceTimersByTime(1);
358
expect(onPressEnd).not.toBeCalled();
359
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
359
+ ref.current.dispatchEvent(createEvent('pointerup'));
360
jest.runAllTimers();
361
expect(onPressEnd).toHaveBeenCalledTimes(1);
362
});
@@ -370,8 +370,8 @@ describe('Event responder: Press', () => {
370
);
371
ReactDOM.render(element, container);
372
373
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
374
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
373
+ ref.current.dispatchEvent(createEvent('pointerdown'));
374
+ ref.current.dispatchEvent(createEvent('pointerup'));
375
expect(onPressEnd).toHaveBeenCalledTimes(1);
376
});
377
});
@@ -391,10 +391,10 @@ describe('Event responder: Press', () => {
391
});
392
393
it('is called after "pointerdown" and "pointerup" events', () => {
394
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
394
+ ref.current.dispatchEvent(createEvent('pointerdown'));
395
expect(onPressChange).toHaveBeenCalledTimes(1);
396
expect(onPressChange).toHaveBeenCalledWith(true);
397
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
397
+ ref.current.dispatchEvent(createEvent('pointerup'));
398
expect(onPressChange).toHaveBeenCalledTimes(2);
399
expect(onPressChange).toHaveBeenCalledWith(false);
400
});
@@ -416,7 +416,7 @@ describe('Event responder: Press', () => {
416
);
417
ReactDOM.render(element, container);
418
419
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
419
+ ref.current.dispatchEvent(createEvent('pointerdown'));
420
jest.advanceTimersByTime(499);
421
expect(onPressChange).not.toBeCalled();
422
jest.advanceTimersByTime(1);
@@ -439,10 +439,10 @@ describe('Event responder: Press', () => {
439
right: 500,
440
});
441
442
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
442
+ ref.current.dispatchEvent(createEvent('pointerdown'));
443
jest.advanceTimersByTime(100);
444
ref.current.dispatchEvent(
445
- createPointerEvent('pointerup', {
445
+ createEvent('pointerup', {
446
pageX: 55,
447
pageY: 55,
448
}),
@@ -461,10 +461,10 @@ describe('Event responder: Press', () => {
461
);
462
ReactDOM.render(element, container);
463
464
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
464
+ ref.current.dispatchEvent(createEvent('pointerdown'));
465
expect(onPressChange).toHaveBeenCalledTimes(1);
466
expect(onPressChange).toHaveBeenCalledWith(true);
467
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
467
+ ref.current.dispatchEvent(createEvent('pointerup'));
468
jest.advanceTimersByTime(499);
469
expect(onPressChange).toHaveBeenCalledTimes(1);
470
jest.advanceTimersByTime(1);
@@ -474,18 +474,18 @@ describe('Event responder: Press', () => {
474
475
// No PointerEvent fallbacks
476
it('is called after "mousedown" and "mouseup" events', () => {
477
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
477
+ ref.current.dispatchEvent(createEvent('mousedown'));
478
expect(onPressChange).toHaveBeenCalledTimes(1);
479
expect(onPressChange).toHaveBeenCalledWith(true);
480
- ref.current.dispatchEvent(createPointerEvent('mouseup'));
480
+ ref.current.dispatchEvent(createEvent('mouseup'));
481
expect(onPressChange).toHaveBeenCalledTimes(2);
482
expect(onPressChange).toHaveBeenCalledWith(false);
483
});
484
it('is called after "touchstart" and "touchend" events', () => {
485
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
485
+ ref.current.dispatchEvent(createEvent('touchstart'));
486
expect(onPressChange).toHaveBeenCalledTimes(1);
487
expect(onPressChange).toHaveBeenCalledWith(true);
488
- ref.current.dispatchEvent(createPointerEvent('touchend'));
488
+ ref.current.dispatchEvent(createEvent('touchend'));
489
expect(onPressChange).toHaveBeenCalledTimes(2);
490
expect(onPressChange).toHaveBeenCalledWith(false);
491
});
@@ -513,10 +513,10 @@ describe('Event responder: Press', () => {
513
514
it('is called after "pointerup" event', () => {
515
ref.current.dispatchEvent(
516
- createPointerEvent('pointerdown', {pointerType: 'pen'}),
516
+ createEvent('pointerdown', {pointerType: 'pen'}),
517
);
518
ref.current.dispatchEvent(
519
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
519
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
520
);
521
expect(onPress).toHaveBeenCalledTimes(1);
522
expect(onPress).toHaveBeenCalledWith(
@@ -541,9 +541,9 @@ describe('Event responder: Press', () => {
541
);
542
ReactDOM.render(element, container);
543
544
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
544
+ ref.current.dispatchEvent(createEvent('pointerdown'));
545
ref.current.dispatchEvent(
546
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
546
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
547
);
548
expect(onPress).toHaveBeenCalledTimes(1);
549
});
@@ -551,8 +551,8 @@ describe('Event responder: Press', () => {
551
// No PointerEvent fallbacks
552
// TODO: jsdom missing APIs
553
// it('is called after "touchend" event', () => {
554
- // ref.current.dispatchEvent(createPointerEvent('touchstart'));
555
- // ref.current.dispatchEvent(createPointerEvent('touchend'));
554
+ // ref.current.dispatchEvent(createEvent('touchstart'));
555
+ // ref.current.dispatchEvent(createEvent('touchend'));
556
// expect(onPress).toHaveBeenCalledTimes(1);
557
// });
558
});
@@ -573,7 +573,7 @@ describe('Event responder: Press', () => {
573
574
it('is called if "pointerdown" lasts default delay', () => {
575
ref.current.dispatchEvent(
576
- createPointerEvent('pointerdown', {pointerType: 'pen'}),
576
+ createEvent('pointerdown', {pointerType: 'pen'}),
577
);
578
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1);
579
expect(onLongPress).not.toBeCalled();
@@ -585,9 +585,9 @@ describe('Event responder: Press', () => {
585
});
586
587
it('is not called if "pointerup" is dispatched before delay', () => {
588
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
588
+ ref.current.dispatchEvent(createEvent('pointerdown'));
589
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY - 1);
590
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
590
+ ref.current.dispatchEvent(createEvent('pointerup'));
591
jest.advanceTimersByTime(1);
592
expect(onLongPress).not.toBeCalled();
593
});
@@ -619,10 +619,10 @@ describe('Event responder: Press', () => {
619
right: 100,
620
});
621
ref.current.dispatchEvent(
622
- createPointerEvent('pointerdown', {pageX: 10, pageY: 10}),
622
+ createEvent('pointerdown', {pageX: 10, pageY: 10}),
623
);
624
ref.current.dispatchEvent(
625
- createPointerEvent('pointermove', {pageX: 50, pageY: 50}),
625
+ createEvent('pointermove', {pageX: 50, pageY: 50}),
626
);
627
jest.runAllTimers();
628
expect(onLongPress).not.toBeCalled();
@@ -637,7 +637,7 @@ describe('Event responder: Press', () => {
637
);
638
ReactDOM.render(element, container);
639
640
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
640
+ ref.current.dispatchEvent(createEvent('pointerdown'));
641
jest.advanceTimersByTime(1999);
642
expect(onLongPress).not.toBeCalled();
643
jest.advanceTimersByTime(1);
@@ -652,7 +652,7 @@ describe('Event responder: Press', () => {
652
);
653
ReactDOM.render(element, container);
654
655
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
655
+ ref.current.dispatchEvent(createEvent('pointerdown'));
656
jest.advanceTimersByTime(9);
657
expect(onLongPress).not.toBeCalled();
658
jest.advanceTimersByTime(1);
@@ -668,7 +668,7 @@ describe('Event responder: Press', () => {
668
);
669
ReactDOM.render(element, container);
670
671
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
671
+ ref.current.dispatchEvent(createEvent('pointerdown'));
672
jest.advanceTimersByTime(
673
delayPressStart + DEFAULT_LONG_PRESS_DELAY - 1,
674
);
@@ -690,11 +690,11 @@ describe('Event responder: Press', () => {
690
);
691
ReactDOM.render(element, container);
692
693
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
693
+ ref.current.dispatchEvent(createEvent('pointerdown'));
694
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
695
expect(onLongPressChange).toHaveBeenCalledTimes(1);
696
expect(onLongPressChange).toHaveBeenCalledWith(true);
697
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
697
+ ref.current.dispatchEvent(createEvent('pointerup'));
698
expect(onLongPressChange).toHaveBeenCalledTimes(2);
699
expect(onLongPressChange).toHaveBeenCalledWith(false);
700
});
@@ -709,11 +709,11 @@ describe('Event responder: Press', () => {
709
);
710
ReactDOM.render(element, container);
711
712
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
712
+ ref.current.dispatchEvent(createEvent('pointerdown'));
713
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
714
expect(onLongPressChange).toHaveBeenCalledTimes(1);
715
expect(onLongPressChange).toHaveBeenCalledWith(true);
716
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
716
+ ref.current.dispatchEvent(createEvent('pointerup'));
717
jest.advanceTimersByTime(499);
718
expect(onLongPressChange).toHaveBeenCalledTimes(1);
719
jest.advanceTimersByTime(1);
@@ -739,10 +739,10 @@ describe('Event responder: Press', () => {
739
ReactDOM.render(element, container);
740
741
// NOTE: onPressChange behavior should not be affected
742
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
742
+ ref.current.dispatchEvent(createEvent('pointerdown'));
743
expect(onPressChange).toHaveBeenCalledTimes(1);
744
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
745
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
745
+ ref.current.dispatchEvent(createEvent('pointerup'));
746
expect(onPress).not.toBeCalled();
747
expect(onPressChange).toHaveBeenCalledTimes(2);
748
});
@@ -766,10 +766,10 @@ describe('Event responder: Press', () => {
766
right: 100,
767
});
768
ref.current.dispatchEvent(
769
- createPointerEvent('pointerdown', {pointerType: 'touch'}),
769
+ createEvent('pointerdown', {pointerType: 'touch'}),
770
);
771
ref.current.dispatchEvent(
772
- createPointerEvent('pointermove', {
772
+ createEvent('pointermove', {
773
pointerType: 'touch',
774
pageX: 10,
775
pageY: 10,
@@ -799,7 +799,7 @@ describe('Event responder: Press', () => {
799
});
800
ref.current.dispatchEvent(createKeyboardEvent('keydown', {key: 'Enter'}));
801
ref.current.dispatchEvent(
802
- createPointerEvent('pointermove', {
802
+ createEvent('pointermove', {
803
pointerType: 'mouse',
804
pageX: 10,
805
pageY: 10,
@@ -825,23 +825,23 @@ describe('Event responder: Press', () => {
825
right: 100,
826
});
827
ref.current.dispatchEvent(
828
- createPointerEvent('pointerdown', {pointerType: 'touch'}),
828
+ createEvent('pointerdown', {pointerType: 'touch'}),
829
);
830
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
830
+ ref.current.dispatchEvent(createEvent('touchstart'));
831
ref.current.dispatchEvent(
832
- createPointerEvent('pointermove', {
832
+ createEvent('pointermove', {
833
pointerType: 'touch',
834
pageX: 10,
835
pageY: 10,
836
}),
837
);
838
- ref.current.dispatchEvent(createPointerEvent('touchmove'));
839
- ref.current.dispatchEvent(createPointerEvent('mousemove'));
838
+ ref.current.dispatchEvent(createEvent('touchmove'));
839
+ ref.current.dispatchEvent(createEvent('mousemove'));
840
expect(onPressMove).toHaveBeenCalledTimes(1);
841
});
842
});
843
844
- describe('press with movement', () => {
844
+ describe('press with movement (pointer events)', () => {
845
const rectMock = {
846
width: 100,
847
height: 100,
@@ -890,13 +890,11 @@ describe('Event responder: Press', () => {
890
ReactDOM.render(element, container);
891
892
ref.current.getBoundingClientRect = getBoundingClientRectMock;
893
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
893
+ ref.current.dispatchEvent(createEvent('pointerdown'));
894
ref.current.dispatchEvent(
895
- createPointerEvent('pointermove', coordinatesInside),
896
- );
897
- ref.current.dispatchEvent(
898
- createPointerEvent('pointerup', coordinatesInside),
895
+ createEvent('pointermove', coordinatesInside),
896
);
897
+ ref.current.dispatchEvent(createEvent('pointerup', coordinatesInside));
898
jest.runAllTimers();
899
900
expect(events).toEqual([
@@ -931,9 +929,9 @@ describe('Event responder: Press', () => {
929
ReactDOM.render(element, container);
930
931
ref.current.getBoundingClientRect = getBoundingClientRectMock;
934
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
932
+ ref.current.dispatchEvent(createEvent('pointerdown'));
933
ref.current.dispatchEvent(
936
- createPointerEvent('pointermove', coordinatesInside),
934
+ createEvent('pointermove', coordinatesInside),
935
);
936
jest.advanceTimersByTime(499);
937
expect(events).toEqual(['onPressMove']);
@@ -943,9 +941,7 @@ describe('Event responder: Press', () => {
941
expect(events).toEqual(['onPressStart', 'onPressChange']);
942
events = [];
943
946
- ref.current.dispatchEvent(
947
- createPointerEvent('pointerup', coordinatesInside),
948
- );
944
+ ref.current.dispatchEvent(createEvent('pointerup', coordinatesInside));
945
expect(events).toEqual(['onPressEnd', 'onPressChange', 'onPress']);
946
});
947
@@ -971,16 +967,14 @@ describe('Event responder: Press', () => {
967
968
ReactDOM.render(element, container);
969
ref.current.getBoundingClientRect = getBoundingClientRectMock;
974
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
970
+ ref.current.dispatchEvent(createEvent('pointerdown'));
971
ref.current.dispatchEvent(
976
- createPointerEvent('pointermove', {
972
+ createEvent('pointermove', {
973
pageX: rectMock.left - pressRetentionOffset.left,
974
pageY: rectMock.top - pressRetentionOffset.top,
975
}),
976
);
981
- ref.current.dispatchEvent(
982
- createPointerEvent('pointerup', coordinatesInside),
983
- );
977
+ ref.current.dispatchEvent(createEvent('pointerup', coordinatesInside));
978
expect(events).toEqual([
979
'onPressStart',
980
'onPressChange',
@@ -1009,7 +1003,7 @@ describe('Event responder: Press', () => {
1003
1004
ReactDOM.render(element, container);
1005
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1012
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1006
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1007
// emulate smaller dimensions change on activation
1008
ref.current.getBoundingClientRect = () => ({
1009
width: 80,
@@ -1024,10 +1018,8 @@ describe('Event responder: Press', () => {
1018
pageY: rectMock.top,
1019
};
1020
// move to an area within the pre-activation region
1027
- ref.current.dispatchEvent(
1028
- createPointerEvent('pointermove', coordinates),
1029
- );
1030
- ref.current.dispatchEvent(createPointerEvent('pointerup', coordinates));
1021
+ ref.current.dispatchEvent(createEvent('pointermove', coordinates));
1022
+ ref.current.dispatchEvent(createEvent('pointerup', coordinates));
1023
expect(events).toEqual(['onPressStart', 'onPressEnd', 'onPress']);
1024
});
1025
@@ -1049,7 +1041,7 @@ describe('Event responder: Press', () => {
1041
1042
ReactDOM.render(element, container);
1043
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1052
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1044
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1045
// emulate larger dimensions change on activation
1046
ref.current.getBoundingClientRect = () => ({
1047
width: 200,
@@ -1064,10 +1056,8 @@ describe('Event responder: Press', () => {
1056
pageY: rectMock.top - 50,
1057
};
1058
// move to an area within the post-activation region
1067
- ref.current.dispatchEvent(
1068
- createPointerEvent('pointermove', coordinates),
1069
- );
1070
- ref.current.dispatchEvent(createPointerEvent('pointerup', coordinates));
1059
+ ref.current.dispatchEvent(createEvent('pointermove', coordinates));
1060
+ ref.current.dispatchEvent(createEvent('pointerup', coordinates));
1061
expect(events).toEqual(['onPressStart', 'onPressEnd', 'onPress']);
1062
});
1063
});
@@ -1103,16 +1093,12 @@ describe('Event responder: Press', () => {
1093
ReactDOM.render(element, container);
1094
1095
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1106
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1096
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1097
ref.current.dispatchEvent(
1108
- createPointerEvent('pointermove', coordinatesInside),
1109
- );
1110
- container.dispatchEvent(
1111
- createPointerEvent('pointermove', coordinatesOutside),
1112
- );
1113
- container.dispatchEvent(
1114
- createPointerEvent('pointerup', coordinatesOutside),
1098
+ createEvent('pointermove', coordinatesInside),
1099
);
1100
+ container.dispatchEvent(createEvent('pointermove', coordinatesOutside));
1101
+ container.dispatchEvent(createEvent('pointerup', coordinatesOutside));
1102
jest.runAllTimers();
1103
1104
expect(events).toEqual([
@@ -1148,19 +1134,15 @@ describe('Event responder: Press', () => {
1134
ReactDOM.render(element, container);
1135
1136
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1151
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1137
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1138
ref.current.dispatchEvent(
1153
- createPointerEvent('pointermove', coordinatesInside),
1154
- );
1155
- container.dispatchEvent(
1156
- createPointerEvent('pointermove', coordinatesOutside),
1139
+ createEvent('pointermove', coordinatesInside),
1140
);
1141
+ container.dispatchEvent(createEvent('pointermove', coordinatesOutside));
1142
jest.runAllTimers();
1143
expect(events).toEqual(['onPressMove']);
1144
events = [];
1161
- container.dispatchEvent(
1162
- createPointerEvent('pointerup', coordinatesOutside),
1163
- );
1145
+ container.dispatchEvent(createEvent('pointerup', coordinatesOutside));
1146
jest.runAllTimers();
1147
expect(events).toEqual([]);
1148
});
@@ -1188,24 +1170,24 @@ describe('Event responder: Press', () => {
1170
1171
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1172
ref.current.dispatchEvent(
1191
- createPointerEvent('pointerdown', {
1173
+ createEvent('pointerdown', {
1174
pointerType: 'mouse',
1175
}),
1176
);
1177
ref.current.dispatchEvent(
1196
- createPointerEvent('pointermove', {
1178
+ createEvent('pointermove', {
1179
...coordinatesInside,
1180
pointerType: 'mouse',
1181
}),
1182
);
1183
container.dispatchEvent(
1202
- createPointerEvent('pointermove', {
1184
+ createEvent('pointermove', {
1185
...coordinatesOutside,
1186
pointerType: 'mouse',
1187
}),
1188
);
1189
container.dispatchEvent(
1208
- createPointerEvent('pointerup', {
1190
+ createEvent('pointerup', {
1191
...coordinatesOutside,
1192
pointerType: 'mouse',
1193
}),
@@ -1243,30 +1225,30 @@ describe('Event responder: Press', () => {
1225
1226
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1227
ref.current.dispatchEvent(
1246
- createPointerEvent('pointerdown', {
1228
+ createEvent('pointerdown', {
1229
pointerType: 'mouse',
1230
}),
1231
);
1232
ref.current.dispatchEvent(
1251
- createPointerEvent('pointermove', {
1233
+ createEvent('pointermove', {
1234
...coordinatesInside,
1235
pointerType: 'mouse',
1236
}),
1237
);
1238
container.dispatchEvent(
1257
- createPointerEvent('pointermove', {
1239
+ createEvent('pointermove', {
1240
...coordinatesOutside,
1241
pointerType: 'mouse',
1242
}),
1243
);
1244
container.dispatchEvent(
1263
- createPointerEvent('pointermove', {
1245
+ createEvent('pointermove', {
1246
...coordinatesInside,
1247
pointerType: 'mouse',
1248
}),
1249
);
1250
container.dispatchEvent(
1269
- createPointerEvent('pointerup', {
1251
+ createEvent('pointerup', {
1252
...coordinatesInside,
1253
pointerType: 'mouse',
1254
}),
@@ -1309,30 +1291,404 @@ describe('Event responder: Press', () => {
1291
1292
ref.current.getBoundingClientRect = getBoundingClientRectMock;
1293
ref.current.dispatchEvent(
1312
- createPointerEvent('pointerdown', {
1294
+ createEvent('pointerdown', {
1295
+ pointerType: 'touch',
1296
+ }),
1297
+ );
1298
+ ref.current.dispatchEvent(
1299
+ createEvent('pointermove', {
1300
+ ...coordinatesInside,
1301
+ pointerType: 'touch',
1302
+ }),
1303
+ );
1304
+ container.dispatchEvent(
1305
+ createEvent('pointermove', {
1306
+ ...coordinatesOutside,
1307
+ pointerType: 'touch',
1308
+ }),
1309
+ );
1310
+ container.dispatchEvent(
1311
+ createEvent('pointermove', {
1312
+ ...coordinatesInside,
1313
+ pointerType: 'touch',
1314
+ }),
1315
+ );
1316
+ container.dispatchEvent(
1317
+ createEvent('pointerup', {
1318
+ ...coordinatesInside,
1319
+ pointerType: 'touch',
1320
+ }),
1321
+ );
1322
+ jest.runAllTimers();
1323
+
1324
+ expect(events).toEqual([
1325
+ 'onPressStart',
1326
+ 'onPressChange',
1327
+ 'onPressMove',
1328
+ 'onPressEnd',
1329
+ 'onPressChange',
1330
+ 'onPressStart',
1331
+ 'onPressChange',
1332
+ 'onPressEnd',
1333
+ 'onPressChange',
1334
+ 'onPress',
1335
+ ]);
1336
+ });
1337
+ });
1338
+
1339
+ describe('press with movement (touch events fallback)', () => {
1340
+ const rectMock = {
1341
+ width: 100,
1342
+ height: 100,
1343
+ top: 50,
1344
+ left: 50,
1345
+ right: 500,
1346
+ bottom: 500,
1347
+ };
1348
+ const pressRectOffset = 20;
1349
+ const getBoundingClientRectMock = () => rectMock;
1350
+ const coordinatesInside = {
1351
+ changedTouches: [
1352
+ {
1353
+ pageX: rectMock.left - pressRectOffset,
1354
+ pageY: rectMock.top - pressRectOffset,
1355
+ },
1356
+ ],
1357
+ };
1358
+ const coordinatesOutside = {
1359
+ changedTouches: [
1360
+ {
1361
+ pageX: rectMock.left - pressRectOffset - 1,
1362
+ pageY: rectMock.top - pressRectOffset - 1,
1363
+ },
1364
+ ],
1365
+ };
1366
+
1367
+ describe('within bounds of hit rect', () => {
1368
+ /** ┌──────────────────┐
1369
+ * │ ┌────────────┐ │
1370
+ * │ │ VisualRect │ │
1371
+ * │ └────────────┘ │
1372
+ * │ HitRect X │ <= Move to X and release
1373
+ * └──────────────────┘
1374
+ */
1375
+ it('no delay and "onPress*" events are called immediately', () => {
1376
+ let events = [];
1377
+ const ref = React.createRef();
1378
+ const createEventHandler = msg => () => {
1379
+ events.push(msg);
1380
+ };
1381
+
1382
+ const element = (
1383
+ <Press
1384
+ onPress={createEventHandler('onPress')}
1385
+ onPressChange={createEventHandler('onPressChange')}
1386
+ onPressMove={createEventHandler('onPressMove')}
1387
+ onPressStart={createEventHandler('onPressStart')}
1388
+ onPressEnd={createEventHandler('onPressEnd')}>
1389
+ <div ref={ref} />
1390
+ </Press>
1391
+ );
1392
+
1393
+ ReactDOM.render(element, container);
1394
+
1395
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1396
+ ref.current.dispatchEvent(createEvent('touchstart'));
1397
+ ref.current.dispatchEvent(createEvent('touchmove', coordinatesInside));
1398
+ ref.current.dispatchEvent(createEvent('touchend', coordinatesInside));
1399
+ jest.runAllTimers();
1400
+
1401
+ expect(events).toEqual([
1402
+ 'onPressStart',
1403
+ 'onPressChange',
1404
+ 'onPressMove',
1405
+ 'onPressEnd',
1406
+ 'onPressChange',
1407
+ 'onPress',
1408
+ ]);
1409
+ });
1410
+
1411
+ it('delay and "onPressMove" is called before "onPress*" events', () => {
1412
+ let events = [];
1413
+ const ref = React.createRef();
1414
+ const createEventHandler = msg => () => {
1415
+ events.push(msg);
1416
+ };
1417
+
1418
+ const element = (
1419
+ <Press
1420
+ delayPressStart={500}
1421
+ onPress={createEventHandler('onPress')}
1422
+ onPressChange={createEventHandler('onPressChange')}
1423
+ onPressMove={createEventHandler('onPressMove')}
1424
+ onPressStart={createEventHandler('onPressStart')}
1425
+ onPressEnd={createEventHandler('onPressEnd')}>
1426
+ <div ref={ref} />
1427
+ </Press>
1428
+ );
1429
+
1430
+ ReactDOM.render(element, container);
1431
+
1432
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1433
+ ref.current.dispatchEvent(createEvent('touchstart'));
1434
+ ref.current.dispatchEvent(createEvent('touchmove', coordinatesInside));
1435
+ jest.advanceTimersByTime(499);
1436
+ expect(events).toEqual(['onPressMove']);
1437
+ events = [];
1438
+
1439
+ jest.advanceTimersByTime(1);
1440
+ expect(events).toEqual(['onPressStart', 'onPressChange']);
1441
+ events = [];
1442
+
1443
+ ref.current.dispatchEvent(createEvent('touchend', coordinatesInside));
1444
+ expect(events).toEqual(['onPressEnd', 'onPressChange', 'onPress']);
1445
+ });
1446
+
1447
+ it('press retention offset can be configured', () => {
1448
+ let events = [];
1449
+ const ref = React.createRef();
1450
+ const createEventHandler = msg => () => {
1451
+ events.push(msg);
1452
+ };
1453
+ const pressRetentionOffset = {top: 40, bottom: 40, left: 40, right: 40};
1454
+
1455
+ const element = (
1456
+ <Press
1457
+ pressRetentionOffset={pressRetentionOffset}
1458
+ onPress={createEventHandler('onPress')}
1459
+ onPressChange={createEventHandler('onPressChange')}
1460
+ onPressMove={createEventHandler('onPressMove')}
1461
+ onPressStart={createEventHandler('onPressStart')}
1462
+ onPressEnd={createEventHandler('onPressEnd')}>
1463
+ <div ref={ref} />
1464
+ </Press>
1465
+ );
1466
+
1467
+ ReactDOM.render(element, container);
1468
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1469
+ ref.current.dispatchEvent(createEvent('touchstart'));
1470
+ ref.current.dispatchEvent(
1471
+ createEvent('touchmove', {
1472
+ pageX: rectMock.left - pressRetentionOffset.left,
1473
+ pageY: rectMock.top - pressRetentionOffset.top,
1474
+ }),
1475
+ );
1476
+ ref.current.dispatchEvent(createEvent('touchend', coordinatesInside));
1477
+ expect(events).toEqual([
1478
+ 'onPressStart',
1479
+ 'onPressChange',
1480
+ 'onPressMove',
1481
+ 'onPressEnd',
1482
+ 'onPressChange',
1483
+ 'onPress',
1484
+ ]);
1485
+ });
1486
+
1487
+ it('responder region accounts for decrease in element dimensions', () => {
1488
+ let events = [];
1489
+ const ref = React.createRef();
1490
+ const createEventHandler = msg => () => {
1491
+ events.push(msg);
1492
+ };
1493
+
1494
+ const element = (
1495
+ <Press
1496
+ onPress={createEventHandler('onPress')}
1497
+ onPressStart={createEventHandler('onPressStart')}
1498
+ onPressEnd={createEventHandler('onPressEnd')}>
1499
+ <div ref={ref} />
1500
+ </Press>
1501
+ );
1502
+
1503
+ ReactDOM.render(element, container);
1504
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1505
+ ref.current.dispatchEvent(createEvent('touchstart'));
1506
+ // emulate smaller dimensions change on activation
1507
+ ref.current.getBoundingClientRect = () => ({
1508
+ width: 80,
1509
+ height: 80,
1510
+ top: 60,
1511
+ left: 60,
1512
+ right: 490,
1513
+ bottom: 490,
1514
+ });
1515
+ const coordinates = {
1516
+ pageX: rectMock.left,
1517
+ pageY: rectMock.top,
1518
+ };
1519
+ // move to an area within the pre-activation region
1520
+ ref.current.dispatchEvent(createEvent('touchmove', coordinates));
1521
+ ref.current.dispatchEvent(createEvent('touchend', coordinates));
1522
+ expect(events).toEqual(['onPressStart', 'onPressEnd', 'onPress']);
1523
+ });
1524
+
1525
+ it('responder region accounts for increase in element dimensions', () => {
1526
+ let events = [];
1527
+ const ref = React.createRef();
1528
+ const createEventHandler = msg => () => {
1529
+ events.push(msg);
1530
+ };
1531
+
1532
+ const element = (
1533
+ <Press
1534
+ onPress={createEventHandler('onPress')}
1535
+ onPressStart={createEventHandler('onPressStart')}
1536
+ onPressEnd={createEventHandler('onPressEnd')}>
1537
+ <div ref={ref} />
1538
+ </Press>
1539
+ );
1540
+
1541
+ ReactDOM.render(element, container);
1542
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1543
+ ref.current.dispatchEvent(createEvent('touchstart'));
1544
+ // emulate larger dimensions change on activation
1545
+ ref.current.getBoundingClientRect = () => ({
1546
+ width: 200,
1547
+ height: 200,
1548
+ top: 0,
1549
+ left: 0,
1550
+ right: 550,
1551
+ bottom: 550,
1552
+ });
1553
+ const coordinates = {
1554
+ pageX: rectMock.left - 50,
1555
+ pageY: rectMock.top - 50,
1556
+ };
1557
+ // move to an area within the post-activation region
1558
+ ref.current.dispatchEvent(createEvent('touchmove', coordinates));
1559
+ ref.current.dispatchEvent(createEvent('touchend', coordinates));
1560
+ expect(events).toEqual(['onPressStart', 'onPressEnd', 'onPress']);
1561
+ });
1562
+ });
1563
+
1564
+ describe('beyond bounds of hit rect', () => {
1565
+ /** ┌──────────────────┐
1566
+ * │ ┌────────────┐ │
1567
+ * │ │ VisualRect │ │
1568
+ * │ └────────────┘ │
1569
+ * │ HitRect │
1570
+ * └──────────────────┘
1571
+ * X <= Move to X and release
1572
+ */
1573
+
1574
+ it('"onPress" is not called on release', () => {
1575
+ let events = [];
1576
+ const ref = React.createRef();
1577
+ const createEventHandler = msg => () => {
1578
+ events.push(msg);
1579
+ };
1580
+
1581
+ const element = (
1582
+ <Press
1583
+ onPress={createEventHandler('onPress')}
1584
+ onPressChange={createEventHandler('onPressChange')}
1585
+ onPressMove={createEventHandler('onPressMove')}
1586
+ onPressStart={createEventHandler('onPressStart')}
1587
+ onPressEnd={createEventHandler('onPressEnd')}>
1588
+ <div ref={ref} />
1589
+ </Press>
1590
+ );
1591
+
1592
+ ReactDOM.render(element, container);
1593
+
1594
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1595
+ ref.current.dispatchEvent(createEvent('touchstart'));
1596
+ ref.current.dispatchEvent(createEvent('touchmove', coordinatesInside));
1597
+ container.dispatchEvent(createEvent('touchmove', coordinatesOutside));
1598
+ container.dispatchEvent(createEvent('touchend', coordinatesOutside));
1599
+ jest.runAllTimers();
1600
+
1601
+ expect(events).toEqual([
1602
+ 'onPressStart',
1603
+ 'onPressChange',
1604
+ 'onPressMove',
1605
+ 'onPressEnd',
1606
+ 'onPressChange',
1607
+ ]);
1608
+ });
1609
+
1610
+ it('"onPress*" events are not called after delay expires', () => {
1611
+ let events = [];
1612
+ const ref = React.createRef();
1613
+ const createEventHandler = msg => () => {
1614
+ events.push(msg);
1615
+ };
1616
+
1617
+ const element = (
1618
+ <Press
1619
+ delayPressStart={500}
1620
+ delayPressEnd={500}
1621
+ onLongPress={createEventHandler('onLongPress')}
1622
+ onPress={createEventHandler('onPress')}
1623
+ onPressChange={createEventHandler('onPressChange')}
1624
+ onPressMove={createEventHandler('onPressMove')}
1625
+ onPressStart={createEventHandler('onPressStart')}
1626
+ onPressEnd={createEventHandler('onPressEnd')}>
1627
+ <div ref={ref} />
1628
+ </Press>
1629
+ );
1630
+
1631
+ ReactDOM.render(element, container);
1632
+
1633
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1634
+ ref.current.dispatchEvent(createEvent('touchstart'));
1635
+ ref.current.dispatchEvent(createEvent('touchmove', coordinatesInside));
1636
+ container.dispatchEvent(createEvent('touchmove', coordinatesOutside));
1637
+ jest.runAllTimers();
1638
+ expect(events).toEqual(['onPressMove']);
1639
+ events = [];
1640
+ container.dispatchEvent(createEvent('touchend', coordinatesOutside));
1641
+ jest.runAllTimers();
1642
+ expect(events).toEqual([]);
1643
+ });
1644
+ });
1645
+
1646
+ it('"onPress" is called on re-entry to hit rect for touch', () => {
1647
+ let events = [];
1648
+ const ref = React.createRef();
1649
+ const createEventHandler = msg => () => {
1650
+ events.push(msg);
1651
+ };
1652
+
1653
+ const element = (
1654
+ <Press
1655
+ onPress={createEventHandler('onPress')}
1656
+ onPressChange={createEventHandler('onPressChange')}
1657
+ onPressMove={createEventHandler('onPressMove')}
1658
+ onPressStart={createEventHandler('onPressStart')}
1659
+ onPressEnd={createEventHandler('onPressEnd')}>
1660
+ <div ref={ref} />
1661
+ </Press>
1662
+ );
1663
+
1664
+ ReactDOM.render(element, container);
1665
+
1666
+ ref.current.getBoundingClientRect = getBoundingClientRectMock;
1667
+ ref.current.dispatchEvent(
1668
+ createEvent('touchstart', {
1669
pointerType: 'touch',
1670
}),
1671
);
1672
ref.current.dispatchEvent(
1317
- createPointerEvent('pointermove', {
1673
+ createEvent('touchmove', {
1674
...coordinatesInside,
1675
pointerType: 'touch',
1676
}),
1677
);
1678
container.dispatchEvent(
1323
- createPointerEvent('pointermove', {
1679
+ createEvent('touchmove', {
1680
...coordinatesOutside,
1681
pointerType: 'touch',
1682
}),
1683
);
1684
container.dispatchEvent(
1329
- createPointerEvent('pointermove', {
1685
+ createEvent('touchmove', {
1686
...coordinatesInside,
1687
pointerType: 'touch',
1688
}),
1689
);
1690
container.dispatchEvent(
1335
- createPointerEvent('pointerup', {
1691
+ createEvent('touchend', {
1692
...coordinatesInside,
1693
pointerType: 'touch',
1694
}),
@@ -1386,13 +1742,13 @@ describe('Event responder: Press', () => {
1742
1743
// 1
1744
events = [];
1389
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1745
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1746
ref.current.dispatchEvent(
1391
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
1747
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
1748
);
1393
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1749
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1750
ref.current.dispatchEvent(
1395
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
1751
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
1752
);
1753
jest.runAllTimers();
1754
@@ -1408,11 +1764,11 @@ describe('Event responder: Press', () => {
1764
1765
// 2
1766
events = [];
1411
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1767
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1768
jest.advanceTimersByTime(250);
1769
jest.advanceTimersByTime(500);
1770
ref.current.dispatchEvent(
1415
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
1771
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
1772
);
1773
jest.runAllTimers();
1774
@@ -1468,9 +1824,9 @@ describe('Event responder: Press', () => {
1824
right: 0,
1825
});
1826
1471
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1827
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1828
ref.current.dispatchEvent(
1473
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
1829
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
1830
);
1831
expect(events).toEqual([
1832
'inner: onPressStart',
@@ -1502,9 +1858,9 @@ describe('Event responder: Press', () => {
1858
right: 0,
1859
});
1860
1505
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1861
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1862
ref.current.dispatchEvent(
1507
- createPointerEvent('pointerup', {pageX: 10, pageY: 10}),
1863
+ createEvent('pointerup', {pageX: 10, pageY: 10}),
1864
);
1865
expect(fn).toHaveBeenCalledTimes(1);
1866
});
@@ -1521,9 +1877,9 @@ describe('Event responder: Press', () => {
1877
);
1878
ReactDOM.render(element, container);
1879
1524
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1880
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1881
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
1526
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1882
+ ref.current.dispatchEvent(createEvent('pointerup'));
1883
expect(fn).toHaveBeenCalledTimes(1);
1884
});
1885
@@ -1540,10 +1896,10 @@ describe('Event responder: Press', () => {
1896
);
1897
ReactDOM.render(element, container);
1898
1543
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1899
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1900
expect(fn).toHaveBeenCalledTimes(1);
1901
expect(fn2).toHaveBeenCalledTimes(0);
1546
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1902
+ ref.current.dispatchEvent(createEvent('pointerup'));
1903
expect(fn).toHaveBeenCalledTimes(1);
1904
expect(fn2).toHaveBeenCalledTimes(1);
1905
});
@@ -1560,9 +1916,9 @@ describe('Event responder: Press', () => {
1916
);
1917
ReactDOM.render(element, container);
1918
1563
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1919
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1920
expect(fn).toHaveBeenCalledTimes(1);
1565
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1921
+ ref.current.dispatchEvent(createEvent('pointerup'));
1922
expect(fn).toHaveBeenCalledTimes(2);
1923
});
1924
});
@@ -1580,9 +1936,9 @@ describe('Event responder: Press', () => {
1936
);
1937
ReactDOM.render(element, container);
1938
1583
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1584
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1585
- ref.current.dispatchEvent(createPointerEvent('click', {preventDefault}));
1939
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1940
+ ref.current.dispatchEvent(createEvent('pointerup'));
1941
+ ref.current.dispatchEvent(createEvent('click', {preventDefault}));
1942
expect(preventDefault).toBeCalled();
1943
});
1944
@@ -1599,13 +1955,13 @@ describe('Event responder: Press', () => {
1955
1956
['metaKey', 'ctrlKey', 'shiftKey'].forEach(modifierKey => {
1957
ref.current.dispatchEvent(
1602
- createPointerEvent('pointerdown', {[modifierKey]: true}),
1958
+ createEvent('pointerdown', {[modifierKey]: true}),
1959
);
1960
ref.current.dispatchEvent(
1605
- createPointerEvent('pointerup', {[modifierKey]: true}),
1961
+ createEvent('pointerup', {[modifierKey]: true}),
1962
);
1963
ref.current.dispatchEvent(
1608
- createPointerEvent('click', {[modifierKey]: true, preventDefault}),
1964
+ createEvent('click', {[modifierKey]: true, preventDefault}),
1965
);
1966
expect(preventDefault).not.toBeCalled();
1967
});
@@ -1622,9 +1978,9 @@ describe('Event responder: Press', () => {
1978
);
1979
ReactDOM.render(element, container);
1980
1625
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1626
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1627
- ref.current.dispatchEvent(createPointerEvent('click', {preventDefault}));
1981
+ ref.current.dispatchEvent(createEvent('pointerdown'));
1982
+ ref.current.dispatchEvent(createEvent('pointerup'));
1983
+ ref.current.dispatchEvent(createEvent('click', {preventDefault}));
1984
expect(preventDefault).not.toBeCalled();
1985
});
1986
});
@@ -1641,8 +1997,8 @@ describe('Event responder: Press', () => {
1997
);
1998
ReactDOM.render(element, container);
1999
1644
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1645
- ref.current.dispatchEvent(createPointerEvent('scroll'));
2000
+ ref.current.dispatchEvent(createEvent('pointerdown'));
2001
+ ref.current.dispatchEvent(createEvent('scroll'));
2002
expect(onPressEnd).toHaveBeenCalledTimes(1);
2003
jest.runAllTimers();
2004
expect(onLongPress).not.toBeCalled();
@@ -1651,8 +2007,8 @@ describe('Event responder: Press', () => {
2007
onPressEnd.mockReset();
2008
2009
// When pointer events are supported
1654
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
1655
- ref.current.dispatchEvent(createPointerEvent('pointercancel'));
2010
+ ref.current.dispatchEvent(createEvent('pointerdown'));
2011
+ ref.current.dispatchEvent(createEvent('pointercancel'));
2012
expect(onPressEnd).toHaveBeenCalledTimes(1);
2013
jest.runAllTimers();
2014
expect(onLongPress).not.toBeCalled();
@@ -1661,8 +2017,8 @@ describe('Event responder: Press', () => {
2017
onPressEnd.mockReset();
2018
2019
// Touch fallback
1664
- ref.current.dispatchEvent(createPointerEvent('touchstart'));
1665
- ref.current.dispatchEvent(createPointerEvent('touchcancel'));
2020
+ ref.current.dispatchEvent(createEvent('touchstart'));
2021
+ ref.current.dispatchEvent(createEvent('touchcancel'));
2022
expect(onPressEnd).toHaveBeenCalledTimes(1);
2023
jest.runAllTimers();
2024
expect(onLongPress).not.toBeCalled();
@@ -1671,8 +2027,8 @@ describe('Event responder: Press', () => {
2027
onPressEnd.mockReset();
2028
2029
// Mouse fallback
1674
- ref.current.dispatchEvent(createPointerEvent('mousedown'));
1675
- ref.current.dispatchEvent(createPointerEvent('dragstart'));
2030
+ ref.current.dispatchEvent(createEvent('mousedown'));
2031
+ ref.current.dispatchEvent(createEvent('dragstart'));
2032
expect(onPressEnd).toHaveBeenCalledTimes(1);
2033
jest.runAllTimers();
2034
expect(onLongPress).not.toBeCalled();
@@ -1692,11 +2048,11 @@ describe('Event responder: Press', () => {
2048
);
2049
ReactDOM.render(element, container);
2050
1695
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
2051
+ ref.current.dispatchEvent(createEvent('pointerdown'));
2052
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
1697
- ref.current.dispatchEvent(createPointerEvent('pointermove'));
1698
- ref.current.dispatchEvent(createPointerEvent('pointerup'));
1699
- ref.current.dispatchEvent(createPointerEvent('pointerdown'));
2053
+ ref.current.dispatchEvent(createEvent('pointermove'));
2054
+ ref.current.dispatchEvent(createEvent('pointerup'));
2055
+ ref.current.dispatchEvent(createEvent('pointerdown'));
2056
ReactDOM.render(element, container);
2057
});
2058
});