All files / react-native-web/src/modules/createEventHandle index.js

91.43% Statements 32/35
71.43% Branches 10/14
81.82% Functions 9/11
91.18% Lines 31/34

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98                                            5x     5x     5x 5x 5x 5x   5x 5x     5x 5x     5x     5x     305x 30x   275x                             242x 242x 242x 242x 242x             305x   305x 244x       244x 244x 242x 210x 210x 153x 153x       34x        
/**
 * 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
 */
 
'use strict';
 
import { canUseDOM } from 'fbjs/lib/ExecutionEnvironment';
 
type Listener = (e: any) => void;
 
type EventHandle = (target: EventTarget, callback: ?Listener) => () => 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
  Eif (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): 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 default function createEventHandle(type: string, options: ?EventOptions): EventHandle {
  const opts = getOptions(options);
 
  return function (target: EventTarget, listener: ?Listener) {
    Iif (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() {
        Eif (element != null) {
          element.removeEventListener(type, compatListener, opts);
        }
      };
    } else {
      return emptyFunction;
    }
  };
}