From 33d670ef8498cab640b1141467f7c45b79f9a304 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 29 Apr 2019 14:09:15 +0100 Subject: [PATCH 1/6] Event API: fallback correctly registers DOM listener --- .../react-dom/src/events/ReactDOMEventListener.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index f5fa9d31706..97c6272999a 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -195,10 +195,16 @@ export function trapEventForResponderEventSystem( } // Check if interactive and wrap in interactiveUpdates const listener = dispatchEvent.bind(null, topLevelType, eventFlags); - addEventListener(element, rawEventName, listener, { - capture, - passive, - }); + if (passiveBrowserEventsSupported) { + addEventListener(element, rawEventName, listener, { + capture, + passive, + }); + } else if (capture) { + addEventCaptureListener(element, rawEventName, listener); + } else { + addEventBubbleListener(element, rawEventName, listener); + } } } From 61f85a4cd7c0bd5ce5315832ef336394371af5ca Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 29 Apr 2019 23:32:49 +0100 Subject: [PATCH 2/6] Remove capture option and make it baked in --- packages/events/EventSystemFlags.js | 3 +- .../react-dom/src/client/ReactDOMComponent.js | 12 +------- .../src/events/DOMEventResponderSystem.js | 30 ++----------------- .../react-dom/src/events/EventListener.js | 9 ++++-- .../src/events/ReactDOMEventListener.js | 19 +++++------- .../src/events/forks/EventListener-www.js | 14 ++------- packages/react-events/README.md | 2 +- packages/react-events/src/Focus.js | 4 +-- packages/react-events/src/FocusScope.js | 2 +- packages/shared/ReactTypes.js | 2 +- scripts/flow/environment.js | 6 ++++ 11 files changed, 31 insertions(+), 72 deletions(-) diff --git a/packages/events/EventSystemFlags.js b/packages/events/EventSystemFlags.js index 2d64878ce74..be5e3544a2e 100644 --- a/packages/events/EventSystemFlags.js +++ b/packages/events/EventSystemFlags.js @@ -13,5 +13,4 @@ export const PLUGIN_EVENT_SYSTEM = 1; export const RESPONDER_EVENT_SYSTEM = 1 << 1; export const IS_PASSIVE = 1 << 2; export const IS_ACTIVE = 1 << 3; -export const IS_CAPTURE = 1 << 4; -export const PASSIVE_NOT_SUPPORTED = 1 << 5; +export const PASSIVE_NOT_SUPPORTED = 1 << 4; diff --git a/packages/react-dom/src/client/ReactDOMComponent.js b/packages/react-dom/src/client/ReactDOMComponent.js index 00424efe2c9..b354f16801a 100644 --- a/packages/react-dom/src/client/ReactDOMComponent.js +++ b/packages/react-dom/src/client/ReactDOMComponent.js @@ -1294,7 +1294,6 @@ export function listenToEventResponderEventTypes( for (let i = 0, length = eventTypes.length; i < length; ++i) { const targetEventType = eventTypes[i]; let topLevelType; - let capture = false; let passive = true; // If no event config object is provided (i.e. - only a string), @@ -1313,26 +1312,17 @@ export function listenToEventResponderEventTypes( const targetEventConfigObject = ((targetEventType: any): { name: string, passive?: boolean, - capture?: boolean, }); topLevelType = targetEventConfigObject.name; if (targetEventConfigObject.passive !== undefined) { passive = targetEventConfigObject.passive; } - if (targetEventConfigObject.capture !== undefined) { - capture = targetEventConfigObject.capture; - } } - const listeningName = generateListeningKey( - topLevelType, - passive, - capture, - ); + const listeningName = generateListeningKey(topLevelType, passive); if (!listeningSet.has(listeningName)) { trapEventForResponderEventSystem( element, ((topLevelType: any): DOMTopLevelEventType), - capture, passive, ); listeningSet.add(listeningName); diff --git a/packages/react-dom/src/events/DOMEventResponderSystem.js b/packages/react-dom/src/events/DOMEventResponderSystem.js index 23133a9ba6b..4e9b2396950 100644 --- a/packages/react-dom/src/events/DOMEventResponderSystem.js +++ b/packages/react-dom/src/events/DOMEventResponderSystem.js @@ -9,7 +9,6 @@ import { type EventSystemFlags, IS_PASSIVE, - IS_CAPTURE, PASSIVE_NOT_SUPPORTED, } from 'events/EventSystemFlags'; import type {AnyNativeEvent} from 'events/PluginModuleType'; @@ -247,28 +246,22 @@ const eventResponderContext: ReactResponderContext = { for (let i = 0; i < rootEventTypes.length; i++) { const rootEventType = rootEventTypes[i]; let name = rootEventType; - let capture = false; let passive = true; if (typeof rootEventType !== 'string') { const targetEventConfigObject = ((rootEventType: any): { name: string, passive?: boolean, - capture?: boolean, }); name = targetEventConfigObject.name; if (targetEventConfigObject.passive !== undefined) { passive = targetEventConfigObject.passive; } - if (targetEventConfigObject.capture !== undefined) { - capture = targetEventConfigObject.capture; - } } const listeningName = generateListeningKey( ((name: any): string), passive, - capture, ); let rootEventComponents = rootEventTypesToEventComponentInstances.get( listeningName, @@ -537,27 +530,21 @@ function getTargetEventTypesSet( for (let i = 0; i < eventTypes.length; i++) { const eventType = eventTypes[i]; let name = eventType; - let capture = false; let passive = true; if (typeof eventType !== 'string') { const targetEventConfigObject = ((eventType: any): { name: string, passive?: boolean, - capture?: boolean, }); name = targetEventConfigObject.name; if (targetEventConfigObject.passive !== undefined) { passive = targetEventConfigObject.passive; } - if (targetEventConfigObject.capture !== undefined) { - capture = targetEventConfigObject.capture; - } } const listeningName = generateListeningKey( ((name: any): string), passive, - capture, ); cachedSet.add(listeningName); } @@ -640,12 +627,10 @@ function traverseAndHandleEventResponderInstances( eventSystemFlags: EventSystemFlags, ): void { const isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0; - const isCaptureEvent = (eventSystemFlags & IS_CAPTURE) !== 0; const isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0; const listeningName = generateListeningKey( ((topLevelType: any): string), isPassiveEvent || !isPassiveSupported, - isCaptureEvent, ); // Trigger event responders in this order: @@ -875,29 +860,20 @@ function registerRootEventType( eventComponentInstance: ReactEventComponentInstance, ): void { let name = rootEventType; - let capture = false; let passive = true; if (typeof rootEventType !== 'string') { const targetEventConfigObject = ((rootEventType: any): { name: string, passive?: boolean, - capture?: boolean, }); name = targetEventConfigObject.name; if (targetEventConfigObject.passive !== undefined) { passive = targetEventConfigObject.passive; } - if (targetEventConfigObject.capture !== undefined) { - capture = targetEventConfigObject.capture; - } } - const listeningName = generateListeningKey( - ((name: any): string), - passive, - capture, - ); + const listeningName = generateListeningKey(((name: any): string), passive); let rootEventComponentInstances = rootEventTypesToEventComponentInstances.get( listeningName, ); @@ -928,12 +904,10 @@ function registerRootEventType( export function generateListeningKey( topLevelType: string, passive: boolean, - capture: boolean, ): string { // Create a unique name for this event, plus its properties. We'll // use this to ensure we don't listen to the same event with the same // properties again. const passiveKey = passive ? '_passive' : '_active'; - const captureKey = capture ? '_capture' : ''; - return `${topLevelType}${passiveKey}${captureKey}`; + return `${topLevelType}${passiveKey}`; } diff --git a/packages/react-dom/src/events/EventListener.js b/packages/react-dom/src/events/EventListener.js index a44d160e797..7e6161136b7 100644 --- a/packages/react-dom/src/events/EventListener.js +++ b/packages/react-dom/src/events/EventListener.js @@ -23,11 +23,14 @@ export function addEventCaptureListener( element.addEventListener(eventType, listener, true); } -export function addEventListener( +export function addEventCaptureListenerWithPassiveFlag( element: Document | Element | Node, eventType: string, listener: Function, - options: {passive: boolean}, + passive: boolean, ): void { - element.addEventListener(eventType, listener, (options: any)); + element.addEventListener(eventType, listener, { + capture: true, + passive, + }); } diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index 97c6272999a..813f978eada 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -22,14 +22,13 @@ import { RESPONDER_EVENT_SYSTEM, IS_PASSIVE, IS_ACTIVE, - IS_CAPTURE, PASSIVE_NOT_SUPPORTED, } from 'events/EventSystemFlags'; import { addEventBubbleListener, addEventCaptureListener, - addEventListener, + addEventCaptureListenerWithPassiveFlag, } from './EventListener'; import getEventTarget from './getEventTarget'; import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree'; @@ -168,7 +167,6 @@ export function trapCapturedEvent( export function trapEventForResponderEventSystem( element: Document | Element | Node, topLevelType: DOMTopLevelEventType, - capture: boolean, passive: boolean, ): void { if (enableEventAPI) { @@ -190,20 +188,17 @@ export function trapEventForResponderEventSystem( } else { eventFlags |= IS_ACTIVE; } - if (capture) { - eventFlags |= IS_CAPTURE; - } // Check if interactive and wrap in interactiveUpdates const listener = dispatchEvent.bind(null, topLevelType, eventFlags); if (passiveBrowserEventsSupported) { - addEventListener(element, rawEventName, listener, { - capture, + addEventCaptureListenerWithPassiveFlag( + element, + rawEventName, + listener, passive, - }); - } else if (capture) { - addEventCaptureListener(element, rawEventName, listener); + ); } else { - addEventBubbleListener(element, rawEventName, listener); + addEventCaptureListener(element, rawEventName, listener); } } } diff --git a/packages/react-dom/src/events/forks/EventListener-www.js b/packages/react-dom/src/events/forks/EventListener-www.js index d217a52ce63..159dcb6082f 100644 --- a/packages/react-dom/src/events/forks/EventListener-www.js +++ b/packages/react-dom/src/events/forks/EventListener-www.js @@ -12,8 +12,6 @@ const EventListenerWWW = require('EventListener'); import typeof * as EventListenerType from '../EventListener'; import typeof * as EventListenerShimType from './EventListener-www'; -const NORMAL_PRIORITY = 0; - export function addEventBubbleListener( element: Element, eventType: string, @@ -30,19 +28,13 @@ export function addEventCaptureListener( EventListenerWWW.capture(element, eventType, listener); } -export function addEventListener( +export function addEventCaptureListenerWithPassiveFlag( element: Element, eventType: string, listener: Function, - options: {passive: boolean}, + passive: boolean, ): void { - EventListenerWWW.listen( - element, - eventType, - listener, - NORMAL_PRIORITY, - options, - ); + EventListenerWWW.listenWithPassiveFlag(element, eventType, listener, passive); } // Flow magic to verify the exports of this file match the original version. diff --git a/packages/react-events/README.md b/packages/react-events/README.md index 4780b7bf7b5..744c0b87153 100644 --- a/packages/react-events/README.md +++ b/packages/react-events/README.md @@ -34,7 +34,7 @@ events, and implement a state machine. // types type ResponderEventType = | string - | {name: string, passive?: boolean, capture?: boolean}; + | {name: string, passive?: boolean}; type ResponderEvent = {| nativeEvent: any, diff --git a/packages/react-events/src/Focus.js b/packages/react-events/src/Focus.js index 052a6e06369..5e01ea235ab 100644 --- a/packages/react-events/src/Focus.js +++ b/packages/react-events/src/Focus.js @@ -34,8 +34,8 @@ type FocusEvent = {| |}; const targetEventTypes = [ - {name: 'focus', passive: true, capture: true}, - {name: 'blur', passive: true, capture: true}, + {name: 'focus', passive: true}, + {name: 'blur', passive: true}, ]; function createFocusEvent( diff --git a/packages/react-events/src/FocusScope.js b/packages/react-events/src/FocusScope.js index c31e11d8f8e..05493f12527 100644 --- a/packages/react-events/src/FocusScope.js +++ b/packages/react-events/src/FocusScope.js @@ -25,7 +25,7 @@ type FocusScopeState = { }; const targetEventTypes = [{name: 'keydown', passive: false}]; -const rootEventTypes = [{name: 'focus', passive: true, capture: true}]; +const rootEventTypes = [{name: 'focus', passive: true}]; function focusElement(element: ?HTMLElement) { if (element != null) { diff --git a/packages/shared/ReactTypes.js b/packages/shared/ReactTypes.js index 7a28c554a61..72d66cd3810 100644 --- a/packages/shared/ReactTypes.js +++ b/packages/shared/ReactTypes.js @@ -83,7 +83,7 @@ export type RefObject = {| export type ReactEventResponderEventType = | string - | {name: string, passive?: boolean, capture?: boolean}; + | {name: string, passive?: boolean}; export type ReactEventResponder = { targetEventTypes?: Array, diff --git a/scripts/flow/environment.js b/scripts/flow/environment.js index 153e6b37a8c..7810f496357 100644 --- a/scripts/flow/environment.js +++ b/scripts/flow/environment.js @@ -39,5 +39,11 @@ declare module 'EventListener' { options?: {passive: boolean}, ) => mixed, capture: (target: Element, type: string, callback: Function) => mixed, + listenWithPassiveFlag: ( + target: Element, + type: string, + callback: Function, + passive: boolean, + ) => mixed, }; } From a12817236baee8621a254b314fc4149ec5f50d21 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Mon, 29 Apr 2019 23:35:26 +0100 Subject: [PATCH 3/6] Make all events use capture phase. Remove capture option and fix tests. --- packages/react-events/src/__tests__/Press-test.internal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-events/src/__tests__/Press-test.internal.js b/packages/react-events/src/__tests__/Press-test.internal.js index cb770076aee..9a25bd704c2 100644 --- a/packages/react-events/src/__tests__/Press-test.internal.js +++ b/packages/react-events/src/__tests__/Press-test.internal.js @@ -1269,13 +1269,13 @@ describe('Event responder: Press', () => { createPointerEvent('pointerup', {pageX: 10, pageY: 10}), ); expect(events).toEqual([ - 'pointerdown', 'inner: onPressStart', 'inner: onPressChange', - 'pointerup', + 'pointerdown', 'inner: onPressEnd', 'inner: onPressChange', 'inner: onPress', + 'pointerup', ]); }); From 1d87299c04e9eb6178be7519005253110ce55745 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 30 Apr 2019 00:33:32 +0100 Subject: [PATCH 4/6] rename --- packages/react-dom/src/events/forks/EventListener-www.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-dom/src/events/forks/EventListener-www.js b/packages/react-dom/src/events/forks/EventListener-www.js index 159dcb6082f..8192d391c88 100644 --- a/packages/react-dom/src/events/forks/EventListener-www.js +++ b/packages/react-dom/src/events/forks/EventListener-www.js @@ -34,7 +34,7 @@ export function addEventCaptureListenerWithPassiveFlag( listener: Function, passive: boolean, ): void { - EventListenerWWW.listenWithPassiveFlag(element, eventType, listener, passive); + EventListenerWWW.captureWithPassiveFlag(element, eventType, listener, passive); } // Flow magic to verify the exports of this file match the original version. From 18c83d82cd56ee5b8d243ab436887e32dddb04a7 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 30 Apr 2019 00:45:21 +0100 Subject: [PATCH 5/6] Run prettier --- packages/react-dom/src/events/forks/EventListener-www.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/src/events/forks/EventListener-www.js b/packages/react-dom/src/events/forks/EventListener-www.js index 8192d391c88..99b337f0e78 100644 --- a/packages/react-dom/src/events/forks/EventListener-www.js +++ b/packages/react-dom/src/events/forks/EventListener-www.js @@ -34,7 +34,12 @@ export function addEventCaptureListenerWithPassiveFlag( listener: Function, passive: boolean, ): void { - EventListenerWWW.captureWithPassiveFlag(element, eventType, listener, passive); + EventListenerWWW.captureWithPassiveFlag( + element, + eventType, + listener, + passive, + ); } // Flow magic to verify the exports of this file match the original version. From 329292a836e67a0e5d41903e6444197992093bb7 Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 30 Apr 2019 10:48:35 +0100 Subject: [PATCH 6/6] Fix Flow type --- scripts/flow/environment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/flow/environment.js b/scripts/flow/environment.js index 7810f496357..8a0806c4a97 100644 --- a/scripts/flow/environment.js +++ b/scripts/flow/environment.js @@ -39,7 +39,7 @@ declare module 'EventListener' { options?: {passive: boolean}, ) => mixed, capture: (target: Element, type: string, callback: Function) => mixed, - listenWithPassiveFlag: ( + captureWithPassiveFlag: ( target: Element, type: string, callback: Function,