Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,8 @@
// Check for referential equality
expect(ref1.current).toBe(event.target);
expect(ref1.current).toBe(event.currentTarget);

expect(global.event).toBe(event);
}}
onStartShouldSetResponder={() => true}
/>
Expand All @@ -1110,6 +1112,8 @@
// Check for referential equality
expect(ref2.current).toBe(event.target);
expect(ref2.current).toBe(event.currentTarget);

expect(global.event).toBe(event);
}}
onStartShouldSetResponder={() => true}
/>
Expand All @@ -1123,6 +1127,9 @@
const [dispatchEvent] =
nativeFabricUIManager.registerEventHandler.mock.calls[0];

const preexistingEvent = {};
global.event = preexistingEvent;

dispatchEvent(getViewById('one').instanceHandle, 'topTouchStart', {
target: getViewById('one').reactTag,
identifier: 17,
Expand Down Expand Up @@ -1150,7 +1157,141 @@
changedTouches: [],
});

expect.assertions(6);
expect(global.event).toBe(preexistingEvent);

expect.assertions(9);
});

it('propagates timeStamps from native events and sets defaults', async () => {
const View = createReactNativeComponentClass('RCTView', () => ({
validAttributes: {
id: true,
},
uiViewClassName: 'RCTView',
directEventTypes: {
topTouchStart: {
registrationName: 'onTouchStart',
},
topTouchEnd: {
registrationName: 'onTouchEnd',
},
},
}));

function getViewById(id) {
const [reactTag, , , , instanceHandle] =
nativeFabricUIManager.createNode.mock.calls.find(
args => args[3] && args[3].id === id,
);

return {reactTag, instanceHandle};
}

const ref1 = React.createRef();
const ref2 = React.createRef();
const ref3 = React.createRef();

Check failure on line 1192 in packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js

View workflow job for this annotation

GitHub Actions / Run eslint

'ref3' is assigned a value but never used

Check failure on line 1192 in packages/react-native-renderer/src/__tests__/ReactFabric-test.internal.js

View workflow job for this annotation

GitHub Actions / Run eslint

'ref3' is assigned a value but never used

const explicitTimeStampCamelCase = 'explicit-timestamp-camelcase';
const explicitTimeStampLowerCase = 'explicit-timestamp-lowercase';
const performanceNowValue = 'performance-now-timestamp';

jest.spyOn(performance, 'now').mockReturnValue(performanceNowValue);

await act(() => {
ReactFabric.render(
<>
<View
ref={ref1}
id="default"
onTouchEnd={event => {
expect(event.timeStamp).toBe(performanceNowValue);
}}
/>
<View
ref={ref2}
id="explicitTimeStampCamelCase"
onTouchEnd={event => {
expect(event.timeStamp).toBe(explicitTimeStampCamelCase);
}}
/>
<View
ref={ref2}
id="explicitTimeStampLowerCase"
onTouchEnd={event => {
expect(event.timeStamp).toBe(explicitTimeStampLowerCase);
}}
/>
</>,
1,
null,
true,
);
});

const [dispatchEvent] =
nativeFabricUIManager.registerEventHandler.mock.calls[0];

dispatchEvent(getViewById('default').instanceHandle, 'topTouchStart', {
target: getViewById('default').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
});
dispatchEvent(getViewById('default').instanceHandle, 'topTouchEnd', {
target: getViewById('default').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
// No timeStamp property
});

dispatchEvent(
getViewById('explicitTimeStampCamelCase').instanceHandle,
'topTouchStart',
{
target: getViewById('explicitTimeStampCamelCase').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
},
);

dispatchEvent(
getViewById('explicitTimeStampCamelCase').instanceHandle,
'topTouchEnd',
{
target: getViewById('explicitTimeStampCamelCase').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
timeStamp: explicitTimeStampCamelCase,
},
);

dispatchEvent(
getViewById('explicitTimeStampLowerCase').instanceHandle,
'topTouchStart',
{
target: getViewById('explicitTimeStampLowerCase').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
},
);

dispatchEvent(
getViewById('explicitTimeStampLowerCase').instanceHandle,
'topTouchEnd',
{
target: getViewById('explicitTimeStampLowerCase').reactTag,
identifier: 17,
touches: [],
changedTouches: [],
timestamp: explicitTimeStampLowerCase,
},
);

expect.assertions(3);
});

it('findHostInstance_DEPRECATED should warn if used to find a host component inside StrictMode', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ function validateEventDispatches(event) {
*/
export function executeDispatch(event, listener, inst) {
event.currentTarget = getNodeFromInstance(inst);
const currentEvent = global.event;
global.event = event;

try {
listener(event);
} catch (error) {
Expand All @@ -77,6 +80,8 @@ export function executeDispatch(event, listener, inst) {
// TODO: Make sure this error gets logged somehow.
}
}

global.event = currentEvent;
event.currentTarget = null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ import assign from 'shared/assign';

const EVENT_POOL_SIZE = 10;

let currentTimeStamp = () => {
// Lazily define the function based on the existence of performance.now()
if (
typeof performance === 'object' &&
performance !== null &&
typeof performance.now === 'function'
) {
currentTimeStamp = () => performance.now();
} else {
currentTimeStamp = () => Date.now();
}

return currentTimeStamp();
};

/**
* @interface Event
* @see http://www.w3.org/TR/DOM-Level-3-Events/
Expand All @@ -26,7 +41,7 @@ const EventInterface = {
bubbles: null,
cancelable: null,
timeStamp: function (event) {
return event.timeStamp || Date.now();
return event.timeStamp || event.timestamp || currentTimeStamp();
},
defaultPrevented: null,
isTrusted: null,
Expand Down
Loading