mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 12:20:20 +01:00
Initial
This commit is contained in:
parent
26185759e4
commit
2f5d455e44
|
|
@ -66,6 +66,10 @@ function recomputePluginOrdering(): void {
|
|||
);
|
||||
plugins[pluginIndex] = pluginModule;
|
||||
const publishedEvents = pluginModule.eventTypes;
|
||||
if (!publishedEvents) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const eventName in publishedEvents) {
|
||||
invariant(
|
||||
publishEventForPlugin(
|
||||
|
|
@ -145,8 +149,11 @@ function publishRegistrationName(
|
|||
registrationName,
|
||||
);
|
||||
registrationNameModules[registrationName] = pluginModule;
|
||||
registrationNameDependencies[registrationName] =
|
||||
pluginModule.eventTypes[eventName].dependencies;
|
||||
|
||||
if (pluginModule.eventTypes) {
|
||||
registrationNameDependencies[registrationName] =
|
||||
pluginModule.eventTypes[eventName].dependencies;
|
||||
}
|
||||
|
||||
if (__DEV__) {
|
||||
const lowerCasedName = registrationName.toLowerCase();
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export type AnyNativeEvent = Event | KeyboardEvent | MouseEvent | Touch;
|
|||
export type PluginName = string;
|
||||
|
||||
export type PluginModule<NativeEvent> = {
|
||||
eventTypes: EventTypes,
|
||||
eventTypes?: EventTypes,
|
||||
extractEvents: (
|
||||
topLevelType: string,
|
||||
targetInst: Fiber,
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
// TODO: direct imports like some-package/src/* are bad. Fix me.
|
||||
import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
|
||||
import {registrationNameModules} from 'events/EventPluginRegistry';
|
||||
import emptyFunction from 'fbjs/lib/emptyFunction';
|
||||
import warning from 'fbjs/lib/warning';
|
||||
|
||||
|
|
@ -312,7 +311,7 @@ function setInitialDOMProperties(
|
|||
} else if (propKey === AUTOFOCUS) {
|
||||
// We polyfill it separately on the client during commit.
|
||||
// We blacklist it here rather than in the property list because we emit it in SSR.
|
||||
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
||||
} else if (propKey[0] === 'o' && propKey[1] === 'n') {
|
||||
if (nextProp != null) {
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
warnForInvalidEventListener(propKey, nextProp);
|
||||
|
|
@ -651,7 +650,7 @@ export function diffProperties(
|
|||
// Noop
|
||||
} else if (propKey === AUTOFOCUS) {
|
||||
// Noop. It doesn't work on updates anyway.
|
||||
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
||||
} else if (propKey[0] === 'o' && propKey[1] === 'n') {
|
||||
// This is a special case. If any listener updates we need to ensure
|
||||
// that the "current" fiber pointer gets updated so we need a commit
|
||||
// to update this element.
|
||||
|
|
@ -740,7 +739,7 @@ export function diffProperties(
|
|||
propKey === SUPPRESS_HYDRATION_WARNING
|
||||
) {
|
||||
// Noop
|
||||
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
||||
} else if (propKey[0] === 'o' && propKey[1] === 'n') {
|
||||
if (nextProp != null) {
|
||||
// We eagerly listen to this even though we haven't committed yet.
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
|
|
@ -966,7 +965,7 @@ export function diffHydratedProperties(
|
|||
updatePayload = [CHILDREN, '' + nextProp];
|
||||
}
|
||||
}
|
||||
} else if (registrationNameModules.hasOwnProperty(propKey)) {
|
||||
} else if (propKey[0] === 'o' && propKey[1] === 'n') {
|
||||
if (nextProp != null) {
|
||||
if (__DEV__ && typeof nextProp !== 'function') {
|
||||
warnForInvalidEventListener(propKey, nextProp);
|
||||
|
|
|
|||
|
|
@ -81,6 +81,15 @@ let reactTopListenersCounter = 0;
|
|||
*/
|
||||
const topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
|
||||
|
||||
function getEventsFromRegistraionName(registrationName) {
|
||||
if (!(registrationName in registrationNameDependencies)) {
|
||||
registrationNameDependencies[registrationName] = [
|
||||
`top${registrationName.slice(2)}`,
|
||||
];
|
||||
}
|
||||
return registrationNameDependencies[registrationName];
|
||||
}
|
||||
|
||||
function getListeningForDocument(mountAt) {
|
||||
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
|
||||
// directly.
|
||||
|
|
@ -115,7 +124,7 @@ function getListeningForDocument(mountAt) {
|
|||
export function listenTo(registrationName, contentDocumentHandle) {
|
||||
const mountAt = contentDocumentHandle;
|
||||
const isListening = getListeningForDocument(mountAt);
|
||||
const dependencies = registrationNameDependencies[registrationName];
|
||||
const dependencies = getEventsFromRegistraionName(registrationName);
|
||||
|
||||
for (let i = 0; i < dependencies.length; i++) {
|
||||
const dependency = dependencies[i];
|
||||
|
|
|
|||
271
packages/react-dom/src/events/SimpleEventPlugin.js
vendored
271
packages/react-dom/src/events/SimpleEventPlugin.js
vendored
|
|
@ -13,11 +13,10 @@ import type {
|
|||
ReactSyntheticEvent,
|
||||
} from 'events/ReactSyntheticEventType';
|
||||
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
||||
import type {EventTypes, PluginModule} from 'events/PluginModuleType';
|
||||
import type {PluginModule} from 'events/PluginModuleType';
|
||||
|
||||
import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
|
||||
import SyntheticEvent from 'events/SyntheticEvent';
|
||||
import warning from 'fbjs/lib/warning';
|
||||
|
||||
import SyntheticAnimationEvent from './SyntheticAnimationEvent';
|
||||
import SyntheticClipboardEvent from './SyntheticClipboardEvent';
|
||||
|
|
@ -31,247 +30,83 @@ import SyntheticUIEvent from './SyntheticUIEvent';
|
|||
import SyntheticWheelEvent from './SyntheticWheelEvent';
|
||||
import getEventCharCode from './getEventCharCode';
|
||||
|
||||
/**
|
||||
* Turns
|
||||
* ['abort', ...]
|
||||
* into
|
||||
* eventTypes = {
|
||||
* 'abort': {
|
||||
* phasedRegistrationNames: {
|
||||
* bubbled: 'onAbort',
|
||||
* captured: 'onAbortCapture',
|
||||
* },
|
||||
* dependencies: ['topAbort'],
|
||||
* },
|
||||
* ...
|
||||
* };
|
||||
* topLevelEventsToDispatchConfig = {
|
||||
* 'topAbort': { sameConfig }
|
||||
* };
|
||||
*/
|
||||
const eventTypes: EventTypes = {};
|
||||
const topLevelEventsToDispatchConfig: {
|
||||
[key: TopLevelTypes]: DispatchConfig,
|
||||
} = {};
|
||||
[
|
||||
'abort',
|
||||
'animationEnd',
|
||||
'animationIteration',
|
||||
'animationStart',
|
||||
'blur',
|
||||
'cancel',
|
||||
'canPlay',
|
||||
'canPlayThrough',
|
||||
'click',
|
||||
'close',
|
||||
'contextMenu',
|
||||
'copy',
|
||||
'cut',
|
||||
'doubleClick',
|
||||
'drag',
|
||||
'dragEnd',
|
||||
'dragEnter',
|
||||
'dragExit',
|
||||
'dragLeave',
|
||||
'dragOver',
|
||||
'dragStart',
|
||||
'drop',
|
||||
'durationChange',
|
||||
'emptied',
|
||||
'encrypted',
|
||||
'ended',
|
||||
'error',
|
||||
'focus',
|
||||
'input',
|
||||
'invalid',
|
||||
'keyDown',
|
||||
'keyPress',
|
||||
'keyUp',
|
||||
'load',
|
||||
'loadedData',
|
||||
'loadedMetadata',
|
||||
'loadStart',
|
||||
'mouseDown',
|
||||
'mouseMove',
|
||||
'mouseOut',
|
||||
'mouseOver',
|
||||
'mouseUp',
|
||||
'paste',
|
||||
'pause',
|
||||
'play',
|
||||
'playing',
|
||||
'progress',
|
||||
'rateChange',
|
||||
'reset',
|
||||
'scroll',
|
||||
'seeked',
|
||||
'seeking',
|
||||
'stalled',
|
||||
'submit',
|
||||
'suspend',
|
||||
'timeUpdate',
|
||||
'toggle',
|
||||
'touchCancel',
|
||||
'touchEnd',
|
||||
'touchMove',
|
||||
'touchStart',
|
||||
'transitionEnd',
|
||||
'volumeChange',
|
||||
'waiting',
|
||||
'wheel',
|
||||
].forEach(event => {
|
||||
const capitalizedEvent = event[0].toUpperCase() + event.slice(1);
|
||||
const onEvent = 'on' + capitalizedEvent;
|
||||
const topEvent = 'top' + capitalizedEvent;
|
||||
|
||||
const type = {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: onEvent,
|
||||
captured: onEvent + 'Capture',
|
||||
},
|
||||
dependencies: [topEvent],
|
||||
};
|
||||
eventTypes[event] = type;
|
||||
topLevelEventsToDispatchConfig[topEvent] = type;
|
||||
});
|
||||
|
||||
// Only used in DEV for exhaustiveness validation.
|
||||
const knownHTMLTopLevelTypes = [
|
||||
'topAbort',
|
||||
'topCancel',
|
||||
'topCanPlay',
|
||||
'topCanPlayThrough',
|
||||
'topClose',
|
||||
'topDurationChange',
|
||||
'topEmptied',
|
||||
'topEncrypted',
|
||||
'topEnded',
|
||||
'topError',
|
||||
'topInput',
|
||||
'topInvalid',
|
||||
'topLoad',
|
||||
'topLoadedData',
|
||||
'topLoadedMetadata',
|
||||
'topLoadStart',
|
||||
'topPause',
|
||||
'topPlay',
|
||||
'topPlaying',
|
||||
'topProgress',
|
||||
'topRateChange',
|
||||
'topReset',
|
||||
'topSeeked',
|
||||
'topSeeking',
|
||||
'topStalled',
|
||||
'topSubmit',
|
||||
'topSuspend',
|
||||
'topTimeUpdate',
|
||||
'topToggle',
|
||||
'topVolumeChange',
|
||||
'topWaiting',
|
||||
];
|
||||
function getDispatchConfig(topLevelType) {
|
||||
if (!topLevelEventsToDispatchConfig[topLevelType]) {
|
||||
const onEvent = `on${topLevelType.slice(3)}`;
|
||||
topLevelEventsToDispatchConfig[topLevelType] = {
|
||||
phasedRegistrationNames: {
|
||||
bubbled: onEvent,
|
||||
captured: `${onEvent}Capture`,
|
||||
},
|
||||
dependencies: [topLevelType],
|
||||
};
|
||||
}
|
||||
return topLevelEventsToDispatchConfig[topLevelType];
|
||||
}
|
||||
|
||||
const SimpleEventPlugin: PluginModule<MouseEvent> = {
|
||||
eventTypes: eventTypes,
|
||||
|
||||
extractEvents: function(
|
||||
extractEvents(
|
||||
topLevelType: TopLevelTypes,
|
||||
targetInst: Fiber,
|
||||
nativeEvent: MouseEvent,
|
||||
nativeEventTarget: EventTarget,
|
||||
): null | ReactSyntheticEvent {
|
||||
const dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
|
||||
if (!dispatchConfig) {
|
||||
return null;
|
||||
}
|
||||
let EventConstructor;
|
||||
switch (topLevelType) {
|
||||
case 'topKeyPress':
|
||||
// Firefox creates a keypress event for function keys too. This removes
|
||||
// the unwanted keypress events. Enter is however both printable and
|
||||
// non-printable. One would expect Tab to be as well (but it isn't).
|
||||
if (getEventCharCode(nativeEvent) === 0) {
|
||||
return null;
|
||||
}
|
||||
/* falls through */
|
||||
case 'topKeyDown':
|
||||
case 'topKeyUp':
|
||||
EventConstructor = SyntheticKeyboardEvent;
|
||||
break;
|
||||
case 'topBlur':
|
||||
case 'topFocus':
|
||||
EventConstructor = SyntheticFocusEvent;
|
||||
break;
|
||||
case 'topClick':
|
||||
// Firefox creates a click event on right mouse clicks. This removes the
|
||||
// unwanted click events.
|
||||
if (nativeEvent.button === 2) {
|
||||
return null;
|
||||
}
|
||||
/* falls through */
|
||||
case 'topDoubleClick':
|
||||
case 'topMouseDown':
|
||||
case 'topMouseMove':
|
||||
case 'topMouseUp':
|
||||
// TODO: Disabled elements should not respond to mouse events
|
||||
/* falls through */
|
||||
case 'topMouseOut':
|
||||
case 'topMouseOver':
|
||||
case 'topContextMenu':
|
||||
let nativeCtor = nativeEvent.constructor.name;
|
||||
|
||||
switch (nativeCtor) {
|
||||
case 'MouseEvent':
|
||||
EventConstructor = SyntheticMouseEvent;
|
||||
break;
|
||||
case 'topDrag':
|
||||
case 'topDragEnd':
|
||||
case 'topDragEnter':
|
||||
case 'topDragExit':
|
||||
case 'topDragLeave':
|
||||
case 'topDragOver':
|
||||
case 'topDragStart':
|
||||
case 'topDrop':
|
||||
EventConstructor = SyntheticDragEvent;
|
||||
case 'FocusEvent':
|
||||
EventConstructor = SyntheticFocusEvent;
|
||||
break;
|
||||
case 'topTouchCancel':
|
||||
case 'topTouchEnd':
|
||||
case 'topTouchMove':
|
||||
case 'topTouchStart':
|
||||
EventConstructor = SyntheticTouchEvent;
|
||||
case 'KeyboardEvent':
|
||||
EventConstructor = SyntheticKeyboardEvent;
|
||||
break;
|
||||
case 'topAnimationEnd':
|
||||
case 'topAnimationIteration':
|
||||
case 'topAnimationStart':
|
||||
EventConstructor = SyntheticAnimationEvent;
|
||||
break;
|
||||
case 'topTransitionEnd':
|
||||
case 'TransitionEvent':
|
||||
EventConstructor = SyntheticTransitionEvent;
|
||||
break;
|
||||
case 'topScroll':
|
||||
case 'AnimationEvent':
|
||||
EventConstructor = SyntheticAnimationEvent;
|
||||
break;
|
||||
case 'DragEvent':
|
||||
EventConstructor = SyntheticDragEvent;
|
||||
break;
|
||||
case 'UIEvent':
|
||||
EventConstructor = SyntheticUIEvent;
|
||||
break;
|
||||
case 'topWheel':
|
||||
EventConstructor = SyntheticWheelEvent;
|
||||
break;
|
||||
case 'topCopy':
|
||||
case 'topCut':
|
||||
case 'topPaste':
|
||||
case 'ClipboardEvent':
|
||||
EventConstructor = SyntheticClipboardEvent;
|
||||
break;
|
||||
default:
|
||||
if (__DEV__) {
|
||||
if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
|
||||
warning(
|
||||
false,
|
||||
'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' +
|
||||
'is likely caused by a bug in React. Please file an issue.',
|
||||
topLevelType,
|
||||
);
|
||||
}
|
||||
}
|
||||
// HTML Events
|
||||
// @see http://www.w3.org/TR/html5/index.html#events-0
|
||||
EventConstructor = SyntheticEvent;
|
||||
case 'TouchEvent':
|
||||
EventConstructor = SyntheticTouchEvent;
|
||||
break;
|
||||
case 'WheelEvent':
|
||||
EventConstructor = SyntheticWheelEvent;
|
||||
break;
|
||||
default:
|
||||
EventConstructor = SyntheticEvent;
|
||||
}
|
||||
|
||||
// Firefox creates a keypress event for function keys too. This removes
|
||||
// the unwanted keypress events. Enter is however both printable and
|
||||
// non-printable. One would expect Tab to be as well (but it isn't).
|
||||
if (topLevelType === 'topKeyPress' && getEventCharCode(nativeEvent) === 0) {
|
||||
return null;
|
||||
}
|
||||
// Firefox creates a click event on right mouse clicks. This removes the
|
||||
// unwanted click events.
|
||||
if (topLevelType === 'topKeyPress' && nativeEvent.button === 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const event = EventConstructor.getPooled(
|
||||
dispatchConfig,
|
||||
getDispatchConfig(topLevelType),
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import {
|
||||
registrationNameModules,
|
||||
possibleRegistrationNames,
|
||||
} from 'events/EventPluginRegistry';
|
||||
import {possibleRegistrationNames} from 'events/EventPluginRegistry';
|
||||
import {ReactDebugCurrentFrame} from 'shared/ReactGlobalSharedState';
|
||||
import warning from 'fbjs/lib/warning';
|
||||
|
||||
|
|
@ -55,7 +52,7 @@ if (__DEV__) {
|
|||
|
||||
// We can't rely on the event system being injected on the server.
|
||||
if (canUseEventSystem) {
|
||||
if (registrationNameModules.hasOwnProperty(name)) {
|
||||
if (name[0] === 'o' && name[1] === 'n') {
|
||||
return true;
|
||||
}
|
||||
const registrationName = possibleRegistrationNames.hasOwnProperty(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user