-
Notifications
You must be signed in to change notification settings - Fork 45.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make event plugin injection statically resolvable #19234
Changes from 4 commits
5fc0370
1baeaa1
4873496
3a50ffe
d395955
101b1ee
52669a8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,7 +17,6 @@ import type {EventSystemFlags} from './EventSystemFlags'; | |
import type {EventPriority, ReactScopeInstance} from 'shared/ReactTypes'; | ||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes'; | ||
import type { | ||
ModernPluginModule, | ||
DispatchQueue, | ||
DispatchQueueItem, | ||
DispatchQueueItemPhase, | ||
|
@@ -28,8 +27,10 @@ import type { | |
CustomDispatchConfig, | ||
} from '../events/ReactSyntheticEventType'; | ||
|
||
import {registrationNameDependencies} from '../events/EventPluginRegistry'; | ||
import {plugins} from '../events/EventPluginRegistry'; | ||
import { | ||
extractEvents, | ||
registrationNameDependencies, | ||
} from '../events/EventPluginRegistry'; | ||
import { | ||
PLUGIN_EVENT_SYSTEM, | ||
LEGACY_FB_SUPPORT, | ||
|
@@ -218,22 +219,17 @@ function dispatchEventsForPlugins( | |
targetInst: null | Fiber, | ||
targetContainer: EventTarget, | ||
): void { | ||
const modernPlugins = ((plugins: any): Array<ModernPluginModule<Event>>); | ||
const nativeEventTarget = getEventTarget(nativeEvent); | ||
const dispatchQueue: DispatchQueue = []; | ||
|
||
for (let i = 0; i < modernPlugins.length; i++) { | ||
const plugin = modernPlugins[i]; | ||
plugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
} | ||
extractEvents( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This calls into a function that will statically enumerate each of them. |
||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
dispatchEventsInBatch(dispatchQueue); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,33 +7,22 @@ | |
* @flow | ||
*/ | ||
|
||
import type {DispatchConfig} from './ReactSyntheticEventType'; | ||
import type { | ||
AnyNativeEvent, | ||
LegacyPluginModule, | ||
ModernPluginModule, | ||
} from './PluginModuleType'; | ||
import ModernBeforeInputEventPlugin from '../events/plugins/ModernBeforeInputEventPlugin'; | ||
import ModernChangeEventPlugin from '../events/plugins/ModernChangeEventPlugin'; | ||
import ModernEnterLeaveEventPlugin from '../events/plugins/ModernEnterLeaveEventPlugin'; | ||
import ModernSelectEventPlugin from '../events/plugins/ModernSelectEventPlugin'; | ||
import ModernSimpleEventPlugin from '../events/plugins/ModernSimpleEventPlugin'; | ||
import type {TopLevelType} from './TopLevelEventTypes'; | ||
import type {DispatchQueue} from './PluginModuleType'; | ||
import type {EventSystemFlags} from './EventSystemFlags'; | ||
import type {AnyNativeEvent, EventTypes} from './PluginModuleType'; | ||
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes'; | ||
|
||
import * as ModernBeforeInputEventPlugin from '../events/plugins/ModernBeforeInputEventPlugin'; | ||
import * as ModernChangeEventPlugin from '../events/plugins/ModernChangeEventPlugin'; | ||
import * as ModernEnterLeaveEventPlugin from '../events/plugins/ModernEnterLeaveEventPlugin'; | ||
import * as ModernSelectEventPlugin from '../events/plugins/ModernSelectEventPlugin'; | ||
import * as ModernSimpleEventPlugin from '../events/plugins/ModernSimpleEventPlugin'; | ||
|
||
import invariant from 'shared/invariant'; | ||
|
||
/** | ||
* Publishes an event so that it can be dispatched by the supplied plugin. | ||
* | ||
* @param {object} dispatchConfig Dispatch configuration for the event. | ||
* @param {object} PluginModule Plugin publishing the event. | ||
* @return {boolean} True if the event was successfully published. | ||
* @private | ||
*/ | ||
function publishEventForPlugin( | ||
dispatchConfig: DispatchConfig, | ||
pluginModule: | ||
| LegacyPluginModule<AnyNativeEvent> | ||
| ModernPluginModule<AnyNativeEvent>, | ||
eventTypes: EventTypes, | ||
eventName: string, | ||
): boolean { | ||
invariant( | ||
|
@@ -42,55 +31,43 @@ function publishEventForPlugin( | |
'event name, `%s`.', | ||
eventName, | ||
); | ||
const dispatchConfig = eventTypes[eventName]; | ||
eventNameDispatchConfigs[eventName] = dispatchConfig; | ||
|
||
const phasedRegistrationNames = dispatchConfig.phasedRegistrationNames; | ||
if (phasedRegistrationNames) { | ||
for (const phaseName in phasedRegistrationNames) { | ||
if (phasedRegistrationNames.hasOwnProperty(phaseName)) { | ||
const phasedRegistrationName = phasedRegistrationNames[phaseName]; | ||
publishRegistrationName( | ||
phasedRegistrationName, | ||
pluginModule, | ||
eventName, | ||
); | ||
publishRegistrationName(phasedRegistrationName, eventTypes, eventName); | ||
} | ||
} | ||
return true; | ||
} else if (dispatchConfig.registrationName) { | ||
publishRegistrationName( | ||
dispatchConfig.registrationName, | ||
pluginModule, | ||
eventTypes, | ||
eventName, | ||
); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Publishes a registration name that is used to identify dispatched events. | ||
* | ||
* @param {string} registrationName Registration name to add. | ||
* @param {object} PluginModule Plugin publishing the event. | ||
* @private | ||
*/ | ||
function publishRegistrationName( | ||
registrationName: string, | ||
pluginModule: | ||
| LegacyPluginModule<AnyNativeEvent> | ||
| ModernPluginModule<AnyNativeEvent>, | ||
eventTypes: EventTypes, | ||
eventName: string, | ||
): void { | ||
invariant( | ||
!registrationNameModules[registrationName], | ||
!registrationNames[registrationName], | ||
'EventPluginRegistry: More than one plugin attempted to publish the same ' + | ||
'registration name, `%s`.', | ||
registrationName, | ||
); | ||
registrationNameModules[registrationName] = pluginModule; | ||
registrationNames[registrationName] = true; | ||
registrationNameDependencies[registrationName] = | ||
pluginModule.eventTypes[eventName].dependencies; | ||
eventTypes[eventName].dependencies; | ||
|
||
if (__DEV__) { | ||
const lowerCasedName = registrationName.toLowerCase(); | ||
|
@@ -102,15 +79,6 @@ function publishRegistrationName( | |
} | ||
} | ||
|
||
/** | ||
* Registers plugins so that they can extract and dispatch events. | ||
*/ | ||
|
||
/** | ||
* Ordered list of injected plugins. | ||
*/ | ||
export const plugins = []; | ||
|
||
/** | ||
* Mapping from event name to dispatch config | ||
*/ | ||
|
@@ -119,7 +87,7 @@ export const eventNameDispatchConfigs = {}; | |
/** | ||
* Mapping from registration name to plugin module | ||
*/ | ||
export const registrationNameModules = {}; | ||
export const registrationNames = {}; | ||
|
||
/** | ||
* Mapping from registration name to event name | ||
|
@@ -135,17 +103,71 @@ export const registrationNameDependencies = {}; | |
export const possibleRegistrationNames = __DEV__ ? {} : (null: any); | ||
// Trust the developer to only use possibleRegistrationNames in __DEV__ | ||
|
||
function injectEventPlugin(pluginModule: ModernPluginModule<any>): void { | ||
plugins.push(pluginModule); | ||
const publishedEvents = pluginModule.eventTypes; | ||
for (const eventName in publishedEvents) { | ||
publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName); | ||
function injectEventPlugin(eventTypes: EventTypes): void { | ||
for (const eventName in eventTypes) { | ||
publishEventForPlugin(eventTypes, eventName); | ||
} | ||
} | ||
|
||
export function extractEvents( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the new static thing. |
||
dispatchQueue: DispatchQueue, | ||
topLevelType: TopLevelType, | ||
targetInst: null | Fiber, | ||
nativeEvent: AnyNativeEvent, | ||
nativeEventTarget: null | EventTarget, | ||
eventSystemFlags: EventSystemFlags, | ||
targetContainer: null | EventTarget, | ||
) { | ||
ModernSimpleEventPlugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
ModernEnterLeaveEventPlugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
ModernChangeEventPlugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
ModernSelectEventPlugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
ModernBeforeInputEventPlugin.extractEvents( | ||
dispatchQueue, | ||
topLevelType, | ||
targetInst, | ||
nativeEvent, | ||
nativeEventTarget, | ||
eventSystemFlags, | ||
targetContainer, | ||
); | ||
} | ||
|
||
// TODO: remove top-level side effect. | ||
injectEventPlugin(ModernSimpleEventPlugin); | ||
injectEventPlugin(ModernEnterLeaveEventPlugin); | ||
injectEventPlugin(ModernChangeEventPlugin); | ||
injectEventPlugin(ModernSelectEventPlugin); | ||
injectEventPlugin(ModernBeforeInputEventPlugin); | ||
injectEventPlugin(ModernSimpleEventPlugin.eventTypes); | ||
injectEventPlugin(ModernEnterLeaveEventPlugin.eventTypes); | ||
injectEventPlugin(ModernChangeEventPlugin.eventTypes); | ||
injectEventPlugin(ModernSelectEventPlugin.eventTypes); | ||
injectEventPlugin(ModernBeforeInputEventPlugin.eventTypes); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ import type { | |
DispatchConfig, | ||
ReactSyntheticEvent, | ||
} from './ReactSyntheticEventType'; | ||
import type {TopLevelType} from './TopLevelEventTypes'; | ||
|
||
export type EventTypes = {[key: string]: DispatchConfig, ...}; | ||
|
||
|
@@ -22,19 +21,6 @@ export type PluginName = string; | |
|
||
export type EventSystemFlags = number; | ||
|
||
export type LegacyPluginModule<NativeEvent> = { | ||
eventTypes: EventTypes, | ||
extractEvents: ( | ||
topLevelType: TopLevelType, | ||
targetInst: null | Fiber, | ||
nativeTarget: NativeEvent, | ||
nativeEventTarget: null | EventTarget, | ||
eventSystemFlags?: number, | ||
container?: null | EventTarget, | ||
) => ?ReactSyntheticEvent, | ||
tapMoveThreshold?: number, | ||
}; | ||
|
||
export type DispatchQueueItemPhaseEntry = {| | ||
instance: null | Fiber, | ||
listener: Function, | ||
|
@@ -50,16 +36,3 @@ export type DispatchQueueItem = {| | |
|}; | ||
|
||
export type DispatchQueue = Array<DispatchQueueItem>; | ||
|
||
export type ModernPluginModule<NativeEvent> = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This concept sort of goes away. |
||
eventTypes: EventTypes, | ||
extractEvents: ( | ||
dispatchQueue: DispatchQueue, | ||
topLevelType: TopLevelType, | ||
targetInst: null | Fiber, | ||
nativeTarget: NativeEvent, | ||
nativeEventTarget: null | EventTarget, | ||
eventSystemFlags: number, | ||
container: null | EventTarget, | ||
) => void, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be an object hash of name -> plugin. But the plugin object wasn't actually used. I changed it to a hash of name -> true. This lets us get rid of object "plugin" representations.