"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
var _testUtils = _interopRequireDefault(require("react-dom/test-utils"));
var _values = _interopRequireDefault(require("../utils/operators/values"));
var _DataAttr = require("./DataAttr");
var dropdownLayoutDriverFactory = _ref => {
  var {
    element,
    wrapper
  } = _ref;
  var byDataHook = dataHook => element.querySelector("[data-hook=\"".concat(dataHook, "\"]"));
  var contentContainer = byDataHook(_DataAttr.DATA_HOOKS.CONTENT_CONTAINER);
  var infiniteScrollContainer = byDataHook(_DataAttr.DATA_HOOKS.INFINITE_SCROLL_CONTAINER);
  var optionElementsContainer = byDataHook(_DataAttr.DATA_HOOKS.DROPDOWN_LAYOUT_OPTIONS);
  var optionElements = infiniteScrollContainer ? infiniteScrollContainer : optionElementsContainer;
  var getListItemPositionAtSelector = position => "[data-list-type=\"action\"] [data-hook=".concat(_DataAttr.DATA_HOOKS.DROPDOWN_LAYOUT_OPTIONS, "] > *:nth-child(").concat(position + 1, ") > *");
  var optionElementAt = position => {
    return element.querySelector(getListItemPositionAtSelector(position)) || optionElements.childNodes[position];
  };
  var optionsLength = () => optionElements.childNodes.length;
  var doIfOptionExists = (position, onSuccess) => {
    if (optionsLength() <= position) {
      throw new Error("index out of bounds, try to get option ".concat(position, " while only ").concat(optionsLength(), " options exists"));
    }
    return onSuccess();
  };
  var getOptionDriver = position => doIfOptionExists(position, () => createOptionDriver(optionElementAt(position)));
  var options = () => (0, _values.default)(optionElements.childNodes);
  return {
    /** @deprecated */
    classes: () => optionElementsContainer.className,
    clickAtOption: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.click();
    }),
    clickAtOptionWithValue: value => {
      for (var _option of options()) {
        var optionDriver = createOptionDriver(_option);
        if (optionDriver.content() === value) {
          return optionDriver.click();
        }
      }
    },
    exists: () => !!element,
    /** @deprecated deprecated prop */
    hasTopArrow: () => !!element.querySelector("[data-hook=\"".concat(_DataAttr.DATA_HOOKS.TOP_ARROW, "\"]")),
    /** @deprecated deprecated prop */
    isDown: () => contentContainer.getAttribute(_DataAttr.DATA_DIRECTION) === _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.DOWN,
    /** @deprecated deprecated prop */
    isUp: () => contentContainer.getAttribute(_DataAttr.DATA_DIRECTION) === _DataAttr.DROPDOWN_LAYOUT_DIRECTIONS.UP,
    isLinkOption: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.isLink();
    }),
    isOptionADivider: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.isDivider();
    }),
    isOptionExists: optionText => [].filter.call(optionElements.childNodes, opt => opt.textContent === optionText).length > 0,
    /** returns if an option is hovered. notice that it checks by index and __not__ by id */
    isOptionHovered: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.isHovered();
    }),
    isOptionSelected: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.isSelected();
    }),
    /** @deprecated */
    isOptionHeightSmall: position => doIfOptionExists(position, () => optionElementAt(position).getAttribute(_DataAttr.DATA_OPTION.SIZE) === 'small'),
    /** @deprecated */
    isOptionHeightBig: position => doIfOptionExists(position, () => optionElementAt(position).getAttribute(_DataAttr.DATA_OPTION.SIZE) === 'big'),
    isListItemFocused: position => document.activeElement === element.querySelector(getListItemPositionAtSelector(position)),
    isShown: () => contentContainer.hasAttribute(_DataAttr.DATA_SHOWN),
    mouseEnter: () => _testUtils.default.Simulate.mouseEnter(element),
    mouseEnterAtOption: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.mouseEnter();
    }),
    mouseLeave: () => _testUtils.default.Simulate.mouseLeave(element),
    /** @deprecated deprecated prop */
    mouseClickOutside: () => document.body.dispatchEvent(new Event('mouseup', {
      cancelable: true,
      bubbles: true
    })),
    mouseLeaveAtOption: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.mouseLeave();
    }),
    /** @deprecated Use optionDriver*/
    optionAt: optionElementAt,
    /** @deprecated This should be a private method since the hook include internal parts ('dropdown-divider-{id}, dropdown-item-{id})') */
    optionByHook: hook => {
      var option = optionElements.querySelector("[data-hook=".concat(hook, "]"));
      if (!option) {
        throw new Error("an option with data-hook ".concat(hook, " was not found"));
      }
      return createOptionDriver(option);
    },
    optionById(optionId) {
      return this.optionByHook("dropdown-item-".concat(optionId));
    },
    optionContentAt: position => doIfOptionExists(position, () => {
      var optionDriver = getOptionDriver(position);
      return optionDriver.content();
    }),
    /** Get option driver given an option index */
    optionDriver: createOptionDriver,
    /** Get an array of all options including dividers (drivers) */
    options: () => {
      var drivers = [];
      for (var position = 0; position < optionsLength(); position++) {
        drivers.push(getOptionDriver(position));
      }
      return drivers;
    },
    optionsContent: () => {
      var contentArray = [];
      for (var option of options()) {
        var optionDriver = createOptionDriver(option);
        contentArray.push(optionDriver.content());
      }
      return contentArray;
    },
    markedOption: function () {
      var _markedOption = (0, _asyncToGenerator2.default)(function* () {
        var hoveredOption = optionElements.querySelector("[".concat(_DataAttr.DATA_OPTION.HOVERED, "=\"true\"]"));
        return hoveredOption && createOptionDriver(hoveredOption).content() || null;
      });
      function markedOption() {
        return _markedOption.apply(this, arguments);
      }
      return markedOption;
    }(),
    getSelectedOptionId: () => contentContainer.getAttribute(_DataAttr.DATA_SELECTED_OPTION_ID),
    optionsLength,
    /** @deprecated should be private */
    optionsScrollTop: () => optionElements.scrollTop,
    pressDownKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: 'ArrowDown'
    }),
    pressUpKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: 'ArrowUp'
    }),
    pressEnterKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: 'Enter'
    }),
    pressSpaceKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: ' '
    }),
    pressTabKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: 'Tab'
    }),
    pressEscKey: () => _testUtils.default.Simulate.keyDown(element, {
      key: 'Escape'
    }),
    keyDownListItem: (position, key) => doIfOptionExists(position, () => {
      return _testUtils.default.Simulate.keyDown(element.querySelector(getListItemPositionAtSelector(position)), {
        key
      });
    }),
    tabIndex: () => element.tabIndex,
    getListItemAttribute: (position, attribute) => optionElementAt(position).getAttribute(attribute),
    getListType: function () {
      var _getListType = (0, _asyncToGenerator2.default)(function* (dataHook) {
        return wrapper.querySelector("[data-hook=\"".concat(dataHook, "\"]")).getAttribute('data-list-type');
      });
      function getListType(_x) {
        return _getListType.apply(this, arguments);
      }
      return getListType;
    }(),
    getOptionsContainerRole: () => optionElementsContainer.getAttribute('role')
  };
};
var createOptionDriver = option => ({
  element: () => option,
  mouseEnter: () => _testUtils.default.Simulate.mouseEnter(option),
  mouseLeave: () => _testUtils.default.Simulate.mouseLeave(option),
  isHovered: () => option.hasAttribute(_DataAttr.DATA_OPTION.HOVERED),
  isSelected: () => option.hasAttribute(_DataAttr.DATA_OPTION.SELECTED),
  content: () => option.textContent,
  click: () => _testUtils.default.Simulate.click(option),
  isDivider: () => {
    var divider = option.querySelector("[data-hook=\"".concat(_DataAttr.OPTION_DATA_HOOKS.DIVIDER, "\"]"));
    return !!divider;
  },
  isDisabled: () => option.hasAttribute(_DataAttr.DATA_OPTION.DISABLED),
  isLink: () => option.tagName.toLowerCase() === 'a'
});
var _default = exports.default = dropdownLayoutDriverFactory;
//# sourceMappingURL=DropdownLayout.driver.js.map