mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
[Flare] Revise responder event types (#16081)
This commit is contained in:
parent
2a0f6390ed
commit
67e3f3fb6e
6
packages/react-art/src/ReactARTHostConfig.js
vendored
6
packages/react-art/src/ReactARTHostConfig.js
vendored
|
|
@ -428,19 +428,19 @@ export function unhideTextInstance(textInstance, text): void {
|
|||
}
|
||||
|
||||
export function mountEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
) {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function updateEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
) {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
||||
export function unmountEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
): void {
|
||||
throw new Error('Not yet implemented.');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,9 @@ import {registrationNameModules} from 'events/EventPluginRegistry';
|
|||
import warning from 'shared/warning';
|
||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||
import warningWithoutStack from 'shared/warningWithoutStack';
|
||||
import type {ReactDOMEventResponderEventType} from 'shared/ReactDOMTypes';
|
||||
import endsWith from 'shared/endsWith';
|
||||
import type {DOMTopLevelEventType} from 'events/TopLevelEventTypes';
|
||||
import {
|
||||
setListenToResponderEventTypes,
|
||||
generateListeningKey,
|
||||
} from '../events/DOMEventResponderSystem';
|
||||
import {setListenToResponderEventTypes} from '../events/DOMEventResponderSystem';
|
||||
|
||||
import {
|
||||
getValueForAttribute,
|
||||
|
|
@ -1284,7 +1281,7 @@ export function restoreControlledState(
|
|||
}
|
||||
|
||||
export function listenToEventResponderEventTypes(
|
||||
eventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
eventTypes: Array<string>,
|
||||
element: Element | Document,
|
||||
): void {
|
||||
if (enableFlareAPI) {
|
||||
|
|
@ -1294,40 +1291,19 @@ export function listenToEventResponderEventTypes(
|
|||
|
||||
// Go through each target event type of the event responder
|
||||
for (let i = 0, length = eventTypes.length; i < length; ++i) {
|
||||
const targetEventType = eventTypes[i];
|
||||
let topLevelType;
|
||||
let passive = true;
|
||||
|
||||
// If no event config object is provided (i.e. - only a string),
|
||||
// we default to enabling passive and not capture.
|
||||
if (typeof targetEventType === 'string') {
|
||||
topLevelType = targetEventType;
|
||||
} else {
|
||||
if (__DEV__) {
|
||||
warning(
|
||||
typeof targetEventType === 'object' && targetEventType !== null,
|
||||
'Event Responder: invalid entry in event types array. ' +
|
||||
'Entry must be string or an object. Instead, got %s.',
|
||||
targetEventType,
|
||||
);
|
||||
}
|
||||
const targetEventConfigObject = ((targetEventType: any): {
|
||||
name: string,
|
||||
passive?: boolean,
|
||||
});
|
||||
topLevelType = targetEventConfigObject.name;
|
||||
if (targetEventConfigObject.passive !== undefined) {
|
||||
passive = targetEventConfigObject.passive;
|
||||
}
|
||||
}
|
||||
const listeningName = generateListeningKey(topLevelType, passive);
|
||||
if (!listeningSet.has(listeningName)) {
|
||||
const eventType = eventTypes[i];
|
||||
const isPassive = !endsWith(eventType, '_active');
|
||||
const eventKey = isPassive ? eventType + '_passive' : eventType;
|
||||
const targetEventType = isPassive
|
||||
? eventType
|
||||
: eventType.substring(0, eventType.length - 7);
|
||||
if (!listeningSet.has(eventKey)) {
|
||||
trapEventForResponderEventSystem(
|
||||
element,
|
||||
((topLevelType: any): DOMTopLevelEventType),
|
||||
passive,
|
||||
((targetEventType: any): DOMTopLevelEventType),
|
||||
isPassive,
|
||||
);
|
||||
listeningSet.add(listeningName);
|
||||
listeningSet.add(eventKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import type {EventPriority} from 'shared/ReactTypes';
|
|||
import type {
|
||||
ReactDOMEventResponder,
|
||||
ReactDOMEventComponentInstance,
|
||||
ReactDOMEventResponderEventType,
|
||||
ReactDOMResponderContext,
|
||||
ReactDOMResponderEvent,
|
||||
} from 'shared/ReactDOMTypes';
|
||||
|
|
@ -95,10 +94,6 @@ const rootEventTypesToEventComponentInstances: Map<
|
|||
DOMTopLevelEventType | string,
|
||||
Set<ReactDOMEventComponentInstance>,
|
||||
> = new Map();
|
||||
const targetEventTypeCached: Map<
|
||||
Array<ReactDOMEventResponderEventType>,
|
||||
Set<string>,
|
||||
> = new Map();
|
||||
const ownershipChangeListeners: Set<ReactDOMEventComponentInstance> = new Set();
|
||||
const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
|
||||
const eventListeners:
|
||||
|
|
@ -248,9 +243,7 @@ const eventResponderContext: ReactDOMResponderContext = {
|
|||
}
|
||||
return false;
|
||||
},
|
||||
addRootEventTypes(
|
||||
rootEventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
): void {
|
||||
addRootEventTypes(rootEventTypes: Array<string>): void {
|
||||
validateResponderContext();
|
||||
const activeDocument = getActiveDocument();
|
||||
listenToResponderEventTypesImpl(rootEventTypes, activeDocument);
|
||||
|
|
@ -260,37 +253,17 @@ const eventResponderContext: ReactDOMResponderContext = {
|
|||
registerRootEventType(rootEventType, eventComponentInstance);
|
||||
}
|
||||
},
|
||||
removeRootEventTypes(
|
||||
rootEventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
): void {
|
||||
removeRootEventTypes(rootEventTypes: Array<string>): void {
|
||||
validateResponderContext();
|
||||
for (let i = 0; i < rootEventTypes.length; i++) {
|
||||
const rootEventType = rootEventTypes[i];
|
||||
let name = rootEventType;
|
||||
let passive = true;
|
||||
|
||||
if (typeof rootEventType !== 'string') {
|
||||
const targetEventConfigObject = ((rootEventType: any): {
|
||||
name: string,
|
||||
passive?: boolean,
|
||||
});
|
||||
name = targetEventConfigObject.name;
|
||||
if (targetEventConfigObject.passive !== undefined) {
|
||||
passive = targetEventConfigObject.passive;
|
||||
}
|
||||
}
|
||||
|
||||
const listeningName = generateListeningKey(
|
||||
((name: any): string),
|
||||
passive,
|
||||
);
|
||||
let rootEventComponents = rootEventTypesToEventComponentInstances.get(
|
||||
listeningName,
|
||||
rootEventType,
|
||||
);
|
||||
let rootEventTypesSet = ((currentInstance: any): ReactDOMEventComponentInstance)
|
||||
.rootEventTypes;
|
||||
if (rootEventTypesSet !== null) {
|
||||
rootEventTypesSet.delete(listeningName);
|
||||
rootEventTypesSet.delete(rootEventType);
|
||||
}
|
||||
if (rootEventComponents !== undefined) {
|
||||
rootEventComponents.delete(
|
||||
|
|
@ -595,41 +568,20 @@ function processEventQueue(): void {
|
|||
}
|
||||
}
|
||||
|
||||
function getDOMTargetEventTypesSet(
|
||||
eventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
): Set<string> {
|
||||
let cachedSet = targetEventTypeCached.get(eventTypes);
|
||||
|
||||
if (cachedSet === undefined) {
|
||||
cachedSet = new Set();
|
||||
for (let i = 0; i < eventTypes.length; i++) {
|
||||
const eventType = eventTypes[i];
|
||||
let name = eventType;
|
||||
let passive = true;
|
||||
|
||||
if (typeof eventType !== 'string') {
|
||||
const targetEventConfigObject = ((eventType: any): {
|
||||
name: string,
|
||||
passive?: boolean,
|
||||
});
|
||||
name = targetEventConfigObject.name;
|
||||
if (targetEventConfigObject.passive !== undefined) {
|
||||
passive = targetEventConfigObject.passive;
|
||||
}
|
||||
}
|
||||
const listeningName = generateListeningKey(
|
||||
((name: any): string),
|
||||
passive,
|
||||
);
|
||||
cachedSet.add(listeningName);
|
||||
function responderEventTypesContainType(
|
||||
eventTypes: Array<string>,
|
||||
type: string,
|
||||
): boolean {
|
||||
for (let i = 0, len = eventTypes.length; i < len; i++) {
|
||||
if (eventTypes[i] === type) {
|
||||
return true;
|
||||
}
|
||||
targetEventTypeCached.set(eventTypes, cachedSet);
|
||||
}
|
||||
return cachedSet;
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleTargetEventResponderInstance(
|
||||
listeningName: string,
|
||||
eventType: string,
|
||||
responderEvent: ReactDOMResponderEvent,
|
||||
eventComponentInstance: ReactDOMEventComponentInstance,
|
||||
hookComponentResponderValidation: null | Set<ReactDOMEventResponder>,
|
||||
|
|
@ -639,8 +591,7 @@ function handleTargetEventResponderInstance(
|
|||
const targetEventTypes = responder.targetEventTypes;
|
||||
// Validate the target event type exists on the responder
|
||||
if (targetEventTypes !== undefined) {
|
||||
const targetEventTypesSet = getDOMTargetEventTypesSet(targetEventTypes);
|
||||
if (targetEventTypesSet.has(listeningName)) {
|
||||
if (responderEventTypesContainType(targetEventTypes, eventType)) {
|
||||
if (hookComponentResponderValidation !== null) {
|
||||
hookComponentResponderValidation.add(responder);
|
||||
}
|
||||
|
|
@ -700,7 +651,7 @@ function checkForLocalPropagationContinuation(
|
|||
}
|
||||
|
||||
function traverseAndHandleEventResponderInstances(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
topLevelType: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: EventTarget,
|
||||
|
|
@ -708,17 +659,15 @@ function traverseAndHandleEventResponderInstances(
|
|||
): void {
|
||||
const isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0;
|
||||
const isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0;
|
||||
const listeningName = generateListeningKey(
|
||||
((topLevelType: any): string),
|
||||
isPassiveEvent || !isPassiveSupported,
|
||||
);
|
||||
const isPassive = isPassiveEvent || !isPassiveSupported;
|
||||
const eventType = isPassive ? topLevelType : topLevelType + '_active';
|
||||
|
||||
// Trigger event responders in this order:
|
||||
// - Bubble target phase
|
||||
// - Root phase
|
||||
|
||||
const responderEvent = createDOMResponderEvent(
|
||||
((topLevelType: any): string),
|
||||
topLevelType,
|
||||
nativeEvent,
|
||||
((nativeEventTarget: any): Element | Document),
|
||||
isPassiveEvent,
|
||||
|
|
@ -743,7 +692,7 @@ function traverseAndHandleEventResponderInstances(
|
|||
// Switch to the current fiber tree
|
||||
node = eventComponentInstance.currentFiber;
|
||||
handleTargetEventResponderInstance(
|
||||
listeningName,
|
||||
eventType,
|
||||
responderEvent,
|
||||
eventComponentInstance,
|
||||
hookComponentResponderValidation,
|
||||
|
|
@ -760,7 +709,7 @@ function traverseAndHandleEventResponderInstances(
|
|||
)
|
||||
) {
|
||||
handleTargetEventResponderInstance(
|
||||
listeningName,
|
||||
eventType,
|
||||
responderEvent,
|
||||
eventComponentInstance,
|
||||
null,
|
||||
|
|
@ -776,7 +725,7 @@ function traverseAndHandleEventResponderInstances(
|
|||
responderEvent.currentTarget = null;
|
||||
// Root phase
|
||||
const rootEventInstances = rootEventTypesToEventComponentInstances.get(
|
||||
listeningName,
|
||||
eventType,
|
||||
);
|
||||
if (rootEventInstances !== undefined) {
|
||||
const rootEventComponentInstances = Array.from(rootEventInstances);
|
||||
|
|
@ -906,7 +855,7 @@ function validateResponderContext(): void {
|
|||
}
|
||||
|
||||
export function dispatchEventForResponderEventSystem(
|
||||
topLevelType: DOMTopLevelEventType,
|
||||
topLevelType: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
nativeEventTarget: EventTarget,
|
||||
|
|
@ -950,7 +899,7 @@ export function dispatchEventForResponderEventSystem(
|
|||
|
||||
export function addRootEventTypesForComponentInstance(
|
||||
eventComponentInstance: ReactDOMEventComponentInstance,
|
||||
rootEventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
rootEventTypes: Array<string>,
|
||||
): void {
|
||||
for (let i = 0; i < rootEventTypes.length; i++) {
|
||||
const rootEventType = rootEventTypes[i];
|
||||
|
|
@ -959,31 +908,16 @@ export function addRootEventTypesForComponentInstance(
|
|||
}
|
||||
|
||||
function registerRootEventType(
|
||||
rootEventType: ReactDOMEventResponderEventType,
|
||||
rootEventType: string,
|
||||
eventComponentInstance: ReactDOMEventComponentInstance,
|
||||
): void {
|
||||
let name = rootEventType;
|
||||
let passive = true;
|
||||
|
||||
if (typeof rootEventType !== 'string') {
|
||||
const targetEventConfigObject = ((rootEventType: any): {
|
||||
name: string,
|
||||
passive?: boolean,
|
||||
});
|
||||
name = targetEventConfigObject.name;
|
||||
if (targetEventConfigObject.passive !== undefined) {
|
||||
passive = targetEventConfigObject.passive;
|
||||
}
|
||||
}
|
||||
|
||||
const listeningName = generateListeningKey(((name: any): string), passive);
|
||||
let rootEventComponentInstances = rootEventTypesToEventComponentInstances.get(
|
||||
listeningName,
|
||||
rootEventType,
|
||||
);
|
||||
if (rootEventComponentInstances === undefined) {
|
||||
rootEventComponentInstances = new Set();
|
||||
rootEventTypesToEventComponentInstances.set(
|
||||
listeningName,
|
||||
rootEventType,
|
||||
rootEventComponentInstances,
|
||||
);
|
||||
}
|
||||
|
|
@ -992,23 +926,12 @@ function registerRootEventType(
|
|||
rootEventTypesSet = eventComponentInstance.rootEventTypes = new Set();
|
||||
}
|
||||
invariant(
|
||||
!rootEventTypesSet.has(listeningName),
|
||||
!rootEventTypesSet.has(rootEventType),
|
||||
'addRootEventTypes() found a duplicate root event ' +
|
||||
'type of "%s". This might be because the event type exists in the event responder "rootEventTypes" ' +
|
||||
'array or because of a previous addRootEventTypes() using this root event type.',
|
||||
name,
|
||||
rootEventType,
|
||||
);
|
||||
rootEventTypesSet.add(listeningName);
|
||||
rootEventTypesSet.add(rootEventType);
|
||||
rootEventComponentInstances.add(eventComponentInstance);
|
||||
}
|
||||
|
||||
export function generateListeningKey(
|
||||
topLevelType: string,
|
||||
passive: boolean,
|
||||
): string {
|
||||
// Create a unique name for this event, plus its properties. We'll
|
||||
// use this to ensure we don't listen to the same event with the same
|
||||
// properties again.
|
||||
const passiveKey = passive ? '_passive' : '_active';
|
||||
return `${topLevelType}${passiveKey}`;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ export function dispatchEvent(
|
|||
} else {
|
||||
// React Flare event system
|
||||
dispatchEventForResponderEventSystem(
|
||||
topLevelType,
|
||||
(topLevelType: any),
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ describe('DOMEventResponderSystem', () => {
|
|||
const buttonRef = React.createRef();
|
||||
|
||||
const ClickEventComponent1 = createReactEventComponent({
|
||||
targetEventTypes: [{name: 'click', passive: false, capture: false}],
|
||||
targetEventTypes: ['click_active'],
|
||||
onEvent: event => {
|
||||
clickEventComponent1Fired++;
|
||||
eventLog.push({
|
||||
|
|
@ -639,7 +639,7 @@ describe('DOMEventResponderSystem', () => {
|
|||
});
|
||||
|
||||
const ClickEventComponent2 = createReactEventComponent({
|
||||
targetEventTypes: [{name: 'click', passive: true, capture: false}],
|
||||
targetEventTypes: ['click'],
|
||||
onEvent: event => {
|
||||
clickEventComponent2Fired++;
|
||||
eventLog.push({
|
||||
|
|
@ -686,7 +686,7 @@ describe('DOMEventResponderSystem', () => {
|
|||
let eventLog = [];
|
||||
|
||||
const ClickEventComponent1 = createReactEventComponent({
|
||||
rootEventTypes: [{name: 'click', passive: false, capture: false}],
|
||||
rootEventTypes: ['click_active'],
|
||||
onRootEvent: event => {
|
||||
clickEventComponent1Fired++;
|
||||
eventLog.push({
|
||||
|
|
@ -698,7 +698,7 @@ describe('DOMEventResponderSystem', () => {
|
|||
});
|
||||
|
||||
const ClickEventComponent2 = createReactEventComponent({
|
||||
rootEventTypes: [{name: 'click', passive: true, capture: false}],
|
||||
rootEventTypes: ['click'],
|
||||
onRootEvent: event => {
|
||||
clickEventComponent2Fired++;
|
||||
eventLog.push({
|
||||
|
|
|
|||
17
packages/react-events/src/dom/Drag.js
vendored
17
packages/react-events/src/dom/Drag.js
vendored
|
|
@ -18,11 +18,7 @@ import React from 'react';
|
|||
import {DiscreteEvent, UserBlockingEvent} from 'shared/ReactTypes';
|
||||
|
||||
const targetEventTypes = ['pointerdown'];
|
||||
const rootEventTypes = [
|
||||
'pointerup',
|
||||
'pointercancel',
|
||||
{name: 'pointermove', passive: false},
|
||||
];
|
||||
const rootEventTypes = ['pointerup', 'pointercancel', 'pointermove_active'];
|
||||
|
||||
type DragState = {
|
||||
dragTarget: null | Element | Document,
|
||||
|
|
@ -38,10 +34,13 @@ type DragState = {
|
|||
// too
|
||||
if (typeof window !== 'undefined' && window.PointerEvent === undefined) {
|
||||
targetEventTypes.push('touchstart', 'mousedown');
|
||||
rootEventTypes.push('mouseup', 'mousemove', 'touchend', 'touchcancel', {
|
||||
name: 'touchmove',
|
||||
passive: false,
|
||||
});
|
||||
rootEventTypes.push(
|
||||
'mouseup',
|
||||
'mousemove',
|
||||
'touchend',
|
||||
'touchcancel',
|
||||
'touchmove_active',
|
||||
);
|
||||
}
|
||||
|
||||
type EventData = {
|
||||
|
|
|
|||
5
packages/react-events/src/dom/Focus.js
vendored
5
packages/react-events/src/dom/Focus.js
vendored
|
|
@ -46,10 +46,7 @@ const isMac =
|
|||
? /^Mac/.test(window.navigator.platform)
|
||||
: false;
|
||||
|
||||
const targetEventTypes = [
|
||||
{name: 'focus', passive: true},
|
||||
{name: 'blur', passive: true},
|
||||
];
|
||||
const targetEventTypes = ['focus', 'blur'];
|
||||
|
||||
const rootEventTypes = [
|
||||
'keydown',
|
||||
|
|
|
|||
4
packages/react-events/src/dom/FocusScope.js
vendored
4
packages/react-events/src/dom/FocusScope.js
vendored
|
|
@ -25,8 +25,8 @@ type FocusScopeState = {
|
|||
currentFocusedNode: null | HTMLElement,
|
||||
};
|
||||
|
||||
const targetEventTypes = [{name: 'keydown', passive: false}];
|
||||
const rootEventTypes = [{name: 'focus', passive: true}];
|
||||
const targetEventTypes = ['keydown_active'];
|
||||
const rootEventTypes = ['focus'];
|
||||
|
||||
function focusElement(element: ?HTMLElement) {
|
||||
if (element != null) {
|
||||
|
|
|
|||
10
packages/react-events/src/dom/Press.js
vendored
10
packages/react-events/src/dom/Press.js
vendored
|
|
@ -123,12 +123,12 @@ const DEFAULT_PRESS_RETENTION_OFFSET = {
|
|||
};
|
||||
|
||||
const targetEventTypes = [
|
||||
{name: 'keydown', passive: false},
|
||||
{name: 'contextmenu', passive: false},
|
||||
'keydown_active',
|
||||
'contextmenu_active',
|
||||
// We need to preventDefault on pointerdown for mouse/pen events
|
||||
// that are in hit target area but not the element area.
|
||||
{name: 'pointerdown', passive: false},
|
||||
{name: 'click', passive: false},
|
||||
'pointerdown_active',
|
||||
'click_active',
|
||||
];
|
||||
const rootEventTypes = [
|
||||
'click',
|
||||
|
|
@ -139,7 +139,7 @@ const rootEventTypes = [
|
|||
'pointercancel',
|
||||
// We listen to this here so stopPropagation can
|
||||
// block other mouseup events used internally
|
||||
{name: 'mouseup', passive: false},
|
||||
'mouseup_active',
|
||||
'touchend',
|
||||
];
|
||||
|
||||
|
|
|
|||
17
packages/react-events/src/dom/Swipe.js
vendored
17
packages/react-events/src/dom/Swipe.js
vendored
|
|
@ -18,20 +18,19 @@ import React from 'react';
|
|||
import {UserBlockingEvent, DiscreteEvent} from 'shared/ReactTypes';
|
||||
|
||||
const targetEventTypes = ['pointerdown'];
|
||||
const rootEventTypes = [
|
||||
'pointerup',
|
||||
'pointercancel',
|
||||
{name: 'pointermove', passive: false},
|
||||
];
|
||||
const rootEventTypes = ['pointerup', 'pointercancel', 'pointermove_active'];
|
||||
|
||||
// In the case we don't have PointerEvents (Safari), we listen to touch events
|
||||
// too
|
||||
if (typeof window !== 'undefined' && window.PointerEvent === undefined) {
|
||||
targetEventTypes.push('touchstart', 'mousedown');
|
||||
rootEventTypes.push('mouseup', 'mousemove', 'touchend', 'touchcancel', {
|
||||
name: 'touchmove',
|
||||
passive: false,
|
||||
});
|
||||
rootEventTypes.push(
|
||||
'mouseup',
|
||||
'mousemove',
|
||||
'touchend',
|
||||
'touchcancel',
|
||||
'touchmove_active',
|
||||
);
|
||||
}
|
||||
|
||||
type EventData = {
|
||||
|
|
|
|||
2
packages/react-events/src/rn/Press.js
vendored
2
packages/react-events/src/rn/Press.js
vendored
|
|
@ -10,7 +10,6 @@
|
|||
import type {
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeEventTarget,
|
||||
PointerType,
|
||||
ReactFaricEventTouch,
|
||||
|
|
@ -24,7 +23,6 @@ import {
|
|||
} from 'react-native-renderer/src/ReactNativeTypes';
|
||||
|
||||
type ReactNativeEventResponder = ReactEventResponder<
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import type {
|
|||
ReactEventComponentInstance,
|
||||
} from 'shared/ReactTypes';
|
||||
import type {
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderContext,
|
||||
ReactNativeResponderEvent,
|
||||
EventPriority,
|
||||
|
|
@ -74,13 +73,11 @@ type EventQueue = {
|
|||
};
|
||||
|
||||
type ReactNativeEventResponder = ReactEventResponder<
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
>;
|
||||
|
||||
type ReactNativeEventComponentInstance = ReactEventComponentInstance<
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
>;
|
||||
|
|
@ -89,13 +86,9 @@ const {measureInWindow} = nativeFabricUIManager;
|
|||
|
||||
const activeTimeouts: Map<number, ResponderTimeout> = new Map();
|
||||
const rootEventTypesToEventComponentInstances: Map<
|
||||
ReactNativeEventResponderEventType | string,
|
||||
string,
|
||||
Set<ReactNativeEventComponentInstance>,
|
||||
> = new Map();
|
||||
const targetEventTypeCached: Map<
|
||||
Array<ReactNativeEventResponderEventType>,
|
||||
Set<ReactNativeEventResponderEventType>,
|
||||
> = new Map();
|
||||
const ownershipChangeListeners: Set<
|
||||
ReactNativeEventComponentInstance,
|
||||
> = new Set();
|
||||
|
|
@ -214,9 +207,7 @@ const eventResponderContext: ReactNativeResponderContext = {
|
|||
});
|
||||
});
|
||||
},
|
||||
addRootEventTypes(
|
||||
rootEventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
): void {
|
||||
addRootEventTypes(rootEventTypes: Array<string>): void {
|
||||
validateResponderContext();
|
||||
for (let i = 0; i < rootEventTypes.length; i++) {
|
||||
const rootEventType = rootEventTypes[i];
|
||||
|
|
@ -224,9 +215,7 @@ const eventResponderContext: ReactNativeResponderContext = {
|
|||
registerRootEventType(rootEventType, eventComponentInstance);
|
||||
}
|
||||
},
|
||||
removeRootEventTypes(
|
||||
rootEventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
): void {
|
||||
removeRootEventTypes(rootEventTypes: Array<string>): void {
|
||||
validateResponderContext();
|
||||
for (let i = 0; i < rootEventTypes.length; i++) {
|
||||
const rootEventType = rootEventTypes[i];
|
||||
|
|
@ -330,7 +319,7 @@ function processTimers(
|
|||
}
|
||||
|
||||
function createFabricResponderEvent(
|
||||
topLevelType: ReactNativeEventResponderEventType,
|
||||
topLevelType: string,
|
||||
nativeEvent: ReactFaricEvent,
|
||||
target: null | ReactNativeEventTarget,
|
||||
): ReactNativeResponderEvent {
|
||||
|
|
@ -451,19 +440,18 @@ function processEvents(events: Array<EventObjectType>): void {
|
|||
}
|
||||
}
|
||||
|
||||
function getFabricTargetEventTypesSet(
|
||||
eventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
): Set<ReactNativeEventResponderEventType> {
|
||||
let cachedSet = targetEventTypeCached.get(eventTypes);
|
||||
|
||||
if (cachedSet === undefined) {
|
||||
cachedSet = new Set();
|
||||
for (let i = 0; i < eventTypes.length; i++) {
|
||||
cachedSet.add(eventTypes[i]);
|
||||
// TODO this function is almost an exact copy of the DOM version, we should
|
||||
// somehow share the logic
|
||||
function responderEventTypesContainType(
|
||||
eventTypes: Array<string>,
|
||||
type: string,
|
||||
): boolean {
|
||||
for (let i = 0, len = eventTypes.length; i < len; i++) {
|
||||
if (eventTypes[i] === type) {
|
||||
return true;
|
||||
}
|
||||
targetEventTypeCached.set(eventTypes, cachedSet);
|
||||
}
|
||||
return cachedSet;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO this function is almost an exact copy of the DOM version, we should
|
||||
|
|
@ -499,7 +487,7 @@ function checkForLocalPropagationContinuation(
|
|||
// TODO this function is almost an exact copy of the DOM version, we should
|
||||
// somehow share the logic
|
||||
function handleTargetEventResponderInstance(
|
||||
topLevelType: ReactNativeEventResponderEventType,
|
||||
topLevelType: string,
|
||||
responderEvent: ReactNativeResponderEvent,
|
||||
eventComponentInstance: ReactNativeEventComponentInstance,
|
||||
hookComponentResponderValidation: null | Set<ReactNativeEventResponder>,
|
||||
|
|
@ -509,8 +497,7 @@ function handleTargetEventResponderInstance(
|
|||
const targetEventTypes = responder.targetEventTypes;
|
||||
// Validate the target event type exists on the responder
|
||||
if (targetEventTypes !== undefined) {
|
||||
const targetEventTypesSet = getFabricTargetEventTypesSet(targetEventTypes);
|
||||
if (targetEventTypesSet.has(topLevelType)) {
|
||||
if (responderEventTypesContainType(targetEventTypes, topLevelType)) {
|
||||
if (hookComponentResponderValidation !== null) {
|
||||
hookComponentResponderValidation.add(responder);
|
||||
}
|
||||
|
|
@ -544,7 +531,7 @@ function handleTargetEventResponderInstance(
|
|||
// TODO this function is almost an exact copy of the DOM version, we should
|
||||
// somehow share the logic
|
||||
function traverseAndHandleEventResponderInstances(
|
||||
topLevelType: ReactNativeEventResponderEventType,
|
||||
topLevelType: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: ReactFaricEvent,
|
||||
): void {
|
||||
|
|
@ -642,7 +629,7 @@ function traverseAndHandleEventResponderInstances(
|
|||
// TODO this function is almost an exact copy of the DOM version, we should
|
||||
// somehow share the logic
|
||||
export function dispatchEventForResponderEventSystem(
|
||||
topLevelType: ReactNativeEventResponderEventType,
|
||||
topLevelType: string,
|
||||
targetFiber: null | Fiber,
|
||||
nativeEvent: ReactFaricEvent,
|
||||
): void {
|
||||
|
|
@ -745,7 +732,7 @@ export function unmountEventResponder(
|
|||
}
|
||||
|
||||
function registerRootEventType(
|
||||
rootEventType: ReactNativeEventResponderEventType,
|
||||
rootEventType: string,
|
||||
eventComponentInstance: ReactNativeEventComponentInstance,
|
||||
) {
|
||||
let rootEventComponentInstances = rootEventTypesToEventComponentInstances.get(
|
||||
|
|
@ -775,7 +762,7 @@ function registerRootEventType(
|
|||
|
||||
export function addRootEventTypesForComponentInstance(
|
||||
eventComponentInstance: ReactNativeEventComponentInstance,
|
||||
rootEventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
rootEventTypes: Array<string>,
|
||||
): void {
|
||||
for (let i = 0; i < rootEventTypes.length; i++) {
|
||||
const rootEventType = rootEventTypes[i];
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@ import type {
|
|||
MeasureOnSuccessCallback,
|
||||
NativeMethodsMixinType,
|
||||
ReactNativeBaseComponentViewConfig,
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
} from './ReactNativeTypes';
|
||||
|
|
@ -66,7 +65,6 @@ const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
|
|||
let nextReactTag = 2;
|
||||
|
||||
type ReactNativeEventComponentInstance = ReactEventComponentInstance<
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
import type {
|
||||
ReactNativeBaseComponentViewConfig,
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
} from './ReactNativeTypes';
|
||||
|
|
@ -35,7 +34,6 @@ import ReactNativeFiberHostComponent from './ReactNativeFiberHostComponent';
|
|||
const {get: getViewConfigForType} = ReactNativeViewConfigRegistry;
|
||||
|
||||
type ReactNativeEventComponentInstance = ReactEventComponentInstance<
|
||||
ReactNativeEventResponderEventType,
|
||||
ReactNativeResponderEvent,
|
||||
ReactNativeResponderContext,
|
||||
>;
|
||||
|
|
|
|||
|
|
@ -157,17 +157,6 @@ export type ReactFabricType = {
|
|||
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: SecretInternalsFabricType,
|
||||
};
|
||||
|
||||
export type ReactNativeEventResponderEventType =
|
||||
| 'topMouseDown'
|
||||
| 'topMouseMove'
|
||||
| 'topMouseUp'
|
||||
| 'topScroll'
|
||||
| 'topSelectionChange'
|
||||
| 'topTouchCancel'
|
||||
| 'topTouchEnd'
|
||||
| 'topTouchMove'
|
||||
| 'topTouchStart';
|
||||
|
||||
export type ReactNativeEventTarget = {
|
||||
node: Object,
|
||||
canonical: {
|
||||
|
|
@ -202,7 +191,7 @@ export type ReactNativeResponderEvent = {
|
|||
currentTarget: null | ReactNativeEventTarget,
|
||||
nativeEvent: ReactFaricEvent,
|
||||
target: null | ReactNativeEventTarget,
|
||||
type: ReactNativeEventResponderEventType,
|
||||
type: string,
|
||||
};
|
||||
|
||||
export type ReactNativeResponderContext = {
|
||||
|
|
@ -224,12 +213,8 @@ export type ReactNativeResponderContext = {
|
|||
bottom: number,
|
||||
}) => void,
|
||||
): void,
|
||||
addRootEventTypes: (
|
||||
rootEventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
) => void,
|
||||
removeRootEventTypes: (
|
||||
rootEventTypes: Array<ReactNativeEventResponderEventType>,
|
||||
) => void,
|
||||
addRootEventTypes: (rootEventTypes: Array<string>) => void,
|
||||
removeRootEventTypes: (rootEventTypes: Array<string>) => void,
|
||||
setTimeout: (func: () => void, timeout: number) => number,
|
||||
clearTimeout: (timerId: number) => void,
|
||||
getTimeStamp: () => number,
|
||||
|
|
|
|||
2
packages/react-reconciler/src/ReactFiber.js
vendored
2
packages/react-reconciler/src/ReactFiber.js
vendored
|
|
@ -103,7 +103,7 @@ if (__DEV__) {
|
|||
export type Dependencies = {
|
||||
expirationTime: ExpirationTime,
|
||||
firstContext: ContextDependency<mixed> | null,
|
||||
events: Array<ReactEventComponentInstance<any, any, any>> | null,
|
||||
events: Array<ReactEventComponentInstance<any, any>> | null,
|
||||
};
|
||||
|
||||
// A Fiber is work on a Component that needs to be done or was done. There can
|
||||
|
|
|
|||
|
|
@ -1126,7 +1126,6 @@ function completeWork(
|
|||
let eventComponentInstance: ReactEventComponentInstance<
|
||||
any,
|
||||
any,
|
||||
any,
|
||||
> | null =
|
||||
workInProgress.stateNode;
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ export function prepareToReadEventComponents(workInProgress: Fiber): void {
|
|||
currentEventComponentInstanceIndex = 0;
|
||||
}
|
||||
|
||||
export function updateEventComponentInstance<T, E, C>(
|
||||
eventComponent: ReactEventComponent<T, E, C>,
|
||||
export function updateEventComponentInstance<E, C>(
|
||||
eventComponent: ReactEventComponent<E, C>,
|
||||
props: Object,
|
||||
): void {
|
||||
const responder = eventComponent.responder;
|
||||
|
|
@ -82,14 +82,14 @@ export function updateEventComponentInstance<T, E, C>(
|
|||
}
|
||||
}
|
||||
|
||||
export function createEventComponentInstance<T, E, C>(
|
||||
export function createEventComponentInstance<E, C>(
|
||||
currentFiber: Fiber,
|
||||
props: Object,
|
||||
responder: ReactEventResponder<T, E, C>,
|
||||
responder: ReactEventResponder<E, C>,
|
||||
rootInstance: mixed,
|
||||
state: Object,
|
||||
isHook: boolean,
|
||||
): ReactEventComponentInstance<T, E, C> {
|
||||
): ReactEventComponentInstance<E, C> {
|
||||
return {
|
||||
currentFiber,
|
||||
isHook,
|
||||
|
|
|
|||
14
packages/react-reconciler/src/ReactFiberHooks.js
vendored
14
packages/react-reconciler/src/ReactFiberHooks.js
vendored
|
|
@ -83,8 +83,8 @@ export type Dispatcher = {
|
|||
deps: Array<mixed> | void | null,
|
||||
): void,
|
||||
useDebugValue<T>(value: T, formatterFn: ?(value: T) => mixed): void,
|
||||
useEvent<T, E, C>(
|
||||
eventComponent: ReactEventComponent<T, E, C>,
|
||||
useEvent<E, C>(
|
||||
eventComponent: ReactEventComponent<E, C>,
|
||||
props: Object,
|
||||
): void,
|
||||
};
|
||||
|
|
@ -1416,7 +1416,7 @@ if (__DEV__) {
|
|||
mountHookTypesDev();
|
||||
return mountDebugValue(value, formatterFn);
|
||||
},
|
||||
useEvent<T, E, C>(eventComponent: ReactEventComponent<T, E, C>, props) {
|
||||
useEvent<E, C>(eventComponent: ReactEventComponent<E, C>, props) {
|
||||
currentHookNameInDev = 'useEvent';
|
||||
mountHookTypesDev();
|
||||
updateEventComponentInstance(eventComponent, props);
|
||||
|
|
@ -1518,7 +1518,7 @@ if (__DEV__) {
|
|||
updateHookTypesDev();
|
||||
return mountDebugValue(value, formatterFn);
|
||||
},
|
||||
useEvent<T, E, C>(eventComponent: ReactEventComponent<T, E, C>, props) {
|
||||
useEvent<E, C>(eventComponent: ReactEventComponent<E, C>, props) {
|
||||
currentHookNameInDev = 'useEvent';
|
||||
updateHookTypesDev();
|
||||
updateEventComponentInstance(eventComponent, props);
|
||||
|
|
@ -1620,7 +1620,7 @@ if (__DEV__) {
|
|||
updateHookTypesDev();
|
||||
return updateDebugValue(value, formatterFn);
|
||||
},
|
||||
useEvent<T, E, C>(eventComponent: ReactEventComponent<T, E, C>, props) {
|
||||
useEvent<E, C>(eventComponent: ReactEventComponent<E, C>, props) {
|
||||
currentHookNameInDev = 'useEvent';
|
||||
updateHookTypesDev();
|
||||
updateEventComponentInstance(eventComponent, props);
|
||||
|
|
@ -1733,7 +1733,7 @@ if (__DEV__) {
|
|||
mountHookTypesDev();
|
||||
return mountDebugValue(value, formatterFn);
|
||||
},
|
||||
useEvent<T, E, C>(eventComponent: ReactEventComponent<T, E, C>, props) {
|
||||
useEvent<E, C>(eventComponent: ReactEventComponent<E, C>, props) {
|
||||
currentHookNameInDev = 'useEvent';
|
||||
warnInvalidHookAccess();
|
||||
mountHookTypesDev();
|
||||
|
|
@ -1847,7 +1847,7 @@ if (__DEV__) {
|
|||
updateHookTypesDev();
|
||||
return updateDebugValue(value, formatterFn);
|
||||
},
|
||||
useEvent<T, E, C>(eventComponent: ReactEventComponent<T, E, C>, props) {
|
||||
useEvent<E, C>(eventComponent: ReactEventComponent<E, C>, props) {
|
||||
currentHookNameInDev = 'useEvent';
|
||||
warnInvalidHookAccess();
|
||||
updateHookTypesDev();
|
||||
|
|
|
|||
|
|
@ -286,19 +286,19 @@ export function unhideTextInstance(
|
|||
}
|
||||
|
||||
export function mountEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
export function updateEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
): void {
|
||||
// noop
|
||||
}
|
||||
|
||||
export function unmountEventComponent(
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any, any>,
|
||||
eventComponentInstance: ReactEventComponentInstance<any, any>,
|
||||
): void {
|
||||
// noop
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,8 +138,8 @@ export function useDebugValue(value: any, formatterFn: ?(value: any) => any) {
|
|||
|
||||
export const emptyObject = {};
|
||||
|
||||
export function useEvent<T, E, C>(
|
||||
eventComponent: ReactEventComponent<T, E, C>,
|
||||
export function useEvent<E, C>(
|
||||
eventComponent: ReactEventComponent<E, C>,
|
||||
props: null | Object,
|
||||
) {
|
||||
const dispatcher = resolveDispatcher();
|
||||
|
|
|
|||
|
|
@ -15,10 +15,6 @@ import type {
|
|||
|
||||
type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch;
|
||||
|
||||
export type ReactDOMEventResponderEventType =
|
||||
| string
|
||||
| {name: string, passive?: boolean};
|
||||
|
||||
export type PointerType =
|
||||
| ''
|
||||
| 'mouse'
|
||||
|
|
@ -39,13 +35,11 @@ export type ReactDOMResponderEvent = {
|
|||
};
|
||||
|
||||
export type ReactDOMEventResponder = ReactEventResponder<
|
||||
ReactDOMEventResponderEventType,
|
||||
ReactDOMResponderEvent,
|
||||
ReactDOMResponderContext,
|
||||
>;
|
||||
|
||||
export type ReactDOMEventComponentInstance = ReactEventComponentInstance<
|
||||
ReactDOMEventResponderEventType,
|
||||
ReactDOMResponderEvent,
|
||||
ReactDOMResponderContext,
|
||||
>;
|
||||
|
|
@ -62,12 +56,8 @@ export type ReactDOMResponderContext = {
|
|||
) => boolean,
|
||||
isTargetWithinEventComponent: (Element | Document) => boolean,
|
||||
isTargetWithinEventResponderScope: (Element | Document) => boolean,
|
||||
addRootEventTypes: (
|
||||
rootEventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
) => void,
|
||||
removeRootEventTypes: (
|
||||
rootEventTypes: Array<ReactDOMEventResponderEventType>,
|
||||
) => void,
|
||||
addRootEventTypes: (rootEventTypes: Array<string>) => void,
|
||||
removeRootEventTypes: (rootEventTypes: Array<string>) => void,
|
||||
hasOwnership: () => boolean,
|
||||
requestGlobalOwnership: () => boolean,
|
||||
releaseOwnership: () => boolean,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export type ReactNode =
|
|||
| ReactFragment
|
||||
| ReactProvider<any>
|
||||
| ReactConsumer<any>
|
||||
| ReactEventComponent<any, any, any>;
|
||||
| ReactEventComponent<any, any>;
|
||||
|
||||
export type ReactEmpty = null | void | boolean;
|
||||
|
||||
|
|
@ -80,20 +80,20 @@ export type RefObject = {|
|
|||
current: any,
|
||||
|};
|
||||
|
||||
export type ReactEventComponentInstance<T, E, C> = {|
|
||||
export type ReactEventComponentInstance<E, C> = {|
|
||||
currentFiber: mixed,
|
||||
isHook: boolean,
|
||||
props: Object,
|
||||
responder: ReactEventResponder<T, E, C>,
|
||||
responder: ReactEventResponder<E, C>,
|
||||
rootEventTypes: null | Set<string>,
|
||||
rootInstance: null | mixed,
|
||||
state: Object,
|
||||
|};
|
||||
|
||||
export type ReactEventResponder<T, E, C> = {
|
||||
export type ReactEventResponder<E, C> = {
|
||||
displayName: string,
|
||||
targetEventTypes?: Array<T>,
|
||||
rootEventTypes?: Array<T>,
|
||||
targetEventTypes?: Array<string>,
|
||||
rootEventTypes?: Array<string>,
|
||||
getInitialState?: (props: Object) => Object,
|
||||
allowMultipleHostChildren: boolean,
|
||||
allowEventHooks: boolean,
|
||||
|
|
@ -104,9 +104,9 @@ export type ReactEventResponder<T, E, C> = {
|
|||
onOwnershipChange?: (context: C, props: Object, state: Object) => void,
|
||||
};
|
||||
|
||||
export type ReactEventComponent<T, E, C> = {|
|
||||
export type ReactEventComponent<E, C> = {|
|
||||
$$typeof: Symbol | number,
|
||||
responder: ReactEventResponder<T, E, C>,
|
||||
responder: ReactEventResponder<E, C>,
|
||||
|};
|
||||
|
||||
export opaque type EventPriority = 0 | 1 | 2;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@ if (__DEV__) {
|
|||
}
|
||||
}
|
||||
|
||||
export default function createEventComponent<T, E, C>(
|
||||
responder: ReactEventResponder<T, E, C>,
|
||||
): ReactEventComponent<T, E, C> {
|
||||
export default function createEventComponent<E, C>(
|
||||
responder: ReactEventResponder<E, C>,
|
||||
): ReactEventComponent<E, C> {
|
||||
// We use responder as a Map key later on. When we have a bad
|
||||
// polyfill, then we can't use it as a key as the polyfill tries
|
||||
// to add a property to the object.
|
||||
|
|
|
|||
13
packages/shared/endsWith.js
Normal file
13
packages/shared/endsWith.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/**
|
||||
* 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
|
||||
*/
|
||||
|
||||
export default function endsWith(subject: string, search: string): boolean {
|
||||
const length = subject.length;
|
||||
return subject.substring(length - search.length, length) === search;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user