[Flare] Listen to document.body + add stopPropagation to Press (#15853)
[Flare] Listen to document.body + add stopPropagation to Press (#15853)
Dominic Gannaway committed
Jun 10, 2019 at 16:51 UTC
f4cd7a38d2a5dc8f9081b41da124ac380d33dc62
3 files changed
+33
-5
packages/react-dom/src/client/ReactDOMHostConfig.js
+4
-3
@@ -897,18 +897,19 @@ export function mountEventComponent(
897
): void {
898
if (enableEventAPI) {
899
const rootContainerInstance = ((eventComponentInstance.rootInstance: any): Container);
900
- const rootElement = rootContainerInstance.ownerDocument;
900
+ const doc = rootContainerInstance.ownerDocument;
901
+ const documentBody = doc.body || doc;
902
const responder = eventComponentInstance.responder;
903
const {rootEventTypes, targetEventTypes} = responder;
904
if (targetEventTypes !== undefined) {
904
- listenToEventResponderEventTypes(targetEventTypes, rootElement);
905
+ listenToEventResponderEventTypes(targetEventTypes, documentBody);
906
}
907
if (rootEventTypes !== undefined) {
908
addRootEventTypesForComponentInstance(
909
eventComponentInstance,
910
rootEventTypes,
911
);
911
- listenToEventResponderEventTypes(rootEventTypes, rootElement);
912
+ listenToEventResponderEventTypes(rootEventTypes, documentBody);
913
}
914
mountEventResponder(eventComponentInstance);
915
}
packages/react-events/src/Press.js
+11
-2
@@ -37,6 +37,7 @@ type PressProps = {
37
left: number,
38
},
39
preventDefault: boolean,
40
+ stopPropagation: boolean,
41
};
42
43
type PointerType = '' | 'mouse' | 'keyboard' | 'pen' | 'touch';
@@ -130,16 +131,18 @@ const rootEventTypes = [
131
'pointermove',
132
'scroll',
133
'pointercancel',
134
+ // We listen to this here so stopPropagation can
135
+ // block other mouseup events used internally
136
+ {name: 'mouseup', passive: false},
137
+ 'touchend',
138
];
139
140
// If PointerEvents is not supported (e.g., Safari), also listen to touch and mouse events.
141
if (typeof window !== 'undefined' && window.PointerEvent === undefined) {
142
targetEventTypes.push('touchstart', 'mousedown');
143
rootEventTypes.push(
139
- {name: 'mouseup', passive: false},
144
'mousemove',
145
'touchmove',
142
- 'touchend',
146
'touchcancel',
147
// Used as a 'cancel' signal for mouse interactions
148
'dragstart',
@@ -617,6 +620,9 @@ const PressResponder = {
620
const nativeEvent: any = event.nativeEvent;
621
const pointerType = context.getEventPointerType(event);
622
623
+ if (props.stopPropagation === true) {
624
+ nativeEvent.stopPropagation();
625
+ }
626
switch (type) {
627
// START
628
case 'pointerdown':
@@ -740,6 +746,9 @@ const PressResponder = {
746
const nativeEvent: any = event.nativeEvent;
747
const pointerType = context.getEventPointerType(event);
748
749
+ if (props.stopPropagation === true) {
750
+ nativeEvent.stopPropagation();
751
+ }
752
switch (type) {
753
// MOVE
754
case 'pointermove':
packages/react-events/src/__tests__/Press-test.internal.js
+18
@@ -2591,4 +2591,22 @@ describe('Event responder: Press', () => {
2591
expect(onContextMenu).toHaveBeenCalledTimes(0);
2592
});
2593
});
2594
+
2595
+ it('should work correctly with stopPropagation set to true', () => {
2596
+ const ref = React.createRef();
2597
+ const element = (
2598
+ <Press stopPropagation={true}>
2599
+ <div ref={ref} />
2600
+ </Press>
2601
+ );
2602
+ const pointerDownEvent = jest.fn();
2603
+ container.addEventListener('pointerdown', pointerDownEvent);
2604
+ ReactDOM.render(element, container);
2605
+
2606
+ ref.current.dispatchEvent(
2607
+ createEvent('pointerdown', {pointerType: 'mouse', button: 0}),
2608
+ );
2609
+ container.removeEventListener('pointerdown', pointerDownEvent);
2610
+ expect(pointerDownEvent).toHaveBeenCalledTimes(0);
2611
+ });
2612
});