Remove internal createEventHandle module

Migrate to 'addEventListener' helper.

Fix #2459
This commit is contained in:
Nicolas Gallagher
2023-04-12 13:46:44 -07:00
parent e160546ec8
commit 39b94b1945
5 changed files with 92 additions and 128 deletions

View File

@@ -10,18 +10,17 @@
import * as React from 'react';
import { act, render } from '@testing-library/react';
import { createEventTarget } from 'dom-event-testing-library';
import createEventHandle from '..';
import { addEventListener } from '..';
describe('create-event-handle', () => {
describe('createEventTarget()', () => {
describe('addEventListener', () => {
describe('addEventListener()', () => {
test('event dispatched on target', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component() {
React.useEffect(() => {
return addClickListener(targetRef.current, listener);
return addEventListener(targetRef.current, 'click', listener);
});
return <div ref={targetRef} />;
}
@@ -42,20 +41,19 @@ describe('create-event-handle', () => {
const listenerCapture = jest.fn();
const targetRef = React.createRef();
const parentRef = React.createRef();
const addClickListener = createEventHandle('click');
const addClickCaptureListener = createEventHandle('click', {
capture: true
});
function Component() {
React.useEffect(() => {
const removeClickListener = addClickListener(
const removeClickListener = addEventListener(
targetRef.current,
'click',
listener
);
const removeClickCaptureListener = addClickCaptureListener(
const removeClickCaptureListener = addEventListener(
targetRef.current,
listenerCapture
'click',
listenerCapture,
{ capture: true }
);
return () => {
removeClickListener();
@@ -91,20 +89,19 @@ describe('create-event-handle', () => {
});
const targetRef = React.createRef();
const childRef = React.createRef();
const addClickListener = createEventHandle('click');
const addClickCaptureListener = createEventHandle('click', {
capture: true
});
function Component() {
React.useEffect(() => {
const removeClickListener = addClickListener(
const removeClickListener = addEventListener(
targetRef.current,
'click',
listener
);
const removeClickCaptureListener = addClickCaptureListener(
const removeClickCaptureListener = addEventListener(
targetRef.current,
listenerCapture
'click',
listenerCapture,
{ capture: true }
);
return () => {
removeClickListener();
@@ -135,11 +132,10 @@ describe('create-event-handle', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const childRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component() {
React.useEffect(() => {
return addClickListener(targetRef.current, listener);
return addEventListener(targetRef.current, 'click', listener);
});
return (
<div ref={targetRef}>
@@ -162,11 +158,10 @@ describe('create-event-handle', () => {
test('listener can be attached to document', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component({ target }) {
React.useEffect(() => {
return addClickListener(target, listener);
return addEventListener(target, 'click', listener);
});
return <div ref={targetRef} />;
}
@@ -184,11 +179,10 @@ describe('create-event-handle', () => {
test('listener can be attached to window ', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component({ target }) {
React.useEffect(() => {
return addClickListener(target, listener);
return addEventListener(target, 'click', listener);
});
return <div ref={targetRef} />;
}
@@ -206,11 +200,10 @@ describe('create-event-handle', () => {
test('custom event dispatched on target', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const addMagicEventListener = createEventHandle('magic-event');
function Component() {
React.useEffect(() => {
return addMagicEventListener(targetRef.current, listener);
return addEventListener(targetRef.current, 'magic-event', listener);
});
return <div ref={targetRef} />;
}
@@ -230,10 +223,7 @@ describe('create-event-handle', () => {
const targetRef = React.createRef();
const parentRef = React.createRef();
const childRef = React.createRef();
const addClickListener = createEventHandle('click');
const addClickCaptureListener = createEventHandle('click', {
capture: true
});
const listener = jest.fn((e) => {
log.push(['bubble', e.currentTarget.id]);
});
@@ -244,10 +234,14 @@ describe('create-event-handle', () => {
function Component() {
React.useEffect(() => {
// the same event handle is used to set listeners on different targets
addClickListener(targetRef.current, listener);
addClickListener(parentRef.current, listener);
addClickCaptureListener(targetRef.current, listenerCapture);
addClickCaptureListener(parentRef.current, listenerCapture);
addEventListener(targetRef.current, 'click', listener);
addEventListener(parentRef.current, 'click', listener);
addEventListener(targetRef.current, 'click', listenerCapture, {
capture: true
});
addEventListener(parentRef.current, 'click', listenerCapture, {
capture: true
});
});
return (
<div id="parent" ref={parentRef}>
@@ -280,14 +274,6 @@ describe('create-event-handle', () => {
const log = [];
const targetRef = React.createRef();
const childRef = React.createRef();
const addClickListener = createEventHandle('click');
const addClickAltListener = createEventHandle('click');
const addClickCaptureListener = createEventHandle('click', {
capture: true
});
const addClickCaptureAltListener = createEventHandle('click', {
capture: true
});
const listener = jest.fn((e) => {
log.push(['bubble', 'target']);
});
@@ -303,10 +289,14 @@ describe('create-event-handle', () => {
function Component() {
React.useEffect(() => {
addClickListener(targetRef.current, listener);
addClickAltListener(targetRef.current, listenerAlt);
addClickCaptureListener(targetRef.current, listenerCapture);
addClickCaptureAltListener(targetRef.current, listenerCaptureAlt);
addEventListener(targetRef.current, 'click', listener);
addEventListener(targetRef.current, 'click', listenerAlt);
addEventListener(targetRef.current, 'click', listenerCapture, {
capture: true
});
addEventListener(targetRef.current, 'click', listenerCaptureAlt, {
capture: true
});
});
return (
<div id="target" ref={targetRef}>
@@ -344,12 +334,11 @@ describe('create-event-handle', () => {
const targetListener = jest.fn();
const targetRef = React.createRef();
const childRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component() {
React.useEffect(() => {
addClickListener(childRef.current, childListener);
addClickListener(targetRef.current, targetListener);
addEventListener(childRef.current, 'click', childListener);
addEventListener(targetRef.current, 'click', targetListener);
});
return (
<div ref={targetRef}>
@@ -376,13 +365,11 @@ describe('create-event-handle', () => {
});
const secondListener = jest.fn();
const targetRef = React.createRef();
const addFirstClickListener = createEventHandle('click');
const addSecondClickListener = createEventHandle('click');
function Component() {
React.useEffect(() => {
addFirstClickListener(targetRef.current, firstListener);
addSecondClickListener(targetRef.current, secondListener);
addEventListener(targetRef.current, 'click', firstListener);
addEventListener(targetRef.current, 'click', secondListener);
});
return <div ref={targetRef} />;
}

View File

@@ -9,17 +9,16 @@
import * as React from 'react';
import * as ReactDOMServer from 'react-dom/server';
import createEventHandle from '..';
import { addEventListener } from '..';
describe('create-event-handle', () => {
describe('addEventListener', () => {
test('can render correctly using ReactDOMServer', () => {
const listener = jest.fn();
const targetRef = React.createRef();
const addClickListener = createEventHandle('click');
function Component() {
React.useEffect(() => {
return addClickListener(targetRef.current, listener);
return addEventListener(targetRef.current, 'click', listener);
});
return <div ref={targetRef} />;
}

View File

@@ -12,11 +12,10 @@ import canUseDOM from '../canUseDom';
type Listener = (e: any) => void;
type EventHandle = (target: EventTarget, callback: ?Listener) => () => void;
export type EventOptions = {
capture?: boolean,
passive?: boolean
passive?: boolean,
once?: boolean
};
const emptyFunction = () => {};
@@ -72,28 +71,19 @@ function normalizeEvent(event: any) {
/**
*
*/
export default function createEventHandle(
type: string,
export function addEventListener(
target: EventTarget,
type: any,
listener: Listener,
options: ?EventOptions
): EventHandle {
): () => void {
const opts = getOptions(options);
const compatListener = (e: any) => listener(normalizeEvent(e));
target.addEventListener(type, compatListener, opts);
return function (target: EventTarget, listener: ?Listener) {
if (target == null || typeof target.addEventListener !== 'function') {
throw new Error('createEventHandle: called on an invalid target.');
}
const element = (target: any);
if (listener != null) {
const compatListener = (e) => listener(normalizeEvent(e));
element.addEventListener(type, compatListener, opts);
return function removeListener() {
if (element != null) {
element.removeEventListener(type, compatListener, opts);
}
};
} else {
return emptyFunction;
return function removeEventListener() {
if (target != null) {
target.removeEventListener(type, compatListener, opts);
}
};
}

View File

@@ -7,7 +7,7 @@
* @flow
*/
import createEventHandle from '../createEventHandle';
import { addEventListener } from '../addEventListener';
import canUseDOM from '../canUseDom';
export type Modality = 'keyboard' | 'mouse' | 'touch' | 'pen';
@@ -45,32 +45,6 @@ const VISIBILITYCHANGE = 'visibilitychange';
const bubbleOptions = { passive: true };
const captureOptions = { capture: true, passive: true };
// Window events
const addBlurListener = createEventHandle(BLUR, bubbleOptions);
const addFocusListener = createEventHandle(FOCUS, bubbleOptions);
// Must be capture phase because 'stopPropagation' might prevent these
// events bubbling to the document.
const addVisibilityChangeListener = createEventHandle(
VISIBILITYCHANGE,
captureOptions
);
const addKeyDownListener = createEventHandle(KEYDOWN, captureOptions);
const addPointerDownListener = createEventHandle(POINTERDOWN, captureOptions);
const addPointerMoveListener = createEventHandle(POINTERMOVE, captureOptions);
// Fallback events
const addContextMenuListener = createEventHandle(CONTEXTMENU, captureOptions);
const addMouseDownListener = createEventHandle(MOUSEDOWN, captureOptions);
const addMouseMoveListener = createEventHandle(MOUSEMOVE, captureOptions);
const addMouseUpListener = createEventHandle(MOUSEUP, captureOptions);
const addScrollListener = createEventHandle(SCROLL, captureOptions);
const addSelectiomChangeListener = createEventHandle(
SELECTIONCHANGE,
captureOptions
);
const addTouchCancelListener = createEventHandle(TOUCHCANCEL, captureOptions);
const addTouchMoveListener = createEventHandle(TOUCHMOVE, captureOptions);
const addTouchStartListener = createEventHandle(TOUCHSTART, captureOptions);
function restoreModality() {
if (previousModality != null || previousActiveModality != null) {
if (previousModality != null) {
@@ -184,22 +158,30 @@ function onPointerish(event: any) {
}
if (canUseDOM) {
addBlurListener(window, onBlurWindow);
addFocusListener(window, onFocusWindow);
addKeyDownListener(document, onKeyDown);
addPointerDownListener(document, onPointerish);
addPointerMoveListener(document, onPointerish);
addVisibilityChangeListener(document, onVisibilityChange);
// fallbacks
addContextMenuListener(document, onPointerish);
addMouseDownListener(document, onPointerish);
addMouseMoveListener(document, onPointerish);
addMouseUpListener(document, onPointerish);
addTouchCancelListener(document, onPointerish);
addTouchMoveListener(document, onPointerish);
addTouchStartListener(document, onPointerish);
addSelectiomChangeListener(document, onPointerish);
addScrollListener(document, onPointerish);
// Window events
addEventListener(window, BLUR, onBlurWindow, bubbleOptions);
addEventListener(window, FOCUS, onFocusWindow, bubbleOptions);
// Must be capture phase because 'stopPropagation' might prevent these
// events bubbling to the document.
addEventListener(document, KEYDOWN, onKeyDown, captureOptions);
addEventListener(
document,
VISIBILITYCHANGE,
onVisibilityChange,
captureOptions
);
addEventListener(document, POINTERDOWN, onPointerish, captureOptions);
addEventListener(document, POINTERMOVE, onPointerish, captureOptions);
// Fallback events
addEventListener(document, CONTEXTMENU, onPointerish, captureOptions);
addEventListener(document, MOUSEDOWN, onPointerish, captureOptions);
addEventListener(document, MOUSEMOVE, onPointerish, captureOptions);
addEventListener(document, MOUSEUP, onPointerish, captureOptions);
addEventListener(document, TOUCHCANCEL, onPointerish, captureOptions);
addEventListener(document, TOUCHMOVE, onPointerish, captureOptions);
addEventListener(document, TOUCHSTART, onPointerish, captureOptions);
addEventListener(document, SELECTIONCHANGE, onPointerish, captureOptions);
addEventListener(document, SCROLL, onPointerish, captureOptions);
}
function callListeners() {

View File

@@ -7,7 +7,7 @@
* @flow
*/
import createEventHandle from '../createEventHandle';
import { addEventListener } from '../addEventListener';
import useLayoutEffect from '../useLayoutEffect';
import useStable from '../useStable';
@@ -27,16 +27,16 @@ type AddListener = (
* }).
*/
export default function useEvent(
event: string,
eventType: string,
options?: ?{
capture?: boolean,
passive?: boolean
passive?: boolean,
once?: boolean
}
): AddListener {
const targetListeners = useStable(() => new Map());
const addListener = useStable(() => {
const addEventListener = createEventHandle(event, options);
return (target: EventTarget, callback: Callback) => {
const removeTargetListener = targetListeners.get(target);
if (removeTargetListener != null) {
@@ -44,8 +44,14 @@ export default function useEvent(
}
if (callback == null) {
targetListeners.delete(target);
callback = () => {};
}
const removeEventListener = addEventListener(target, callback);
const removeEventListener = addEventListener(
target,
eventType,
callback,
options
);
targetListeners.set(target, removeEventListener);
return removeEventListener;
};