@samitouri / QOS-React / commits / 38fa84088a

Experiemental event API - wrap async dispatched events (#15299)

Dominic Gannaway committed Apr 3, 2019 at 10:25 UTC 38fa84088a4ef0347a89ee176a501c2c2ee8ea96
3 files changed +50 -39
packages/events/EventTypes.js
+1
@@ -39,4 +39,5 @@ export type EventResponderContext = {
39 ) => void,
40 requestOwnership: (target: Element | Document | null) => boolean,
41 releaseOwnership: (target: Element | Document | null) => boolean,
42 + withAsyncDispatching: (func: () => void) => void,
43 };
packages/react-dom/src/events/DOMEventResponderSystem.js
+15 -14
@@ -58,19 +58,13 @@ type EventQueue = {
58 bubble: null | Array<$Shape<PartialEventObject>>,
59 capture: null | Array<$Shape<PartialEventObject>>,
60 discrete: boolean,
61 - phase: EventQueuePhase,
61 };
63 -type EventQueuePhase = 0 | 1;
62
65 -const DURING_EVENT_PHASE = 0;
66 -const AFTER_EVENT_PHASE = 1;
67 -
68 -function createEventQueue(phase: EventQueuePhase): EventQueue {
63 +function createEventQueue(): EventQueue {
64 return {
65 bubble: null,
66 capture: null,
67 discrete: false,
73 - phase,
68 };
69 }
70
@@ -134,7 +128,7 @@ function DOMEventResponderContext(
128 this._discreteEvents = null;
129 this._nonDiscreteEvents = null;
130 this._isBatching = true;
137 - this._eventQueue = createEventQueue(DURING_EVENT_PHASE);
131 + this._eventQueue = createEventQueue();
132 }
133
134 DOMEventResponderContext.prototype.isPassive = function(): boolean {
@@ -203,9 +197,6 @@ DOMEventResponderContext.prototype.dispatchEvent = function(
197 if (stopPropagation) {
198 eventsWithStopPropagation.add(eventObject);
199 }
206 - if (eventQueue.phase === AFTER_EVENT_PHASE) {
207 - batchedUpdates(processEventQueue, eventQueue);
208 - }
200 };
201
202 DOMEventResponderContext.prototype.isTargetWithinEventComponent = function(
@@ -320,6 +311,19 @@ DOMEventResponderContext.prototype.releaseOwnership = function(
311 return false;
312 };
313
314 +DOMEventResponderContext.prototype.withAsyncDispatching = function(
315 + func: () => void,
316 +) {
317 + const previousEventQueue = this._eventQueue;
318 + this._eventQueue = createEventQueue();
319 + try {
320 + func();
321 + batchedUpdates(processEventQueue, this._eventQueue);
322 + } finally {
323 + this._eventQueue = previousEventQueue;
324 + }
325 +};
326 +
327 function getTargetEventTypes(
328 eventTypes: Array<ReactEventResponderEventType>,
329 ): Set<DOMTopLevelEventType> {
@@ -401,8 +405,5 @@ export function runResponderEventsInBatch(
405 }
406 }
407 processEventQueue(context._eventQueue);
404 - // In order to capture and process async events from responder modules
405 - // we create a new event queue.
406 - context._eventQueue = createEventQueue(AFTER_EVENT_PHASE);
408 }
409 }
packages/react-events/src/Press.js
+34 -25
@@ -118,33 +118,42 @@ function dispatchPressStartEvents(
118 DEFAULT_LONG_PRESS_DELAY_MS,
119 );
120
121 - state.longPressTimeout = setTimeout(() => {
122 - state.isLongPressed = true;
123 - state.longPressTimeout = null;
121 + state.longPressTimeout = setTimeout(
122 + () =>
123 + context.withAsyncDispatching(() => {
124 + state.isLongPressed = true;
125 + state.longPressTimeout = null;
126
125 - if (props.onLongPress) {
126 - const longPressEventListener = e => {
127 - props.onLongPress(e);
128 - // TODO address this again at some point
129 - // if (e.nativeEvent.defaultPrevented) {
130 - // state.defaultPrevented = true;
131 - // }
132 - };
133 - dispatchPressEvent(context, state, 'longpress', longPressEventListener);
134 - }
127 + if (props.onLongPress) {
128 + const longPressEventListener = e => {
129 + props.onLongPress(e);
130 + // TODO address this again at some point
131 + // if (e.nativeEvent.defaultPrevented) {
132 + // state.defaultPrevented = true;
133 + // }
134 + };
135 + dispatchPressEvent(
136 + context,
137 + state,
138 + 'longpress',
139 + longPressEventListener,
140 + );
141 + }
142
136 - if (props.onLongPressChange) {
137 - const longPressChangeEventListener = () => {
138 - props.onLongPressChange(true);
139 - };
140 - dispatchPressEvent(
141 - context,
142 - state,
143 - 'longpresschange',
144 - longPressChangeEventListener,
145 - );
146 - }
147 - }, delayLongPress);
143 + if (props.onLongPressChange) {
144 + const longPressChangeEventListener = () => {
145 + props.onLongPressChange(true);
146 + };
147 + dispatchPressEvent(
148 + context,
149 + state,
150 + 'longpresschange',
151 + longPressChangeEventListener,
152 + );
153 + }
154 + }),
155 + delayLongPress,
156 + );
157 }
158 }
159