Event API: Fix bug where Press root events were not being cleared (#15507)

This commit is contained in:
Dominic Gannaway
2019-04-26 10:30:38 +01:00
committed by GitHub
parent a14e24efab
commit 7a482af5d8
2 changed files with 41 additions and 5 deletions
+24 -5
View File
@@ -44,6 +44,7 @@ type PressProps = {
type PointerType = '' | 'mouse' | 'keyboard' | 'pen' | 'touch';
type PressState = {
addedRootEvents: boolean,
isActivePressed: boolean,
isActivePressStart: boolean,
isLongPressed: boolean,
@@ -300,6 +301,7 @@ function dispatchPressEndEvents(
deactivate(context, props, state);
}
}
removeRootEventTypes(context, state);
}
function isAnchorTagElement(eventTarget: EventTarget): boolean {
@@ -394,7 +396,6 @@ function unmountResponder(
): void {
if (state.isPressed) {
dispatchPressEndEvents(context, props, state);
context.removeRootEventTypes(rootEventTypes);
}
}
@@ -411,15 +412,35 @@ function dispatchCancel(
} else {
state.ignoreEmulatedMouseEvents = false;
dispatchPressEndEvents(context, props, state);
context.removeRootEventTypes(rootEventTypes);
}
}
}
function addRootEventTypes(
context: ReactResponderContext,
state: PressState,
): void {
if (!state.addedRootEvents) {
state.addedRootEvents = true;
context.addRootEventTypes(rootEventTypes);
}
}
function removeRootEventTypes(
context: ReactResponderContext,
state: PressState,
): void {
if (state.addedRootEvents) {
state.addedRootEvents = false;
context.removeRootEventTypes(rootEventTypes);
}
}
const PressResponder = {
targetEventTypes,
createInitialState(): PressState {
return {
addedRootEvents: false,
didDispatchEvent: false,
isActivePressed: false,
isActivePressStart: false,
@@ -447,7 +468,6 @@ const PressResponder = {
if (props.disabled) {
dispatchPressEndEvents(context, props, state);
context.removeRootEventTypes(rootEventTypes);
state.ignoreEmulatedMouseEvents = false;
return;
}
@@ -500,7 +520,7 @@ const PressResponder = {
);
state.isPressWithinResponderRegion = true;
dispatchPressStartEvents(context, props, state);
context.addRootEventTypes(rootEventTypes);
addRootEventTypes(context, state);
} else {
// Prevent spacebar press from scrolling the window
if (isValidKeyPress(nativeEvent.key) && nativeEvent.key === ' ') {
@@ -630,7 +650,6 @@ const PressResponder = {
}
}
}
context.removeRootEventTypes(rootEventTypes);
} else if (type === 'mouseup' && state.ignoreEmulatedMouseEvents) {
state.ignoreEmulatedMouseEvents = false;
}
@@ -1428,4 +1428,21 @@ describe('Event responder: Press', () => {
it('expect displayName to show up for event component', () => {
expect(Press.displayName).toBe('Press');
});
it('should not trigger an invariant in addRootEventTypes()', () => {
const ref = React.createRef();
const element = (
<Press>
<button ref={ref} />
</Press>
);
ReactDOM.render(element, container);
ref.current.dispatchEvent(createPointerEvent('pointerdown'));
jest.advanceTimersByTime(DEFAULT_LONG_PRESS_DELAY);
ref.current.dispatchEvent(createPointerEvent('pointermove'));
ref.current.dispatchEvent(createPointerEvent('pointerup'));
ref.current.dispatchEvent(createPointerEvent('pointerdown'));
ReactDOM.render(element, container);
});
});