Skip to content
Closed
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
11 changes: 10 additions & 1 deletion packages/react-native/src/private/webapis/dom/events/Event.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {setPlatformObject} from '../../webidl/PlatformObjects';
import {
COMPOSED_PATH_KEY,
CURRENT_TARGET_KEY,
EVENT_INIT_TIMESTAMP_KEY,
EVENT_PHASE_KEY,
IN_PASSIVE_LISTENER_FLAG_KEY,
IS_TRUSTED_KEY,
Expand Down Expand Up @@ -60,7 +61,7 @@ export default class Event {
_type: string;

_defaultPrevented: boolean = false;
_timeStamp: number = performance.now();
_timeStamp: number;

// $FlowExpectedError[unsupported-syntax]
[COMPOSED_PATH_KEY]: boolean = [];
Expand Down Expand Up @@ -109,6 +110,14 @@ export default class Event {
this._bubbles = Boolean(options?.bubbles);
this._cancelable = Boolean(options?.cancelable);
this._composed = Boolean(options?.composed);

// 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.
// $FlowExpectedError[prop-missing]
const initTimestamp: number | void = options?.[EVENT_INIT_TIMESTAMP_KEY];
this._timeStamp =
initTimestamp !== undefined ? initTimestamp : performance.now();
}

get bubbles(): boolean {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
import '@react-native/fantom/src/setUpDefaultReactNativeEnvironment';

import Event from 'react-native/src/private/webapis/dom/events/Event';
import {setInPassiveListenerFlag} from 'react-native/src/private/webapis/dom/events/internals/EventInternals';
import {
setEventInitTimeStamp,
setInPassiveListenerFlag,
} from 'react-native/src/private/webapis/dom/events/internals/EventInternals';

describe('Event', () => {
it('provides read-only constants for event phases', () => {
Expand Down Expand Up @@ -233,6 +236,23 @@ describe('Event', () => {
expect(event.timeStamp).toBeLessThanOrEqual(upperBoundTimestamp);
});

it('should use a custom timestamp when set via setEventInitTimeStamp', () => {
const customTimestamp = 12345.678;
const options = {};
setEventInitTimeStamp(options, customTimestamp);
const event = new Event('custom', options);

expect(event.timeStamp).toBe(customTimestamp);
});

it('should accept zero as a valid custom timestamp', () => {
const options = {};
setEventInitTimeStamp(options, 0);
const event = new Event('custom', options);

expect(event.timeStamp).toBe(0);
});

describe('preventDefault', () => {
let originalConsoleError;
let consoleErrorMock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* (only with public exports).
*/

import type Event, {EventPhase} from '../Event';
import type Event, {EventInit, EventPhase} from '../Event';
import type EventTarget from '../EventTarget';

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

// 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.
export const EVENT_INIT_TIMESTAMP_KEY: symbol = Symbol('eventInitTimestamp');

export function getCurrentTarget(event: Event): EventTarget | null {
// $FlowExpectedError[prop-missing]
return event[CURRENT_TARGET_KEY];
Expand Down Expand Up @@ -118,3 +123,15 @@ export function setTarget(event: Event, target: EventTarget | null): void {
// $FlowExpectedError[prop-missing]
event[TARGET_KEY] = target;
}

export function setEventInitTimeStamp(
eventInit: EventInit,
timeStamp: number,
): void {
if (typeof timeStamp !== 'number') {
return;
}
// $FlowExpectedError[prop-missing]
// $FlowExpectedError[invalid-computed-prop]
eventInit[EVENT_INIT_TIMESTAMP_KEY] = timeStamp;
}
Loading