diff --git a/packages/react-dom/src/events/EventListener.js b/packages/react-dom/src/events/EventListener.js new file mode 100644 index 0000000000..e87c3886eb --- /dev/null +++ b/packages/react-dom/src/events/EventListener.js @@ -0,0 +1,24 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +export function addEventBubbleListener( + element: Element, + eventType: string, + listener: Function, +): void { + element.addEventListener(eventType, listener, false); +} + +export function addEventCaptureListener( + element: Element, + eventType: string, + listener: Function, +): void { + element.addEventListener(eventType, listener, true); +} diff --git a/packages/react-dom/src/events/ReactDOMEventListener.js b/packages/react-dom/src/events/ReactDOMEventListener.js index 3ba6de4cd8..1fa4f67c3a 100644 --- a/packages/react-dom/src/events/ReactDOMEventListener.js +++ b/packages/react-dom/src/events/ReactDOMEventListener.js @@ -8,8 +8,8 @@ import {batchedUpdates} from 'events/ReactGenericBatching'; import {isFiberMounted} from 'react-reconciler/reflection'; import {HostRoot} from 'shared/ReactTypeOfWork'; -import EventListener from 'fbjs/lib/EventListener'; +import {addEventBubbleListener, addEventCaptureListener} from './EventListener'; import getEventTarget from './getEventTarget'; import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree'; @@ -124,7 +124,7 @@ export function trapBubbledEvent(topLevelType, handlerBaseName, element) { if (!element) { return null; } - return EventListener.listen( + addEventBubbleListener( element, handlerBaseName, dispatchEvent.bind(null, topLevelType), @@ -145,7 +145,7 @@ export function trapCapturedEvent(topLevelType, handlerBaseName, element) { if (!element) { return null; } - return EventListener.capture( + addEventCaptureListener( element, handlerBaseName, dispatchEvent.bind(null, topLevelType), diff --git a/packages/react-dom/src/events/forks/EventListener-www.js b/packages/react-dom/src/events/forks/EventListener-www.js new file mode 100644 index 0000000000..0f6ddaf5bd --- /dev/null +++ b/packages/react-dom/src/events/forks/EventListener-www.js @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2013-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +var EventListenerWWW = require('EventListener'); + +import typeof * as EventListenerType from '../EventListener'; +import typeof * as EventListenerShimType from './EventListener-www'; + +export function addEventBubbleListener( + element: Element, + eventType: string, + listener: Function, +): void { + EventListenerWWW.listen(element, eventType, listener); +} + +export function addEventCaptureListener( + element: Element, + eventType: string, + listener: Function, +): void { + EventListenerWWW.capture(element, eventType, listener); +} + +// Flow magic to verify the exports of this file match the original version. +// eslint-disable-next-line no-unused-vars +type Check<_X, Y: _X, X: Y = _X> = null; +// eslint-disable-next-line no-unused-expressions +(null: Check); diff --git a/scripts/flow/environment.js b/scripts/flow/environment.js index ca9ab99c1b..e7f477360e 100644 --- a/scripts/flow/environment.js +++ b/scripts/flow/environment.js @@ -24,3 +24,11 @@ declare module 'ReactFiberErrorDialog' { showErrorDialog: (error: mixed) => boolean, }; } + +// EventListener www fork +declare module 'EventListener' { + declare module.exports: { + listen: (target: Element, type: string, callback: Function) => mixed, + capture: (target: Element, type: string, callback: Function) => mixed, + }; +} diff --git a/scripts/rollup/forks.js b/scripts/rollup/forks.js index fe8626bcfa..f2302b1e36 100644 --- a/scripts/rollup/forks.js +++ b/scripts/rollup/forks.js @@ -101,6 +101,18 @@ const forks = Object.freeze({ return null; } }, + + // We wrap top-level listeners into guards on www. + 'react-dom/src/events/EventListener': (bundleType, entry) => { + switch (bundleType) { + case FB_DEV: + case FB_PROD: + // Use the www fork which is integrated with TimeSlice profiling. + return 'react-dom/src/events/forks/EventListener-www.js'; + default: + return null; + } + }, }); module.exports = forks;