[Flare] Improve runtime performance of hit target intersection (#15836)

This commit is contained in:
Dominic Gannaway
2019-06-07 15:57:10 +01:00
committed by GitHub
parent def56c9797
commit 425473f43f
6 changed files with 14 additions and 41 deletions
+8 -8
View File
@@ -189,15 +189,15 @@ const eventResponderContext: ReactResponderContext = {
eventListeners.set(eventObject, listener);
eventQueue.events.push(eventObject);
},
isPositionWithinTouchHitTarget(x: number, y: number): boolean {
isEventWithinTouchHitTarget(event: ReactResponderEvent): boolean {
validateResponderContext();
const doc = getActiveDocument();
// This isn't available in some environments (JSDOM)
if (typeof doc.elementFromPoint !== 'function') {
return false;
}
const target = doc.elementFromPoint(x, y);
if (target === null) {
const target = event.target;
const nativeEvent = event.nativeEvent;
// We should always be dealing with a mouse event or touch event here.
// If we are not, these won't exist and we can early return.
const x = (nativeEvent: any).clientX;
const y = (nativeEvent: any).clientY;
if (x === undefined || y === undefined) {
return false;
}
const childFiber = getClosestInstanceFromNode(target);
+1 -1
View File
@@ -127,7 +127,7 @@ Component instance.
Returns `true` if the instance has taken ownership of the responder.
### isPositionWithinTouchHitTarget(x: number, y: number): boolean
### isEventWithinTouchHitTarget(event: ResponderEvent): boolean
Returns `true` if the global coordinates lie within the TouchHitTarget.
+3 -4
View File
@@ -13,7 +13,6 @@ import type {
} from 'shared/ReactTypes';
import React from 'react';
import {isEventPositionWithinTouchHitTarget} from './utils';
import {UserBlockingEvent} from 'shared/ReactTypes';
type HoverProps = {
@@ -326,7 +325,7 @@ const HoverResponder = {
return;
}
if (isEventPositionWithinTouchHitTarget(event, context)) {
if (context.isEventWithinTouchHitTarget(event)) {
state.isOverTouchHitTarget = true;
return;
}
@@ -345,14 +344,14 @@ const HoverResponder = {
if (state.isOverTouchHitTarget) {
// If we were moving over the TouchHitTarget and have now moved
// over the Responder target
if (!isEventPositionWithinTouchHitTarget(event, context)) {
if (!context.isEventWithinTouchHitTarget(event)) {
dispatchHoverStartEvents(event, context, props, state);
state.isOverTouchHitTarget = false;
}
} else {
// If we were moving over the Responder target and have now moved
// over the TouchHitTarget
if (isEventPositionWithinTouchHitTarget(event, context)) {
if (context.isEventWithinTouchHitTarget(event)) {
dispatchHoverEndEvents(event, context, props, state);
state.isOverTouchHitTarget = true;
} else {
+1 -2
View File
@@ -14,7 +14,6 @@ import type {
import type {EventPriority} from 'shared/ReactTypes';
import React from 'react';
import {isEventPositionWithinTouchHitTarget} from './utils';
import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes';
type PressProps = {
@@ -644,7 +643,7 @@ const PressResponder = {
const isMouseType = pointerType === 'mouse';
if (
(isMouseType || pointerType === 'pen') &&
isEventPositionWithinTouchHitTarget(event, context)
context.isEventWithinTouchHitTarget(event)
) {
// We need to prevent the native event to block the focus
nativeEvent.preventDefault();
-25
View File
@@ -1,25 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import type {
ReactResponderEvent,
ReactResponderContext,
} from 'shared/ReactTypes';
export function isEventPositionWithinTouchHitTarget(
event: ReactResponderEvent,
context: ReactResponderContext,
) {
const nativeEvent: any = event.nativeEvent;
return context.isPositionWithinTouchHitTarget(
// x and y can be doubles, so ensure they are integers
parseInt(nativeEvent.clientX, 10),
parseInt(nativeEvent.clientY, 10),
);
}
+1 -1
View File
@@ -176,7 +176,7 @@ export type ReactResponderContext = {
) => boolean,
isTargetWithinEventComponent: (Element | Document) => boolean,
isTargetWithinEventResponderScope: (Element | Document) => boolean,
isPositionWithinTouchHitTarget: (x: number, y: number) => boolean,
isEventWithinTouchHitTarget: (event: ReactResponderEvent) => boolean,
addRootEventTypes: (
rootEventTypes: Array<ReactEventResponderEventType>,
) => void,