"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
exports.isEventEnabled = isEventEnabled;
exports.isTouchResponder = isTouchResponder;
var _act = _interopRequireDefault(require("./act"));
var _pointerEvents = require("./helpers/pointer-events");
var _componentTree = require("./helpers/component-tree");
var _hostComponentNames = require("./helpers/host-component-names");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isTouchResponder(element) {
  if (!(0, _componentTree.isHostElement)(element)) {
    return false;
  }
  return Boolean(element.props.onStartShouldSetResponder) || (0, _hostComponentNames.isHostTextInput)(element);
}

/**
 * List of events affected by `pointerEvents` prop.
 *
 * Note: `fireEvent` is accepting both `press` and `onPress` for event names,
 * so we need cover both forms.
 */
const eventsAffectedByPointerEventsProp = new Set(['press', 'onPress']);

/**
 * List of `TextInput` events not affected by `editable` prop.
 *
 * Note: `fireEvent` is accepting both `press` and `onPress` for event names,
 * so we need cover both forms.
 */
const textInputEventsIgnoringEditableProp = new Set(['contentSizeChange', 'onContentSizeChange', 'layout', 'onLayout', 'scroll', 'onScroll']);
function isEventEnabled(element, eventName, nearestTouchResponder) {
  if ((0, _hostComponentNames.isHostTextInput)(nearestTouchResponder)) {
    return nearestTouchResponder?.props.editable !== false || textInputEventsIgnoringEditableProp.has(eventName);
  }
  if (eventsAffectedByPointerEventsProp.has(eventName) && !(0, _pointerEvents.isPointerEventEnabled)(element)) {
    return false;
  }
  const touchStart = nearestTouchResponder?.props.onStartShouldSetResponder?.();
  const touchMove = nearestTouchResponder?.props.onMoveShouldSetResponder?.();
  if (touchStart || touchMove) {
    return true;
  }
  return touchStart === undefined && touchMove === undefined;
}
function findEventHandler(element, eventName, nearestTouchResponder) {
  const touchResponder = isTouchResponder(element) ? element : nearestTouchResponder;
  const handler = getEventHandler(element, eventName);
  if (handler && isEventEnabled(element, eventName, touchResponder)) return handler;
  if (element.parent === null || element.parent.parent === null) {
    return null;
  }
  return findEventHandler(element.parent, eventName, touchResponder);
}
function getEventHandler(element, eventName) {
  const eventHandlerName = getEventHandlerName(eventName);
  if (typeof element.props[eventHandlerName] === 'function') {
    return element.props[eventHandlerName];
  }
  if (typeof element.props[eventName] === 'function') {
    return element.props[eventName];
  }
  return undefined;
}
function getEventHandlerName(eventName) {
  return `on${eventName.charAt(0).toUpperCase()}${eventName.slice(1)}`;
}

// Allows any string but will provide autocomplete for type T

// String union type of keys of T that start with on, stripped from on

function fireEvent(element, eventName, ...data) {
  const handler = findEventHandler(element, eventName);
  if (!handler) {
    return;
  }
  let returnValue;
  (0, _act.default)(() => {
    returnValue = handler(...data);
  });
  return returnValue;
}
fireEvent.press = (element, ...data) => fireEvent(element, 'press', ...data);
fireEvent.changeText = (element, ...data) => fireEvent(element, 'changeText', ...data);
fireEvent.scroll = (element, ...data) => fireEvent(element, 'scroll', ...data);
var _default = fireEvent;
exports.default = _default;
//# sourceMappingURL=fireEvent.js.map