From 05344faca42468ff7e9225fa26d79fb89377c0cb Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 27 Jul 2020 15:03:11 +0100 Subject: [PATCH] Follow up fix to 19452 (#19454) --- .../src/__tests__/ReactDOMEventListener-test.js | 14 +++++++++++++- .../react-dom/src/events/DOMPluginEventSystem.js | 3 --- .../src/events/plugins/SimpleEventPlugin.js | 8 ++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js b/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js index 1b92c0ff53..86ddbbff30 100644 --- a/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMEventListener-test.js @@ -595,7 +595,8 @@ describe('ReactDOMEventListener', () => { const container = document.createElement('div'); const innerRef = React.createRef(); const outerRef = React.createRef(); - const onPlayCapture = jest.fn(); + const onPlayCapture = jest.fn(e => log.push(e.currentTarget)); + const log = []; document.body.appendChild(container); try { ReactDOM.render( @@ -612,12 +613,23 @@ describe('ReactDOMEventListener', () => { }), ); expect(onPlayCapture).toHaveBeenCalledTimes(3); + expect(log).toEqual([ + outerRef.current, + outerRef.current.firstChild, + innerRef.current, + ]); outerRef.current.dispatchEvent( new Event('play', { bubbles: false, }), ); expect(onPlayCapture).toHaveBeenCalledTimes(4); + expect(log).toEqual([ + outerRef.current, + outerRef.current.firstChild, + innerRef.current, + outerRef.current, + ]); } finally { document.body.removeChild(container); } diff --git a/packages/react-dom/src/events/DOMPluginEventSystem.js b/packages/react-dom/src/events/DOMPluginEventSystem.js index 161f3931df..3083031fd3 100644 --- a/packages/react-dom/src/events/DOMPluginEventSystem.js +++ b/packages/react-dom/src/events/DOMPluginEventSystem.js @@ -718,9 +718,6 @@ export function accumulateSinglePhaseListeners( const captured = bubbled !== null ? bubbled + 'Capture' : null; const listeners: Array = []; - // If we are not handling EventTarget only phase, then we're doing the - // usual two phase accumulation using the React fiber tree to pick up - // all relevant useEvent and on* prop events. let instance = targetFiber; let lastHostComponent = null; const targetType = event.type; diff --git a/packages/react-dom/src/events/plugins/SimpleEventPlugin.js b/packages/react-dom/src/events/plugins/SimpleEventPlugin.js index a09d2d7bc7..641e8a4ed9 100644 --- a/packages/react-dom/src/events/plugins/SimpleEventPlugin.js +++ b/packages/react-dom/src/events/plugins/SimpleEventPlugin.js @@ -43,6 +43,7 @@ import getEventCharCode from '../getEventCharCode'; import {IS_CAPTURE_PHASE, IS_NON_DELEGATED} from '../EventSystemFlags'; import {enableCreateEventHandleAPI} from 'shared/ReactFeatureFlags'; +import {getClosestInstanceFromNode} from '../../client/ReactDOMComponentTree'; function extractEvents( dispatchQueue: DispatchQueue, @@ -174,6 +175,13 @@ function extractEvents( // TODO: We may also want to re-use the accumulateTargetOnly flag to // special case bubbling for onScroll/media events at a later point. const accumulateTargetOnly = inCapturePhase && isNonDelegatedEvent; + // If we are not handling accumulateTargetOnly, then we should traverse + // through all React fiber tree, finding all relevant useEvent and + // on* prop events as we traverse the tree. Otherwise, we should + // only handle the target fiber and stop traversal straight after. + if (accumulateTargetOnly) { + targetInst = getClosestInstanceFromNode(((targetContainer: any): Node)); + } // We traverse only capture or bubble phase listeners accumulateSinglePhaseListeners(