From 68b42c20592cd658f2e08ab72840308b047ab0a1 Mon Sep 17 00:00:00 2001 From: Nathan Hunzaker Date: Wed, 15 Nov 2017 20:13:27 -0500 Subject: [PATCH] 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. --- .../src/client/ReactDOMFiberComponent.js | 12 ++--- .../src/events/BrowserEventConstants.js | 9 ++++ .../src/events/ReactBrowserEventEmitter.js | 46 ++++--------------- 3 files changed, 23 insertions(+), 44 deletions(-) diff --git a/packages/react-dom/src/client/ReactDOMFiberComponent.js b/packages/react-dom/src/client/ReactDOMFiberComponent.js index 4bda1da6bec14..ac0efa8349a37 100644 --- a/packages/react-dom/src/client/ReactDOMFiberComponent.js +++ b/packages/react-dom/src/client/ReactDOMFiberComponent.js @@ -420,14 +420,14 @@ export function setInitialProperties( props = ReactDOMFiberSelect.getHostProps(domElement, rawProps); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. - listenTo('onChange', domElement); + listenTo('onChange', domElement, rootContainerElement); break; case 'textarea': ReactDOMFiberTextarea.initWrapperState(domElement, rawProps); props = ReactDOMFiberTextarea.getHostProps(domElement, rawProps); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. - listenTo('onChange', domElement); + listenTo('onChange', domElement, rootContainerElement); break; default: props = rawProps; @@ -728,7 +728,7 @@ export function diffHydratedProperties( ReactDOMFiberInput.initWrapperState(domElement, rawProps); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. - listenTo('onChange', rootContainerElement); + listenTo('onChange', domElement, rootContainerElement); break; case 'option': ReactDOMFiberOption.validateProps(domElement, rawProps); @@ -737,13 +737,13 @@ export function diffHydratedProperties( ReactDOMFiberSelect.initWrapperState(domElement, rawProps); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. - listenTo('onChange', rootContainerElement); + listenTo('onChange', domElement, rootContainerElement); break; case 'textarea': ReactDOMFiberTextarea.initWrapperState(domElement, rawProps); // For controlled components we always need to ensure we're listening // to onChange. Even if there is no listener. - listenTo('onChange', rootContainerElement); + listenTo('onChange', domElement, rootContainerElement); break; } @@ -810,7 +810,7 @@ export function diffHydratedProperties( if (__DEV__ && typeof nextProp !== 'function') { warnForInvalidEventListener(propKey, nextProp); } - listenTo(propKey, domElement); + listenTo(propKey, domElement, rootContainerElement); } } else if (__DEV__) { // Validate that the properties correspond to their expected values. diff --git a/packages/react-dom/src/events/BrowserEventConstants.js b/packages/react-dom/src/events/BrowserEventConstants.js index 276df6ee76f22..5ba415d730eff 100644 --- a/packages/react-dom/src/events/BrowserEventConstants.js +++ b/packages/react-dom/src/events/BrowserEventConstants.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +import isEventSupported from './isEventSupported'; import getVendorPrefixedEventName from './getVendorPrefixedEventName'; /** @@ -88,6 +89,14 @@ var topLevelTypes = { topWheel: 'wheel', }; +if (isEventSupported('wheel')) { + topLevelTypes.topWheel = 'wheel'; +} else if (isEventSupported('mousewheel')) { + topLevelTypes.topWheel = 'mousewheel'; +} else { + topLevelTypes.topWheel = 'DOMMouseScroll'; +} + export type TopLevelTypes = $Enum; var BrowserEventConstants = { diff --git a/packages/react-dom/src/events/ReactBrowserEventEmitter.js b/packages/react-dom/src/events/ReactBrowserEventEmitter.js index c05eff2c95316..d9f44840f3178 100644 --- a/packages/react-dom/src/events/ReactBrowserEventEmitter.js +++ b/packages/react-dom/src/events/ReactBrowserEventEmitter.js @@ -14,7 +14,6 @@ import { trapCapturedEvent, } from './ReactDOMEventListener'; import {DOCUMENT_NODE, DOCUMENT_FRAGMENT_NODE} from '../shared/HTMLNodeType'; -import isEventSupported from './isEventSupported'; import BrowserEventConstants from './BrowserEventConstants'; export * from 'events/ReactEventEmitterMixin'; @@ -133,52 +132,23 @@ function getListeningForDocument(mountAt) { * @param {string} registrationName Name of listener (e.g. `onClick`). * @param {object} contentDocumentHandle Document which owns the container */ -export function listenTo(registrationName, contentDocumentHandle, root) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); +export function listenTo(registrationName, domElement, rootContainerElement) { + var isListening = getListeningForDocument(domElement); var dependencies = registrationNameDependencies[registrationName]; for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i]; + var eventName = topLevelTypes[dependency]; if (!(isListening.hasOwnProperty(dependency) && isListening[dependency])) { if (forceDelegation.hasOwnProperty(dependency)) { trapBubbledEvent( dependency, - topLevelTypes[dependency], - documentForRoot(root), + eventName, + documentForRoot(rootContainerElement), ); - } else if (dependency === 'topWheel') { - if (isEventSupported('wheel')) { - trapBubbledEvent('topWheel', 'wheel', mountAt); - } else if (isEventSupported('mousewheel')) { - trapBubbledEvent('topWheel', 'mousewheel', mountAt); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - trapBubbledEvent('topWheel', 'DOMMouseScroll', mountAt); - } - } else if (dependency === 'topScroll') { - trapCapturedEvent('topScroll', 'scroll', mountAt); - } else if (dependency === 'topFocus' || dependency === 'topBlur') { - trapCapturedEvent('topFocus', 'focus', mountAt); - trapCapturedEvent('topBlur', 'blur', mountAt); - - // to make sure blur and focus event listeners are only attached once - isListening.topBlur = true; - isListening.topFocus = true; - } else if (dependency === 'topCancel') { - if (isEventSupported('cancel', true)) { - trapCapturedEvent('topCancel', 'cancel', mountAt); - } - isListening.topCancel = true; - } else if (dependency === 'topClose') { - if (isEventSupported('close', true)) { - trapCapturedEvent('topClose', 'close', mountAt); - } - isListening.topClose = true; } else if (topLevelTypes.hasOwnProperty(dependency)) { - trapBubbledEvent(dependency, topLevelTypes[dependency], mountAt); + trapBubbledEvent(dependency, eventName, domElement); } isListening[dependency] = true; @@ -186,8 +156,8 @@ export function listenTo(registrationName, contentDocumentHandle, root) { } } -export function isListeningToAllDependencies(registrationName, mountAt) { - var isListening = getListeningForDocument(mountAt); +export function isListeningToAllDependencies(registrationName, domElement) { + var isListening = getListeningForDocument(domElement); var dependencies = registrationNameDependencies[registrationName]; for (var i = 0; i < dependencies.length; i++) { var dependency = dependencies[i];