[Flare] Ensure mouse events can use target to validate press (#16172)
Dominic Gannaway committed
Jul 22, 2019 at 12:31 UTC
783b8f4ae1320d4a4a1188bf2bd40e8ecb3c1f10
3 files changed
+61
-27
packages/react-dom/src/events/DOMEventResponderSystem.js
+2
-1
@@ -234,10 +234,11 @@ const eventResponderContext: ReactDOMResponderContext = {
234
validateResponderContext();
235
const childFiber = getClosestInstanceFromNode(childTarget);
236
const parentFiber = getClosestInstanceFromNode(parentTarget);
237
+ const parentAlternateFiber = parentFiber.alternate;
238
239
let node = childFiber;
240
while (node !== null) {
240
- if (node === parentFiber) {
241
+ if (node === parentFiber || node === parentAlternateFiber) {
242
return true;
243
}
244
node = node.return;
packages/react-events/src/dom/Press.js
+33
-26
@@ -837,20 +837,22 @@ const PressResponder: ReactDOMEventResponder = {
837
}
838
const pressTarget = state.pressTarget;
839
840
- if (
841
- pressTarget !== null &&
842
- !targetIsDocument(pressTarget) &&
843
- (pointerType !== 'mouse' ||
844
- !context.isTargetWithinNode(target, pressTarget))
845
- ) {
846
- // Calculate the responder region we use for deactivation, as the
847
- // element dimensions may have changed since activation.
848
- updateIsPressWithinResponderRegion(
849
- touchEvent || nativeEvent,
850
- context,
851
- props,
852
- state,
853
- );
840
+ if (pressTarget !== null && !targetIsDocument(pressTarget)) {
841
+ if (
842
+ pointerType === 'mouse' &&
843
+ context.isTargetWithinNode(target, pressTarget)
844
+ ) {
845
+ state.isPressWithinResponderRegion = true;
846
+ } else {
847
+ // Calculate the responder region we use for deactivation, as the
848
+ // element dimensions may have changed since activation.
849
+ updateIsPressWithinResponderRegion(
850
+ touchEvent || nativeEvent,
851
+ context,
852
+ props,
853
+ state,
854
+ );
855
+ }
856
}
857
858
if (state.isPressWithinResponderRegion) {
@@ -958,19 +960,24 @@ const PressResponder: ReactDOMEventResponder = {
960
if (
961
!isKeyboardEvent &&
962
pressTarget !== null &&
961
- !targetIsDocument(pressTarget) &&
962
- (pointerType !== 'mouse' ||
963
- !context.isTargetWithinNode(target, pressTarget))
963
+ !targetIsDocument(pressTarget)
964
) {
965
- // If the event target isn't within the press target, check if we're still
966
- // within the responder region. The region may have changed if the
967
- // element's layout was modified after activation.
968
- updateIsPressWithinResponderRegion(
969
- touchEvent || nativeEvent,
970
- context,
971
- props,
972
- state,
973
- );
965
+ if (
966
+ pointerType === 'mouse' &&
967
+ context.isTargetWithinNode(target, pressTarget)
968
+ ) {
969
+ state.isPressWithinResponderRegion = true;
970
+ } else {
971
+ // If the event target isn't within the press target, check if we're still
972
+ // within the responder region. The region may have changed if the
973
+ // element's layout was modified after activation.
974
+ updateIsPressWithinResponderRegion(
975
+ touchEvent || nativeEvent,
976
+ context,
977
+ props,
978
+ state,
979
+ );
980
+ }
981
}
982
if (state.isPressWithinResponderRegion && button !== 1) {
983
if (
packages/react-events/src/dom/__tests__/Press-test.internal.js
+26
@@ -812,6 +812,32 @@ describe('Event responder: Press', () => {
812
);
813
});
814
815
+ it('is called if target rect is not right but the target is (for mouse events)', () => {
816
+ const buttonRef = React.createRef();
817
+ const divRef = React.createRef();
818
+ const element = (
819
+ <Press onPress={onPress}>
820
+ <div ref={divRef}>
821
+ <button ref={buttonRef} />
822
+ </div>
823
+ </Press>
824
+ );
825
+ ReactDOM.render(element, container);
826
+ divRef.current.getBoundingClientRect = () => ({
827
+ left: 0,
828
+ right: 0,
829
+ bottom: 0,
830
+ top: 0,
831
+ });
832
+ buttonRef.current.dispatchEvent(
833
+ createEvent('pointerdown', {pointerType: 'mouse'}),
834
+ );
835
+ buttonRef.current.dispatchEvent(
836
+ createEvent('pointerup', {pointerType: 'mouse'}),
837
+ );
838
+ expect(onPress).toBeCalled();
839
+ });
840
+
841
// No PointerEvent fallbacks
842
// TODO: jsdom missing APIs
843
// it('is called after "touchend" event', () => {