Experimental Event API: reduce code size of event modules (#15590)
Dominic Gannaway committed
May 8, 2019 at 19:09 UTC
51e66cf9fa3448efdc7c5938405757dbb53c9079
6 files changed
+72
-68
packages/react-dom/src/events/DOMEventResponderSystem.js
+47
-13
@@ -163,19 +163,7 @@ const eventResponderContext: ReactResponderContext = {
163
}
164
return false;
165
},
166
- isTargetWithinEventComponent(target: Element | Document): boolean {
167
- validateResponderContext();
168
- if (target != null) {
169
- let fiber = getClosestInstanceFromNode(target);
170
- while (fiber !== null) {
171
- if (fiber.stateNode === currentInstance) {
172
- return true;
173
- }
174
- fiber = fiber.return;
175
- }
176
- }
177
- return false;
178
- },
166
+ isTargetWithinEventComponent,
167
isTargetWithinEventResponderScope(target: Element | Document): boolean {
168
validateResponderContext();
169
const responder = ((currentInstance: any): ReactEventComponentInstance)
@@ -371,8 +359,54 @@ const eventResponderContext: ReactResponderContext = {
359
return focusableElements;
360
},
361
getActiveDocument,
362
+ objectAssign: Object.assign,
363
+ getEventPointerType(
364
+ event: ReactResponderEvent,
365
+ ): '' | 'mouse' | 'keyboard' | 'pen' | 'touch' {
366
+ const nativeEvent: any = event.nativeEvent;
367
+ const {type, pointerType} = nativeEvent;
368
+ if (pointerType != null) {
369
+ return pointerType;
370
+ }
371
+ if (type.indexOf('mouse') === 0) {
372
+ return 'mouse';
373
+ }
374
+ if (type.indexOf('touch') === 0) {
375
+ return 'touch';
376
+ }
377
+ if (type.indexOf('key') === 0) {
378
+ return 'keyboard';
379
+ }
380
+ return '';
381
+ },
382
+ getEventCurrentTarget(event: ReactResponderEvent): Element {
383
+ const target: any = event.target;
384
+ let currentTarget = target;
385
+ while (
386
+ currentTarget.parentNode &&
387
+ currentTarget.parentNode.nodeType === Node.ELEMENT_NODE &&
388
+ isTargetWithinEventComponent(currentTarget.parentNode)
389
+ ) {
390
+ currentTarget = currentTarget.parentNode;
391
+ }
392
+ return currentTarget;
393
+ },
394
};
395
396
+function isTargetWithinEventComponent(target: Element | Document): boolean {
397
+ validateResponderContext();
398
+ if (target != null) {
399
+ let fiber = getClosestInstanceFromNode(target);
400
+ while (fiber !== null) {
401
+ if (fiber.stateNode === currentInstance) {
402
+ return true;
403
+ }
404
+ fiber = fiber.return;
405
+ }
406
+ }
407
+ return false;
408
+}
409
+
410
function getActiveDocument(): Document {
411
const eventComponentInstance = ((currentInstance: any): ReactEventComponentInstance);
412
const rootElement = ((eventComponentInstance.rootInstance: any): Element);
packages/react-events/src/Focus.js
+2
-3
@@ -13,7 +13,6 @@ import type {
13
} from 'shared/ReactTypes';
14
15
import React from 'react';
16
-import {getEventCurrentTarget} from './utils.js';
16
17
type FocusProps = {
18
disabled: boolean,
@@ -173,7 +172,7 @@ const FocusResponder = {
172
if (!state.isFocused) {
173
// Limit focus events to the direct child of the event component.
174
// Browser focus is not expected to bubble.
176
- state.focusTarget = getEventCurrentTarget(event, context);
175
+ state.focusTarget = context.getEventCurrentTarget(event);
176
if (state.focusTarget === target) {
177
state.isFocused = true;
178
state.isLocalFocusVisible = isGlobalFocusVisible;
@@ -221,7 +220,7 @@ const FocusResponder = {
220
// Focus should stop being visible if a pointer is used on the element
221
// after it was focused using a keyboard.
222
if (
224
- state.focusTarget === getEventCurrentTarget(event, context) &&
223
+ state.focusTarget === context.getEventCurrentTarget(event) &&
224
(type === 'mousedown' ||
225
type === 'touchstart' ||
226
type === 'pointerdown')
packages/react-events/src/Hover.js
+3
-7
@@ -13,11 +13,7 @@ import type {
13
} from 'shared/ReactTypes';
14
15
import React from 'react';
16
-import {
17
- getEventPointerType,
18
- getEventCurrentTarget,
19
- isEventPositionWithinTouchHitTarget,
20
-} from './utils';
16
+import {isEventPositionWithinTouchHitTarget} from './utils';
17
18
type HoverProps = {
19
disabled: boolean,
@@ -264,7 +260,7 @@ const HoverResponder = {
260
}
261
return;
262
}
267
- const pointerType = getEventPointerType(event);
263
+ const pointerType = context.getEventPointerType(event);
264
265
switch (type) {
266
// START
@@ -287,7 +283,7 @@ const HoverResponder = {
283
state.isOverTouchHitTarget = true;
284
return;
285
}
290
- state.hoverTarget = getEventCurrentTarget(event, context);
286
+ state.hoverTarget = context.getEventCurrentTarget(event);
287
state.ignoreEmulatedMouseEvents = true;
288
dispatchHoverStartEvents(event, context, props, state);
289
}
packages/react-events/src/Press.js
+15
-11
@@ -15,11 +15,7 @@ import type {
15
16
import React from 'react';
17
18
-import {
19
- getEventPointerType,
20
- getEventCurrentTarget,
21
- isEventPositionWithinTouchHitTarget,
22
-} from './utils';
18
+import {isEventPositionWithinTouchHitTarget} from './utils';
19
20
type PressProps = {
21
disabled: boolean,
@@ -365,11 +361,16 @@ function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
361
}
362
363
// TODO: account for touch hit slop
368
-function calculateResponderRegion(target: Element, props: PressProps) {
369
- const pressRetentionOffset = {
364
+function calculateResponderRegion(
365
+ context: ReactResponderContext,
366
+ target: Element,
367
+ props: PressProps,
368
+) {
369
+ const pressRetentionOffset = context.objectAssign(
370
+ {},
371
...DEFAULT_PRESS_RETENTION_OFFSET,
372
...props.pressRetentionOffset,
372
- };
373
+ );
374
375
const clientRect = target.getBoundingClientRect();
376
@@ -533,7 +534,7 @@ const PressResponder = {
534
return;
535
}
536
const nativeEvent: any = event.nativeEvent;
536
- const pointerType = getEventPointerType(event);
537
+ const pointerType = context.getEventPointerType(event);
538
539
switch (type) {
540
// START
@@ -575,8 +576,9 @@ const PressResponder = {
576
577
state.allowPressReentry = true;
578
state.pointerType = pointerType;
578
- state.pressTarget = getEventCurrentTarget(event, context);
579
+ state.pressTarget = context.getEventCurrentTarget(event);
580
state.responderRegionOnActivation = calculateResponderRegion(
581
+ context,
582
state.pressTarget,
583
props,
584
);
@@ -620,7 +622,7 @@ const PressResponder = {
622
const {target, type} = event;
623
624
const nativeEvent: any = event.nativeEvent;
623
- const pointerType = getEventPointerType(event);
625
+ const pointerType = context.getEventPointerType(event);
626
627
switch (type) {
628
// MOVE
@@ -641,6 +643,7 @@ const PressResponder = {
643
state.responderRegionOnDeactivation == null
644
) {
645
state.responderRegionOnDeactivation = calculateResponderRegion(
646
+ context,
647
state.pressTarget,
648
props,
649
);
@@ -708,6 +711,7 @@ const PressResponder = {
711
// already done during move event.
712
if (state.responderRegionOnDeactivation == null) {
713
state.responderRegionOnDeactivation = calculateResponderRegion(
714
+ context,
715
state.pressTarget,
716
props,
717
);
packages/react-events/src/utils.js
-34
@@ -12,40 +12,6 @@ import type {
12
ReactResponderContext,
13
} from 'shared/ReactTypes';
14
15
-export function getEventCurrentTarget(
16
- event: ReactResponderEvent,
17
- context: ReactResponderContext,
18
-): Element {
19
- const target: any = event.target;
20
- let currentTarget = target;
21
- while (
22
- currentTarget.parentNode &&
23
- currentTarget.parentNode.nodeType === Node.ELEMENT_NODE &&
24
- context.isTargetWithinEventComponent(currentTarget.parentNode)
25
- ) {
26
- currentTarget = currentTarget.parentNode;
27
- }
28
- return currentTarget;
29
-}
30
-
31
-export function getEventPointerType(event: ReactResponderEvent) {
32
- const nativeEvent: any = event.nativeEvent;
33
- const {type, pointerType} = nativeEvent;
34
- if (pointerType != null) {
35
- return pointerType;
36
- }
37
- if (type.indexOf('mouse') === 0) {
38
- return 'mouse';
39
- }
40
- if (type.indexOf('touch') === 0) {
41
- return 'touch';
42
- }
43
- if (type.indexOf('key') === 0) {
44
- return 'keyboard';
45
- }
46
- return '';
47
-}
48
-
15
export function isEventPositionWithinTouchHitTarget(
16
event: ReactResponderEvent,
17
context: ReactResponderContext,
packages/shared/ReactTypes.js
+5
@@ -188,4 +188,9 @@ export type ReactResponderContext = {
188
clearTimeout: (timerId: Symbol) => void,
189
getFocusableElementsInScope(): Array<HTMLElement>,
190
getActiveDocument(): Document,
191
+ objectAssign: Function,
192
+ getEventPointerType(
193
+ event: ReactResponderEvent,
194
+ ): '' | 'mouse' | 'keyboard' | 'pen' | 'touch',
195
+ getEventCurrentTarget(event: ReactResponderEvent): Element,
196
};