Skip to content

Commit

Permalink
Adds experimental event component responder surfaces (#15228)
Browse files Browse the repository at this point in the history
* Adds Press and Hover event modules + more features to the Event Responder System
  • Loading branch information
trueadm authored Mar 27, 2019
1 parent d8cb10f commit 669cafb
Show file tree
Hide file tree
Showing 15 changed files with 1,040 additions and 161 deletions.
2 changes: 1 addition & 1 deletion packages/events/EventPluginUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ if (__DEV__) {
* @param {function} listener Application-level callback
* @param {*} inst Internal component instance
*/
function executeDispatch(event, listener, inst) {
export function executeDispatch(event, listener, inst) {
const type = event.type || 'unknown-event';
event.currentTarget = getNodeFromInstance(inst);
invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
Expand Down
37 changes: 37 additions & 0 deletions packages/events/EventTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import SyntheticEvent from 'events/SyntheticEvent';
import type {AnyNativeEvent} from 'events/PluginModuleType';

export type EventResponderContext = {
event: AnyNativeEvent,
eventTarget: EventTarget,
eventType: string,
isPassive: () => boolean,
isPassiveSupported: () => boolean,
dispatchEvent: (
name: string,
listener: (e: SyntheticEvent) => void | null,
pressTarget: EventTarget | null,
discrete: boolean,
extraProperties?: Object,
) => void,
isTargetWithinElement: (
childTarget: EventTarget,
parentTarget: EventTarget,
) => boolean,
isTargetOwned: EventTarget => boolean,
isTargetWithinEventComponent: EventTarget => boolean,
isPositionWithinTouchHitTarget: (x: number, y: number) => boolean,
addRootEventTypes: (rootEventTypes: Array<string>) => void,
removeRootEventTypes: (rootEventTypes: Array<string>) => void,
requestOwnership: (target: EventTarget | null) => boolean,
releaseOwnership: (target: EventTarget | null) => boolean,
};
13 changes: 6 additions & 7 deletions packages/react-dom/src/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ 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 {ReactEventResponderEventType} from 'shared/ReactTypes';
import type {DOMTopLevelEventType} from 'events/TopLevelEventTypes';

import {
Expand Down Expand Up @@ -1277,19 +1277,18 @@ export function restoreControlledState(
}
}

export function listenToEventResponderEvents(
eventResponder: ReactEventResponder,
export function listenToEventResponderEventTypes(
eventTypes: Array<ReactEventResponderEventType>,
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];
for (let i = 0, length = eventTypes.length; i < length; ++i) {
const targetEventType = eventTypes[i];
let topLevelType;
let capture = false;
let passive = true;
Expand Down Expand Up @@ -1323,7 +1322,7 @@ export function listenToEventResponderEvents(
// 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 passiveKey = passive ? '_passive' : '_active';
const captureKey = capture ? '_capture' : '';
const listeningName = `${topLevelType}${passiveKey}${captureKey}`;
if (!listeningSet.has(listeningName)) {
Expand Down
7 changes: 5 additions & 2 deletions packages/react-dom/src/client/ReactDOMHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
warnForDeletedHydratableText,
warnForInsertedHydratedElement,
warnForInsertedHydratedText,
listenToEventResponderEvents,
listenToEventResponderEventTypes,
} from './ReactDOMComponent';
import {getSelectionInformation, restoreSelection} from './ReactInputSelection';
import setTextContent from './setTextContent';
Expand Down Expand Up @@ -864,7 +864,10 @@ export function handleEventComponent(
): void {
if (enableEventAPI) {
const rootElement = rootContainerInstance.ownerDocument;
listenToEventResponderEvents(eventResponder, rootElement);
listenToEventResponderEventTypes(
eventResponder.targetEventTypes,
rootElement,
);
}
}

Expand Down
Loading

0 comments on commit 669cafb

Please sign in to comment.