Skip to content

Commit e7564d6

Browse files
rubennortemeta-codesync[bot]
authored andcommitted
Add support for custom timestamps in Event via EVENT_INIT_TIMESTAMP_KEY (#56304)
Summary: Pull Request resolved: #56304 Add support for specifying a custom `timeStamp` in the `Event` constructor options via a private symbol key (`EVENT_INIT_TIMESTAMP_KEY`) defined in `EventInternals`. This is for internal construction of events using a custom timestamp (instead of event object creation), for use cases like dispatching events from the host platform using the original timestamps. - Added `EVENT_INIT_TIMESTAMP_KEY` symbol to `EventInternals` - Added `setEventInitTimeStamp(eventInit, timeStamp)` helper function in `EventInternals` that validates the type and sets the symbol-keyed property on the event init object - Updated the `Event` constructor to read the custom timestamp from options if present, falling back to `performance.now()` - Added Fantom tests for custom timestamp and zero as a valid timestamp Changelog: [Internal] Reviewed By: huntie Differential Revision: D99076591 fbshipit-source-id: 2ea00394de885a5f338c1b3fe4792d5b4768cd7b
1 parent 654d646 commit e7564d6

3 files changed

Lines changed: 49 additions & 3 deletions

File tree

‎packages/react-native/src/private/webapis/dom/events/Event.js‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {setPlatformObject} from '../../webidl/PlatformObjects';
2121
import {
2222
COMPOSED_PATH_KEY,
2323
CURRENT_TARGET_KEY,
24+
EVENT_INIT_TIMESTAMP_KEY,
2425
EVENT_PHASE_KEY,
2526
IN_PASSIVE_LISTENER_FLAG_KEY,
2627
IS_TRUSTED_KEY,
@@ -60,7 +61,7 @@ export default class Event {
6061
_type: string;
6162

6263
_defaultPrevented: boolean = false;
63-
_timeStamp: number = performance.now();
64+
_timeStamp: number;
6465

6566
// $FlowExpectedError[unsupported-syntax]
6667
[COMPOSED_PATH_KEY]: boolean = [];
@@ -109,6 +110,14 @@ export default class Event {
109110
this._bubbles = Boolean(options?.bubbles);
110111
this._cancelable = Boolean(options?.cancelable);
111112
this._composed = Boolean(options?.composed);
113+
114+
// For internal construction of events using a custom timestamp (instead of
115+
// event object creation), for use cases like dispatching events from the
116+
// host platform using the original timestamps.
117+
// $FlowExpectedError[prop-missing]
118+
const initTimestamp: number | void = options?.[EVENT_INIT_TIMESTAMP_KEY];
119+
this._timeStamp =
120+
initTimestamp !== undefined ? initTimestamp : performance.now();
112121
}
113122

114123
get bubbles(): boolean {

‎packages/react-native/src/private/webapis/dom/events/__tests__/Event-itest.js‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@
1111
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';
1212

1313
import Event from 'react-native/src/private/webapis/dom/events/Event';
14-
import {setInPassiveListenerFlag} from 'react-native/src/private/webapis/dom/events/internals/EventInternals';
14+
import {
15+
setEventInitTimeStamp,
16+
setInPassiveListenerFlag,
17+
} from 'react-native/src/private/webapis/dom/events/internals/EventInternals';
1518

1619
describe('Event', () => {
1720
it('provides read-only constants for event phases', () => {
@@ -233,6 +236,23 @@ describe('Event', () => {
233236
expect(event.timeStamp).toBeLessThanOrEqual(upperBoundTimestamp);
234237
});
235238

239+
it('should use a custom timestamp when set via setEventInitTimeStamp', () => {
240+
const customTimestamp = 12345.678;
241+
const options = {};
242+
setEventInitTimeStamp(options, customTimestamp);
243+
const event = new Event('custom', options);
244+
245+
expect(event.timeStamp).toBe(customTimestamp);
246+
});
247+
248+
it('should accept zero as a valid custom timestamp', () => {
249+
const options = {};
250+
setEventInitTimeStamp(options, 0);
251+
const event = new Event('custom', options);
252+
253+
expect(event.timeStamp).toBe(0);
254+
});
255+
236256
describe('preventDefault', () => {
237257
let originalConsoleError;
238258
let consoleErrorMock;

‎packages/react-native/src/private/webapis/dom/events/internals/EventInternals.js‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* (only with public exports).
1515
*/
1616

17-
import type Event, {EventPhase} from '../Event';
17+
import type Event, {EventInit, EventPhase} from '../Event';
1818
import type EventTarget from '../EventTarget';
1919

2020
export const COMPOSED_PATH_KEY: symbol = Symbol('composedPath');
@@ -30,6 +30,11 @@ export const STOP_IMMEDIATE_PROPAGATION_FLAG_KEY: symbol = Symbol(
3030
export const STOP_PROPAGATION_FLAG_KEY: symbol = Symbol('stopPropagationFlag');
3131
export const TARGET_KEY: symbol = Symbol('target');
3232

33+
// For internal construction of events using a custom timestamp (instead of
34+
// event object creation), for use cases like dispatching events from the host
35+
// platform using the original timestamps.
36+
export const EVENT_INIT_TIMESTAMP_KEY: symbol = Symbol('eventInitTimestamp');
37+
3338
export function getCurrentTarget(event: Event): EventTarget | null {
3439
// $FlowExpectedError[prop-missing]
3540
return event[CURRENT_TARGET_KEY];
@@ -118,3 +123,15 @@ export function setTarget(event: Event, target: EventTarget | null): void {
118123
// $FlowExpectedError[prop-missing]
119124
event[TARGET_KEY] = target;
120125
}
126+
127+
export function setEventInitTimeStamp(
128+
eventInit: EventInit,
129+
timeStamp: number,
130+
): void {
131+
if (typeof timeStamp !== 'number') {
132+
return;
133+
}
134+
// $FlowExpectedError[prop-missing]
135+
// $FlowExpectedError[invalid-computed-prop]
136+
eventInit[EVENT_INIT_TIMESTAMP_KEY] = timeStamp;
137+
}

0 commit comments

Comments
 (0)