Skip to content

Commit 86d7203

Browse files
committed
Refactor DOM plugin system to single module
1 parent a607ea4 commit 86d7203

14 files changed

+453
-383
lines changed

packages/legacy-events/EventPluginHub.js

Lines changed: 0 additions & 176 deletions
This file was deleted.

packages/legacy-events/EventPluginRegistry.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,6 @@ export const possibleRegistrationNames = __DEV__ ? {} : (null: any);
193193
*
194194
* @param {array} InjectedEventPluginOrder
195195
* @internal
196-
* @see {EventPluginHub.injection.injectEventPluginOrder}
197196
*/
198197
export function injectEventPluginOrder(
199198
injectedEventPluginOrder: EventPluginOrder,
@@ -209,14 +208,13 @@ export function injectEventPluginOrder(
209208
}
210209

211210
/**
212-
* Injects plugins to be used by `EventPluginHub`. The plugin names must be
211+
* Injects plugins to be used by plugin event system. The plugin names must be
213212
* in the ordering injected by `injectEventPluginOrder`.
214213
*
215214
* Plugins can be injected as part of page initialization or on-the-fly.
216215
*
217216
* @param {object} injectedNamesToPlugins Map from names to plugin modules.
218217
* @internal
219-
* @see {EventPluginHub.injection.injectEventPluginsByName}
220218
*/
221219
export function injectEventPluginsByName(
222220
injectedNamesToPlugins: NamesToPlugins,

packages/legacy-events/EventPropagators.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
traverseEnterLeave,
1212
} from 'shared/ReactTreeTraversal';
1313

14-
import {getListener} from './EventPluginHub';
14+
import getListener from 'legacy-events/getListener';
1515
import accumulateInto from './accumulateInto';
1616
import forEachAccumulated from './forEachAccumulated';
1717

packages/legacy-events/getListener.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
* @flow
7+
*/
8+
9+
import type {Fiber} from 'react-reconciler/src/ReactFiber';
10+
11+
import invariant from 'shared/invariant';
12+
13+
import {getFiberCurrentPropsFromNode} from './EventPluginUtils';
14+
15+
function isInteractive(tag) {
16+
return (
17+
tag === 'button' ||
18+
tag === 'input' ||
19+
tag === 'select' ||
20+
tag === 'textarea'
21+
);
22+
}
23+
24+
function shouldPreventMouseEvent(name, type, props) {
25+
switch (name) {
26+
case 'onClick':
27+
case 'onClickCapture':
28+
case 'onDoubleClick':
29+
case 'onDoubleClickCapture':
30+
case 'onMouseDown':
31+
case 'onMouseDownCapture':
32+
case 'onMouseMove':
33+
case 'onMouseMoveCapture':
34+
case 'onMouseUp':
35+
case 'onMouseUpCapture':
36+
case 'onMouseEnter':
37+
return !!(props.disabled && isInteractive(type));
38+
default:
39+
return false;
40+
}
41+
}
42+
43+
/**
44+
* @param {object} inst The instance, which is the source of events.
45+
* @param {string} registrationName Name of listener (e.g. `onClick`).
46+
* @return {?function} The stored callback.
47+
*/
48+
export default function getListener(inst: Fiber, registrationName: string) {
49+
let listener;
50+
51+
// TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
52+
// live here; needs to be moved to a better place soon
53+
const stateNode = inst.stateNode;
54+
if (!stateNode) {
55+
// Work in progress (ex: onload events in incremental mode).
56+
return null;
57+
}
58+
const props = getFiberCurrentPropsFromNode(stateNode);
59+
if (!props) {
60+
// Work in progress.
61+
return null;
62+
}
63+
listener = props[registrationName];
64+
if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
65+
return null;
66+
}
67+
invariant(
68+
!listener || typeof listener === 'function',
69+
'Expected `%s` listener to be a function, instead got a value of `%s` type.',
70+
registrationName,
71+
typeof listener,
72+
);
73+
return listener;
74+
}

packages/react-dom/src/__tests__/ReactBrowserEventEmitter-test.internal.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
'use strict';
1111

