Skip to content

Commit

Permalink
Add internal logic for listening to event responders (#15168)
Browse files Browse the repository at this point in the history
* Add the logic for listening to event responders
  • Loading branch information
trueadm committed Mar 21, 2019
1 parent b1a56ab commit 66f280c
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 35 deletions.
73 changes: 72 additions & 1 deletion packages/react-dom/src/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {registrationNameModules} from 'events/EventPluginRegistry';
import warning from 'shared/warning';
import {canUseDOM} from 'shared/ExecutionEnvironment';
import warningWithoutStack from 'shared/warningWithoutStack';
import type {ReactEventResponder} from 'shared/ReactTypes';
import type {DOMTopLevelEventType} from 'events/TopLevelEventTypes';

import {
getValueForAttribute,
Expand Down Expand Up @@ -57,7 +59,12 @@ import {
TOP_SUBMIT,
TOP_TOGGLE,
} from '../events/DOMTopLevelEventTypes';
import {listenTo, trapBubbledEvent} from '../events/ReactBrowserEventEmitter';
import {
listenTo,
trapBubbledEvent,
getListeningSetForElement,
} from '../events/ReactBrowserEventEmitter';
import {trapEventForResponderEventSystem} from '../events/ReactDOMEventListener.js';
import {mediaEventTypes} from '../events/DOMTopLevelEventTypes';
import {
createDangerousStringForStyles,
Expand All @@ -78,6 +85,8 @@ import {validateProperties as validateARIAProperties} from '../shared/ReactDOMIn
import {validateProperties as validateInputProperties} from '../shared/ReactDOMNullInputValuePropHook';
import {validateProperties as validateUnknownProperties} from '../shared/ReactDOMUnknownPropertyHook';

import {enableEventAPI} from 'shared/ReactFeatureFlags';

let didWarnInvalidHydration = false;
let didWarnShadyDOM = false;

Expand Down Expand Up @@ -1267,3 +1276,65 @@ export function restoreControlledState(
return;
}
}

export function listenToEventResponderEvents(
eventResponder: ReactEventResponder,
element: Element | Document,
): void {
if (enableEventAPI) {
const {targetEventTypes} = eventResponder;
// Get the listening Set for this element. We use this to track
// what events we're listening to.
const listeningSet = getListeningSetForElement(element);

// Go through each target event type of the event responder
for (let i = 0, length = targetEventTypes.length; i < length; ++i) {
const targetEventType = targetEventTypes[i];
let topLevelType;
let capture = false;
let passive = true;

// If no event config object is provided (i.e. - only a string),
// we default to enabling passive and not capture.
if (typeof targetEventType === 'string') {
topLevelType = targetEventType;
} else {
if (__DEV__) {
warning(
typeof targetEventType === 'object' && targetEventType !== null,
'Event Responder: invalid entry in targetEventTypes array. ' +
'Entry must be string or an object. Instead, got %s.',
targetEventType,
);
}
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;
}
}
// 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' : '';
const captureKey = capture ? '_capture' : '';
const listeningName = `${topLevelType}${passiveKey}${captureKey}`;
if (!listeningSet.has(listeningName)) {
trapEventForResponderEventSystem(
element,
((topLevelType: any): DOMTopLevelEventType),
capture,
passive,
);
listeningSet.add(listeningName);
}
}
}
}
8 changes: 5 additions & 3 deletions packages/react-dom/src/client/ReactDOMHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
warnForDeletedHydratableText,
warnForInsertedHydratedElement,
warnForInsertedHydratedText,
listenToEventResponderEvents,
} from './ReactDOMComponent';
import {getSelectionInformation, restoreSelection} from './ReactInputSelection';
import setTextContent from './setTextContent';
Expand Down Expand Up @@ -860,15 +861,16 @@ export function handleEventComponent(
eventResponder: ReactEventResponder,
rootContainerInstance: Container,
internalInstanceHandle: Object,
) {
// TODO: add handleEventComponent implementation
): void {
const rootElement = rootContainerInstance.ownerDocument;
listenToEventResponderEvents(eventResponder, rootElement);
}

