@samitouri / QOS-React-2 / commits / 425473f43f

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

Dominic Gannaway committed Jun 7, 2019 at 15:57 UTC 425473f43fd95a564f07ffcf6dbd105cef9f78b9
6 files changed +14 -41
packages/react-dom/src/events/DOMEventResponderSystem.js
+8 -8
@@ -189,15 +189,15 @@ const eventResponderContext: ReactResponderContext = {
189 eventListeners.set(eventObject, listener);
190 eventQueue.events.push(eventObject);
191 },
192 - isPositionWithinTouchHitTarget(x: number, y: number): boolean {
192 + isEventWithinTouchHitTarget(event: ReactResponderEvent): boolean {
193 validateResponderContext();
194 - const doc = getActiveDocument();
195 - // This isn't available in some environments (JSDOM)
196 - if (typeof doc.elementFromPoint !== 'function') {
197 - return false;
198 - }
199 - const target = doc.elementFromPoint(x, y);
200 - if (target === null) {
194 + const target = event.target;
195 + const nativeEvent = event.nativeEvent;
196 + // We should always be dealing with a mouse event or touch event here.
197 + // If we are not, these won't exist and we can early return.
198 + const x = (nativeEvent: any).clientX;
199 + const y = (nativeEvent: any).clientY;
200 + if (x === undefined || y === undefined) {
201 return false;
202 }
203 const childFiber = getClosestInstanceFromNode(target);
packages/react-events/README.md
+1 -1
@@ -127,7 +127,7 @@ Component instance.
127
128 Returns `true` if the instance has taken ownership of the responder.
129
130 -### isPositionWithinTouchHitTarget(x: number, y: number): boolean
130 +### isEventWithinTouchHitTarget(event: ResponderEvent): boolean
131
132 Returns `true` if the global coordinates lie within the TouchHitTarget.
133
packages/react-events/src/Hover.js
+3 -4
@@ -13,7 +13,6 @@ import type {
13 } from 'shared/ReactTypes';
14
15 import React from 'react';
16 -import {isEventPositionWithinTouchHitTarget} from './utils';
16 import {UserBlockingEvent} from 'shared/ReactTypes';
17
18 type HoverProps = {
@@ -326,7 +325,7 @@ const HoverResponder = {
325 return;
326 }
327
329 - if (isEventPositionWithinTouchHitTarget(event, context)) {
328 + if (context.isEventWithinTouchHitTarget(event)) {
329 state.isOverTouchHitTarget = true;
330 return;
331 }
@@ -345,14 +344,14 @@ const HoverResponder = {
344 if (state.isOverTouchHitTarget) {
345 // If we were moving over the TouchHitTarget and have now moved
346 // over the Responder target
348 - if (!isEventPositionWithinTouchHitTarget(event, context)) {
347 + if (!context.isEventWithinTouchHitTarget(event)) {
348 dispatchHoverStartEvents(event, context, props, state);
349 state.isOverTouchHitTarget = false;
350 }
351 } else {
352 // If we were moving over the Responder target and have now moved
353 // over the TouchHitTarget
355 - if (isEventPositionWithinTouchHitTarget(event, context)) {
354 + if (context.isEventWithinTouchHitTarget(event)) {
355 dispatchHoverEndEvents(event, context, props, state);
356 state.isOverTouchHitTarget = true;
357 } else {
packages/react-events/src/Press.js
+1 -2
@@ -14,7 +14,6 @@ import type {
14 import type {EventPriority} from 'shared/ReactTypes';
15
16 import React from 'react';
17 -import {isEventPositionWithinTouchHitTarget} from './utils';
17 import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes';
18
19 type PressProps = {
@@ -644,7 +643,7 @@ const PressResponder = {
643 const isMouseType = pointerType === 'mouse';
644 if (
645 (isMouseType || pointerType === 'pen') &&
647 - isEventPositionWithinTouchHitTarget(event, context)
646 + context.isEventWithinTouchHitTarget(event)
647 ) {
648 // We need to prevent the native event to block the focus
649 nativeEvent.preventDefault();
packages/react-events/src/utils.js deleted
-25
@@ -1,25 +0,0 @@
1 -/**
2 - * Copyright (c) Facebook, Inc. and its affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - *
7 - * @flow
8 - */
9 -
10 -import type {
11 - ReactResponderEvent,
12 - ReactResponderContext,
13 -} from 'shared/ReactTypes';
14 -
15 -export function isEventPositionWithinTouchHitTarget(
16 - event: ReactResponderEvent,
17 - context: ReactResponderContext,
18 -) {
19 - const nativeEvent: any = event.nativeEvent;
20 - return context.isPositionWithinTouchHitTarget(
21 - // x and y can be doubles, so ensure they are integers
22 - parseInt(nativeEvent.clientX, 10),
23 - parseInt(nativeEvent.clientY, 10),
24 - );
25 -}
packages/shared/ReactTypes.js
+1 -1
@@ -176,7 +176,7 @@ export type ReactResponderContext = {
176 ) => boolean,
177 isTargetWithinEventComponent: (Element | Document) => boolean,
178 isTargetWithinEventResponderScope: (Element | Document) => boolean,
179 - isPositionWithinTouchHitTarget: (x: number, y: number) => boolean,
179 + isEventWithinTouchHitTarget: (event: ReactResponderEvent) => boolean,
180 addRootEventTypes: (
181 rootEventTypes: Array<ReactEventResponderEventType>,
182 ) => void,