288 lines
6.9 KiB
JavaScript
288 lines
6.9 KiB
JavaScript
/**
|
|
* Copyright (c) 2013-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import type {TopLevelTypes} from './BrowserEventConstants';
|
|
import type {
|
|
DispatchConfig,
|
|
ReactSyntheticEvent,
|
|
} from 'events/ReactSyntheticEventType';
|
|
import type {Fiber} from 'react-reconciler/src/ReactFiber';
|
|
import type {EventTypes, PluginModule} from 'events/PluginModuleType';
|
|
|
|
var EventPropagators = require('events/EventPropagators');
|
|
var SyntheticEvent = require('events/SyntheticEvent');
|
|
|
|
var SyntheticAnimationEvent = require('./SyntheticAnimationEvent');
|
|
var SyntheticClipboardEvent = require('./SyntheticClipboardEvent');
|
|
var SyntheticFocusEvent = require('./SyntheticFocusEvent');
|
|
var SyntheticKeyboardEvent = require('./SyntheticKeyboardEvent');
|
|
var SyntheticMouseEvent = require('./SyntheticMouseEvent');
|
|
var SyntheticDragEvent = require('./SyntheticDragEvent');
|
|
var SyntheticTouchEvent = require('./SyntheticTouchEvent');
|
|
var SyntheticTransitionEvent = require('./SyntheticTransitionEvent');
|
|
var SyntheticUIEvent = require('./SyntheticUIEvent');
|
|
var SyntheticWheelEvent = require('./SyntheticWheelEvent');
|
|
var getEventCharCode = require('./getEventCharCode');
|
|
|
|
if (__DEV__) {
|
|
var warning = require('fbjs/lib/warning');
|
|
}
|
|
|
|
/**
|
|
* Turns
|
|
* ['abort', ...]
|
|
* into
|
|
* eventTypes = {
|
|
* 'abort': {
|
|
* phasedRegistrationNames: {
|
|
* bubbled: 'onAbort',
|
|
* captured: 'onAbortCapture',
|
|
* },
|
|
* dependencies: ['topAbort'],
|
|
* },
|
|
* ...
|
|
* };
|
|
* topLevelEventsToDispatchConfig = {
|
|
* 'topAbort': { sameConfig }
|
|
* };
|
|
*/
|
|
var eventTypes: EventTypes = {};
|
|
var 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 => {
|
|
var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
|
|
var onEvent = 'on' + capitalizedEvent;
|
|
var topEvent = 'top' + capitalizedEvent;
|
|
|
|
var type = {
|
|
phasedRegistrationNames: {
|
|
bubbled: onEvent,
|
|
captured: onEvent + 'Capture',
|
|
},
|
|
dependencies: [topEvent],
|
|
};
|
|
eventTypes[event] = type;
|
|
topLevelEventsToDispatchConfig[topEvent] = type;
|
|
});
|
|
|
|
// Only used in DEV for exhaustiveness validation.
|
|
var 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',
|
|
];
|
|
|
|
var SimpleEventPlugin: PluginModule<MouseEvent> = {
|
|
eventTypes: eventTypes,
|
|
|
|
extractEvents: function(
|
|
topLevelType: TopLevelTypes,
|
|
targetInst: Fiber,
|
|
nativeEvent: MouseEvent,
|
|
nativeEventTarget: EventTarget,
|
|
): null | ReactSyntheticEvent {
|
|
var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
|
|
if (!dispatchConfig) {
|
|
return null;
|
|
}
|
|
var 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':
|
|
EventConstructor = SyntheticMouseEvent;
|
|
break;
|
|
case 'topDrag':
|
|
case 'topDragEnd':
|
|
case 'topDragEnter':
|
|
case 'topDragExit':
|
|
case 'topDragLeave':
|
|
case 'topDragOver':
|
|
case 'topDragStart':
|
|
case 'topDrop':
|
|
EventConstructor = SyntheticDragEvent;
|
|
break;
|
|
case 'topTouchCancel':
|
|
case 'topTouchEnd':
|
|
case 'topTouchMove':
|
|
case 'topTouchStart':
|
|
EventConstructor = SyntheticTouchEvent;
|
|
break;
|
|
case 'topAnimationEnd':
|
|
case 'topAnimationIteration':
|
|
case 'topAnimationStart':
|
|
EventConstructor = SyntheticAnimationEvent;
|
|
break;
|
|
case 'topTransitionEnd':
|
|
EventConstructor = SyntheticTransitionEvent;
|
|
break;
|
|
case 'topScroll':
|
|
EventConstructor = SyntheticUIEvent;
|
|
break;
|
|
case 'topWheel':
|
|
EventConstructor = SyntheticWheelEvent;
|
|
break;
|
|
case 'topCopy':
|
|
case 'topCut':
|
|
case 'topPaste':
|
|
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;
|
|
break;
|
|
}
|
|
var event = EventConstructor.getPooled(
|
|
dispatchConfig,
|
|
targetInst,
|
|
nativeEvent,
|
|
nativeEventTarget,
|
|
);
|
|
EventPropagators.accumulateTwoPhaseDispatches(event);
|
|
return event;
|
|
},
|
|
};
|
|
|
|
module.exports = SimpleEventPlugin;
|