export function handleEventTarget(
type: Symbol | number,
props: Props,
internalInstanceHandle: Object,
) {
): void {
// Touch target hit slop handling
if (type === REACT_EVENT_TARGET_TOUCH_HIT) {
// Validates that there is a single element
Expand Down
6 changes: 3 additions & 3 deletions packages/react-dom/src/events/ReactBrowserEventEmitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,12 @@ const elementListeningSets:
| WeakMap
| Map<
Document | Element | Node,
Set<DOMTopLevelEventType>,
Set<DOMTopLevelEventType | string>,
> = new PossiblyWeakMap();

function getListeningSetForElement(
export function getListeningSetForElement(
element: Document | Element | Node,
): Set<DOMTopLevelEventType> {
): Set<DOMTopLevelEventType | string> {
let listeningSet = elementListeningSets.get(element);
if (listeningSet === undefined) {
listeningSet = new Set();
Expand Down
56 changes: 28 additions & 28 deletions scripts/rollup/results.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@
"filename": "react-dom.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 798048,
"gzip": 181482
"size": 813661,
"gzip": 184364
},
{
"filename": "react-dom.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 107733,
"gzip": 34431
"size": 108035,
"gzip": 34515
},
{
"filename": "ReactDOM-dev.js",
Expand Down Expand Up @@ -102,15 +102,15 @@
"filename": "react-dom-test-utils.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 47988,
"gzip": 13245
"size": 48334,
"gzip": 13206
},
{
"filename": "react-dom-test-utils.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 10288,
"gzip": 3812
"size": 9954,
"gzip": 3660
},
{
"filename": "ReactTestUtils-dev.js",
Expand All @@ -137,15 +137,15 @@
"filename": "react-dom-unstable-native-dependencies.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 61725,
"gzip": 16151
"size": 61643,
"gzip": 16033
},
{
"filename": "react-dom-unstable-native-dependencies.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 11001,
"gzip": 3783
"size": 10669,
"gzip": 3640
},
{
"filename": "ReactDOMUnstableNativeDependencies-dev.js",
Expand Down Expand Up @@ -179,15 +179,15 @@
"filename": "react-dom-server.browser.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 129302,
"gzip": 34571
"size": 132758,
"gzip": 35195
},
{
"filename": "react-dom-server.browser.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 19590,
"gzip": 7447
"size": 19756,
"gzip": 7540
},
{
"filename": "ReactDOMServer-dev.js",
Expand All @@ -207,15 +207,15 @@
"filename": "react-dom-server.node.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 131409,
"gzip": 35129
"size": 134747,
"gzip": 35752
},
{
"filename": "react-dom-server.node.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 20483,
"gzip": 7757
"size": 20639,
"gzip": 7850
},
{
"filename": "react-art.development.js",
Expand Down Expand Up @@ -718,8 +718,8 @@
"filename": "react-dom.profiling.min.js",
"bundleType": "NODE_PROFILING",
"packageName": "react-dom",
"size": 110923,
"gzip": 35060
"size": 111211,
"gzip": 35133
},
{
"filename": "ReactNativeRenderer-profiling.js",
Expand Down Expand Up @@ -1054,22 +1054,22 @@
"filename": "react-dom-unstable-fire.development.js",
"bundleType": "NODE_DEV",
"packageName": "react-dom",
"size": 798401,
"gzip": 181622
"size": 814014,
"gzip": 184503
},
{
"filename": "react-dom-unstable-fire.production.min.js",
"bundleType": "NODE_PROD",
"packageName": "react-dom",
"size": 107747,
"gzip": 34441
"size": 108049,
"gzip": 34524
},
{
"filename": "react-dom-unstable-fire.profiling.min.js",
"bundleType": "NODE_PROFILING",
"packageName": "react-dom",
"size": 110937,
"gzip": 35069
"size": 111225,
"gzip": 35142
},
{
"filename": "ReactFire-dev.js",
Expand Down

0 comments on commit 66f280c

Please sign in to comment.