Skip to content

Commit e4e8686

Browse files
committed
tweaks
1 parent 6431b95 commit e4e8686

File tree

5 files changed

+73
-100
lines changed

5 files changed

+73
-100
lines changed

src/__tests__/event-handler.test.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as React from 'react';
22
import { Text, View } from 'react-native';
33

44
import { render, screen } from '..';
5-
import { getEventHandler } from '../event-handler';
5+
import { getEventHandlerFromProps } from '../event-handler';
66

77
test('getEventHandler strict mode', () => {
88
const onPress = jest.fn();
@@ -22,13 +22,13 @@ test('getEventHandler strict mode', () => {
2222
const testOnly = screen.getByTestId('testOnly');
2323
const both = screen.getByTestId('both');
2424

25-
expect(getEventHandler(regular, 'press')).toBe(onPress);
26-
expect(getEventHandler(testOnly, 'press')).toBe(testOnlyOnPress);
27-
expect(getEventHandler(both, 'press')).toBe(onPress);
25+
expect(getEventHandlerFromProps(regular.props, 'press')).toBe(onPress);
26+
expect(getEventHandlerFromProps(testOnly.props, 'press')).toBe(testOnlyOnPress);
27+
expect(getEventHandlerFromProps(both.props, 'press')).toBe(onPress);
2828

29-
expect(getEventHandler(regular, 'onPress')).toBe(undefined);
30-
expect(getEventHandler(testOnly, 'onPress')).toBe(undefined);
31-
expect(getEventHandler(both, 'onPress')).toBe(undefined);
29+
expect(getEventHandlerFromProps(regular.props, 'onPress')).toBe(undefined);
30+
expect(getEventHandlerFromProps(testOnly.props, 'onPress')).toBe(undefined);
31+
expect(getEventHandlerFromProps(both.props, 'onPress')).toBe(undefined);
3232
});
3333

3434
test('getEventHandler loose mode', () => {
@@ -49,11 +49,13 @@ test('getEventHandler loose mode', () => {
4949
const testOnly = screen.getByTestId('testOnly');
5050
const both = screen.getByTestId('both');
5151

52-
expect(getEventHandler(regular, 'press', { loose: true })).toBe(onPress);
53-
expect(getEventHandler(testOnly, 'press', { loose: true })).toBe(testOnlyOnPress);
54-
expect(getEventHandler(both, 'press', { loose: true })).toBe(onPress);
52+
expect(getEventHandlerFromProps(regular.props, 'press', { loose: true })).toBe(onPress);
53+
expect(getEventHandlerFromProps(testOnly.props, 'press', { loose: true })).toBe(testOnlyOnPress);
54+
expect(getEventHandlerFromProps(both.props, 'press', { loose: true })).toBe(onPress);
5555

56-
expect(getEventHandler(regular, 'onPress', { loose: true })).toBe(onPress);
57-
expect(getEventHandler(testOnly, 'onPress', { loose: true })).toBe(testOnlyOnPress);
58-
expect(getEventHandler(both, 'onPress', { loose: true })).toBe(onPress);
56+
expect(getEventHandlerFromProps(regular.props, 'onPress', { loose: true })).toBe(onPress);
57+
expect(getEventHandlerFromProps(testOnly.props, 'onPress', { loose: true })).toBe(
58+
testOnlyOnPress,
59+
);
60+
expect(getEventHandlerFromProps(both.props, 'onPress', { loose: true })).toBe(onPress);
5961
});

src/event-handler.ts

Lines changed: 12 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,30 @@
1-
import type { HostElement } from 'universal-test-renderer';
1+
export type EventHandler = (...args: unknown[]) => unknown;
22

33
export type EventHandlerOptions = {
44
/** Include check for event handler named without adding `on*` prefix. */
55
loose?: boolean;
66
};
77

8-
export function getEventHandler(
9-
element: HostElement,
8+
export function getEventHandlerFromProps(
9+
props: Record<string, unknown>,
1010
eventName: string,
1111
options?: EventHandlerOptions,
12-
) {
12+
): EventHandler | undefined {
1313
const handlerName = getEventHandlerName(eventName);
14-
if (typeof element.props[handlerName] === 'function') {
15-
return element.props[handlerName];
14+
if (typeof props[handlerName] === 'function') {
15+
return props[handlerName] as EventHandler;
1616
}
1717

18-
if (options?.loose && typeof element.props[eventName] === 'function') {
19-
return element.props[eventName];
18+
if (options?.loose && typeof props[eventName] === 'function') {
19+
return props[eventName] as EventHandler;
2020
}
2121

22-
if (typeof element.props[`testOnly_${handlerName}`] === 'function') {
23-
return element.props[`testOnly_${handlerName}`];
22+
if (typeof props[`testOnly_${handlerName}`] === 'function') {
23+
return props[`testOnly_${handlerName}`] as EventHandler;
2424
}
2525

26-
if (options?.loose && typeof element.props[`testOnly_${eventName}`] === 'function') {
27-
return element.props[`testOnly_${eventName}`];
28-
}
29-
30-
return undefined;
31-
}
32-
33-
export function getFiberEventHandler(
34-
element: HostElement['unstable_fiber'],
35-
eventName: string,
36-
options?: EventHandlerOptions,
37-
) {
38-
if (element === null || !element.memoizedProps) {
39-
return undefined;
40-
}
41-
42-
const handlerName = getEventHandlerName(eventName);
43-
if (typeof element.memoizedProps[handlerName] === 'function') {
44-
return element.memoizedProps[handlerName];
45-
}
46-
47-
if (options?.loose && typeof element.memoizedProps[eventName] === 'function') {
48-
return element.memoizedProps[eventName];
49-
}
50-
51-
if (typeof element.memoizedProps[`testOnly_${handlerName}`] === 'function') {
52-
return element.memoizedProps[`testOnly_${handlerName}`];
53-
}
54-
55-
if (options?.loose && typeof element.memoizedProps[`testOnly_${eventName}`] === 'function') {
56-
return element.memoizedProps[`testOnly_${eventName}`];
26+
if (options?.loose && typeof props[`testOnly_${eventName}`] === 'function') {
27+
return props[`testOnly_${eventName}`] as EventHandler;
5728
}
5829

5930
return undefined;

src/fire-event.ts

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,16 @@ import type {
88
import type { HostElement } from 'universal-test-renderer';
99

1010
import act from './act';
11-
import { getEventHandler, getFiberEventHandler } from './event-handler';
11+
import type { EventHandler } from './event-handler';
12+
import { getEventHandlerFromProps } from './event-handler';
1213
import { isElementMounted } from './helpers/component-tree';
1314
import { isHostScrollView, isHostTextInput } from './helpers/host-component-names';
1415
import { isPointerEventEnabled } from './helpers/pointer-events';
1516
import { isEditableTextInput } from './helpers/text-input';
1617
import { nativeState } from './native-state';
1718
import type { Point, StringWithAutocomplete } from './types';
1819

19-
type EventHandler = (...args: unknown[]) => unknown;
20-
21-
export function isTouchResponder(element: HostElement) {
22-
return Boolean(element.props.onStartShouldSetResponder) || isHostTextInput(element);
23-
}
20+
type Fiber = HostElement['unstable_fiber'];
2421

2522
/**
2623
* List of events affected by `pointerEvents` prop.
@@ -53,31 +50,6 @@ const textInputEventsIgnoringEditableProp = new Set([
5350
'onScroll',
5451
]);
5552

56-
export function isEventEnabled(
57-
element: HostElement,
58-
eventName: string,
59-
nearestTouchResponder?: HostElement,
60-
) {
61-
if (nearestTouchResponder != null && isHostTextInput(nearestTouchResponder)) {
62-
return (
63-
isEditableTextInput(nearestTouchResponder) ||
64-
textInputEventsIgnoringEditableProp.has(eventName)
65-
);
66-
}
67-
68-
if (eventsAffectedByPointerEventsProp.has(eventName) && !isPointerEventEnabled(element)) {
69-
return false;
70-
}
71-
72-
const touchStart = nearestTouchResponder?.props.onStartShouldSetResponder?.();
73-
const touchMove = nearestTouchResponder?.props.onMoveShouldSetResponder?.();
74-
if (touchStart || touchMove) {
75-
return true;
76-
}
77-
78-
return touchStart === undefined && touchMove === undefined;
79-
}
80-
8153
function findEventHandler(
8254
element: HostElement,
8355
eventName: string,
@@ -86,8 +58,8 @@ function findEventHandler(
8658
const touchResponder = isTouchResponder(element) ? element : nearestTouchResponder;
8759

8860
const handler =
89-
getEventHandler(element, eventName, { loose: true }) ??
90-
findEventHandlerFromFiber(element.unstable_fiber, eventName);
61+
getEventHandlerFromProps(element.props, eventName, { loose: true }) ??
62+
findEventHandlerFromRelatedFibers(element.unstable_fiber, eventName);
9163
if (handler && isEventEnabled(element, eventName, touchResponder)) {
9264
return handler;
9365
}
@@ -99,14 +71,13 @@ function findEventHandler(
9971
return findEventHandler(element.parent, eventName, touchResponder);
10072
}
10173

102-
type Fiber = HostElement['unstable_fiber'];
103-
104-
function findEventHandlerFromFiber(fiber: Fiber, eventName: string): EventHandler | null {
105-
if (fiber === null) {
74+
function findEventHandlerFromRelatedFibers(fiber: Fiber, eventName: string): EventHandler | null {
75+
// Container fibers have memoizedProps set to null
76+
if (!fiber?.memoizedProps) {
10677
return null;
10778
}
10879

109-
const handler = getFiberEventHandler(fiber, eventName, { loose: true });
80+
const handler = getEventHandlerFromProps(fiber.memoizedProps, eventName, { loose: true });
11081
if (handler) {
11182
return handler;
11283
}
@@ -116,7 +87,36 @@ function findEventHandlerFromFiber(fiber: Fiber, eventName: string): EventHandle
11687
return null;
11788
}
11889

119-
return findEventHandlerFromFiber(fiber.return, eventName);
90+
return findEventHandlerFromRelatedFibers(fiber.return, eventName);
91+
}
92+
93+
export function isEventEnabled(
94+
element: HostElement,
95+
eventName: string,
96+
nearestTouchResponder?: HostElement,
97+
) {
98+
if (nearestTouchResponder != null && isHostTextInput(nearestTouchResponder)) {
99+
return (
100+
isEditableTextInput(nearestTouchResponder) ||
101+
textInputEventsIgnoringEditableProp.has(eventName)
102+
);
103+
}
104+
105+
if (eventsAffectedByPointerEventsProp.has(eventName) && !isPointerEventEnabled(element)) {
106+
return false;
107+
}
108+
109+
const touchStart = nearestTouchResponder?.props.onStartShouldSetResponder?.();
110+
const touchMove = nearestTouchResponder?.props.onMoveShouldSetResponder?.();
111+
if (touchStart || touchMove) {
112+
return true;
113+
}
114+
115+
return touchStart === undefined && touchMove === undefined;
116+
}
117+
118+
export function isTouchResponder(element: HostElement) {
119+
return Boolean(element.props.onStartShouldSetResponder) || isHostTextInput(element);
120120
}
121121

122122
// String union type of keys of T that start with on, stripped of 'on'

src/user-event/press/press.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { HostElement } from 'universal-test-renderer';
22

33
import act from '../../act';
4-
import { getEventHandler } from '../../event-handler';
4+
import { getEventHandlerFromProps } from '../../event-handler';
55
import { isHostText, isHostTextInput } from '../../helpers/host-component-names';
66
import { isPointerEventEnabled } from '../../helpers/pointer-events';
77
import { EventBuilder } from '../event-builder';
@@ -84,10 +84,10 @@ function isEnabledTouchResponder(element: HostElement) {
8484

8585
function hasPressEventHandler(element: HostElement) {
8686
return (
87-
getEventHandler(element, 'press') ||
88-
getEventHandler(element, 'longPress') ||
89-
getEventHandler(element, 'pressIn') ||
90-
getEventHandler(element, 'pressOut')
87+
getEventHandlerFromProps(element.props, 'press') ||
88+
getEventHandlerFromProps(element.props, 'longPress') ||
89+
getEventHandlerFromProps(element.props, 'pressIn') ||
90+
getEventHandlerFromProps(element.props, 'pressOut')
9191
);
9292
}
9393

src/user-event/utils/dispatch-event.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { HostElement } from 'universal-test-renderer';
22

33
import act from '../../act';
4-
import { getEventHandler } from '../../event-handler';
4+
import { getEventHandlerFromProps } from '../../event-handler';
55
import { isElementMounted } from '../../helpers/component-tree';
66

77
/**
@@ -16,7 +16,7 @@ export function dispatchEvent(element: HostElement, eventName: string, ...event:
1616
return;
1717
}
1818

19-
const handler = getEventHandler(element, eventName);
19+
const handler = getEventHandlerFromProps(element.props, eventName);
2020
if (!handler) {
2121
return;
2222
}

0 commit comments

Comments
 (0)