diff --git a/fixtures/dom/src/components/fixtures/password-inputs/index.js b/fixtures/dom/src/components/fixtures/password-inputs/index.js
index f94dce97dcefc..1c37f09d58ba9 100644
--- a/fixtures/dom/src/components/fixtures/password-inputs/index.js
+++ b/fixtures/dom/src/components/fixtures/password-inputs/index.js
@@ -15,7 +15,7 @@ function NumberInputs() {
`}
affectedBrowsers="IE Edge, IE 11">
- Type any string (not an actual password
+ Type any string (not an actual password)
diff --git a/package.json b/package.json
index 3b1e2f6168991..b8eb946ea7f75 100644
--- a/package.json
+++ b/package.json
@@ -36,7 +36,7 @@
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-preset-react": "^6.5.0",
"babel-traverse": "^6.9.0",
- "babylon": "6.15.0",
+ "babylon": "6.18.0",
"bundle-collapser": "^1.1.1",
"chalk": "^1.1.3",
"cli-table": "^0.3.1",
diff --git a/packages/events/EventPluginHub.js b/packages/events/EventPluginHub.js
index d59ba35ff68c7..27840402efe82 100644
--- a/packages/events/EventPluginHub.js
+++ b/packages/events/EventPluginHub.js
@@ -25,6 +25,7 @@ import type {PluginModule} from './PluginModuleType';
import type {ReactSyntheticEvent} from './ReactSyntheticEventType';
import type {Fiber} from 'react-reconciler/src/ReactFiber';
import type {AnyNativeEvent} from './PluginModuleType';
+import type {TopLevelType} from './TopLevelEventTypes';
/**
* Internal queue of events that have accumulated their dispatches and are
@@ -165,7 +166,7 @@ export function getListener(inst: Fiber, registrationName: string) {
* @internal
*/
function extractEvents(
- topLevelType: string,
+ topLevelType: TopLevelType,
targetInst: Fiber,
nativeEvent: AnyNativeEvent,
nativeEventTarget: EventTarget,
@@ -227,7 +228,7 @@ export function runEventsInBatch(
}
export function runExtractedEventsInBatch(
- topLevelType: string,
+ topLevelType: TopLevelType,
targetInst: Fiber,
nativeEvent: AnyNativeEvent,
nativeEventTarget: EventTarget,
diff --git a/packages/events/EventPluginUtils.js b/packages/events/EventPluginUtils.js
index d5e5a5e847754..19a89e30de825 100644
--- a/packages/events/EventPluginUtils.js
+++ b/packages/events/EventPluginUtils.js
@@ -30,21 +30,6 @@ export const injection = {
},
};
-export function isEndish(topLevelType) {
- return (
- topLevelType === 'topMouseUp' ||
- topLevelType === 'topTouchEnd' ||
- topLevelType === 'topTouchCancel'
- );
-}
-
-export function isMoveish(topLevelType) {
- return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove';
-}
-export function isStartish(topLevelType) {
- return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart';
-}
-
let validateEventDispatches;
if (__DEV__) {
validateEventDispatches = function(event) {
diff --git a/packages/events/PluginModuleType.js b/packages/events/PluginModuleType.js
index 5657ac3514b6c..22d53b1ccb567 100644
--- a/packages/events/PluginModuleType.js
+++ b/packages/events/PluginModuleType.js
@@ -12,6 +12,7 @@ import type {
DispatchConfig,
ReactSyntheticEvent,
} from './ReactSyntheticEventType';
+import type {TopLevelType} from './TopLevelEventTypes';
export type EventTypes = {[key: string]: DispatchConfig};
@@ -22,7 +23,7 @@ export type PluginName = string;
export type PluginModule = {
eventTypes: EventTypes,
extractEvents: (
- topLevelType: string,
+ topLevelType: TopLevelType,
targetInst: Fiber,
nativeTarget: NativeEvent,
nativeEventTarget: EventTarget,
diff --git a/packages/events/ReactSyntheticEventType.js b/packages/events/ReactSyntheticEventType.js
index b2b0b688fc602..2f248f7029855 100644
--- a/packages/events/ReactSyntheticEventType.js
+++ b/packages/events/ReactSyntheticEventType.js
@@ -9,9 +9,10 @@
*/
import type {Fiber} from 'react-reconciler/src/ReactFiber';
+import type {TopLevelType} from './TopLevelEventTypes';
export type DispatchConfig = {
- dependencies: Array,
+ dependencies: Array,
phasedRegistrationNames?: {
bubbled: string,
captured: string,
diff --git a/packages/events/ResponderEventPlugin.js b/packages/events/ResponderEventPlugin.js
index 202f8931f991f..dc14523fff455 100644
--- a/packages/events/ResponderEventPlugin.js
+++ b/packages/events/ResponderEventPlugin.js
@@ -8,9 +8,6 @@
import {getLowestCommonAncestor, isAncestor} from 'shared/ReactTreeTraversal';
import {
- isStartish,
- isMoveish,
- isEndish,
executeDirectDispatch,
hasDispatches,
executeDispatchesInOrderStopAtTrue,
@@ -24,6 +21,17 @@ import {
import ResponderSyntheticEvent from './ResponderSyntheticEvent';
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
import accumulate from './accumulate';
+import {
+ TOP_SCROLL,
+ TOP_SELECTION_CHANGE,
+ TOP_TOUCH_CANCEL,
+ isStartish,
+ isMoveish,
+ isEndish,
+ startDependencies,
+ moveDependencies,
+ endDependencies,
+} from './ResponderTopLevelEventTypes';
/**
* Instance of element that should respond to touch/move types of interactions,
@@ -37,11 +45,6 @@ let responderInst = null;
*/
let trackedTouchCount = 0;
-/**
- * Last reported number of active touches.
- */
-let previousActiveTouches = 0;
-
const changeResponder = function(nextResponderInst, blockHostResponder) {
const oldResponderInst = responderInst;
responderInst = nextResponderInst;
@@ -64,6 +67,7 @@ const eventTypes = {
bubbled: 'onStartShouldSetResponder',
captured: 'onStartShouldSetResponderCapture',
},
+ dependencies: startDependencies,
},
/**
@@ -80,6 +84,7 @@ const eventTypes = {
bubbled: 'onScrollShouldSetResponder',
captured: 'onScrollShouldSetResponderCapture',
},
+ dependencies: [TOP_SCROLL],
},
/**
@@ -94,6 +99,7 @@ const eventTypes = {
bubbled: 'onSelectionChangeShouldSetResponder',
captured: 'onSelectionChangeShouldSetResponderCapture',
},
+ dependencies: [TOP_SELECTION_CHANGE],
},
/**
@@ -105,21 +111,44 @@ const eventTypes = {
bubbled: 'onMoveShouldSetResponder',
captured: 'onMoveShouldSetResponderCapture',
},
+ dependencies: moveDependencies,
},
/**
* Direct responder events dispatched directly to responder. Do not bubble.
*/
- responderStart: {registrationName: 'onResponderStart'},
- responderMove: {registrationName: 'onResponderMove'},
- responderEnd: {registrationName: 'onResponderEnd'},
- responderRelease: {registrationName: 'onResponderRelease'},
+ responderStart: {
+ registrationName: 'onResponderStart',
+ dependencies: startDependencies,
+ },
+ responderMove: {
+ registrationName: 'onResponderMove',
+ dependencies: moveDependencies,
+ },
+ responderEnd: {
+ registrationName: 'onResponderEnd',
+ dependencies: endDependencies,
+ },
+ responderRelease: {
+ registrationName: 'onResponderRelease',
+ dependencies: endDependencies,
+ },
responderTerminationRequest: {
registrationName: 'onResponderTerminationRequest',
+ dependencies: [],
+ },
+ responderGrant: {
+ registrationName: 'onResponderGrant',
+ dependencies: [],
+ },
+ responderReject: {
+ registrationName: 'onResponderReject',
+ dependencies: [],
+ },
+ responderTerminate: {
+ registrationName: 'onResponderTerminate',
+ dependencies: [],
},
- responderGrant: {registrationName: 'onResponderGrant'},
- responderReject: {registrationName: 'onResponderReject'},
- responderTerminate: {registrationName: 'onResponderTerminate'},
};
/**
@@ -322,7 +351,7 @@ function setResponderAndExtractTransfer(
? eventTypes.startShouldSetResponder
: isMoveish(topLevelType)
? eventTypes.moveShouldSetResponder
- : topLevelType === 'topSelectionChange'
+ : topLevelType === TOP_SELECTION_CHANGE
? eventTypes.selectionChangeShouldSetResponder
: eventTypes.scrollShouldSetResponder;
@@ -427,8 +456,8 @@ function canTriggerTransfer(topLevelType, topLevelInst, nativeEvent) {
// responderIgnoreScroll: We are trying to migrate away from specifically
// tracking native scroll events here and responderIgnoreScroll indicates we
// will send topTouchCancel to handle canceling touch events instead
- ((topLevelType === 'topScroll' && !nativeEvent.responderIgnoreScroll) ||
- (trackedTouchCount > 0 && topLevelType === 'topSelectionChange') ||
+ ((topLevelType === TOP_SCROLL && !nativeEvent.responderIgnoreScroll) ||
+ (trackedTouchCount > 0 && topLevelType === TOP_SELECTION_CHANGE) ||
isStartish(topLevelType) ||
isMoveish(topLevelType))
);
@@ -534,7 +563,7 @@ const ResponderEventPlugin = {
}
const isResponderTerminate =
- responderInst && topLevelType === 'topTouchCancel';
+ responderInst && topLevelType === TOP_TOUCH_CANCEL;
const isResponderRelease =
responderInst &&
!isResponderTerminate &&
@@ -556,23 +585,10 @@ const ResponderEventPlugin = {
changeResponder(null);
}
- const numberActiveTouches =
- ResponderTouchHistoryStore.touchHistory.numberActiveTouches;
- if (
- ResponderEventPlugin.GlobalInteractionHandler &&
- numberActiveTouches !== previousActiveTouches
- ) {
- ResponderEventPlugin.GlobalInteractionHandler.onChange(
- numberActiveTouches,
- );
- }
- previousActiveTouches = numberActiveTouches;
-
return extracted;
},
GlobalResponderHandler: null,
- GlobalInteractionHandler: null,
injection: {
/**
@@ -580,17 +596,9 @@ const ResponderEventPlugin = {
* Object that handles any change in responder. Use this to inject
* integration with an existing touch handling system etc.
*/
- injectGlobalResponderHandler: function(GlobalResponderHandler) {
+ injectGlobalResponderHandler(GlobalResponderHandler) {
ResponderEventPlugin.GlobalResponderHandler = GlobalResponderHandler;
},
-
- /**
- * @param {{onChange: (numberActiveTouches) => void} GlobalInteractionHandler
- * Object that handles any change in the number of active touches.
- */
- injectGlobalInteractionHandler: function(GlobalInteractionHandler) {
- ResponderEventPlugin.GlobalInteractionHandler = GlobalInteractionHandler;
- },
},
};
diff --git a/packages/events/ResponderTopLevelEventTypes.js b/packages/events/ResponderTopLevelEventTypes.js
new file mode 100644
index 0000000000000..54ad053a66464
--- /dev/null
+++ b/packages/events/ResponderTopLevelEventTypes.js
@@ -0,0 +1,31 @@
+/**
+ * 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
+ */
+
+export const TOP_TOUCH_START = 'topTouchStart';
+export const TOP_TOUCH_MOVE = 'topTouchMove';
+export const TOP_TOUCH_END = 'topTouchEnd';
+export const TOP_TOUCH_CANCEL = 'topTouchCancel';
+export const TOP_SCROLL = 'topScroll';
+export const TOP_SELECTION_CHANGE = 'topSelectionChange';
+
+export function isStartish(topLevelType: mixed): boolean {
+ return topLevelType === TOP_TOUCH_START;
+}
+
+export function isMoveish(topLevelType: mixed): boolean {
+ return topLevelType === TOP_TOUCH_MOVE;
+}
+
+export function isEndish(topLevelType: mixed): boolean {
+ return topLevelType === TOP_TOUCH_END || topLevelType === TOP_TOUCH_CANCEL;
+}
+
+export const startDependencies = [TOP_TOUCH_START];
+export const moveDependencies = [TOP_TOUCH_MOVE];
+export const endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END];
diff --git a/packages/events/ResponderTouchHistoryStore.js b/packages/events/ResponderTouchHistoryStore.js
index 0c703a5970017..807a5a08d9912 100644
--- a/packages/events/ResponderTouchHistoryStore.js
+++ b/packages/events/ResponderTouchHistoryStore.js
@@ -10,7 +10,7 @@
import invariant from 'fbjs/lib/invariant';
import warning from 'fbjs/lib/warning';
-import {isEndish, isMoveish, isStartish} from './EventPluginUtils';
+import {isStartish, isMoveish, isEndish} from './ResponderTopLevelEventTypes';
/**
* Tracks the position and time of each active touch by `touch.identifier`. We
diff --git a/packages/events/TopLevelEventTypes.js b/packages/events/TopLevelEventTypes.js
new file mode 100644
index 0000000000000..f9d4722abb8c1
--- /dev/null
+++ b/packages/events/TopLevelEventTypes.js
@@ -0,0 +1,23 @@
+/**
+ * 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
+ */
+
+import type {DOMTopLevelEventType} from 'react-dom/src/events/DOMTopLevelEventTypes';
+
+type RNTopLevelEventType =
+ | 'topMouseDown'
+ | 'topMouseMove'
+ | 'topMouseUp'
+ | 'topScroll'
+ | 'topSelectionChange'
+ | 'topTouchCancel'
+ | 'topTouchEnd'
+ | 'topTouchMove'
+ | 'topTouchStart';
+
+export type TopLevelType = DOMTopLevelEventType | RNTopLevelEventType;
diff --git a/packages/events/forks/ResponderTopLevelEventTypes.dom.js b/packages/events/forks/ResponderTopLevelEventTypes.dom.js
new file mode 100644
index 0000000000000..5e009dc56cd78
--- /dev/null
+++ b/packages/events/forks/ResponderTopLevelEventTypes.dom.js
@@ -0,0 +1,41 @@
+/**
+ * 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
+ */
+
+// Note: ideally these would be imported from DOMTopLevelEventTypes,
+// but our build system currently doesn't let us do that from a fork.
+
+export const TOP_TOUCH_START = 'touchstart';
+export const TOP_TOUCH_MOVE = 'touchmove';
+export const TOP_TOUCH_END = 'touchend';
+export const TOP_TOUCH_CANCEL = 'touchcancel';
+export const TOP_SCROLL = 'scroll';
+export const TOP_SELECTION_CHANGE = 'selectionchange';
+export const TOP_MOUSE_DOWN = 'mousedown';
+export const TOP_MOUSE_MOVE = 'mousemove';
+export const TOP_MOUSE_UP = 'mouseup';
+
+export function isStartish(topLevelType: mixed): boolean {
+ return topLevelType === TOP_TOUCH_START || topLevelType === TOP_MOUSE_DOWN;
+}
+
+export function isMoveish(topLevelType: mixed): boolean {
+ return topLevelType === TOP_TOUCH_MOVE || topLevelType === TOP_MOUSE_MOVE;
+}
+
+export function isEndish(topLevelType: mixed): boolean {
+ return (
+ topLevelType === TOP_TOUCH_END ||
+ topLevelType === TOP_TOUCH_CANCEL ||
+ topLevelType === TOP_MOUSE_UP
+ );
+}
+
+export const startDependencies = [TOP_TOUCH_START, TOP_MOUSE_DOWN];
+export const moveDependencies = [TOP_TOUCH_MOVE, TOP_MOUSE_MOVE];
+export const endDependencies = [TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_MOUSE_UP];
diff --git a/packages/react-dom/src/__tests__/ReactDOM-test.js b/packages/react-dom/src/__tests__/ReactDOM-test.js
index 5e7d2772e3e2e..cca40165fd458 100644
--- a/packages/react-dom/src/__tests__/ReactDOM-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOM-test.js
@@ -309,14 +309,9 @@ describe('ReactDOM', () => {
const actual = [];
function click(node) {
- const fakeNativeEvent = function() {};
- fakeNativeEvent.target = node;
- fakeNativeEvent.path = [node, container];
- ReactTestUtils.simulateNativeEventOnNode(
- 'topClick',
- node,
- fakeNativeEvent,
- );
+ ReactTestUtils.Simulate.click(node, {
+ path: [node, container],
+ });
}
class Wrapper extends React.Component {
diff --git a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js
index deffd4680df91..a93dda6ce11e8 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFiber-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFiber-test.js
@@ -838,12 +838,7 @@ describe('ReactDOMFiber', () => {
expect(portal.tagName).toBe('DIV');
- const fakeNativeEvent = {};
- ReactTestUtils.simulateNativeEventOnNode(
- 'topClick',
- portal,
- fakeNativeEvent,
- );
+ ReactTestUtils.Simulate.click(portal);
expect(ops).toEqual(['portal clicked', 'parent clicked']);
});
@@ -858,14 +853,12 @@ describe('ReactDOMFiber', () => {
function simulateMouseMove(from, to) {
if (from) {
- ReactTestUtils.simulateNativeEventOnNode('topMouseOut', from, {
- target: from,
+ ReactTestUtils.SimulateNative.mouseOut(from, {
relatedTarget: to,
});
}
if (to) {
- ReactTestUtils.simulateNativeEventOnNode('topMouseOver', to, {
- target: to,
+ ReactTestUtils.SimulateNative.mouseOver(to, {
relatedTarget: from,
});
}
@@ -983,12 +976,7 @@ describe('ReactDOMFiber', () => {
expect(node.tagName).toEqual('DIV');
function click(target) {
- const fakeNativeEvent = {};
- ReactTestUtils.simulateNativeEventOnNode(
- 'topClick',
- target,
- fakeNativeEvent,
- );
+ ReactTestUtils.Simulate.click(target);
}
click(node);
diff --git a/packages/react-dom/src/__tests__/ReactDOMInput-test.js b/packages/react-dom/src/__tests__/ReactDOMInput-test.js
index 03eed7bc1ec65..f5513557ec3c0 100644
--- a/packages/react-dom/src/__tests__/ReactDOMInput-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMInput-test.js
@@ -694,10 +694,9 @@ describe('ReactDOMInput', () => {
setUntrackedValue.call(node, 'giraffe');
- const fakeNativeEvent = function() {};
- fakeNativeEvent.target = node;
- fakeNativeEvent.path = [node, container];
- ReactTestUtils.simulateNativeEventOnNode('topInput', node, fakeNativeEvent);
+ ReactTestUtils.SimulateNative.input(node, {
+ path: [node, container],
+ });
expect(handled).toBe(true);
});
diff --git a/packages/react-dom/src/client/ReactDOMFiberComponent.js b/packages/react-dom/src/client/ReactDOMFiberComponent.js
index ceb20873c2af2..4c3c7a9c1dd39 100644
--- a/packages/react-dom/src/client/ReactDOMFiberComponent.js
+++ b/packages/react-dom/src/client/ReactDOMFiberComponent.js
@@ -21,8 +21,16 @@ import * as ReactDOMFiberTextarea from './ReactDOMFiberTextarea';
import * as inputValueTracking from './inputValueTracking';
import setInnerHTML from './setInnerHTML';
import setTextContent from './setTextContent';
+import {
+ TOP_ERROR,
+ TOP_INVALID,
+ TOP_LOAD,
+ TOP_RESET,
+ TOP_SUBMIT,
+ TOP_TOGGLE,
+} from '../events/DOMTopLevelEventTypes';
import {listenTo, trapBubbledEvent} from '../events/ReactBrowserEventEmitter';
-import {mediaEventTypes} from '../events/BrowserEventConstants';
+import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
import * as CSSPropertyOperations from '../shared/CSSPropertyOperations';
import {Namespaces, getIntrinsicNamespace} from '../shared/DOMNamespaces';
import {
@@ -440,43 +448,41 @@ export function setInitialProperties(
switch (tag) {
case 'iframe':
case 'object':
- trapBubbledEvent('topLoad', 'load', domElement);
+ trapBubbledEvent(TOP_LOAD, domElement);
props = rawProps;
break;
case 'video':
case 'audio':
// Create listener for each media event
- for (const event in mediaEventTypes) {
- if (mediaEventTypes.hasOwnProperty(event)) {
- trapBubbledEvent(event, mediaEventTypes[event], domElement);
- }
+ for (let i = 0; i < mediaEventTypes.length; i++) {
+ trapBubbledEvent(mediaEventTypes[i], domElement);
}
props = rawProps;
break;
case 'source':
- trapBubbledEvent('topError', 'error', domElement);
+ trapBubbledEvent(TOP_ERROR, domElement);
props = rawProps;
break;
case 'img':
case 'image':
case 'link':
- trapBubbledEvent('topError', 'error', domElement);
- trapBubbledEvent('topLoad', 'load', domElement);
+ trapBubbledEvent(TOP_ERROR, domElement);
+ trapBubbledEvent(TOP_LOAD, domElement);
props = rawProps;
break;
case 'form':
- trapBubbledEvent('topReset', 'reset', domElement);
- trapBubbledEvent('topSubmit', 'submit', domElement);
+ trapBubbledEvent(TOP_RESET, domElement);
+ trapBubbledEvent(TOP_SUBMIT, domElement);
props = rawProps;
break;
case 'details':
- trapBubbledEvent('topToggle', 'toggle', domElement);
+ trapBubbledEvent(TOP_TOGGLE, domElement);
props = rawProps;
break;
case 'input':
ReactDOMFiberInput.initWrapperState(domElement, rawProps);
props = ReactDOMFiberInput.getHostProps(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
@@ -488,7 +494,7 @@ export function setInitialProperties(
case 'select':
ReactDOMFiberSelect.initWrapperState(domElement, rawProps);
props = ReactDOMFiberSelect.getHostProps(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
@@ -496,7 +502,7 @@ export function setInitialProperties(
case 'textarea':
ReactDOMFiberTextarea.initWrapperState(domElement, rawProps);
props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
@@ -829,36 +835,34 @@ export function diffHydratedProperties(
switch (tag) {
case 'iframe':
case 'object':
- trapBubbledEvent('topLoad', 'load', domElement);
+ trapBubbledEvent(TOP_LOAD, domElement);
break;
case 'video':
case 'audio':
// Create listener for each media event
- for (const event in mediaEventTypes) {
- if (mediaEventTypes.hasOwnProperty(event)) {
- trapBubbledEvent(event, mediaEventTypes[event], domElement);
- }
+ for (let i = 0; i < mediaEventTypes.length; i++) {
+ trapBubbledEvent(mediaEventTypes[i], domElement);
}
break;
case 'source':
- trapBubbledEvent('topError', 'error', domElement);
+ trapBubbledEvent(TOP_ERROR, domElement);
break;
case 'img':
case 'image':
case 'link':
- trapBubbledEvent('topError', 'error', domElement);
- trapBubbledEvent('topLoad', 'load', domElement);
+ trapBubbledEvent(TOP_ERROR, domElement);
+ trapBubbledEvent(TOP_LOAD, domElement);
break;
case 'form':
- trapBubbledEvent('topReset', 'reset', domElement);
- trapBubbledEvent('topSubmit', 'submit', domElement);
+ trapBubbledEvent(TOP_RESET, domElement);
+ trapBubbledEvent(TOP_SUBMIT, domElement);
break;
case 'details':
- trapBubbledEvent('topToggle', 'toggle', domElement);
+ trapBubbledEvent(TOP_TOGGLE, domElement);
break;
case 'input':
ReactDOMFiberInput.initWrapperState(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
@@ -868,14 +872,14 @@ export function diffHydratedProperties(
break;
case 'select':
ReactDOMFiberSelect.initWrapperState(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
break;
case 'textarea':
ReactDOMFiberTextarea.initWrapperState(domElement, rawProps);
- trapBubbledEvent('topInvalid', 'invalid', domElement);
+ trapBubbledEvent(TOP_INVALID, domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
diff --git a/packages/react-dom/src/events/BeforeInputEventPlugin.js b/packages/react-dom/src/events/BeforeInputEventPlugin.js
index 3307a70bdec6c..9bdb8dab7d01c 100644
--- a/packages/react-dom/src/events/BeforeInputEventPlugin.js
+++ b/packages/react-dom/src/events/BeforeInputEventPlugin.js
@@ -5,11 +5,23 @@
* LICENSE file in the root directory of this source tree.
*/
-import type {TopLevelTypes} from './BrowserEventConstants';
+import type {TopLevelType} from 'events/TopLevelEventTypes';
import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';
+import {
+ TOP_BLUR,
+ TOP_COMPOSITION_START,
+ TOP_COMPOSITION_END,
+ TOP_COMPOSITION_UPDATE,
+ TOP_KEY_DOWN,
+ TOP_KEY_PRESS,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
+ TOP_TEXT_INPUT,
+ TOP_PASTE,
+} from './DOMTopLevelEventTypes';
import * as FallbackCompositionState from './FallbackCompositionState';
import SyntheticCompositionEvent from './SyntheticCompositionEvent';
import SyntheticInputEvent from './SyntheticInputEvent';
@@ -50,10 +62,10 @@ const eventTypes = {
captured: 'onBeforeInputCapture',
},
dependencies: [
- 'topCompositionEnd',
- 'topKeyPress',
- 'topTextInput',
- 'topPaste',
+ TOP_COMPOSITION_END,
+ TOP_KEY_PRESS,
+ TOP_TEXT_INPUT,
+ TOP_PASTE,
],
},
compositionEnd: {
@@ -62,12 +74,12 @@ const eventTypes = {
captured: 'onCompositionEndCapture',
},
dependencies: [
- 'topBlur',
- 'topCompositionEnd',
- 'topKeyDown',
- 'topKeyPress',
- 'topKeyUp',
- 'topMouseDown',
+ TOP_BLUR,
+ TOP_COMPOSITION_END,
+ TOP_KEY_DOWN,
+ TOP_KEY_PRESS,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
],
},
compositionStart: {
@@ -76,12 +88,12 @@ const eventTypes = {
captured: 'onCompositionStartCapture',
},
dependencies: [
- 'topBlur',
- 'topCompositionStart',
- 'topKeyDown',
- 'topKeyPress',
- 'topKeyUp',
- 'topMouseDown',
+ TOP_BLUR,
+ TOP_COMPOSITION_START,
+ TOP_KEY_DOWN,
+ TOP_KEY_PRESS,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
],
},
compositionUpdate: {
@@ -90,12 +102,12 @@ const eventTypes = {
captured: 'onCompositionUpdateCapture',
},
dependencies: [
- 'topBlur',
- 'topCompositionUpdate',
- 'topKeyDown',
- 'topKeyPress',
- 'topKeyUp',
- 'topMouseDown',
+ TOP_BLUR,
+ TOP_COMPOSITION_UPDATE,
+ TOP_KEY_DOWN,
+ TOP_KEY_PRESS,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
],
},
};
@@ -124,11 +136,11 @@ function isKeypressCommand(nativeEvent) {
*/
function getCompositionEventType(topLevelType) {
switch (topLevelType) {
- case 'topCompositionStart':
+ case TOP_COMPOSITION_START:
return eventTypes.compositionStart;
- case 'topCompositionEnd':
+ case TOP_COMPOSITION_END:
return eventTypes.compositionEnd;
- case 'topCompositionUpdate':
+ case TOP_COMPOSITION_UPDATE:
return eventTypes.compositionUpdate;
}
}
@@ -142,7 +154,7 @@ function getCompositionEventType(topLevelType) {
* @return {boolean}
*/
function isFallbackCompositionStart(topLevelType, nativeEvent) {
- return topLevelType === 'topKeyDown' && nativeEvent.keyCode === START_KEYCODE;
+ return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
}
/**
@@ -154,16 +166,16 @@ function isFallbackCompositionStart(topLevelType, nativeEvent) {
*/
function isFallbackCompositionEnd(topLevelType, nativeEvent) {
switch (topLevelType) {
- case 'topKeyUp':
+ case TOP_KEY_UP:
// Command keys insert or clear IME input.
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
- case 'topKeyDown':
+ case TOP_KEY_DOWN:
// Expect IME keyCode on each keydown. If we get any other
// code we must have exited earlier.
return nativeEvent.keyCode !== START_KEYCODE;
- case 'topKeyPress':
- case 'topMouseDown':
- case 'topBlur':
+ case TOP_KEY_PRESS:
+ case TOP_MOUSE_DOWN:
+ case TOP_BLUR:
// Events are not possible without cancelling IME.
return true;
default:
@@ -252,15 +264,15 @@ function extractCompositionEvent(
}
/**
- * @param {TopLevelTypes} topLevelType Record from `BrowserEventConstants`.
+ * @param {TopLevelType} topLevelType Number from `TopLevelType`.
* @param {object} nativeEvent Native browser event.
* @return {?string} The string corresponding to this `beforeInput` event.
*/
-function getNativeBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
+function getNativeBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
switch (topLevelType) {
- case 'topCompositionEnd':
+ case TOP_COMPOSITION_END:
return getDataFromCustomEvent(nativeEvent);
- case 'topKeyPress':
+ case TOP_KEY_PRESS:
/**
* If native `textInput` events are available, our goal is to make
* use of them. However, there is a special case: the spacebar key.
@@ -283,7 +295,7 @@ function getNativeBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
hasSpaceKeypress = true;
return SPACEBAR_CHAR;
- case 'topTextInput':
+ case TOP_TEXT_INPUT:
// Record the characters to be added to the DOM.
const chars = nativeEvent.data;
@@ -306,18 +318,18 @@ function getNativeBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
* For browsers that do not provide the `textInput` event, extract the
* appropriate string to use for SyntheticInputEvent.
*
- * @param {string} topLevelType Record from `BrowserEventConstants`.
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
* @param {object} nativeEvent Native browser event.
* @return {?string} The fallback string for this `beforeInput` event.
*/
-function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
+function getFallbackBeforeInputChars(topLevelType: TopLevelType, nativeEvent) {
// If we are currently composing (IME) and using a fallback to do so,
// try to extract the composed characters from the fallback object.
// If composition event is available, we extract a string only at
// compositionevent, otherwise extract it at fallback events.
if (isComposing) {
if (
- topLevelType === 'topCompositionEnd' ||
+ topLevelType === TOP_COMPOSITION_END ||
(!canUseCompositionEvent &&
isFallbackCompositionEnd(topLevelType, nativeEvent))
) {
@@ -330,11 +342,11 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
}
switch (topLevelType) {
- case 'topPaste':
+ case TOP_PASTE:
// If a paste event occurs after a keypress, throw out the input
// chars. Paste events should not lead to BeforeInput events.
return null;
- case 'topKeyPress':
+ case TOP_KEY_PRESS:
/**
* As of v27, Firefox may fire keypress events even when no character
* will be inserted. A few possibilities:
@@ -365,7 +377,7 @@ function getFallbackBeforeInputChars(topLevelType: TopLevelTypes, nativeEvent) {
}
}
return null;
- case 'topCompositionEnd':
+ case TOP_COMPOSITION_END:
return useFallbackCompositionData ? null : nativeEvent.data;
default:
return null;
diff --git a/packages/react-dom/src/events/BrowserEventConstants.js b/packages/react-dom/src/events/BrowserEventConstants.js
deleted file mode 100644
index 203752892f69c..0000000000000
--- a/packages/react-dom/src/events/BrowserEventConstants.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * 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.
- */
-
-import getVendorPrefixedEventName from './getVendorPrefixedEventName';
-
-/**
- * Types of raw signals from the browser caught at the top level.
- *
- * For events like 'submit' or audio/video events which don't consistently
- * bubble (which we trap at a lower node than `document`), binding
- * at `document` would cause duplicate events so we don't include them here.
- */
-export const topLevelTypes = {
- topAnimationEnd: getVendorPrefixedEventName('animationend'),
- topAnimationIteration: getVendorPrefixedEventName('animationiteration'),
- topAnimationStart: getVendorPrefixedEventName('animationstart'),
- topBlur: 'blur',
- topCancel: 'cancel',
- topChange: 'change',
- topClick: 'click',
- topClose: 'close',
- topCompositionEnd: 'compositionend',
- topCompositionStart: 'compositionstart',
- topCompositionUpdate: 'compositionupdate',
- topContextMenu: 'contextmenu',
- topCopy: 'copy',
- topCut: 'cut',
- topDoubleClick: 'dblclick',
- topDrag: 'drag',
- topDragEnd: 'dragend',
- topDragEnter: 'dragenter',
- topDragExit: 'dragexit',
- topDragLeave: 'dragleave',
- topDragOver: 'dragover',
- topDragStart: 'dragstart',
- topDrop: 'drop',
- topFocus: 'focus',
- topInput: 'input',
- topKeyDown: 'keydown',
- topKeyPress: 'keypress',
- topKeyUp: 'keyup',
- topLoad: 'load',
- topLoadStart: 'loadstart',
- topMouseDown: 'mousedown',
- topMouseMove: 'mousemove',
- topMouseOut: 'mouseout',
- topMouseOver: 'mouseover',
- topMouseUp: 'mouseup',
- topPaste: 'paste',
- topScroll: 'scroll',
- topSelectionChange: 'selectionchange',
- topTextInput: 'textInput',
- topToggle: 'toggle',
- topTouchCancel: 'touchcancel',
- topTouchEnd: 'touchend',
- topTouchMove: 'touchmove',
- topTouchStart: 'touchstart',
- topTransitionEnd: getVendorPrefixedEventName('transitionend'),
- topWheel: 'wheel',
-};
-
-// There are so many media events, it makes sense to just
-// maintain a list of them. Note these aren't technically
-// "top-level" since they don't bubble. We should come up
-// with a better naming convention if we come to refactoring
-// the event system.
-export const mediaEventTypes = {
- topAbort: 'abort',
- topCanPlay: 'canplay',
- topCanPlayThrough: 'canplaythrough',
- topDurationChange: 'durationchange',
- topEmptied: 'emptied',
- topEncrypted: 'encrypted',
- topEnded: 'ended',
- topError: 'error',
- topLoadedData: 'loadeddata',
- topLoadedMetadata: 'loadedmetadata',
- topLoadStart: 'loadstart',
- topPause: 'pause',
- topPlay: 'play',
- topPlaying: 'playing',
- topProgress: 'progress',
- topRateChange: 'ratechange',
- topSeeked: 'seeked',
- topSeeking: 'seeking',
- topStalled: 'stalled',
- topSuspend: 'suspend',
- topTimeUpdate: 'timeupdate',
- topVolumeChange: 'volumechange',
- topWaiting: 'waiting',
-};
-
-export type TopLevelTypes = $Enum;
diff --git a/packages/react-dom/src/events/ChangeEventPlugin.js b/packages/react-dom/src/events/ChangeEventPlugin.js
index 5e0dcbb3be4b9..ce0d328d876d5 100644
--- a/packages/react-dom/src/events/ChangeEventPlugin.js
+++ b/packages/react-dom/src/events/ChangeEventPlugin.js
@@ -13,6 +13,16 @@ import SyntheticEvent from 'events/SyntheticEvent';
import isTextInputElement from 'shared/isTextInputElement';
import ExecutionEnvironment from 'fbjs/lib/ExecutionEnvironment';
+import {
+ TOP_BLUR,
+ TOP_CHANGE,
+ TOP_CLICK,
+ TOP_FOCUS,
+ TOP_INPUT,
+ TOP_KEY_DOWN,
+ TOP_KEY_UP,
+ TOP_SELECTION_CHANGE,
+} from './DOMTopLevelEventTypes';
import getEventTarget from './getEventTarget';
import isEventSupported from './isEventSupported';
import {getNodeFromInstance} from '../client/ReactDOMComponentTree';
@@ -26,14 +36,14 @@ const eventTypes = {
captured: 'onChangeCapture',
},
dependencies: [
- 'topBlur',
- 'topChange',
- 'topClick',
- 'topFocus',
- 'topInput',
- 'topKeyDown',
- 'topKeyUp',
- 'topSelectionChange',
+ TOP_BLUR,
+ TOP_CHANGE,
+ TOP_CLICK,
+ TOP_FOCUS,
+ TOP_INPUT,
+ TOP_KEY_DOWN,
+ TOP_KEY_UP,
+ TOP_SELECTION_CHANGE,
],
},
};
@@ -100,7 +110,7 @@ function getInstIfValueChanged(targetInst) {
}
function getTargetInstForChangeEvent(topLevelType, targetInst) {
- if (topLevelType === 'topChange') {
+ if (topLevelType === TOP_CHANGE) {
return targetInst;
}
}
@@ -155,7 +165,7 @@ function handlePropertyChange(nativeEvent) {
}
function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
- if (topLevelType === 'topFocus') {
+ if (topLevelType === TOP_FOCUS) {
// In IE9, propertychange fires for most input events but is buggy and
// doesn't fire when text is deleted, but conveniently, selectionchange
// appears to fire in all of the remaining cases so we catch those and
@@ -168,7 +178,7 @@ function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
// missed a blur event somehow.
stopWatchingForValueChange();
startWatchingForValueChange(target, targetInst);
- } else if (topLevelType === 'topBlur') {
+ } else if (topLevelType === TOP_BLUR) {
stopWatchingForValueChange();
}
}
@@ -176,9 +186,9 @@ function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
// For IE8 and IE9.
function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
if (
- topLevelType === 'topSelectionChange' ||
- topLevelType === 'topKeyUp' ||
- topLevelType === 'topKeyDown'
+ topLevelType === TOP_SELECTION_CHANGE ||
+ topLevelType === TOP_KEY_UP ||
+ topLevelType === TOP_KEY_DOWN
) {
// On the selectionchange event, the target is just document which isn't
// helpful for us so just check activeElement instead.
@@ -210,13 +220,13 @@ function shouldUseClickEvent(elem) {
}
function getTargetInstForClickEvent(topLevelType, targetInst) {
- if (topLevelType === 'topClick') {
+ if (topLevelType === TOP_CLICK) {
return getInstIfValueChanged(targetInst);
}
}
function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
- if (topLevelType === 'topInput' || topLevelType === 'topChange') {
+ if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
return getInstIfValueChanged(targetInst);
}
}
@@ -292,7 +302,7 @@ const ChangeEventPlugin = {
}
// When blurring, set the value attribute for number inputs
- if (topLevelType === 'topBlur') {
+ if (topLevelType === TOP_BLUR) {
handleControlledInputBlur(targetInst, targetNode);
}
},
diff --git a/packages/react-dom/src/events/DOMTopLevelEventTypes.js b/packages/react-dom/src/events/DOMTopLevelEventTypes.js
new file mode 100644
index 0000000000000..79f13057f9ef9
--- /dev/null
+++ b/packages/react-dom/src/events/DOMTopLevelEventTypes.js
@@ -0,0 +1,205 @@
+/**
+ * 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
+ */
+
+import type {TopLevelType} from 'events/TopLevelEventTypes';
+import getVendorPrefixedEventName from './getVendorPrefixedEventName';
+
+/**
+ * To identify top level events in react-dom, we use constants defined by this
+ * module. Those are completely opaque to every other module but we rely on them
+ * being the raw DOM event names inside this module. This allows us to build a
+ * very efficient mapping from top level identifiers to the raw event type.
+ *
+ * The use of an `opaque` flow type makes sure that we can only access the value
+ * of a constant in this module.
+ */
+
+// eslint-disable-next-line no-undef
+export opaque type DOMTopLevelEventType =
+ | 'abort'
+ | 'animationend'
+ | 'animationiteration'
+ | 'animationstart'
+ | 'blur'
+ | 'canplay'
+ | 'canplaythrough'
+ | 'cancel'
+ | 'change'
+ | 'click'
+ | 'close'
+ | 'compositionend'
+ | 'compositionstart'
+ | 'compositionupdate'
+ | 'contextmenu'
+ | 'copy'
+ | 'cut'
+ | 'dblclick'
+ | 'drag'
+ | 'dragend'
+ | 'dragenter'
+ | 'dragexit'
+ | 'dragleave'
+ | 'dragover'
+ | 'dragstart'
+ | 'drop'
+ | 'durationchange'
+ | 'emptied'
+ | 'encrypted'
+ | 'ended'
+ | 'error'
+ | 'focus'
+ | 'input'
+ | 'invalid'
+ | 'keydown'
+ | 'keypress'
+ | 'keyup'
+ | 'load'
+ | 'loadstart'
+ | 'loadeddata'
+ | 'loadedmetadata'
+ | 'mousedown'
+ | 'mousemove'
+ | 'mouseout'
+ | 'mouseover'
+ | 'mouseup'
+ | 'paste'
+ | 'pause'
+ | 'play'
+ | 'playing'
+ | 'progress'
+ | 'ratechange'
+ | 'reset'
+ | 'scroll'
+ | 'seeked'
+ | 'seeking'
+ | 'selectionchange'
+ | 'stalled'
+ | 'submit'
+ | 'suspend'
+ | 'textInput'
+ | 'timeupdate'
+ | 'toggle'
+ | 'touchcancel'
+ | 'touchend'
+ | 'touchmove'
+ | 'touchstart'
+ | 'transitionend'
+ | 'volumechange'
+ | 'waiting'
+ | 'wheel';
+
+export const TOP_ABORT: TopLevelType = 'abort';
+export const TOP_ANIMATION_END: TopLevelType = getVendorPrefixedEventName(
+ 'animationend',
+);
+export const TOP_ANIMATION_ITERATION: TopLevelType = getVendorPrefixedEventName(
+ 'animationiteration',
+);
+export const TOP_ANIMATION_START: TopLevelType = getVendorPrefixedEventName(
+ 'animationstart',
+);
+export const TOP_BLUR: TopLevelType = 'blur';
+export const TOP_CAN_PLAY: TopLevelType = 'canplay';
+export const TOP_CAN_PLAY_THROUGH: TopLevelType = 'canplaythrough';
+export const TOP_CANCEL: TopLevelType = 'cancel';
+export const TOP_CHANGE: TopLevelType = 'change';
+export const TOP_CLICK: TopLevelType = 'click';
+export const TOP_CLOSE: TopLevelType = 'close';
+export const TOP_COMPOSITION_END: TopLevelType = 'compositionend';
+export const TOP_COMPOSITION_START: TopLevelType = 'compositionstart';
+export const TOP_COMPOSITION_UPDATE: TopLevelType = 'compositionupdate';
+export const TOP_CONTEXT_MENU: TopLevelType = 'contextmenu';
+export const TOP_COPY: TopLevelType = 'copy';
+export const TOP_CUT: TopLevelType = 'cut';
+export const TOP_DOUBLE_CLICK: TopLevelType = 'dblclick';
+export const TOP_DRAG: TopLevelType = 'drag';
+export const TOP_DRAG_END: TopLevelType = 'dragend';
+export const TOP_DRAG_ENTER: TopLevelType = 'dragenter';
+export const TOP_DRAG_EXIT: TopLevelType = 'dragexit';
+export const TOP_DRAG_LEAVE: TopLevelType = 'dragleave';
+export const TOP_DRAG_OVER: TopLevelType = 'dragover';
+export const TOP_DRAG_START: TopLevelType = 'dragstart';
+export const TOP_DROP: TopLevelType = 'drop';
+export const TOP_DURATION_CHANGE: TopLevelType = 'durationchange';
+export const TOP_EMPTIED: TopLevelType = 'emptied';
+export const TOP_ENCRYPTED: TopLevelType = 'encrypted';
+export const TOP_ENDED: TopLevelType = 'ended';
+export const TOP_ERROR: TopLevelType = 'error';
+export const TOP_FOCUS: TopLevelType = 'focus';
+export const TOP_INPUT: TopLevelType = 'input';
+export const TOP_INVALID: TopLevelType = 'invalid';
+export const TOP_KEY_DOWN: TopLevelType = 'keydown';
+export const TOP_KEY_PRESS: TopLevelType = 'keypress';
+export const TOP_KEY_UP: TopLevelType = 'keyup';
+export const TOP_LOAD: TopLevelType = 'load';
+export const TOP_LOAD_START: TopLevelType = 'loadstart';
+export const TOP_LOADED_DATA: TopLevelType = 'loadeddata';
+export const TOP_LOADED_METADATA: TopLevelType = 'loadedmetadata';
+export const TOP_MOUSE_DOWN: TopLevelType = 'mousedown';
+export const TOP_MOUSE_MOVE: TopLevelType = 'mousemove';
+export const TOP_MOUSE_OUT: TopLevelType = 'mouseout';
+export const TOP_MOUSE_OVER: TopLevelType = 'mouseover';
+export const TOP_MOUSE_UP: TopLevelType = 'mouseup';
+export const TOP_PASTE: TopLevelType = 'paste';
+export const TOP_PAUSE: TopLevelType = 'pause';
+export const TOP_PLAY: TopLevelType = 'play';
+export const TOP_PLAYING: TopLevelType = 'playing';
+export const TOP_PROGRESS: TopLevelType = 'progress';
+export const TOP_RATE_CHANGE: TopLevelType = 'ratechange';
+export const TOP_RESET: TopLevelType = 'reset';
+export const TOP_SCROLL: TopLevelType = 'scroll';
+export const TOP_SEEKED: TopLevelType = 'seeked';
+export const TOP_SEEKING: TopLevelType = 'seeking';
+export const TOP_SELECTION_CHANGE: TopLevelType = 'selectionchange';
+export const TOP_STALLED: TopLevelType = 'stalled';
+export const TOP_SUBMIT: TopLevelType = 'submit';
+export const TOP_SUSPEND: TopLevelType = 'suspend';
+export const TOP_TEXT_INPUT: TopLevelType = 'textInput';
+export const TOP_TIME_UPDATE: TopLevelType = 'timeupdate';
+export const TOP_TOGGLE: TopLevelType = 'toggle';
+export const TOP_TOUCH_CANCEL: TopLevelType = 'touchcancel';
+export const TOP_TOUCH_END: TopLevelType = 'touchend';
+export const TOP_TOUCH_MOVE: TopLevelType = 'touchmove';
+export const TOP_TOUCH_START: TopLevelType = 'touchstart';
+export const TOP_TRANSITION_END: TopLevelType = getVendorPrefixedEventName(
+ 'transitionend',
+);
+export const TOP_VOLUME_CHANGE: TopLevelType = 'volumechange';
+export const TOP_WAITING: TopLevelType = 'waiting';
+export const TOP_WHEEL: TopLevelType = 'wheel';
+
+export const mediaEventTypes: Array = [
+ TOP_ABORT,
+ TOP_CAN_PLAY,
+ TOP_CAN_PLAY_THROUGH,
+ TOP_DURATION_CHANGE,
+ TOP_EMPTIED,
+ TOP_ENCRYPTED,
+ TOP_ENDED,
+ TOP_ERROR,
+ TOP_LOADED_DATA,
+ TOP_LOADED_METADATA,
+ TOP_LOAD_START,
+ TOP_PAUSE,
+ TOP_PLAY,
+ TOP_PLAYING,
+ TOP_PROGRESS,
+ TOP_RATE_CHANGE,
+ TOP_SEEKED,
+ TOP_SEEKING,
+ TOP_STALLED,
+ TOP_SUSPEND,
+ TOP_TIME_UPDATE,
+ TOP_VOLUME_CHANGE,
+ TOP_WAITING,
+];
+
+export function getRawEventName(topLevelType: TopLevelType): string {
+ return topLevelType;
+}
diff --git a/packages/react-dom/src/events/EnterLeaveEventPlugin.js b/packages/react-dom/src/events/EnterLeaveEventPlugin.js
index 9a2be568c108c..3e15dd8a90cd2 100644
--- a/packages/react-dom/src/events/EnterLeaveEventPlugin.js
+++ b/packages/react-dom/src/events/EnterLeaveEventPlugin.js
@@ -7,6 +7,7 @@
import {accumulateEnterLeaveDispatches} from 'events/EventPropagators';
+import {TOP_MOUSE_OUT, TOP_MOUSE_OVER} from './DOMTopLevelEventTypes';
import SyntheticMouseEvent from './SyntheticMouseEvent';
import {
getClosestInstanceFromNode,
@@ -16,11 +17,11 @@ import {
const eventTypes = {
mouseEnter: {
registrationName: 'onMouseEnter',
- dependencies: ['topMouseOut', 'topMouseOver'],
+ dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER],
},
mouseLeave: {
registrationName: 'onMouseLeave',
- dependencies: ['topMouseOut', 'topMouseOver'],
+ dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER],
},
};
@@ -41,12 +42,12 @@ const EnterLeaveEventPlugin = {
nativeEventTarget,
) {
if (
- topLevelType === 'topMouseOver' &&
+ topLevelType === TOP_MOUSE_OVER &&
(nativeEvent.relatedTarget || nativeEvent.fromElement)
) {
return null;
}
- if (topLevelType !== 'topMouseOut' && topLevelType !== 'topMouseOver') {
+ if (topLevelType !== TOP_MOUSE_OUT && topLevelType !== TOP_MOUSE_OVER) {
// Must not be a mouse in or mouse out - ignoring.
return null;
}
@@ -67,7 +68,7 @@ const EnterLeaveEventPlugin = {
let from;
let to;
- if (topLevelType === 'topMouseOut') {
+ if (topLevelType === TOP_MOUSE_OUT) {
from = targetInst;
const related = nativeEvent.relatedTarget || nativeEvent.toElement;
to = related ? getClosestInstanceFromNode(related) : null;
diff --git a/packages/react-dom/src/events/EventListener.js b/packages/react-dom/src/events/EventListener.js
index e87c3886eb8ef..8bec245b13fb7 100644
--- a/packages/react-dom/src/events/EventListener.js
+++ b/packages/react-dom/src/events/EventListener.js
@@ -8,7 +8,7 @@
*/
export function addEventBubbleListener(
- element: Element,
+ element: Document | Element,
eventType: string,
listener: Function,
): void {
@@ -16,7 +16,7 @@ export function addEventBubbleListener(
}
export function addEventCaptureListener(
- element: Element,
+ element: Document | Element,
eventType: string,
listener: Function,
): void {
diff --git a/packages/react-dom/src/events/ReactBrowserEventEmitter.js b/packages/react-dom/src/events/ReactBrowserEventEmitter.js
index 8991734a750a3..0a2742a654eec 100644
--- a/packages/react-dom/src/events/ReactBrowserEventEmitter.js
+++ b/packages/react-dom/src/events/ReactBrowserEventEmitter.js
@@ -3,9 +3,18 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
+ *
+ * @flow
*/
import {registrationNameDependencies} from 'events/EventPluginRegistry';
+import {
+ TOP_BLUR,
+ TOP_CANCEL,
+ TOP_CLOSE,
+ TOP_FOCUS,
+ TOP_SCROLL,
+} from './DOMTopLevelEventTypes';
import {
setEnabled,
isEnabled,
@@ -13,7 +22,6 @@ import {
trapCapturedEvent,
} from './ReactDOMEventListener';
import isEventSupported from './isEventSupported';
-import {topLevelTypes} from './BrowserEventConstants';
/**
* Summary of `ReactBrowserEventEmitter` event handling:
@@ -79,7 +87,7 @@ let reactTopListenersCounter = 0;
*/
const topListenersIDKey = '_reactListenersID' + ('' + Math.random()).slice(2);
-function getListeningForDocument(mountAt) {
+function getListeningForDocument(mountAt: any) {
// In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty`
// directly.
if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) {
@@ -108,37 +116,39 @@ function getListeningForDocument(mountAt) {
* they bubble to document.
*
* @param {string} registrationName Name of listener (e.g. `onClick`).
- * @param {object} contentDocumentHandle Document which owns the container
+ * @param {object} mountAt Container where to mount the listener
*/
-export function listenTo(registrationName, contentDocumentHandle) {
- const mountAt = contentDocumentHandle;
+export function listenTo(
+ registrationName: string,
+ mountAt: Document | Element,
+) {
const isListening = getListeningForDocument(mountAt);
const dependencies = registrationNameDependencies[registrationName];
for (let i = 0; i < dependencies.length; i++) {
const dependency = dependencies[i];
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
- if (dependency === 'topScroll') {
- trapCapturedEvent('topScroll', 'scroll', mountAt);
- } else if (dependency === 'topFocus' || dependency === 'topBlur') {
- trapCapturedEvent('topFocus', 'focus', mountAt);
- trapCapturedEvent('topBlur', 'blur', mountAt);
+ if (dependency === TOP_SCROLL) {
+ trapCapturedEvent(TOP_SCROLL, mountAt);
+ } else if (dependency === TOP_FOCUS || dependency === TOP_BLUR) {
+ trapCapturedEvent(TOP_FOCUS, mountAt);
+ trapCapturedEvent(TOP_BLUR, mountAt);
// to make sure blur and focus event listeners are only attached once
- isListening.topBlur = true;
- isListening.topFocus = true;
- } else if (dependency === 'topCancel') {
+ isListening[TOP_BLUR] = true;
+ isListening[TOP_FOCUS] = true;
+ } else if (dependency === TOP_CANCEL) {
if (isEventSupported('cancel', true)) {
- trapCapturedEvent('topCancel', 'cancel', mountAt);
+ trapCapturedEvent(TOP_CANCEL, mountAt);
}
- isListening.topCancel = true;
- } else if (dependency === 'topClose') {
+ isListening[TOP_CANCEL] = true;
+ } else if (dependency === TOP_CLOSE) {
if (isEventSupported('close', true)) {
- trapCapturedEvent('topClose', 'close', mountAt);
+ trapCapturedEvent(TOP_CLOSE, mountAt);
}
- isListening.topClose = true;
- } else if (topLevelTypes.hasOwnProperty(dependency)) {
- trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
+ isListening[TOP_CLOSE] = true;
+ } else {
+ trapBubbledEvent(dependency, mountAt);
}
isListening[dependency] = true;
@@ -146,7 +156,10 @@ export function listenTo(registrationName, contentDocumentHandle) {
}
}
-export function isListeningToAllDependencies(registrationName, mountAt) {
+export function isListeningToAllDependencies(
+ registrationName: string,
+ mountAt: Document | Element,
+) {
const isListening = getListeningForDocument(mountAt);
const dependencies = registrationNameDependencies[registrationName];
for (let i = 0; i < dependencies.length; i++) {
diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js
index df831eb848224..0125a8437b41d 100644
--- a/packages/react-dom/src/events/ReactDOMEventListener.js
+++ b/packages/react-dom/src/events/ReactDOMEventListener.js
@@ -3,17 +3,23 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
+ *
+ * @flow
*/
import {batchedUpdates, interactiveUpdates} from 'events/ReactGenericBatching';
import {runExtractedEventsInBatch} from 'events/EventPluginHub';
import {isFiberMounted} from 'react-reconciler/reflection';
import {HostRoot} from 'shared/ReactTypeOfWork';
+import type {AnyNativeEvent} from 'events/PluginModuleType';
+import type {TopLevelType} from 'events/TopLevelEventTypes';
+import type {Fiber} from 'react-reconciler/src/ReactFiber';
import {addEventBubbleListener, addEventCaptureListener} from './EventListener';
import getEventTarget from './getEventTarget';
import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
import SimpleEventPlugin from './SimpleEventPlugin';
+import {getRawEventName} from './DOMTopLevelEventTypes';
const {isInteractiveTopLevelEventType} = SimpleEventPlugin;
@@ -40,7 +46,16 @@ function findRootContainerNode(inst) {
}
// Used to store ancestor hierarchy in top level callback
-function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst) {
+function getTopLevelCallbackBookKeeping(
+ topLevelType,
+ nativeEvent,
+ targetInst,
+): {
+ topLevelType: ?TopLevelType,
+ nativeEvent: ?AnyNativeEvent,
+ targetInst: Fiber,
+ ancestors: Array,
+} {
if (callbackBookkeepingPool.length) {
const instance = callbackBookkeepingPool.pop();
instance.topLevelType = topLevelType;
@@ -101,7 +116,7 @@ function handleTopLevel(bookKeeping) {
// TODO: can we stop exporting these?
export let _enabled = true;
-export function setEnabled(enabled) {
+export function setEnabled(enabled: ?boolean) {
_enabled = !!enabled;
}
@@ -112,14 +127,16 @@ export function isEnabled() {
/**
* Traps top-level events by using event bubbling.
*
- * @param {string} topLevelType Record from `BrowserEventConstants`.
- * @param {string} handlerBaseName Event name (e.g. "click").
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
* @param {object} element Element on which to attach listener.
* @return {?object} An object with a remove function which will forcefully
* remove the listener.
* @internal
*/
-export function trapBubbledEvent(topLevelType, handlerBaseName, element) {
+export function trapBubbledEvent(
+ topLevelType: TopLevelType,
+ element: Document | Element,
+) {
if (!element) {
return null;
}
@@ -129,7 +146,7 @@ export function trapBubbledEvent(topLevelType, handlerBaseName, element) {
addEventBubbleListener(
element,
- handlerBaseName,
+ getRawEventName(topLevelType),
// Check if interactive and wrap in interactiveUpdates
dispatch.bind(null, topLevelType),
);
@@ -138,14 +155,16 @@ export function trapBubbledEvent(topLevelType, handlerBaseName, element) {
/**
* Traps a top-level event by using event capturing.
*
- * @param {string} topLevelType Record from `BrowserEventConstants`.
- * @param {string} handlerBaseName Event name (e.g. "click").
+ * @param {number} topLevelType Number from `TopLevelEventTypes`.
* @param {object} element Element on which to attach listener.
* @return {?object} An object with a remove function which will forcefully
* remove the listener.
* @internal
*/
-export function trapCapturedEvent(topLevelType, handlerBaseName, element) {
+export function trapCapturedEvent(
+ topLevelType: TopLevelType,
+ element: Document | Element,
+) {
if (!element) {
return null;
}
@@ -155,7 +174,7 @@ export function trapCapturedEvent(topLevelType, handlerBaseName, element) {
addEventCaptureListener(
element,
- handlerBaseName,
+ getRawEventName(topLevelType),
// Check if interactive and wrap in interactiveUpdates
dispatch.bind(null, topLevelType),
);
@@ -165,7 +184,10 @@ function dispatchInteractiveEvent(topLevelType, nativeEvent) {
interactiveUpdates(dispatchEvent, topLevelType, nativeEvent);
}
-export function dispatchEvent(topLevelType, nativeEvent) {
+export function dispatchEvent(
+ topLevelType: TopLevelType,
+ nativeEvent: AnyNativeEvent,
+) {
if (!_enabled) {
return;
}
diff --git a/packages/react-dom/src/events/SelectEventPlugin.js b/packages/react-dom/src/events/SelectEventPlugin.js
index e6193c7973a8c..81cc5d5186740 100644
--- a/packages/react-dom/src/events/SelectEventPlugin.js
+++ b/packages/react-dom/src/events/SelectEventPlugin.js
@@ -12,6 +12,16 @@ import isTextInputElement from 'shared/isTextInputElement';
import getActiveElement from 'fbjs/lib/getActiveElement';
import shallowEqual from 'fbjs/lib/shallowEqual';
+import {
+ TOP_BLUR,
+ TOP_CONTEXT_MENU,
+ TOP_FOCUS,
+ TOP_KEY_DOWN,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
+ TOP_MOUSE_UP,
+ TOP_SELECTION_CHANGE,
+} from './DOMTopLevelEventTypes';
import {isListeningToAllDependencies} from './ReactBrowserEventEmitter';
import {getNodeFromInstance} from '../client/ReactDOMComponentTree';
import * as ReactInputSelection from '../client/ReactInputSelection';
@@ -29,14 +39,14 @@ const eventTypes = {
captured: 'onSelectCapture',
},
dependencies: [
- 'topBlur',
- 'topContextMenu',
- 'topFocus',
- 'topKeyDown',
- 'topKeyUp',
- 'topMouseDown',
- 'topMouseUp',
- 'topSelectionChange',
+ TOP_BLUR,
+ TOP_CONTEXT_MENU,
+ TOP_FOCUS,
+ TOP_KEY_DOWN,
+ TOP_KEY_UP,
+ TOP_MOUSE_DOWN,
+ TOP_MOUSE_UP,
+ TOP_SELECTION_CHANGE,
],
},
};
@@ -156,7 +166,7 @@ const SelectEventPlugin = {
switch (topLevelType) {
// Track the input node that has focus.
- case 'topFocus':
+ case TOP_FOCUS:
if (
isTextInputElement(targetNode) ||
targetNode.contentEditable === 'true'
@@ -166,18 +176,18 @@ const SelectEventPlugin = {
lastSelection = null;
}
break;
- case 'topBlur':
+ case TOP_BLUR:
activeElement = null;
activeElementInst = null;
lastSelection = null;
break;
// Don't fire the event while the user is dragging. This matches the
// semantics of the native select event.
- case 'topMouseDown':
+ case TOP_MOUSE_DOWN:
mouseDown = true;
break;
- case 'topContextMenu':
- case 'topMouseUp':
+ case TOP_CONTEXT_MENU:
+ case TOP_MOUSE_UP:
mouseDown = false;
return constructSelectEvent(nativeEvent, nativeEventTarget);
// Chrome and IE fire non-standard event when selection is changed (and
@@ -189,13 +199,13 @@ const SelectEventPlugin = {
// keyup, but we check on keydown as well in the case of holding down a
// key, when multiple keydown events are fired but only one keyup is.
// This is also our approach for IE handling, for the reason above.
- case 'topSelectionChange':
+ case TOP_SELECTION_CHANGE:
if (skipSelectionChangeEvent) {
break;
}
// falls through
- case 'topKeyDown':
- case 'topKeyUp':
+ case TOP_KEY_DOWN:
+ case TOP_KEY_UP:
return constructSelectEvent(nativeEvent, nativeEventTarget);
}
diff --git a/packages/react-dom/src/events/SimpleEventPlugin.js b/packages/react-dom/src/events/SimpleEventPlugin.js
index 602624dd312f7..6da1d244c9673 100644
--- a/packages/react-dom/src/events/SimpleEventPlugin.js
+++ b/packages/react-dom/src/events/SimpleEventPlugin.js
@@ -7,7 +7,7 @@
* @flow
*/
-import type {TopLevelTypes} from './BrowserEventConstants';
+import type {TopLevelType} from 'events/TopLevelEventTypes';
import type {
DispatchConfig,
ReactSyntheticEvent,
@@ -17,6 +17,8 @@ import type {EventTypes, PluginModule} from 'events/PluginModuleType';
import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
import SyntheticEvent from 'events/SyntheticEvent';
+
+import * as DOMTopLevelEventTypes from './DOMTopLevelEventTypes';
import warning from 'fbjs/lib/warning';
import SyntheticAnimationEvent from './SyntheticAnimationEvent';
@@ -41,93 +43,96 @@ import getEventCharCode from './getEventCharCode';
* bubbled: 'onAbort',
* captured: 'onAbortCapture',
* },
- * dependencies: ['topAbort'],
+ * dependencies: [TOP_ABORT],
* },
* ...
* };
- * topLevelEventsToDispatchConfig = {
- * 'topAbort': { sameConfig }
- * };
+ * topLevelEventsToDispatchConfig = new Map([
+ * [TOP_ABORT, { sameConfig }],
+ * ]);
*/
-const interactiveEventTypeNames: Array = [
- 'blur',
- 'cancel',
- 'click',
- 'close',
- 'contextMenu',
- 'copy',
- 'cut',
- 'doubleClick',
- 'dragEnd',
- 'dragStart',
- 'drop',
- 'focus',
- 'input',
- 'invalid',
- 'keyDown',
- 'keyPress',
- 'keyUp',
- 'mouseDown',
- 'mouseUp',
- 'paste',
- 'pause',
- 'play',
- 'rateChange',
- 'reset',
- 'seeked',
- 'submit',
- 'touchCancel',
- 'touchEnd',
- 'touchStart',
- 'volumeChange',
+type EventTuple = [TopLevelType, string];
+const interactiveEventTypeNames: Array = [
+ [DOMTopLevelEventTypes.TOP_BLUR, 'blur'],
+ [DOMTopLevelEventTypes.TOP_CANCEL, 'cancel'],
+ [DOMTopLevelEventTypes.TOP_CLICK, 'click'],
+ [DOMTopLevelEventTypes.TOP_CLOSE, 'close'],
+ [DOMTopLevelEventTypes.TOP_CONTEXT_MENU, 'contextMenu'],
+ [DOMTopLevelEventTypes.TOP_COPY, 'copy'],
+ [DOMTopLevelEventTypes.TOP_CUT, 'cut'],
+ [DOMTopLevelEventTypes.TOP_DOUBLE_CLICK, 'doubleClick'],
+ [DOMTopLevelEventTypes.TOP_DRAG_END, 'dragEnd'],
+ [DOMTopLevelEventTypes.TOP_DRAG_START, 'dragStart'],
+ [DOMTopLevelEventTypes.TOP_DROP, 'drop'],
+ [DOMTopLevelEventTypes.TOP_FOCUS, 'focus'],
+ [DOMTopLevelEventTypes.TOP_INPUT, 'input'],
+ [DOMTopLevelEventTypes.TOP_INVALID, 'invalid'],
+ [DOMTopLevelEventTypes.TOP_KEY_DOWN, 'keyDown'],
+ [DOMTopLevelEventTypes.TOP_KEY_PRESS, 'keyPress'],
+ [DOMTopLevelEventTypes.TOP_KEY_UP, 'keyUp'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_DOWN, 'mouseDown'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_UP, 'mouseUp'],
+ [DOMTopLevelEventTypes.TOP_PASTE, 'paste'],
+ [DOMTopLevelEventTypes.TOP_PAUSE, 'pause'],
+ [DOMTopLevelEventTypes.TOP_PLAY, 'play'],
+ [DOMTopLevelEventTypes.TOP_RATE_CHANGE, 'rateChange'],
+ [DOMTopLevelEventTypes.TOP_RESET, 'reset'],
+ [DOMTopLevelEventTypes.TOP_SEEKED, 'seeked'],
+ [DOMTopLevelEventTypes.TOP_SUBMIT, 'submit'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_CANCEL, 'touchCancel'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_END, 'touchEnd'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_START, 'touchStart'],
+ [DOMTopLevelEventTypes.TOP_VOLUME_CHANGE, 'volumeChange'],
];
-const nonInteractiveEventTypeNames: Array = [
- 'abort',
- 'animationEnd',
- 'animationIteration',
- 'animationStart',
- 'canPlay',
- 'canPlayThrough',
- 'drag',
- 'dragEnter',
- 'dragExit',
- 'dragLeave',
- 'dragOver',
- 'durationChange',
- 'emptied',
- 'encrypted',
- 'ended',
- 'error',
- 'load',
- 'loadedData',
- 'loadedMetadata',
- 'loadStart',
- 'mouseMove',
- 'mouseOut',
- 'mouseOver',
- 'playing',
- 'progress',
- 'scroll',
- 'seeking',
- 'stalled',
- 'suspend',
- 'timeUpdate',
- 'toggle',
- 'touchMove',
- 'transitionEnd',
- 'waiting',
- 'wheel',
+const nonInteractiveEventTypeNames: Array = [
+ [DOMTopLevelEventTypes.TOP_ABORT, 'abort'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_END, 'animationEnd'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION, 'animationIteration'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_START, 'animationStart'],
+ [DOMTopLevelEventTypes.TOP_CAN_PLAY, 'canPlay'],
+ [DOMTopLevelEventTypes.TOP_CAN_PLAY_THROUGH, 'canPlayThrough'],
+ [DOMTopLevelEventTypes.TOP_DRAG, 'drag'],
+ [DOMTopLevelEventTypes.TOP_DRAG_ENTER, 'dragEnter'],
+ [DOMTopLevelEventTypes.TOP_DRAG_EXIT, 'dragExit'],
+ [DOMTopLevelEventTypes.TOP_DRAG_LEAVE, 'dragLeave'],
+ [DOMTopLevelEventTypes.TOP_DRAG_OVER, 'dragOver'],
+ [DOMTopLevelEventTypes.TOP_DURATION_CHANGE, 'durationChange'],
+ [DOMTopLevelEventTypes.TOP_EMPTIED, 'emptied'],
+ [DOMTopLevelEventTypes.TOP_ENCRYPTED, 'encrypted'],
+ [DOMTopLevelEventTypes.TOP_ENDED, 'ended'],
+ [DOMTopLevelEventTypes.TOP_ERROR, 'error'],
+ [DOMTopLevelEventTypes.TOP_LOAD, 'load'],
+ [DOMTopLevelEventTypes.TOP_LOADED_DATA, 'loadedData'],
+ [DOMTopLevelEventTypes.TOP_LOADED_METADATA, 'loadedMetadata'],
+ [DOMTopLevelEventTypes.TOP_LOAD_START, 'loadStart'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_MOVE, 'mouseMove'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_OUT, 'mouseOut'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_OVER, 'mouseOver'],
+ [DOMTopLevelEventTypes.TOP_PLAYING, 'playing'],
+ [DOMTopLevelEventTypes.TOP_PROGRESS, 'progress'],
+ [DOMTopLevelEventTypes.TOP_SCROLL, 'scroll'],
+ [DOMTopLevelEventTypes.TOP_SEEKING, 'seeking'],
+ [DOMTopLevelEventTypes.TOP_STALLED, 'stalled'],
+ [DOMTopLevelEventTypes.TOP_SUSPEND, 'suspend'],
+ [DOMTopLevelEventTypes.TOP_TIME_UPDATE, 'timeUpdate'],
+ [DOMTopLevelEventTypes.TOP_TOGGLE, 'toggle'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_MOVE, 'touchMove'],
+ [DOMTopLevelEventTypes.TOP_TRANSITION_END, 'transitionEnd'],
+ [DOMTopLevelEventTypes.TOP_WAITING, 'waiting'],
+ [DOMTopLevelEventTypes.TOP_WHEEL, 'wheel'],
];
const eventTypes: EventTypes = {};
const topLevelEventsToDispatchConfig: {
- [key: TopLevelTypes]: DispatchConfig,
+ [key: TopLevelType]: DispatchConfig,
} = {};
-function addEventTypeNameToConfig(event: string, isInteractive: boolean) {
+function addEventTypeNameToConfig(
+ [topEvent, event]: EventTuple,
+ isInteractive: boolean,
+) {
const capitalizedEvent = event[0].toUpperCase() + event.slice(1);
const onEvent = 'on' + capitalizedEvent;
- const topEvent = 'top' + capitalizedEvent;
const type = {
phasedRegistrationNames: {
@@ -141,58 +146,60 @@ function addEventTypeNameToConfig(event: string, isInteractive: boolean) {
topLevelEventsToDispatchConfig[topEvent] = type;
}
-interactiveEventTypeNames.forEach(eventTypeName => {
- addEventTypeNameToConfig(eventTypeName, true);
+interactiveEventTypeNames.forEach(eventTuple => {
+ addEventTypeNameToConfig(eventTuple, true);
});
-nonInteractiveEventTypeNames.forEach(eventTypeName => {
- addEventTypeNameToConfig(eventTypeName, false);
+nonInteractiveEventTypeNames.forEach(eventTuple => {
+ addEventTypeNameToConfig(eventTuple, false);
});
// 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',
+const knownHTMLTopLevelTypes: Array = [
+ DOMTopLevelEventTypes.TOP_ABORT,
+ DOMTopLevelEventTypes.TOP_CANCEL,
+ DOMTopLevelEventTypes.TOP_CAN_PLAY,
+ DOMTopLevelEventTypes.TOP_CAN_PLAY_THROUGH,
+ DOMTopLevelEventTypes.TOP_CLOSE,
+ DOMTopLevelEventTypes.TOP_DURATION_CHANGE,
+ DOMTopLevelEventTypes.TOP_EMPTIED,
+ DOMTopLevelEventTypes.TOP_ENCRYPTED,
+ DOMTopLevelEventTypes.TOP_ENDED,
+ DOMTopLevelEventTypes.TOP_ERROR,
+ DOMTopLevelEventTypes.TOP_INPUT,
+ DOMTopLevelEventTypes.TOP_INVALID,
+ DOMTopLevelEventTypes.TOP_LOAD,
+ DOMTopLevelEventTypes.TOP_LOADED_DATA,
+ DOMTopLevelEventTypes.TOP_LOADED_METADATA,
+ DOMTopLevelEventTypes.TOP_LOAD_START,
+ DOMTopLevelEventTypes.TOP_PAUSE,
+ DOMTopLevelEventTypes.TOP_PLAY,
+ DOMTopLevelEventTypes.TOP_PLAYING,
+ DOMTopLevelEventTypes.TOP_PROGRESS,
+ DOMTopLevelEventTypes.TOP_RATE_CHANGE,
+ DOMTopLevelEventTypes.TOP_RESET,
+ DOMTopLevelEventTypes.TOP_SEEKED,
+ DOMTopLevelEventTypes.TOP_SEEKING,
+ DOMTopLevelEventTypes.TOP_STALLED,
+ DOMTopLevelEventTypes.TOP_SUBMIT,
+ DOMTopLevelEventTypes.TOP_SUSPEND,
+ DOMTopLevelEventTypes.TOP_TIME_UPDATE,
+ DOMTopLevelEventTypes.TOP_TOGGLE,
+ DOMTopLevelEventTypes.TOP_VOLUME_CHANGE,
+ DOMTopLevelEventTypes.TOP_WAITING,
];
-const SimpleEventPlugin: PluginModule = {
+const SimpleEventPlugin: PluginModule & {
+ isInteractiveTopLevelEventType: (topLevelType: TopLevelType) => boolean,
+} = {
eventTypes: eventTypes,
- isInteractiveTopLevelEventType(topLevelType: TopLevelTypes): boolean {
+ isInteractiveTopLevelEventType(topLevelType: TopLevelType): boolean {
const config = topLevelEventsToDispatchConfig[topLevelType];
return config !== undefined && config.isInteractive === true;
},
extractEvents: function(
- topLevelType: TopLevelTypes,
+ topLevelType: TopLevelType,
targetInst: Fiber,
nativeEvent: MouseEvent,
nativeEventTarget: EventTarget,
@@ -203,7 +210,7 @@ const SimpleEventPlugin: PluginModule = {
}
let EventConstructor;
switch (topLevelType) {
- case 'topKeyPress':
+ case DOMTopLevelEventTypes.TOP_KEY_PRESS:
// 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).
@@ -211,65 +218,65 @@ const SimpleEventPlugin: PluginModule = {
return null;
}
/* falls through */
- case 'topKeyDown':
- case 'topKeyUp':
+ case DOMTopLevelEventTypes.TOP_KEY_DOWN:
+ case DOMTopLevelEventTypes.TOP_KEY_UP:
EventConstructor = SyntheticKeyboardEvent;
break;
- case 'topBlur':
- case 'topFocus':
+ case DOMTopLevelEventTypes.TOP_BLUR:
+ case DOMTopLevelEventTypes.TOP_FOCUS:
EventConstructor = SyntheticFocusEvent;
break;
- case 'topClick':
+ case DOMTopLevelEventTypes.TOP_CLICK:
// 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':
+ case DOMTopLevelEventTypes.TOP_DOUBLE_CLICK:
+ case DOMTopLevelEventTypes.TOP_MOUSE_DOWN:
+ case DOMTopLevelEventTypes.TOP_MOUSE_MOVE:
+ case DOMTopLevelEventTypes.TOP_MOUSE_UP:
// TODO: Disabled elements should not respond to mouse events
/* falls through */
- case 'topMouseOut':
- case 'topMouseOver':
- case 'topContextMenu':
+ case DOMTopLevelEventTypes.TOP_MOUSE_OUT:
+ case DOMTopLevelEventTypes.TOP_MOUSE_OVER:
+ case DOMTopLevelEventTypes.TOP_CONTEXT_MENU:
EventConstructor = SyntheticMouseEvent;
break;
- case 'topDrag':
- case 'topDragEnd':
- case 'topDragEnter':
- case 'topDragExit':
- case 'topDragLeave':
- case 'topDragOver':
- case 'topDragStart':
- case 'topDrop':
+ case DOMTopLevelEventTypes.TOP_DRAG:
+ case DOMTopLevelEventTypes.TOP_DRAG_END:
+ case DOMTopLevelEventTypes.TOP_DRAG_ENTER:
+ case DOMTopLevelEventTypes.TOP_DRAG_EXIT:
+ case DOMTopLevelEventTypes.TOP_DRAG_LEAVE:
+ case DOMTopLevelEventTypes.TOP_DRAG_OVER:
+ case DOMTopLevelEventTypes.TOP_DRAG_START:
+ case DOMTopLevelEventTypes.TOP_DROP:
EventConstructor = SyntheticDragEvent;
break;
- case 'topTouchCancel':
- case 'topTouchEnd':
- case 'topTouchMove':
- case 'topTouchStart':
+ case DOMTopLevelEventTypes.TOP_TOUCH_CANCEL:
+ case DOMTopLevelEventTypes.TOP_TOUCH_END:
+ case DOMTopLevelEventTypes.TOP_TOUCH_MOVE:
+ case DOMTopLevelEventTypes.TOP_TOUCH_START:
EventConstructor = SyntheticTouchEvent;
break;
- case 'topAnimationEnd':
- case 'topAnimationIteration':
- case 'topAnimationStart':
+ case DOMTopLevelEventTypes.TOP_ANIMATION_END:
+ case DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION:
+ case DOMTopLevelEventTypes.TOP_ANIMATION_START:
EventConstructor = SyntheticAnimationEvent;
break;
- case 'topTransitionEnd':
+ case DOMTopLevelEventTypes.TOP_TRANSITION_END:
EventConstructor = SyntheticTransitionEvent;
break;
- case 'topScroll':
+ case DOMTopLevelEventTypes.TOP_SCROLL:
EventConstructor = SyntheticUIEvent;
break;
- case 'topWheel':
+ case DOMTopLevelEventTypes.TOP_WHEEL:
EventConstructor = SyntheticWheelEvent;
break;
- case 'topCopy':
- case 'topCut':
- case 'topPaste':
+ case DOMTopLevelEventTypes.TOP_COPY:
+ case DOMTopLevelEventTypes.TOP_CUT:
+ case DOMTopLevelEventTypes.TOP_PASTE:
EventConstructor = SyntheticClipboardEvent;
break;
default:
diff --git a/packages/react-dom/src/events/TapEventPlugin.js b/packages/react-dom/src/events/TapEventPlugin.js
index e1e67a5d70ef9..772e5d405fab2 100644
--- a/packages/react-dom/src/events/TapEventPlugin.js
+++ b/packages/react-dom/src/events/TapEventPlugin.js
@@ -7,12 +7,33 @@
* @flow
*/
-import {isStartish, isEndish} from 'events/EventPluginUtils';
import {accumulateTwoPhaseDispatches} from 'events/EventPropagators';
import TouchEventUtils from 'fbjs/lib/TouchEventUtils';
-
+import type {TopLevelType} from 'events/TopLevelEventTypes';
+
+import {
+ TOP_MOUSE_DOWN,
+ TOP_MOUSE_MOVE,
+ TOP_MOUSE_UP,
+ TOP_TOUCH_CANCEL,
+ TOP_TOUCH_END,
+ TOP_TOUCH_MOVE,
+ TOP_TOUCH_START,
+} from './DOMTopLevelEventTypes';
import SyntheticUIEvent from './SyntheticUIEvent';
+function isStartish(topLevelType) {
+ return topLevelType === TOP_MOUSE_DOWN || topLevelType === TOP_TOUCH_START;
+}
+
+function isEndish(topLevelType) {
+ return (
+ topLevelType === TOP_MOUSE_UP ||
+ topLevelType === TOP_TOUCH_END ||
+ topLevelType === TOP_TOUCH_CANCEL
+ );
+}
+
/**
* We are extending the Flow 'Touch' declaration to enable using bracket
* notation to access properties.
@@ -75,13 +96,13 @@ function getDistance(coords: CoordinatesType, nativeEvent: _Touch): number {
}
const touchEvents = [
- 'topTouchStart',
- 'topTouchCancel',
- 'topTouchEnd',
- 'topTouchMove',
+ TOP_TOUCH_START,
+ TOP_TOUCH_CANCEL,
+ TOP_TOUCH_END,
+ TOP_TOUCH_MOVE,
];
-const dependencies = ['topMouseDown', 'topMouseMove', 'topMouseUp'].concat(
+const dependencies = [TOP_MOUSE_DOWN, TOP_MOUSE_MOVE, TOP_MOUSE_UP].concat(
touchEvents,
);
@@ -105,7 +126,7 @@ const TapEventPlugin = {
eventTypes: eventTypes,
extractEvents: function(
- topLevelType: mixed,
+ topLevelType: TopLevelType,
targetInst: mixed,
nativeEvent: _Touch,
nativeEventTarget: EventTarget,
diff --git a/packages/react-dom/src/__tests__/TapEventPlugin-test.internal.js b/packages/react-dom/src/events/__tests__/TapEventPlugin-test.internal.js
similarity index 100%
rename from packages/react-dom/src/__tests__/TapEventPlugin-test.internal.js
rename to packages/react-dom/src/events/__tests__/TapEventPlugin-test.internal.js
diff --git a/packages/react-dom/src/test-utils/ReactTestUtils.js b/packages/react-dom/src/test-utils/ReactTestUtils.js
index e7cf69b5509cc..d9948291b3cf0 100644
--- a/packages/react-dom/src/test-utils/ReactTestUtils.js
+++ b/packages/react-dom/src/test-utils/ReactTestUtils.js
@@ -18,7 +18,7 @@ import {
import SyntheticEvent from 'events/SyntheticEvent';
import invariant from 'fbjs/lib/invariant';
-import {topLevelTypes, mediaEventTypes} from '../events/BrowserEventConstants';
+import * as DOMTopLevelEventTypes from '../events/DOMTopLevelEventTypes';
const {findDOMNode} = ReactDOM;
const {
@@ -36,6 +36,33 @@ function Event(suffix) {}
* @class ReactTestUtils
*/
+/**
+ * Simulates a top level event being dispatched from a raw event that occurred
+ * on an `Element` node.
+ * @param {number} topLevelType A number from `TopLevelEventTypes`
+ * @param {!Element} node The dom to simulate an event occurring on.
+ * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.
+ */
+function simulateNativeEventOnNode(topLevelType, node, fakeNativeEvent) {
+ fakeNativeEvent.target = node;
+ ReactDOMEventListener.dispatchEvent(topLevelType, fakeNativeEvent);
+}
+
+/**
+ * Simulates a top level event being dispatched from a raw event that occurred
+ * on the `ReactDOMComponent` `comp`.
+ * @param {Object} topLevelType A type from `BrowserEventConstants.topLevelTypes`.
+ * @param {!ReactDOMComponent} comp
+ * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.
+ */
+function simulateNativeEventOnDOMComponent(
+ topLevelType,
+ comp,
+ fakeNativeEvent,
+) {
+ simulateNativeEventOnNode(topLevelType, findDOMNode(comp), fakeNativeEvent);
+}
+
function findAllInRenderedFiberTreeInternal(fiber, test) {
if (!fiber) {
return [];
@@ -291,37 +318,6 @@ const ReactTestUtils = {
return this;
},
- /**
- * Simulates a top level event being dispatched from a raw event that occurred
- * on an `Element` node.
- * @param {Object} topLevelType A type from `BrowserEventConstants.topLevelTypes`
- * @param {!Element} node The dom to simulate an event occurring on.
- * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.
- */
- simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) {
- fakeNativeEvent.target = node;
- ReactDOMEventListener.dispatchEvent(topLevelType, fakeNativeEvent);
- },
-
- /**
- * Simulates a top level event being dispatched from a raw event that occurred
- * on the `ReactDOMComponent` `comp`.
- * @param {Object} topLevelType A type from `BrowserEventConstants.topLevelTypes`.
- * @param {!ReactDOMComponent} comp
- * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent.
- */
- simulateNativeEventOnDOMComponent: function(
- topLevelType,
- comp,
- fakeNativeEvent,
- ) {
- ReactTestUtils.simulateNativeEventOnNode(
- topLevelType,
- findDOMNode(comp),
- fakeNativeEvent,
- );
- },
-
nativeTouchData: function(x, y) {
return {
touches: [{pageX: x, pageY: y}],
@@ -436,20 +432,20 @@ buildSimulators();
* to dispatch synthetic events.
*/
-function makeNativeSimulator(eventType) {
+function makeNativeSimulator(eventType, topLevelType) {
return function(domComponentOrNode, nativeEventData) {
const fakeNativeEvent = new Event(eventType);
Object.assign(fakeNativeEvent, nativeEventData);
if (ReactTestUtils.isDOMComponent(domComponentOrNode)) {
- ReactTestUtils.simulateNativeEventOnDOMComponent(
- eventType,
+ simulateNativeEventOnDOMComponent(
+ topLevelType,
domComponentOrNode,
fakeNativeEvent,
);
} else if (domComponentOrNode.tagName) {
// Will allow on actual dom nodes.
- ReactTestUtils.simulateNativeEventOnNode(
- eventType,
+ simulateNativeEventOnNode(
+ topLevelType,
domComponentOrNode,
fakeNativeEvent,
);
@@ -457,23 +453,84 @@ function makeNativeSimulator(eventType) {
};
}
-const eventKeys = [].concat(
- Object.keys(topLevelTypes),
- Object.keys(mediaEventTypes),
-);
-
-eventKeys.forEach(function(eventType) {
- // Event type is stored as 'topClick' - we transform that to 'click'
- const convenienceName =
- eventType.indexOf('top') === 0
- ? eventType.charAt(3).toLowerCase() + eventType.substr(4)
- : eventType;
+[
+ [DOMTopLevelEventTypes.TOP_ABORT, 'abort'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_END, 'animationEnd'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION, 'animationIteration'],
+ [DOMTopLevelEventTypes.TOP_ANIMATION_START, 'animationStart'],
+ [DOMTopLevelEventTypes.TOP_BLUR, 'blur'],
+ [DOMTopLevelEventTypes.TOP_CAN_PLAY_THROUGH, 'canPlayThrough'],
+ [DOMTopLevelEventTypes.TOP_CAN_PLAY, 'canPlay'],
+ [DOMTopLevelEventTypes.TOP_CANCEL, 'cancel'],
+ [DOMTopLevelEventTypes.TOP_CHANGE, 'change'],
+ [DOMTopLevelEventTypes.TOP_CLICK, 'click'],
+ [DOMTopLevelEventTypes.TOP_CLOSE, 'close'],
+ [DOMTopLevelEventTypes.TOP_COMPOSITION_END, 'compositionEnd'],
+ [DOMTopLevelEventTypes.TOP_COMPOSITION_START, 'compositionStart'],
+ [DOMTopLevelEventTypes.TOP_COMPOSITION_UPDATE, 'compositionUpdate'],
+ [DOMTopLevelEventTypes.TOP_CONTEXT_MENU, 'contextMenu'],
+ [DOMTopLevelEventTypes.TOP_COPY, 'copy'],
+ [DOMTopLevelEventTypes.TOP_CUT, 'cut'],
+ [DOMTopLevelEventTypes.TOP_DOUBLE_CLICK, 'doubleClick'],
+ [DOMTopLevelEventTypes.TOP_DRAG_END, 'dragEnd'],
+ [DOMTopLevelEventTypes.TOP_DRAG_ENTER, 'dragEnter'],
+ [DOMTopLevelEventTypes.TOP_DRAG_EXIT, 'dragExit'],
+ [DOMTopLevelEventTypes.TOP_DRAG_LEAVE, 'dragLeave'],
+ [DOMTopLevelEventTypes.TOP_DRAG_OVER, 'dragOver'],
+ [DOMTopLevelEventTypes.TOP_DRAG_START, 'dragStart'],
+ [DOMTopLevelEventTypes.TOP_DRAG, 'drag'],
+ [DOMTopLevelEventTypes.TOP_DROP, 'drop'],
+ [DOMTopLevelEventTypes.TOP_DURATION_CHANGE, 'durationChange'],
+ [DOMTopLevelEventTypes.TOP_EMPTIED, 'emptied'],
+ [DOMTopLevelEventTypes.TOP_ENCRYPTED, 'encrypted'],
+ [DOMTopLevelEventTypes.TOP_ENDED, 'ended'],
+ [DOMTopLevelEventTypes.TOP_ERROR, 'error'],
+ [DOMTopLevelEventTypes.TOP_FOCUS, 'focus'],
+ [DOMTopLevelEventTypes.TOP_INPUT, 'input'],
+ [DOMTopLevelEventTypes.TOP_KEY_DOWN, 'keyDown'],
+ [DOMTopLevelEventTypes.TOP_KEY_PRESS, 'keyPress'],
+ [DOMTopLevelEventTypes.TOP_KEY_UP, 'keyUp'],
+ [DOMTopLevelEventTypes.TOP_LOAD_START, 'loadStart'],
+ [DOMTopLevelEventTypes.TOP_LOAD_START, 'loadStart'],
+ [DOMTopLevelEventTypes.TOP_LOAD, 'load'],
+ [DOMTopLevelEventTypes.TOP_LOADED_DATA, 'loadedData'],
+ [DOMTopLevelEventTypes.TOP_LOADED_METADATA, 'loadedMetadata'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_DOWN, 'mouseDown'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_MOVE, 'mouseMove'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_OUT, 'mouseOut'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_OVER, 'mouseOver'],
+ [DOMTopLevelEventTypes.TOP_MOUSE_UP, 'mouseUp'],
+ [DOMTopLevelEventTypes.TOP_PASTE, 'paste'],
+ [DOMTopLevelEventTypes.TOP_PAUSE, 'pause'],
+ [DOMTopLevelEventTypes.TOP_PLAY, 'play'],
+ [DOMTopLevelEventTypes.TOP_PLAYING, 'playing'],
+ [DOMTopLevelEventTypes.TOP_PROGRESS, 'progress'],
+ [DOMTopLevelEventTypes.TOP_RATE_CHANGE, 'rateChange'],
+ [DOMTopLevelEventTypes.TOP_SCROLL, 'scroll'],
+ [DOMTopLevelEventTypes.TOP_SEEKED, 'seeked'],
+ [DOMTopLevelEventTypes.TOP_SEEKING, 'seeking'],
+ [DOMTopLevelEventTypes.TOP_SELECTION_CHANGE, 'selectionChange'],
+ [DOMTopLevelEventTypes.TOP_STALLED, 'stalled'],
+ [DOMTopLevelEventTypes.TOP_SUSPEND, 'suspend'],
+ [DOMTopLevelEventTypes.TOP_TEXT_INPUT, 'textInput'],
+ [DOMTopLevelEventTypes.TOP_TIME_UPDATE, 'timeUpdate'],
+ [DOMTopLevelEventTypes.TOP_TOGGLE, 'toggle'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_CANCEL, 'touchCancel'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_END, 'touchEnd'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_MOVE, 'touchMove'],
+ [DOMTopLevelEventTypes.TOP_TOUCH_START, 'touchStart'],
+ [DOMTopLevelEventTypes.TOP_TRANSITION_END, 'transitionEnd'],
+ [DOMTopLevelEventTypes.TOP_VOLUME_CHANGE, 'volumeChange'],
+ [DOMTopLevelEventTypes.TOP_WAITING, 'waiting'],
+ [DOMTopLevelEventTypes.TOP_WHEEL, 'wheel'],
+].forEach(([topLevelType, eventType]) => {
/**
* @param {!Element|ReactDOMComponent} domComponentOrNode
* @param {?Event} nativeEventData Fake native event to use in SyntheticEvent.
*/
- ReactTestUtils.SimulateNative[convenienceName] = makeNativeSimulator(
+ ReactTestUtils.SimulateNative[eventType] = makeNativeSimulator(
eventType,
+ topLevelType,
);
});
diff --git a/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js b/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js
index 69bc7a260a558..59cd7c8f28b2f 100644
--- a/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js
+++ b/packages/react-native-renderer/src/ReactNativeBridgeEventPlugin.js
@@ -12,6 +12,7 @@ import {
accumulateTwoPhaseDispatches,
accumulateDirectDispatches,
} from 'events/EventPropagators';
+import type {TopLevelType} from 'events/TopLevelEventTypes';
import * as ReactNativeViewConfigRegistry from 'ReactNativeViewConfigRegistry';
import SyntheticEvent from 'events/SyntheticEvent';
import invariant from 'fbjs/lib/invariant';
@@ -29,7 +30,7 @@ const ReactNativeBridgeEventPlugin = {
* @see {EventPluginHub.extractEvents}
*/
extractEvents: function(
- topLevelType: string,
+ topLevelType: TopLevelType,
targetInst: Object,
nativeEvent: AnyNativeEvent,
nativeEventTarget: Object,
diff --git a/packages/react-native-renderer/src/ReactNativeEventEmitter.js b/packages/react-native-renderer/src/ReactNativeEventEmitter.js
index e43644a620826..6b61de63319bd 100644
--- a/packages/react-native-renderer/src/ReactNativeEventEmitter.js
+++ b/packages/react-native-renderer/src/ReactNativeEventEmitter.js
@@ -15,6 +15,7 @@ import warning from 'fbjs/lib/warning';
import {getInstanceFromNode} from './ReactNativeComponentTree';
import type {AnyNativeEvent} from 'events/PluginModuleType';
+import type {TopLevelType} from 'events/TopLevelEventTypes';
export {getListener, registrationNameModules as registrationNames};
@@ -88,7 +89,7 @@ const removeTouchesAtIndices = function(
*/
export function _receiveRootNodeIDEvent(
rootNodeID: number,
- topLevelType: string,
+ topLevelType: TopLevelType,
nativeEventParam: ?AnyNativeEvent,
) {
const nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
@@ -114,7 +115,7 @@ export function _receiveRootNodeIDEvent(
*/
export function receiveEvent(
rootNodeID: number,
- topLevelType: string,
+ topLevelType: TopLevelType,
nativeEventParam: AnyNativeEvent,
) {
_receiveRootNodeIDEvent(rootNodeID, topLevelType, nativeEventParam);
@@ -145,7 +146,7 @@ export function receiveEvent(
* identifier 0, also abandoning traditional click handlers.
*/
export function receiveTouches(
- eventTopLevelType: string,
+ eventTopLevelType: TopLevelType,
touches: Array