@samitouri / QOS-React-2 / commits / 783b8f4ae1

[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', () => {