mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Remove SyntheticEvent subtypes (#19436)
* Remove SyntheticEvent subtypes * Code golf
This commit is contained in:
+97
-118
@@ -14,20 +14,15 @@ import getEventCharCode from './getEventCharCode';
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
const EventInterface = {
|
||||
type: null,
|
||||
target: null,
|
||||
// currentTarget is set when dispatching; no use in copying it here
|
||||
currentTarget: function() {
|
||||
return null;
|
||||
},
|
||||
eventPhase: null,
|
||||
bubbles: null,
|
||||
cancelable: null,
|
||||
type: 0,
|
||||
eventPhase: 0,
|
||||
bubbles: 0,
|
||||
cancelable: 0,
|
||||
timeStamp: function(event) {
|
||||
return event.timeStamp || Date.now();
|
||||
},
|
||||
defaultPrevented: null,
|
||||
isTrusted: null,
|
||||
defaultPrevented: 0,
|
||||
isTrusted: 0,
|
||||
};
|
||||
|
||||
function functionThatReturnsTrue() {
|
||||
@@ -56,12 +51,14 @@ export function SyntheticEvent(
|
||||
targetInst,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
Interface = EventInterface,
|
||||
) {
|
||||
this._reactName = reactName;
|
||||
this._targetInst = targetInst;
|
||||
this.nativeEvent = nativeEvent;
|
||||
this.target = nativeEventTarget;
|
||||
this.currentTarget = null;
|
||||
|
||||
const Interface = this.constructor.Interface;
|
||||
for (const propName in Interface) {
|
||||
if (!Interface.hasOwnProperty(propName)) {
|
||||
continue;
|
||||
@@ -70,11 +67,7 @@ export function SyntheticEvent(
|
||||
if (normalize) {
|
||||
this[propName] = normalize(nativeEvent);
|
||||
} else {
|
||||
if (propName === 'target') {
|
||||
this.target = nativeEventTarget;
|
||||
} else {
|
||||
this[propName] = nativeEvent[propName];
|
||||
}
|
||||
this[propName] = nativeEvent[propName];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,36 +137,12 @@ Object.assign(SyntheticEvent.prototype, {
|
||||
isPersistent: functionThatReturnsTrue,
|
||||
});
|
||||
|
||||
SyntheticEvent.Interface = EventInterface;
|
||||
|
||||
/**
|
||||
* Helper to reduce boilerplate when creating subclasses.
|
||||
*/
|
||||
SyntheticEvent.extend = function(Interface) {
|
||||
const Super = this;
|
||||
|
||||
const E = function() {};
|
||||
E.prototype = Super.prototype;
|
||||
const prototype = new E();
|
||||
|
||||
function Class() {
|
||||
return Super.apply(this, arguments);
|
||||
}
|
||||
Object.assign(prototype, Class.prototype);
|
||||
Class.prototype = prototype;
|
||||
Class.prototype.constructor = Class;
|
||||
|
||||
Class.Interface = Object.assign({}, Super.Interface, Interface);
|
||||
Class.extend = Super.extend;
|
||||
|
||||
return Class;
|
||||
export const UIEventInterface = {
|
||||
...EventInterface,
|
||||
view: 0,
|
||||
detail: 0,
|
||||
};
|
||||
|
||||
export const SyntheticUIEvent = SyntheticEvent.extend({
|
||||
view: null,
|
||||
detail: null,
|
||||
});
|
||||
|
||||
let previousScreenX = 0;
|
||||
let previousScreenY = 0;
|
||||
// Use flags to signal movementX/Y has already been set
|
||||
@@ -184,20 +153,21 @@ let isMovementYSet = false;
|
||||
* @interface MouseEvent
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
export const SyntheticMouseEvent = SyntheticUIEvent.extend({
|
||||
screenX: null,
|
||||
screenY: null,
|
||||
clientX: null,
|
||||
clientY: null,
|
||||
pageX: null,
|
||||
pageY: null,
|
||||
ctrlKey: null,
|
||||
shiftKey: null,
|
||||
altKey: null,
|
||||
metaKey: null,
|
||||
export const MouseEventInterface = {
|
||||
...UIEventInterface,
|
||||
screenX: 0,
|
||||
screenY: 0,
|
||||
clientX: 0,
|
||||
clientY: 0,
|
||||
pageX: 0,
|
||||
pageY: 0,
|
||||
ctrlKey: 0,
|
||||
shiftKey: 0,
|
||||
altKey: 0,
|
||||
metaKey: 0,
|
||||
getModifierState: getEventModifierState,
|
||||
button: null,
|
||||
buttons: null,
|
||||
button: 0,
|
||||
buttons: 0,
|
||||
relatedTarget: function(event) {
|
||||
return (
|
||||
event.relatedTarget ||
|
||||
@@ -236,63 +206,67 @@ export const SyntheticMouseEvent = SyntheticUIEvent.extend({
|
||||
|
||||
return event.type === 'mousemove' ? event.screenY - screenY : 0;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface DragEvent
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
export const SyntheticDragEvent = SyntheticMouseEvent.extend({
|
||||
dataTransfer: null,
|
||||
});
|
||||
export const DragEventInterface = {
|
||||
...MouseEventInterface,
|
||||
dataTransfer: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface FocusEvent
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
export const SyntheticFocusEvent = SyntheticUIEvent.extend({
|
||||
relatedTarget: null,
|
||||
});
|
||||
export const FocusEventInterface = {
|
||||
...UIEventInterface,
|
||||
relatedTarget: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface Event
|
||||
* @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
|
||||
*/
|
||||
export const SyntheticAnimationEvent = SyntheticEvent.extend({
|
||||
animationName: null,
|
||||
elapsedTime: null,
|
||||
pseudoElement: null,
|
||||
});
|
||||
export const AnimationEventInterface = {
|
||||
...EventInterface,
|
||||
animationName: 0,
|
||||
elapsedTime: 0,
|
||||
pseudoElement: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface Event
|
||||
* @see http://www.w3.org/TR/clipboard-apis/
|
||||
*/
|
||||
export const SyntheticClipboardEvent = SyntheticEvent.extend({
|
||||
export const ClipboardEventInterface = {
|
||||
...EventInterface,
|
||||
clipboardData: function(event) {
|
||||
return 'clipboardData' in event
|
||||
? event.clipboardData
|
||||
: window.clipboardData;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface Event
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
|
||||
*/
|
||||
export const SyntheticCompositionEvent = SyntheticEvent.extend({
|
||||
data: null,
|
||||
});
|
||||
export const CompositionEventInterface = {
|
||||
...EventInterface,
|
||||
data: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface Event
|
||||
* @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
|
||||
* /#events-inputevents
|
||||
*/
|
||||
export const SyntheticInputEvent = SyntheticEvent.extend({
|
||||
data: null,
|
||||
});
|
||||
// Happens to share the same list for now.
|
||||
export const InputEventInterface = CompositionEventInterface;
|
||||
|
||||
/**
|
||||
* Normalization of deprecated HTML5 `key` values
|
||||
@@ -422,16 +396,17 @@ function getEventModifierState(nativeEvent) {
|
||||
* @interface KeyboardEvent
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
export const SyntheticKeyboardEvent = SyntheticUIEvent.extend({
|
||||
export const KeyboardEventInterface = {
|
||||
...UIEventInterface,
|
||||
key: getEventKey,
|
||||
code: null,
|
||||
location: null,
|
||||
ctrlKey: null,
|
||||
shiftKey: null,
|
||||
altKey: null,
|
||||
metaKey: null,
|
||||
repeat: null,
|
||||
locale: null,
|
||||
code: 0,
|
||||
location: 0,
|
||||
ctrlKey: 0,
|
||||
shiftKey: 0,
|
||||
altKey: 0,
|
||||
metaKey: 0,
|
||||
repeat: 0,
|
||||
locale: 0,
|
||||
getModifierState: getEventModifierState,
|
||||
// Legacy Interface
|
||||
charCode: function(event) {
|
||||
@@ -469,56 +444,60 @@ export const SyntheticKeyboardEvent = SyntheticUIEvent.extend({
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface PointerEvent
|
||||
* @see http://www.w3.org/TR/pointerevents/
|
||||
*/
|
||||
export const SyntheticPointerEvent = SyntheticMouseEvent.extend({
|
||||
pointerId: null,
|
||||
width: null,
|
||||
height: null,
|
||||
pressure: null,
|
||||
tangentialPressure: null,
|
||||
tiltX: null,
|
||||
tiltY: null,
|
||||
twist: null,
|
||||
pointerType: null,
|
||||
isPrimary: null,
|
||||
});
|
||||
export const PointerEventInterface = {
|
||||
...MouseEventInterface,
|
||||
pointerId: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
pressure: 0,
|
||||
tangentialPressure: 0,
|
||||
tiltX: 0,
|
||||
tiltY: 0,
|
||||
twist: 0,
|
||||
pointerType: 0,
|
||||
isPrimary: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface TouchEvent
|
||||
* @see http://www.w3.org/TR/touch-events/
|
||||
*/
|
||||
export const SyntheticTouchEvent = SyntheticUIEvent.extend({
|
||||
touches: null,
|
||||
targetTouches: null,
|
||||
changedTouches: null,
|
||||
altKey: null,
|
||||
metaKey: null,
|
||||
ctrlKey: null,
|
||||
shiftKey: null,
|
||||
export const TouchEventInterface = {
|
||||
...UIEventInterface,
|
||||
touches: 0,
|
||||
targetTouches: 0,
|
||||
changedTouches: 0,
|
||||
altKey: 0,
|
||||
metaKey: 0,
|
||||
ctrlKey: 0,
|
||||
shiftKey: 0,
|
||||
getModifierState: getEventModifierState,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface Event
|
||||
* @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
|
||||
*/
|
||||
export const SyntheticTransitionEvent = SyntheticEvent.extend({
|
||||
propertyName: null,
|
||||
elapsedTime: null,
|
||||
pseudoElement: null,
|
||||
});
|
||||
export const TransitionEventInterface = {
|
||||
...EventInterface,
|
||||
propertyName: 0,
|
||||
elapsedTime: 0,
|
||||
pseudoElement: 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* @interface WheelEvent
|
||||
* @see http://www.w3.org/TR/DOM-Level-3-Events/
|
||||
*/
|
||||
export const SyntheticWheelEvent = SyntheticMouseEvent.extend({
|
||||
export const WheelEventInterface = {
|
||||
...MouseEventInterface,
|
||||
deltaX(event) {
|
||||
return 'deltaX' in event
|
||||
? event.deltaX
|
||||
@@ -538,11 +517,11 @@ export const SyntheticWheelEvent = SyntheticMouseEvent.extend({
|
||||
? -event.wheelDelta
|
||||
: 0;
|
||||
},
|
||||
deltaZ: null,
|
||||
deltaZ: 0,
|
||||
|
||||
// Browsers without "deltaMode" is reporting in raw wheel delta where one
|
||||
// notch on the scroll is always +/- 120, roughly equivalent to pixels.
|
||||
// A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
|
||||
// ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
|
||||
deltaMode: null,
|
||||
});
|
||||
deltaMode: 0,
|
||||
};
|
||||
|
||||
@@ -28,8 +28,9 @@ import {
|
||||
reset as FallbackCompositionStateReset,
|
||||
} from '../FallbackCompositionState';
|
||||
import {
|
||||
SyntheticCompositionEvent,
|
||||
SyntheticInputEvent,
|
||||
CompositionEventInterface,
|
||||
InputEventInterface,
|
||||
SyntheticEvent,
|
||||
} from '../SyntheticEvent';
|
||||
import {accumulateTwoPhaseListeners} from '../DOMPluginEventSystem';
|
||||
|
||||
@@ -237,11 +238,12 @@ function extractCompositionEvent(
|
||||
}
|
||||
}
|
||||
|
||||
const event = new SyntheticCompositionEvent(
|
||||
const event = new SyntheticEvent(
|
||||
eventType,
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
CompositionEventInterface,
|
||||
);
|
||||
accumulateTwoPhaseListeners(targetInst, dispatchQueue, event);
|
||||
|
||||
@@ -407,11 +409,12 @@ function extractBeforeInputEvent(
|
||||
return null;
|
||||
}
|
||||
|
||||
const event = new SyntheticInputEvent(
|
||||
const event = new SyntheticEvent(
|
||||
'onBeforeInput',
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
InputEventInterface,
|
||||
);
|
||||
accumulateTwoPhaseListeners(targetInst, dispatchQueue, event);
|
||||
event.data = chars;
|
||||
|
||||
@@ -13,7 +13,11 @@ import {
|
||||
TOP_POINTER_OVER,
|
||||
} from '../DOMTopLevelEventTypes';
|
||||
import {IS_REPLAYED} from 'react-dom/src/events/EventSystemFlags';
|
||||
import {SyntheticMouseEvent, SyntheticPointerEvent} from '../SyntheticEvent';
|
||||
import {
|
||||
SyntheticEvent,
|
||||
MouseEventInterface,
|
||||
PointerEventInterface,
|
||||
} from '../SyntheticEvent';
|
||||
import {
|
||||
getClosestInstanceFromNode,
|
||||
getNodeFromInstance,
|
||||
@@ -113,7 +117,7 @@ function extractEvents(
|
||||
let eventInterface, leaveEventType, enterEventType, eventTypePrefix;
|
||||
|
||||
if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
|
||||
eventInterface = SyntheticMouseEvent;
|
||||
eventInterface = MouseEventInterface;
|
||||
leaveEventType = 'onMouseLeave';
|
||||
enterEventType = 'onMouseEnter';
|
||||
eventTypePrefix = 'mouse';
|
||||
@@ -121,7 +125,7 @@ function extractEvents(
|
||||
topLevelType === TOP_POINTER_OUT ||
|
||||
topLevelType === TOP_POINTER_OVER
|
||||
) {
|
||||
eventInterface = SyntheticPointerEvent;
|
||||
eventInterface = PointerEventInterface;
|
||||
leaveEventType = 'onPointerLeave';
|
||||
enterEventType = 'onPointerEnter';
|
||||
eventTypePrefix = 'pointer';
|
||||
@@ -130,21 +134,23 @@ function extractEvents(
|
||||
const fromNode = from == null ? win : getNodeFromInstance(from);
|
||||
const toNode = to == null ? win : getNodeFromInstance(to);
|
||||
|
||||
const leave = new eventInterface(
|
||||
const leave = new SyntheticEvent(
|
||||
leaveEventType,
|
||||
from,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
eventInterface,
|
||||
);
|
||||
leave.type = eventTypePrefix + 'leave';
|
||||
leave.target = fromNode;
|
||||
leave.relatedTarget = toNode;
|
||||
|
||||
let enter = new eventInterface(
|
||||
let enter = new SyntheticEvent(
|
||||
enterEventType,
|
||||
to,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
eventInterface,
|
||||
);
|
||||
enter.type = eventTypePrefix + 'enter';
|
||||
enter.target = toNode;
|
||||
|
||||
+25
-25
@@ -15,17 +15,17 @@ import type {EventSystemFlags} from '../EventSystemFlags';
|
||||
|
||||
import {
|
||||
SyntheticEvent,
|
||||
SyntheticAnimationEvent,
|
||||
SyntheticClipboardEvent,
|
||||
SyntheticFocusEvent,
|
||||
SyntheticKeyboardEvent,
|
||||
SyntheticMouseEvent,
|
||||
SyntheticPointerEvent,
|
||||
SyntheticDragEvent,
|
||||
SyntheticTouchEvent,
|
||||
SyntheticTransitionEvent,
|
||||
SyntheticUIEvent,
|
||||
SyntheticWheelEvent,
|
||||
AnimationEventInterface,
|
||||
ClipboardEventInterface,
|
||||
FocusEventInterface,
|
||||
KeyboardEventInterface,
|
||||
MouseEventInterface,
|
||||
PointerEventInterface,
|
||||
DragEventInterface,
|
||||
TouchEventInterface,
|
||||
TransitionEventInterface,
|
||||
UIEventInterface,
|
||||
WheelEventInterface,
|
||||
} from '../../events/SyntheticEvent';
|
||||
|
||||
import * as DOMTopLevelEventTypes from '../DOMTopLevelEventTypes';
|
||||
@@ -57,7 +57,7 @@ function extractEvents(
|
||||
if (reactName === undefined) {
|
||||
return;
|
||||
}
|
||||
let EventConstructor;
|
||||
let EventInterface;
|
||||
switch (topLevelType) {
|
||||
case DOMTopLevelEventTypes.TOP_KEY_PRESS:
|
||||
// Firefox creates a keypress event for function keys too. This removes
|
||||
@@ -69,13 +69,13 @@ function extractEvents(
|
||||
/* falls through */
|
||||
case DOMTopLevelEventTypes.TOP_KEY_DOWN:
|
||||
case DOMTopLevelEventTypes.TOP_KEY_UP:
|
||||
EventConstructor = SyntheticKeyboardEvent;
|
||||
EventInterface = KeyboardEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_FOCUS_IN:
|
||||
case DOMTopLevelEventTypes.TOP_FOCUS_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_BEFORE_BLUR:
|
||||
case DOMTopLevelEventTypes.TOP_AFTER_BLUR:
|
||||
EventConstructor = SyntheticFocusEvent;
|
||||
EventInterface = FocusEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_CLICK:
|
||||
// Firefox creates a click event on right mouse clicks. This removes the
|
||||
@@ -94,7 +94,7 @@ function extractEvents(
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_MOUSE_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_CONTEXT_MENU:
|
||||
EventConstructor = SyntheticMouseEvent;
|
||||
EventInterface = MouseEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_DRAG:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_END:
|
||||
@@ -104,32 +104,32 @@ function extractEvents(
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_DRAG_START:
|
||||
case DOMTopLevelEventTypes.TOP_DROP:
|
||||
EventConstructor = SyntheticDragEvent;
|
||||
EventInterface = DragEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_CANCEL:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_END:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_MOVE:
|
||||
case DOMTopLevelEventTypes.TOP_TOUCH_START:
|
||||
EventConstructor = SyntheticTouchEvent;
|
||||
EventInterface = TouchEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_END:
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_ITERATION:
|
||||
case DOMTopLevelEventTypes.TOP_ANIMATION_START:
|
||||
EventConstructor = SyntheticAnimationEvent;
|
||||
EventInterface = AnimationEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_TRANSITION_END:
|
||||
EventConstructor = SyntheticTransitionEvent;
|
||||
EventInterface = TransitionEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_SCROLL:
|
||||
EventConstructor = SyntheticUIEvent;
|
||||
EventInterface = UIEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_WHEEL:
|
||||
EventConstructor = SyntheticWheelEvent;
|
||||
EventInterface = WheelEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_COPY:
|
||||
case DOMTopLevelEventTypes.TOP_CUT:
|
||||
case DOMTopLevelEventTypes.TOP_PASTE:
|
||||
EventConstructor = SyntheticClipboardEvent;
|
||||
EventInterface = ClipboardEventInterface;
|
||||
break;
|
||||
case DOMTopLevelEventTypes.TOP_GOT_POINTER_CAPTURE:
|
||||
case DOMTopLevelEventTypes.TOP_LOST_POINTER_CAPTURE:
|
||||
@@ -139,18 +139,18 @@ function extractEvents(
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_OUT:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_OVER:
|
||||
case DOMTopLevelEventTypes.TOP_POINTER_UP:
|
||||
EventConstructor = SyntheticPointerEvent;
|
||||
EventInterface = PointerEventInterface;
|
||||
break;
|
||||
default:
|
||||
// Unknown event. This is used by createEventHandle.
|
||||
EventConstructor = SyntheticEvent;
|
||||
break;
|
||||
}
|
||||
const event = new EventConstructor(
|
||||
const event = new SyntheticEvent(
|
||||
reactName,
|
||||
null,
|
||||
nativeEvent,
|
||||
nativeEventTarget,
|
||||
EventInterface,
|
||||
);
|
||||
|
||||
const inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
|
||||
|
||||
Reference in New Issue
Block a user