// @ts-nocheck /** * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ 'use strict' import { canUseDOM } from '../canUseDOM' type Listener = (e: any) => void type EventHandle = (target: EventTarget, callback: Listener | null) => () => void export type EventOptions = { capture?: boolean passive?: boolean } const emptyFunction = () => {} function supportsPassiveEvents(): boolean { let supported = false // Check if browser supports event with passive listeners // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support if (canUseDOM) { try { const options = {} Object.defineProperty(options, 'passive', { get() { supported = true return false }, }) window.addEventListener('test', null, options) window.removeEventListener('test', null, options) } catch (e) {} } return supported } const canUsePassiveEvents = supportsPassiveEvents() function getOptions(options: EventOptions | null): EventOptions | boolean { if (options == null) { return false } return canUsePassiveEvents ? options : Boolean(options.capture) } /** * Shim generic API compatibility with ReactDOM's synthetic events, without needing the * large amount of code ReactDOM uses to do this. Ideally we wouldn't use a synthetic * event wrapper at all. */ function isPropagationStopped() { return this.cancelBubble } function isDefaultPrevented() { return this.defaultPrevented } function normalizeEvent(event: any) { event.nativeEvent = event event.persist = emptyFunction event.isDefaultPrevented = isDefaultPrevented event.isPropagationStopped = isPropagationStopped return event } /** * */ export function createEventHandle( type: string, options?: EventOptions | null ): EventHandle { const opts = getOptions(options) return function (target: EventTarget, listener: Listener | null) { if (target == null || typeof target.addEventListener !== 'function') { throw new Error('createEventHandle: called on an invalid target.') } const element = target as 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 } } }