Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Replace top-level event types with numbers #11894

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions packages/events/EventPluginUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@ import ReactErrorUtils from 'shared/ReactErrorUtils';
import invariant from 'fbjs/lib/invariant';
import warning from 'fbjs/lib/warning';

import {
TOP_MOUSE_DOWN,
TOP_MOUSE_MOVE,
TOP_MOUSE_UP,
TOP_TOUCH_CANCEL,
TOP_TOUCH_END,
TOP_TOUCH_MOVE,
TOP_TOUCH_START,
} from './TopLevelEventTypes';

export let getFiberCurrentPropsFromNode = null;
export let getInstanceFromNode = null;
export let getNodeFromInstance = null;
Expand All @@ -32,17 +42,17 @@ export const injection = {

export function isEndish(topLevelType) {
return (
topLevelType === 'topMouseUp' ||
topLevelType === 'topTouchEnd' ||
topLevelType === 'topTouchCancel'
topLevelType === TOP_MOUSE_UP ||
topLevelType === TOP_TOUCH_END ||
topLevelType === TOP_TOUCH_CANCEL
);
}

export function isMoveish(topLevelType) {
return topLevelType === 'topMouseMove' || topLevelType === 'topTouchMove';
return topLevelType === TOP_MOUSE_MOVE || topLevelType === TOP_TOUCH_MOVE;
}
export function isStartish(topLevelType) {
return topLevelType === 'topMouseDown' || topLevelType === 'topTouchStart';
return topLevelType === TOP_MOUSE_DOWN || topLevelType === TOP_TOUCH_START;
}

let validateEventDispatches;
Expand Down
13 changes: 9 additions & 4 deletions packages/events/ResponderEventPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import {
} from './EventPropagators';
import ResponderSyntheticEvent from './ResponderSyntheticEvent';
import ResponderTouchHistoryStore from './ResponderTouchHistoryStore';
import {
TOP_SCROLL,
TOP_SELECTION_CHANGE,
TOP_TOUCH_CANCEL,
} from './TopLevelEventTypes';
import accumulate from './accumulate';

/**
Expand Down Expand Up @@ -322,7 +327,7 @@ function setResponderAndExtractTransfer(
? eventTypes.startShouldSetResponder
: isMoveish(topLevelType)
? eventTypes.moveShouldSetResponder
: topLevelType === 'topSelectionChange'
: topLevelType === TOP_SELECTION_CHANGE
? eventTypes.selectionChangeShouldSetResponder
: eventTypes.scrollShouldSetResponder;

Expand Down Expand Up @@ -427,8 +432,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))
);
Expand Down Expand Up @@ -534,7 +539,7 @@ const ResponderEventPlugin = {
}

const isResponderTerminate =
responderInst && topLevelType === 'topTouchCancel';
responderInst && topLevelType === TOP_TOUCH_CANCEL;
const isResponderRelease =
responderInst &&
!isResponderTerminate &&
Expand Down
80 changes: 80 additions & 0 deletions packages/events/TopLevelEventTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* 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_ABORT = 0;
export const TOP_ANIMATION_END = 1;
export const TOP_ANIMATION_ITERATION = 2;
export const TOP_ANIMATION_START = 3;
export const TOP_BLUR = 4;
export const TOP_CANCEL = 5;
export const TOP_CAN_PLAY = 6;
export const TOP_CAN_PLAY_THROUGH = 7;
export const TOP_CHANGE = 8;
export const TOP_CLICK = 9;
export const TOP_CLOSE = 10;
export const TOP_COMPOSITION_END = 11;
export const TOP_COMPOSITION_START = 12;
export const TOP_COMPOSITION_UPDATE = 13;
export const TOP_CONTEXT_MENU = 14;
export const TOP_COPY = 15;
export const TOP_CUT = 16;
export const TOP_DOUBLE_CLICK = 17;
export const TOP_DRAG = 18;
export const TOP_DRAG_END = 19;
export const TOP_DRAG_ENTER = 20;
export const TOP_DRAG_EXIT = 21;
export const TOP_DRAG_LEAVE = 22;
export const TOP_DRAG_OVER = 23;
export const TOP_DRAG_START = 24;
export const TOP_DROP = 25;
export const TOP_DURATION_CHANGE = 26;
export const TOP_EMPTIED = 27;
export const TOP_ENCRYPTED = 28;
export const TOP_ENDED = 29;
export const TOP_ERROR = 30;
export const TOP_FOCUS = 31;
export const TOP_INPUT = 32;
export const TOP_INVALID = 33;
export const TOP_KEY_DOWN = 34;
export const TOP_KEY_PRESS = 35;
export const TOP_KEY_UP = 36;
export const TOP_LOADED_DATA = 37;
export const TOP_LOAD = 38;
export const TOP_LOADED_METADATA = 39;
export const TOP_LOAD_START = 40;
export const TOP_MOUSE_DOWN = 41;
export const TOP_MOUSE_MOVE = 42;
export const TOP_MOUSE_OUT = 43;
export const TOP_MOUSE_OVER = 44;
export const TOP_MOUSE_UP = 45;
export const TOP_PASTE = 46;
export const TOP_PAUSE = 47;
export const TOP_PLAY = 48;
export const TOP_PLAYING = 49;
export const TOP_PROGRESS = 50;
export const TOP_RATE_CHANGE = 51;
export const TOP_RESET = 52;
export const TOP_SCROLL = 53;
export const TOP_SEEKED = 54;
export const TOP_SEEKING = 55;
export const TOP_SELECTION_CHANGE = 56;
export const TOP_STALLED = 57;
export const TOP_SUBMIT = 58;
export const TOP_SUSPEND = 59;
export const TOP_TEXT_INPUT = 60;
export const TOP_TIME_UPDATE = 61;
export const TOP_TOGGLE = 62;
export const TOP_TOUCH_CANCEL = 63;
export const TOP_TOUCH_END = 64;
export const TOP_TOUCH_MOVE = 65;
export const TOP_TOUCH_START = 66;
export const TOP_TRANSITION_END = 67;
export const TOP_VOLUME_CHANGE = 68;
export const TOP_WAITING = 69;
export const TOP_WHEEL = 70;
133 changes: 80 additions & 53 deletions packages/react-dom/src/client/ReactDOMFiberComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@
// TODO: direct imports like some-package/src/* are bad. Fix me.
import ReactDebugCurrentFiber from 'react-reconciler/src/ReactDebugCurrentFiber';
import {registrationNameModules} from 'events/EventPluginRegistry';
import {
TOP_ABORT,
TOP_CAN_PLAY,
TOP_CAN_PLAY_THROUGH,
TOP_DURATION_CHANGE,
TOP_EMPTIED,
TOP_ENCRYPTED,
TOP_ENDED,
TOP_ERROR,
TOP_INVALID,
TOP_LOAD,
TOP_LOADED_DATA,
TOP_LOADED_METADATA,
TOP_LOAD_START,
TOP_PAUSE,
TOP_PLAY,
TOP_PLAYING,
TOP_PROGRESS,
TOP_RATE_CHANGE,
TOP_RESET,
TOP_SEEKED,
TOP_SEEKING,
TOP_STALLED,
TOP_SUBMIT,
TOP_SUSPEND,
TOP_TIME_UPDATE,
TOP_TOGGLE,
TOP_VOLUME_CHANGE,
TOP_WAITING,
} from 'events/TopLevelEventTypes';
import emptyFunction from 'fbjs/lib/emptyFunction';
import warning from 'fbjs/lib/warning';

Expand All @@ -22,6 +52,7 @@ import * as inputValueTracking from './inputValueTracking';
import setInnerHTML from './setInnerHTML';
import setTextContent from './setTextContent';
import {listenTo, trapBubbledEvent} from '../events/ReactBrowserEventEmitter';
import {getRawEventName} from '../events/BrowserEventConstants';
import * as CSSPropertyOperations from '../shared/CSSPropertyOperations';
import {Namespaces, getIntrinsicNamespace} from '../shared/DOMNamespaces';
import {
Expand Down Expand Up @@ -224,31 +255,31 @@ function getOwnerDocumentFromRootContainer(

// There are so many media events, it makes sense to just
// maintain a list rather than create a `trapBubbledEvent` for each
const mediaEvents = {
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',
};
const mediaEvents = [
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,
];

function trapClickOnNonInteractiveElement(node: HTMLElement) {
// Mobile Safari does not fire properly bubble click events on
Expand Down Expand Up @@ -465,42 +496,40 @@ export function setInitialProperties(
switch (tag) {
case 'iframe':
case 'object':
trapBubbledEvent('topLoad', 'load', domElement);
trapBubbledEvent(TOP_LOAD, 'load', domElement);
Copy link
Contributor

@aweary aweary Jan 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove all of these event name strings like 'load' if we have trapBubbledEvent/trapCaptureEvent call getRawEventName directly. Assuming we never call it with a mismatched top-level type and event. I don't think we do.

props = rawProps;
break;
case 'video':
case 'audio':
// Create listener for each media event
for (const event in mediaEvents) {
if (mediaEvents.hasOwnProperty(event)) {
trapBubbledEvent(event, mediaEvents[event], domElement);
}
for (let i = 0; i < mediaEvents.length; i++) {
trapBubbledEvent(event, getRawEventName(mediaEvents[i]), domElement);
}
props = rawProps;
break;
case 'source':
trapBubbledEvent('topError', 'error', domElement);
trapBubbledEvent(TOP_ERROR, 'error', domElement);
props = rawProps;
break;
case 'img':
case 'image':
trapBubbledEvent('topError', 'error', domElement);
trapBubbledEvent('topLoad', 'load', domElement);
trapBubbledEvent(TOP_ERROR, 'error', domElement);
trapBubbledEvent(TOP_LOAD, 'load', domElement);
props = rawProps;
break;
case 'form':
trapBubbledEvent('topReset', 'reset', domElement);
trapBubbledEvent('topSubmit', 'submit', domElement);
trapBubbledEvent(TOP_RESET, 'reset', domElement);
trapBubbledEvent(TOP_SUBMIT, 'submit', domElement);
props = rawProps;
break;
case 'details':
trapBubbledEvent('topToggle', 'toggle', domElement);
trapBubbledEvent(TOP_TOGGLE, 'toggle', domElement);
props = rawProps;
break;
case 'input':
ReactDOMFiberInput.initWrapperState(domElement, rawProps);
props = ReactDOMFiberInput.getHostProps(domElement, rawProps);
trapBubbledEvent('topInvalid', 'invalid', domElement);
trapBubbledEvent(TOP_INVALID, 'invalid', domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
Expand All @@ -512,15 +541,15 @@ export function setInitialProperties(
case 'select':
ReactDOMFiberSelect.initWrapperState(domElement, rawProps);
props = ReactDOMFiberSelect.getHostProps(domElement, rawProps);
trapBubbledEvent('topInvalid', 'invalid', domElement);
trapBubbledEvent(TOP_INVALID, '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);
props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps);
trapBubbledEvent('topInvalid', 'invalid', domElement);
trapBubbledEvent(TOP_INVALID, 'invalid', domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
Expand Down Expand Up @@ -842,35 +871,33 @@ export function diffHydratedProperties(
switch (tag) {
case 'iframe':
case 'object':
trapBubbledEvent('topLoad', 'load', domElement);
trapBubbledEvent(TOP_LOAD, 'load', domElement);
break;
case 'video':
case 'audio':
// Create listener for each media event
for (const event in mediaEvents) {
if (mediaEvents.hasOwnProperty(event)) {
trapBubbledEvent(event, mediaEvents[event], domElement);
}
for (let i = 0; i < mediaEvents.length; i++) {
trapBubbledEvent(event, getRawEventName(mediaEvents[i]), domElement);
}
break;
case 'source':
trapBubbledEvent('topError', 'error', domElement);
trapBubbledEvent(TOP_ERROR, 'error', domElement);
break;
case 'img':
case 'image':
trapBubbledEvent('topError', 'error', domElement);
trapBubbledEvent('topLoad', 'load', domElement);
trapBubbledEvent(TOP_ERROR, 'error', domElement);
trapBubbledEvent(TOP_LOAD, 'load', domElement);
break;
case 'form':
trapBubbledEvent('topReset', 'reset', domElement);
trapBubbledEvent('topSubmit', 'submit', domElement);
trapBubbledEvent(TOP_RESET, 'reset', domElement);
trapBubbledEvent(TOP_SUBMIT, 'submit', domElement);
break;
case 'details':
trapBubbledEvent('topToggle', 'toggle', domElement);
trapBubbledEvent(TOP_TOGGLE, 'toggle', domElement);
break;
case 'input':
ReactDOMFiberInput.initWrapperState(domElement, rawProps);
trapBubbledEvent('topInvalid', 'invalid', domElement);
trapBubbledEvent(TOP_INVALID, 'invalid', domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
Expand All @@ -880,14 +907,14 @@ export function diffHydratedProperties(
break;
case 'select':
ReactDOMFiberSelect.initWrapperState(domElement, rawProps);
trapBubbledEvent('topInvalid', 'invalid', domElement);
trapBubbledEvent(TOP_INVALID, '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, 'invalid', domElement);
// For controlled components we always need to ensure we're listening
// to onChange. Even if there is no listener.
ensureListeningTo(rootContainerElement, 'onChange');
Expand Down
Loading