mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[Flare] Improve runtime performance of hit target intersection (#15836)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
Vendored
+3
-4
@@ -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 {
|
||||
|
||||
Vendored
+1
-2
@@ -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();
|
||||
|
||||
Vendored
-25
@@ -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),
|
||||
);
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user