Skip to content

Commit

Permalink
Experiemental event API - wrap async dispatched events (#15299)
Browse files Browse the repository at this point in the history
  • Loading branch information
trueadm authored Apr 3, 2019
1 parent 4d5cb64 commit 38fa840
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 39 deletions.
1 change: 1 addition & 0 deletions packages/events/EventTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ export type EventResponderContext = {
) => void,
requestOwnership: (target: Element | Document | null) => boolean,
releaseOwnership: (target: Element | Document | null) => boolean,
withAsyncDispatching: (func: () => void) => void,
};
29 changes: 15 additions & 14 deletions packages/react-dom/src/events/DOMEventResponderSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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);
}
}
59 changes: 34 additions & 25 deletions packages/react-events/src/Press.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}
}

Expand Down

0 comments on commit 38fa840

Please sign in to comment.