"use strict";

function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = void 0;

var _react = _interopRequireDefault(require("react"));

var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));

var _keyCodes = require("../../accessibility-utils/keyCodes");

var _uniqueId = _interopRequireDefault(require("../../utils/uniqueId"));

var _componentCategories = _interopRequireDefault(require("../../docs-utils/componentCategories"));

var _componentGroups = _interopRequireDefault(require("../../docs-utils/componentGroups"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }

function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }

function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }

function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }

function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }

function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }

function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }

var AccessNavigationManager = function AccessNavigationManager(WrappedComponent) {
  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var activecss = data.activecss,
      wrap = data.wrap,
      focus = data.focus,
      _data$keyName = data.keyName,
      keyName = _data$keyName === void 0 ? {} : _data$keyName,
      grid = data.grid;

  var AccessNavigationManager = /*#__PURE__*/function (_React$Component) {
    _inherits(AccessNavigationManager, _React$Component);

    var _super = _createSuper(AccessNavigationManager);

    function AccessNavigationManager(props) {
      var _this;

      _classCallCheck(this, AccessNavigationManager);

      _this = _super.call(this, props);
      _this.state = {
        activedescendantId: undefined
      };
      _this.rootEle = null;
      _this.uitype = null;
      _this.onKeyDownCallBack = null;
      _this.rootEleId = (0, _uniqueId["default"])();
      _this.getRootRef = _this.getRootRef.bind(_assertThisInitialized(_this));
      _this.currentNodeEle = null;
      _this.currentNodeIndex = 0;
      _this.focusGridView = _this.focusGridView.bind(_assertThisInitialized(_this));
      _this.focusFirst = _this.focusFirst.bind(_assertThisInitialized(_this));
      _this.getFocusableTree = _this.getFocusableTree.bind(_assertThisInitialized(_this));
      _this.defaultKeyPress = _this.defaultKeyPress.bind(_assertThisInitialized(_this));
      _this.getNextRowCurrentIndexEle = _this.getNextRowCurrentIndexEle.bind(_assertThisInitialized(_this));
      _this.getNextRowEle = _this.getNextRowEle.bind(_assertThisInitialized(_this));
      _this.focusManager = _this.focusManager.bind(_assertThisInitialized(_this));
      _this.wrapNextRowChangeIndex = _this.wrapNextRowChangeIndex.bind(_assertThisInitialized(_this));
      _this.setCurrentNodeIndex = _this.setCurrentNodeIndex.bind(_assertThisInitialized(_this));
      _this.getItemProps = _this.getItemProps.bind(_assertThisInitialized(_this));
      _this.keyMoving = _this.keyMoving.bind(_assertThisInitialized(_this));
      _this.navigationProps = _this.navigationProps.bind(_assertThisInitialized(_this));
      return _this;
    }

    _createClass(AccessNavigationManager, [{
      key: "getRootRef",
      value: function getRootRef() {
        if (this.rootEle === null) {
          this.rootEle = document.querySelector("[data-aria-rootid=\"".concat(this.rootEleId, "\"]"));
        }

        return this.rootEle;
      }
    }, {
      key: "componentWillUnmount",
      value: function componentWillUnmount() {
        this.rootEle = null;
      }
    }, {
      key: "wrapNextRowChangeIndex",
      value: function wrapNextRowChangeIndex(mode, node) {
        if (mode === 'next') {
          this.currentNodeIndex = 0;
        } else {
          /** not get parent children in Selection element */
          if (node.getAttribute("data-aria-row") === 'true' && !node.contains(this.currentNodeEle)) {
            this.currentNodeIndex = (node && node.querySelectorAll('[data-aria-col="true"]').length) + 1;
          }
        }
      }
    }, {
      key: "getFocusableTree",
      value: function getFocusableTree(root, mode) {
        var _this2 = this;

        var walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, mode === 'next' || mode === 'previous' ? {
          acceptNode: function acceptNode(node) {
            if (node.getAttribute('data-aria-col') === 'true' || node.getAttribute('data-aria-item') === 'true') {
              return NodeFilter.FILTER_ACCEPT;
            } else {
              _this2.wrapNextRowChangeIndex(mode, node);

              return NodeFilter.FILTER_SKIP;
            }
          }
        } : mode === 'nextRow' ? {
          acceptNode: function acceptNode(node) {
            if (node.getAttribute('data-aria-row') === 'true') {
              return NodeFilter.FILTER_ACCEPT;
            } else {
              return NodeFilter.FILTER_SKIP;
            }
          }
        } : {
          acceptNode: function acceptNode(node) {
            if (node.getAttribute('data-aria-row') === 'true' && _this2.currentNodeIndex <= (node && node.querySelectorAll('[data-aria-col="true"]').length)) {
              return NodeFilter.FILTER_ACCEPT;
            } else {
              return NodeFilter.FILTER_SKIP;
            }
          }
        });
        return walker;
      }
    }, {
      key: "focusManager",
      value: function focusManager(mode) {
        var nextNode;
        var rootEle = this.getRootRef();
        var walker = this.getFocusableTree(rootEle, mode);
        var node = this.currentNodeEle ? this.currentNodeEle : walker.currentNode;

        if (rootEle.contains(node)) {
          walker.currentNode = node;
          nextNode = mode === 'next' ? walker.nextNode() : walker.previousNode();

          if (nextNode !== null) {
            this.currentNodeEle = nextNode;

            if (mode === 'next') {
              this.currentNodeIndex++;
            } else {
              this.currentNodeIndex--;
            }
          } else {
            if (wrap) {
              walker.currentNode = rootEle;
              nextNode = mode === 'next' ? walker.nextNode() : walker.lastChild();

              if (mode === 'next') {
                this.currentNodeIndex++;
              } else {
                this.currentNodeIndex--;
              }
            } else {
              return;
            }
          }

          walker.currentNode = node;

          if (walker.currentNode && this.currentNodeEle) {
            walker.currentNode.classList.remove(activecss);
            walker.currentNode.setAttribute('aria-selected', 'false'); //this.setState({ariaSelected:undefined})
          }
        }

        if (wrap) {
          this.currentNodeEle = nextNode;
        }

        if (this.currentNodeEle && activecss) {
          this.currentNodeEle.classList.add(activecss);
          this.currentNodeEle.setAttribute('aria-selected', 'true');
          this.setState({
            activedescendantId: this.currentNodeEle.id
          });
          !focus && this.currentNodeEle.scrollIntoView({
            block: 'nearest'
          });
          focus && this.currentNodeEle.focus();
        }

        return this.currentNodeEle;
      }
    }, {
      key: "getNextRowCurrentIndexEle",
      value: function getNextRowCurrentIndexEle(nextSibling) {
        var walker = this.getFocusableTree(nextSibling, 'next');

        for (var i = 0; i < this.currentNodeIndex; i++) {
          this.currentNodeEle = walker.nextNode();
        }
      }
    }, {
      key: "getNextRowEle",
      value: function getNextRowEle(mode, currentRoot, nextChildRow) {
        var rootEle = this.getRootRef();
        var gridWalker = this.getFocusableTree(rootEle, nextChildRow || 'nextRow');
        var node = this.currentNodeEle ? this.currentNodeEle : gridWalker.currentNode;
        var previousNode;

        if (rootEle.contains(node)) {
          gridWalker.currentNode = currentRoot || node;
          previousNode = gridWalker.currentNode;
        }

        gridWalker.parentNode();
        var nextSibling = mode === 'last' ? gridWalker.lastChild() : mode === 'next' ? gridWalker.nextNode() : gridWalker.previousNode();
        var nextSiblingChildLength = nextSibling && nextSibling.querySelectorAll('[data-aria-col="true"]').length || 0;
        return {
          nextSibling: nextSibling,
          previousNode: previousNode,
          nextSiblingChildLength: nextSiblingChildLength
        };
      }
    }, {
      key: "focusGridView",
      value: function focusGridView(mode) {
        var rootEle = this.getRootRef();

        var _this$getNextRowEle = this.getNextRowEle(mode),
            nextSibling = _this$getNextRowEle.nextSibling,
            previousNode = _this$getNextRowEle.previousNode,
            nextSiblingChildLength = _this$getNextRowEle.nextSiblingChildLength;

        if (nextSibling !== null) {
          if (this.currentNodeIndex <= nextSiblingChildLength) {
            this.getNextRowCurrentIndexEle(nextSibling);
          } else {
            var _this$getNextRowEle2 = this.getNextRowEle(mode, '', 'nextChildRow'),
                _nextSibling = _this$getNextRowEle2.nextSibling;

            _nextSibling && this.getNextRowCurrentIndexEle(_nextSibling);
          }
        } else {
          if (wrap) {
            var _this$getNextRowEle3 = this.getNextRowEle(mode === 'next' ? 'next' : 'last', rootEle),
                _nextSibling2 = _this$getNextRowEle3.nextSibling,
                _nextSiblingChildLength = _this$getNextRowEle3.nextSiblingChildLength;

            if (this.currentNodeIndex <= _nextSiblingChildLength) {
              this.getNextRowCurrentIndexEle(_nextSibling2);
            }
          } else {
            return;
          }
        }

        if (previousNode && this.currentNodeEle) {
          previousNode.classList.remove(activecss);
        }

        if (this.currentNodeEle && activecss) {
          this.currentNodeEle.classList.add(activecss);
          focus && this.currentNodeEle.focus();
        }
      }
    }, {
      key: "setCurrentNodeIndex",
      value: function setCurrentNodeIndex() {
        var _this3 = this;

        var rootEle = this.getRootRef();
        var walkerRow = this.getFocusableTree(rootEle, 'nextRow');
        walkerRow.currentNode = this.currentNodeEle;
        var getChildNodes = walkerRow.parentNode();

        if (getChildNodes && getChildNodes.children) {
          Object.keys(getChildNodes.children).forEach(function (element, index) {
            if (getChildNodes.children[element] === _this3.currentNodeEle) {
              _this3.currentNodeIndex = index + 1;
            }
          });
        } else {
          return;
        }
      }
    }, {
      key: "focusFirst",
      value: function focusFirst(itemId) {
        var rootEle = this.getRootRef();
        var from = rootEle.querySelector("[data-aria-itemid=\"".concat(itemId, "\"]"));
        var walker = this.getFocusableTree(rootEle, 'next');
        var node = this.currentNodeEle ? this.currentNodeEle : walker.currentNode;

        if (rootEle.contains(node)) {
          node && node.classList.remove(activecss);
        }

        if (!from) {
          this.currentNodeEle = walker.nextNode();
        } else {
          this.currentNodeEle = from;
          this.setCurrentNodeIndex();
        }

        if (this.currentNodeEle && activecss) {
          this.currentNodeEle.classList.add(activecss);
          focus && this.currentNodeEle.focus();
        }

        return this.currentNodeEle;
      }
    }, {
      key: "keyMoving",
      value: function keyMoving(e, keys) {
        if (keys.toLowerCase() === 'left' || keys.toLowerCase() === 'up') {
          if (keys.toLowerCase() === 'up') {
            grid ? this.focusGridView('previous') : this.focusManager('previous');
            e && e.preventDefault();
          } else {
            this.focusManager('previous');
          }
        } else if (keys.toLowerCase() === 'right' || keys.toLowerCase() === 'down') {
          if (keys.toLowerCase() === 'down') {
            grid ? this.focusGridView('next') : this.focusManager('next');
            e && e.preventDefault();
          } else {
            this.focusManager('next');
          }
        } else if (keys.toLowerCase() === 'tabforward' || keys.toLowerCase() === 'tabbackward') {
          if (keys.toLowerCase() === 'tabforward') {
            e && e.preventDefault();
            this.focusManager('next');
          } else {
            this.focusManager('previous');
          }
        }
      }
    }, {
      key: "defaultKeyPress",
      value: function defaultKeyPress(onKeyDown, e) {
        var _this4 = this;

        onKeyDown && onKeyDown(e);
        var keyCode = e.keyCode;
        var arrowleft = _keyCodes.keyNames.arrowleft,
            arrowright = _keyCodes.keyNames.arrowright,
            arrowtop = _keyCodes.keyNames.arrowtop,
            arrowbottom = _keyCodes.keyNames.arrowbottom;
        var leftArrow = _keyCodes.keyCodes.leftArrow,
            rightArrow = _keyCodes.keyCodes.rightArrow,
            topArrow = _keyCodes.keyCodes.topArrow,
            bottomArrow = _keyCodes.keyCodes.bottomArrow;

        if (Object.keys(keyName).length) {
          Object.keys(keyName).forEach(function (keys) {
            keyName[keys].forEach(function (value) {
              if (value.indexOf('shift') !== -1 && event.shiftKey) {
                var splitedKey = value.split('+')[1];

                if (splitedKey.toLowerCase() === e.key.toLowerCase()) {
                  _this4.keyMoving(e, keys);
                }
              } else {
                if (value.toLowerCase() === e.key.toLowerCase()) {
                  _this4.keyMoving(e, keys);
                }
              }
            });
          });
        } else {
          if (keyCode === 37) {
            grid && this.focusManager('previous');
          }

          if (keyCode === 39) {
            grid && this.focusManager('next');
          }

          if (keyCode === 40) {
            e && e.preventDefault();
            grid && this.focusGridView('next');
            !grid && this.focusManager('next');
          }

          if (keyCode === 38) {
            e && e.preventDefault();
            grid && this.focusGridView('previous');
            !grid && this.focusManager('previous');
          }
        }

        if (keyCode === 13) {
          this.currentNodeEle && this.currentNodeEle.click();
        }
      }
    }, {
      key: "getItemProps",
      value: function getItemProps(props) {
        var role = props.role,
            id = props.id,
            _props$dataAriaItem = props.dataAriaItem,
            dataAriaItem = _props$dataAriaItem === void 0 ? {} : _props$dataAriaItem;
        var genratedRadomId = id || (0, _uniqueId["default"])();

        var dataAriaItems = _objectSpread({
          'data-aria-item': 'true',
          'data-aria-itemid': genratedRadomId,
          id: genratedRadomId,
          role: role
        }, dataAriaItem);

        var dataAriaCol = {
          'data-aria-col': 'true',
          'data-aria-itemid': genratedRadomId,
          role: role
        };

        if (this.uitype === 'listbox' || this.uitype === 'grid') {
          dataAriaItems['onKeyDown'] = this.defaultKeyPress.bind(this, this.onKeyDownCallBack);
          dataAriaCol['onKeyDown'] = this.defaultKeyPress.bind(this, this.onKeyDownCallBack);
        }

        return {
          dataAriaCol: dataAriaCol,
          dataAriaColDisabled: {
            'data-aria-col': 'false',
            'aria-disabled': 'true'
          },
          dataAriaRow: {
            'data-aria-row': 'true'
          },
          dataAriaItem: dataAriaItems,
          dataAriaItemDisabled: {
            'data-aria-item': 'false',
            'aria-disabled': 'true'
          },
          itemId: genratedRadomId
        };
      }
    }, {
      key: "navigationProps",
      value: function navigationProps(props) {
        var _ref = props || {},
            onKeyDown = _ref.onKeyDown,
            type = _ref.type,
            popupOpen = _ref.popupOpen,
            _ref$listElementProps = _ref.listElementProps,
            listElementProps = _ref$listElementProps === void 0 ? {} : _ref$listElementProps,
            _ref$targetElementPro = _ref.targetElementProps,
            targetElementProps = _ref$targetElementPro === void 0 ? {} : _ref$targetElementPro,
            _ref$inputProps = _ref.inputProps,
            inputProps = _ref$inputProps === void 0 ? {} : _ref$inputProps;

        this.uitype = type;
        this.onKeyDownCallBack = onKeyDown;
        var rootElementProps = {};

        var listElementProp = _objectSpread({
          role: 'listbox',
          id: this.rootEleId
        }, listElementProps);

        if (type === 'combobox') {
          //rootElementProps['role'] = "combobox"; 
          //rootElementProps['aria-owns'] = this.rootEleId;
          rootElementProps['data-aria-rootid'] = this.rootEleId;
        } else if (type === 'grid') {
          rootElementProps['role'] = "grid";
          rootElementProps['data-aria-rootid'] = this.rootEleId;
        } else {
          listElementProp['aria-activedescendant'] = this.state.activedescendantId;
          rootElementProps['data-aria-rootid'] = this.rootEleId;
        }

        return {
          rootElementProps: rootElementProps,
          focusFirst: this.focusFirst,
          focusManager: this.focusManager,
          inputProps: _objectSpread({
            onKeyDown: this.defaultKeyPress.bind(this, onKeyDown),
            'aria-activedescendant': this.state.activedescendantId,
            'aria-owns': this.rootEleId,
            'role': 'combobox'
          }, inputProps),
          getItemProps: this.getItemProps,
          listElementProps: listElementProp,
          targetElementProps: _objectSpread({
            'aria-controls': this.rootEleId,
            'aria-haspopup': listElementProps.role || 'listbox',
            'aria-expanded': popupOpen ? 'true' : 'false'
          }, targetElementProps)
        };
      }
    }, {
      key: "render",
      value: function render() {
        return /*#__PURE__*/_react["default"].createElement(WrappedComponent, {
          navigationProps: this.navigationProps
        });
      }
    }]);

    return AccessNavigationManager;
  }(_react["default"].Component);

  return (0, _hoistNonReactStatics["default"])(AccessNavigationManager, WrappedComponent);
};

var _default = AccessNavigationManager;
exports["default"] = _default;

if (false) {
  AccessNavigationManager.docs = {
    componentGroup: _componentGroups["default"].Components,
    folderName: _componentCategories["default"].Accessibility
  };
}