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

This commit is contained in:
Dominic Gannaway
2019-04-03 10:25:40 +01:00
committed by GitHub
parent 4d5cb64aa2
commit 38fa84088a
3 changed files with 50 additions and 39 deletions
+1
View File
@@ -39,4 +39,5 @@ export type EventResponderContext = {
) => void,
requestOwnership: (target: Element | Document | null) => boolean,
releaseOwnership: (target: Element | Document | null) => boolean,
withAsyncDispatching: (func: () => void) => void,
};
+15 -14
View File
@@ -58,19 +58,13 @@ type EventQueue = {
bubble: null | Array<$Shape<PartialEventObject>>,
capture: null | Array<$Shape<PartialEventObject>>,
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<ReactEventResponderEventType>,
): Set<DOMTopLevelEventType> {
@@ -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);
}
}
+34 -25
View File
@@ -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,
);
}
}