12-
let EventPluginHub;
12+
let EventPluginGetListener;
1313
let EventPluginRegistry;
1414
let React;
1515
let ReactDOM;
@@ -58,7 +58,7 @@ describe('ReactBrowserEventEmitter', () => {
5858
LISTENER.mockClear();
5959

6060
// TODO: can we express this test with only public API?
61-
EventPluginHub = require('legacy-events/EventPluginHub');
61+
EventPluginGetListener = require('legacy-events/getListener').default;
6262
EventPluginRegistry = require('legacy-events/EventPluginRegistry');
6363
React = require('react');
6464
ReactDOM = require('react-dom');
@@ -100,7 +100,7 @@ describe('ReactBrowserEventEmitter', () => {
100100

101101
getListener = function(node, eventName) {
102102
const inst = ReactDOMComponentTree.getInstanceFromNode(node);
103-
return EventPluginHub.getListener(inst, eventName);
103+
return EventPluginGetListener(inst, eventName);
104104
};
105105
putListener = function(node, eventName, listener) {
106106
switch (node) {

packages/react-dom/src/client/ReactDOM.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ import {
4545
enqueueStateRestore,
4646
restoreStateIfNeeded,
4747
} from 'legacy-events/ReactControlledComponent';
48-
import {injection as EventPluginHubInjection} from 'legacy-events/EventPluginHub';
4948
import {runEventsInBatch} from 'legacy-events/EventBatching';
50-
import {eventNameDispatchConfigs} from 'legacy-events/EventPluginRegistry';
49+
import {
50+
eventNameDispatchConfigs,
51+
injectEventPluginsByName,
52+
} from 'legacy-events/EventPluginRegistry';
5153
import {
5254
accumulateTwoPhaseDispatches,
5355
accumulateDirectDispatches,
@@ -150,7 +152,7 @@ const ReactDOM: Object = {
150152
getInstanceFromNode,
151153
getNodeFromInstance,
152154
getFiberCurrentPropsFromNode,
153-
EventPluginHubInjection.injectEventPluginsByName,
155+
injectEventPluginsByName,
154156
eventNameDispatchConfigs,
155157
accumulateTwoPhaseDispatches,
156158
accumulateDirectDispatches,

packages/react-dom/src/client/ReactDOMClientInjection.js

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* LICENSE file in the root directory of this source tree.
66
*/
77

8-
import {injection as EventPluginHubInjection} from 'legacy-events/EventPluginHub';
98
import {setComponentTree} from 'legacy-events/EventPluginUtils';
109

1110
import {
@@ -15,15 +14,35 @@ import {
1514
} from './ReactDOMComponentTree';
1615
import BeforeInputEventPlugin from '../events/BeforeInputEventPlugin';
1716
import ChangeEventPlugin from '../events/ChangeEventPlugin';
18-
import DOMEventPluginOrder from '../events/DOMEventPluginOrder';
1917
import EnterLeaveEventPlugin from '../events/EnterLeaveEventPlugin';
2018
import SelectEventPlugin from '../events/SelectEventPlugin';
2119
import SimpleEventPlugin from '../events/SimpleEventPlugin';
20+
import {
21+
injectEventPluginOrder,
22+
injectEventPluginsByName,
23+
} from 'legacy-events/EventPluginRegistry';
24+
25+
/**
26+
* Specifies a deterministic ordering of `EventPlugin`s. A convenient way to
27+
* reason about plugins, without having to package every one of them. This
28+
* is better than having plugins be ordered in the same order that they
29+
* are injected because that ordering would be influenced by the packaging order.
30+
* `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
31+
* preventing default on events is convenient in `SimpleEventPlugin` handlers.
32+
*/
33+
const DOMEventPluginOrder = [
34+
'ResponderEventPlugin',
35+
'SimpleEventPlugin',
36+
'EnterLeaveEventPlugin',
37+
'ChangeEventPlugin',
38+
'SelectEventPlugin',
39+
'BeforeInputEventPlugin',
40+
];
2241

2342
/**
2443
* Inject modules for resolving DOM hierarchy and plugin ordering.
2544
*/
26-
EventPluginHubInjection.injectEventPluginOrder(DOMEventPluginOrder);
45+
injectEventPluginOrder(DOMEventPluginOrder);
2746
setComponentTree(
2847
getFiberCurrentPropsFromNode,
2948
getInstanceFromNode,
@@ -34,7 +53,7 @@ setComponentTree(
3453
* Some important event plugins included by default (without having to require
3554
* them).
3655
*/
37-
EventPluginHubInjection.injectEventPluginsByName({
56+
injectEventPluginsByName({
3857
SimpleEventPlugin: SimpleEventPlugin,
3958
EnterLeaveEventPlugin: EnterLeaveEventPlugin,
4059
ChangeEventPlugin: ChangeEventPlugin,

0 commit comments

Comments
 (0)