Skip to content

Commit 68b42c2

Browse files
committed
Use consistent invocation of listenTo(). Move event support checks.
This commit corrects the use of listenTo() when attaching change events. It additionally moves the logic to check for wheel, scroll, and other support, to BrowserEventConstants.
1 parent 85fd3ed commit 68b42c2

3 files changed

Lines changed: 23 additions & 44 deletions

File tree

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -420,14 +420,14 @@ export function setInitialProperties(
420420
props = ReactDOMFiberSelect.getHostProps(domElement, rawProps);
421421
// For controlled components we always need to ensure we're listening
422422
// to onChange. Even if there is no listener.
423-
listenTo('onChange', domElement);
423+
listenTo('onChange', domElement, rootContainerElement);
424424
break;
425425
case 'textarea':
426426
ReactDOMFiberTextarea.initWrapperState(domElement, rawProps);
427427
props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps);
428428
// For controlled components we always need to ensure we're listening
429429
// to onChange. Even if there is no listener.
430-
listenTo('onChange', domElement);
430+
listenTo('onChange', domElement, rootContainerElement);
431431
break;
432432
default:
433433
props = rawProps;
@@ -728,7 +728,7 @@ export function diffHydratedProperties(
728728
ReactDOMFiberInput.initWrapperState(domElement, rawProps);
729729
// For controlled components we always need to ensure we're listening
730730
// to onChange. Even if there is no listener.
731-
listenTo('onChange', rootContainerElement);
731+
listenTo('onChange', domElement, rootContainerElement);
732732
break;
733733
case 'option':
734734
ReactDOMFiberOption.validateProps(domElement, rawProps);
@@ -737,13 +737,13 @@ export function diffHydratedProperties(
737737
ReactDOMFiberSelect.initWrapperState(domElement, rawProps);
738738
// For controlled components we always need to ensure we're listening
739739
// to onChange. Even if there is no listener.
740-
listenTo('onChange', rootContainerElement);
740+
listenTo('onChange', domElement, rootContainerElement);
741741
break;
742742
case 'textarea':
743743
ReactDOMFiberTextarea.initWrapperState(domElement, rawProps);
744744
// For controlled components we always need to ensure we're listening
745745
// to onChange. Even if there is no listener.
746-
listenTo('onChange', rootContainerElement);
746+
listenTo('onChange', domElement, rootContainerElement);
747747
break;
748748
}
749749

@@ -810,7 +810,7 @@ export function diffHydratedProperties(
810810
if (__DEV__ && typeof nextProp !== 'function') {
811811
warnForInvalidEventListener(propKey, nextProp);
812812
}
813-
listenTo(propKey, domElement);
813+
listenTo(propKey, domElement, rootContainerElement);
814814
}
815815
} else if (__DEV__) {
816816
// Validate that the properties correspond to their expected values.

packages/react-dom/src/events/BrowserEventConstants.js

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

8+
import isEventSupported from './isEventSupported';
89
import getVendorPrefixedEventName from './getVendorPrefixedEventName';
910

1011
/**
@@ -88,6 +89,14 @@ var topLevelTypes = {
8889
topWheel: 'wheel',
8990
};
9091

92+
if (isEventSupported('wheel')) {
93+
topLevelTypes.topWheel = 'wheel';
94+
} else if (isEventSupported('mousewheel')) {
95+
topLevelTypes.topWheel = 'mousewheel';
96+
} else {
97+
topLevelTypes.topWheel = 'DOMMouseScroll';
98+
}
99+
91100
export type TopLevelTypes = $Enum<typeof topLevelTypes>;
92101

93102
var BrowserEventConstants = {

packages/react-dom/src/events/ReactBrowserEventEmitter.js

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import {
1414
trapCapturedEvent,
1515
} from './ReactDOMEventListener';
1616
import {DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE} from '../shared/HTMLNodeType';
17-
import isEventSupported from './isEventSupported';
1817
import BrowserEventConstants from './BrowserEventConstants';
1918

2019
export * from 'events/ReactEventEmitterMixin';
@@ -133,61 +132,32 @@ function getListeningForDocument(mountAt) {
133132
* @param {string} registrationName Name of listener (e.g. `onClick`).
134133
* @param {object} contentDocumentHandle Document which owns the container
135134
*/
136-
export function listenTo(registrationName, contentDocumentHandle, root) {
137-
var mountAt = contentDocumentHandle;
138-
var isListening = getListeningForDocument(mountAt);
135+
export function listenTo(registrationName, domElement, rootContainerElement) {
136+
var isListening = getListeningForDocument(domElement);
139137
var dependencies = registrationNameDependencies[registrationName];
140138

141139
for (var i = 0; i < dependencies.length; i++) {
142140
var dependency = dependencies[i];
141+
var eventName = topLevelTypes[dependency];
143142

144143
if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) {
145144
if (forceDelegation.hasOwnProperty(dependency)) {
146145
trapBubbledEvent(
147146
dependency,
148-
topLevelTypes[dependency],
149-
documentForRoot(root),
147+
eventName,
148+
documentForRoot(rootContainerElement),
150149
);
151-
} else if (dependency === 'topWheel') {
152-
if (isEventSupported('wheel')) {
153-
trapBubbledEvent('topWheel', 'wheel', mountAt);
154-
} else if (isEventSupported('mousewheel')) {
155-
trapBubbledEvent('topWheel', 'mousewheel', mountAt);
156-
} else {
157-
// Firefox needs to capture a different mouse scroll event.
158-
// @see http://www.quirksmode.org/dom/events/tests/scroll.html
159-
trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt);
160-
}
161-
} else if (dependency === 'topScroll') {
162-
trapCapturedEvent('topScroll', 'scroll', mountAt);
163-
} else if (dependency === 'topFocus' || dependency === 'topBlur') {
164-
trapCapturedEvent('topFocus', 'focus', mountAt);
165-
trapCapturedEvent('topBlur', 'blur', mountAt);
166-
167-
// to make sure blur and focus event listeners are only attached once
168-
isListening.topBlur = true;
169-
isListening.topFocus = true;
170-
} else if (dependency === 'topCancel') {
171-
if (isEventSupported('cancel', true)) {
172-
trapCapturedEvent('topCancel', 'cancel', mountAt);
173-
}
174-
isListening.topCancel = true;
175-
} else if (dependency === 'topClose') {
176-
if (isEventSupported('close', true)) {
177-
trapCapturedEvent('topClose', 'close', mountAt);
178-
}
179-
isListening.topClose = true;
180150
} else if (topLevelTypes.hasOwnProperty(dependency)) {
181-
trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt);
151+
trapBubbledEvent(dependency, eventName, domElement);
182152
}
183153

184154
isListening[dependency] = true;
185155
}
186156
}
187157
}
188158

189-
export function isListeningToAllDependencies(registrationName, mountAt) {
190-
var isListening = getListeningForDocument(mountAt);
159+
export function isListeningToAllDependencies(registrationName, domElement) {
160+
var isListening = getListeningForDocument(domElement);
191161
var dependencies = registrationNameDependencies[registrationName];
192162
for (var i = 0; i < dependencies.length; i++) {
193163
var dependency = dependencies[i];

0 commit comments

Comments
 (0)