diff --git a/packages/react-dom/src/events/DOMEventResponderSystem.js b/packages/react-dom/src/events/DOMEventResponderSystem.js index 2c76e03e9ab77..a1898b332d6d5 100644 --- a/packages/react-dom/src/events/DOMEventResponderSystem.js +++ b/packages/react-dom/src/events/DOMEventResponderSystem.js @@ -540,8 +540,8 @@ function traverseAndTriggerEventResponderInstances( let shouldStopPropagation = false; let responderEvent; - // Capture target phase if (length > 0) { + // Capture target phase responderEvent = createResponderEvent( ((topLevelType: any): string), nativeEvent, diff --git a/packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js index 35323fde50c4a..7a6b51bb8ca63 100644 --- a/packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js +++ b/packages/react-dom/src/events/__tests__/DOMEventResponderSystem-test.internal.js @@ -49,10 +49,14 @@ function phaseToString(phase) { : 'capture'; } +function dispatchEvent(element, type) { + const event = document.createEvent('Event'); + event.initEvent(type, true, true); + element.dispatchEvent(event); +} + function dispatchClickEvent(element) { - const clickEvent = document.createEvent('Event'); - clickEvent.initEvent('click', true, true); - element.dispatchEvent(clickEvent); + dispatchEvent(element, 'click'); } function createReactEventTarget(type) { @@ -308,7 +312,11 @@ describe('DOMEventResponderSystem', () => { ['click'], undefined, (event, context, props) => { - eventLog.push(`A [${phaseToString(event.phase)}]`); + context.addRootEventTypes(event.target.ownerDocument, [ + 'click', + 'pointermove', + ]); + eventLog.push(`A [${event.type}, ${phaseToString(event.phase)}]`); }, ); @@ -316,7 +324,11 @@ describe('DOMEventResponderSystem', () => { ['click'], undefined, (event, context, props) => { - eventLog.push(`B [${phaseToString(event.phase)}]`); + context.addRootEventTypes(event.target.ownerDocument, [ + 'click', + 'pointermove', + ]); + eventLog.push(`B [${event.type}, ${phaseToString(event.phase)}]`); if (event.phase === stopPropagationOnPhase) { return true; } @@ -337,12 +349,26 @@ describe('DOMEventResponderSystem', () => { ReactDOM.render(, container); let buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); + dispatchEvent(buttonElement, 'pointermove'); } runTestWithPhase(BUBBLE_PHASE); - expect(eventLog).toEqual(['A [capture]', 'B [capture]', 'B [bubble]']); + // Root phase should not be skipped for different event type + expect(eventLog).toEqual([ + 'A [click, capture]', + 'B [click, capture]', + 'B [click, bubble]', + 'A [pointermove, root]', + 'B [pointermove, root]', + ]); runTestWithPhase(CAPTURE_PHASE); - expect(eventLog).toEqual(['A [capture]', 'B [capture]']); + // Root phase should not be skipped for different event type + expect(eventLog).toEqual([ + 'A [click, capture]', + 'B [click, capture]', + 'A [pointermove, root]', + 'B [pointermove, root]', + ]); }); it('nested event responders and their onEvent() should fire in the correct order with stopPropagation #2', () => { @@ -354,7 +380,11 @@ describe('DOMEventResponderSystem', () => { ['click'], undefined, (event, context, props) => { - eventLog.push(`A [${phaseToString(event.phase)}]`); + context.addRootEventTypes(event.target.ownerDocument, [ + 'click', + 'pointermove', + ]); + eventLog.push(`A [${event.type}, ${phaseToString(event.phase)}]`); if (event.phase === stopPropagationOnPhase) { return true; } @@ -365,7 +395,11 @@ describe('DOMEventResponderSystem', () => { ['click'], undefined, (event, context, props) => { - eventLog.push(`B [${phaseToString(event.phase)}]`); + context.addRootEventTypes(event.target.ownerDocument, [ + 'click', + 'pointermove', + ]); + eventLog.push(`B [${event.type}, ${phaseToString(event.phase)}]`); }, ); @@ -383,17 +417,26 @@ describe('DOMEventResponderSystem', () => { ReactDOM.render(, container); let buttonElement = buttonRef.current; dispatchClickEvent(buttonElement); + dispatchEvent(buttonElement, 'pointermove'); } runTestWithPhase(BUBBLE_PHASE); + // Root phase should not be skipped for different event type expect(eventLog).toEqual([ - 'A [capture]', - 'B [capture]', - 'B [bubble]', - 'A [bubble]', + 'A [click, capture]', + 'B [click, capture]', + 'B [click, bubble]', + 'A [click, bubble]', + 'A [pointermove, root]', + 'B [pointermove, root]', ]); runTestWithPhase(CAPTURE_PHASE); - expect(eventLog).toEqual(['A [capture]']); + // Root phase should not be skipped for different event type + expect(eventLog).toEqual([ + 'A [click, capture]', + 'A [pointermove, root]', + 'B [pointermove, root]', + ]); }); it('custom event dispatching for click -> magicClick works', () => {