diff --git a/packages/events/EventTypes.js b/packages/events/EventTypes.js index b48052a6ad7a6..169b34aa07713 100644 --- a/packages/events/EventTypes.js +++ b/packages/events/EventTypes.js @@ -39,4 +39,5 @@ export type EventResponderContext = { ) => void, requestOwnership: (target: Element | Document | null) => boolean, releaseOwnership: (target: Element | Document | null) => boolean, + withAsyncDispatching: (func: () => void) => void, }; diff --git a/packages/react-dom/src/events/DOMEventResponderSystem.js b/packages/react-dom/src/events/DOMEventResponderSystem.js index b4e982142b897..45e6c95e463b6 100644 --- a/packages/react-dom/src/events/DOMEventResponderSystem.js +++ b/packages/react-dom/src/events/DOMEventResponderSystem.js @@ -58,19 +58,13 @@ type EventQueue = { bubble: null | Array<$Shape>, capture: null | Array<$Shape>, discrete: boolean, - phase: EventQueuePhase, }; -type EventQueuePhase = 0 | 1; -const DURING_EVENT_PHASE = 0; -const AFTER_EVENT_PHASE = 1; - -function createEventQueue(phase: EventQueuePhase): EventQueue { +function createEventQueue(): EventQueue { return { bubble: null, capture: null, discrete: false, - phase, }; } @@ -134,7 +128,7 @@ function DOMEventResponderContext( this._discreteEvents = null; this._nonDiscreteEvents = null; this._isBatching = true; - this._eventQueue = createEventQueue(DURING_EVENT_PHASE); + this._eventQueue = createEventQueue(); } DOMEventResponderContext.prototype.isPassive = function(): boolean { @@ -203,9 +197,6 @@ DOMEventResponderContext.prototype.dispatchEvent = function( if (stopPropagation) { eventsWithStopPropagation.add(eventObject); } - if (eventQueue.phase === AFTER_EVENT_PHASE) { - batchedUpdates(processEventQueue, eventQueue); - } }; DOMEventResponderContext.prototype.isTargetWithinEventComponent = function( @@ -320,6 +311,19 @@ DOMEventResponderContext.prototype.releaseOwnership = function( return false; }; +DOMEventResponderContext.prototype.withAsyncDispatching = function( + func: () => void, +) { + const previousEventQueue = this._eventQueue; + this._eventQueue = createEventQueue(); + try { + func(); + batchedUpdates(processEventQueue, this._eventQueue); + } finally { + this._eventQueue = previousEventQueue; + } +}; + function getTargetEventTypes( eventTypes: Array, ): Set { @@ -401,8 +405,5 @@ export function runResponderEventsInBatch( } } processEventQueue(context._eventQueue); - // In order to capture and process async events from responder modules - // we create a new event queue. - context._eventQueue = createEventQueue(AFTER_EVENT_PHASE); } } diff --git a/packages/react-events/src/Press.js b/packages/react-events/src/Press.js index 3b7498153c977..7611d8660c185 100644 --- a/packages/react-events/src/Press.js +++ b/packages/react-events/src/Press.js @@ -118,33 +118,42 @@ function dispatchPressStartEvents( DEFAULT_LONG_PRESS_DELAY_MS, ); - state.longPressTimeout = setTimeout(() => { - state.isLongPressed = true; - state.longPressTimeout = null; + state.longPressTimeout = setTimeout( + () => + context.withAsyncDispatching(() => { + state.isLongPressed = true; + state.longPressTimeout = null; - if (props.onLongPress) { - const longPressEventListener = e => { - props.onLongPress(e); - // TODO address this again at some point - // if (e.nativeEvent.defaultPrevented) { - // state.defaultPrevented = true; - // } - }; - dispatchPressEvent(context, state, 'longpress', longPressEventListener); - } + if (props.onLongPress) { + const longPressEventListener = e => { + props.onLongPress(e); + // TODO address this again at some point + // if (e.nativeEvent.defaultPrevented) { + // state.defaultPrevented = true; + // } + }; + dispatchPressEvent( + context, + state, + 'longpress', + longPressEventListener, + ); + } - if (props.onLongPressChange) { - const longPressChangeEventListener = () => { - props.onLongPressChange(true); - }; - dispatchPressEvent( - context, - state, - 'longpresschange', - longPressChangeEventListener, - ); - } - }, delayLongPress); + if (props.onLongPressChange) { + const longPressChangeEventListener = () => { + props.onLongPressChange(true); + }; + dispatchPressEvent( + context, + state, + 'longpresschange', + longPressChangeEventListener, + ); + } + }), + delayLongPress, + ); } }