"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _comp = require("../../ui/src/comp");
var _xeUtils = _interopRequireDefault(require("xe-utils"));
var _ui = require("../../ui");
var _dom = require("../../ui/src/dom");
var _utils = require("../../ui/src/utils");
var _vn = require("../../ui/src/vn");
var _log = require("../../ui/src/log");
var _loading = _interopRequireDefault(require("../../loading"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var _createComponentLog = (0, _log.createComponentLog)('menu'),
  errLog = _createComponentLog.errLog;
var menus = _ui.VxeUI.menus,
  getConfig = _ui.VxeUI.getConfig,
  getIcon = _ui.VxeUI.getIcon;
var _default2 = exports.default = /* define-vxe-component start */(0, _comp.defineVxeComponent)({
  name: 'VxeMenu',
  mixins: [_ui.globalMixins.sizeMixin, _ui.globalMixins.permissionMixin],
  props: {
    value: [String, Number],
    expandAll: Boolean,
    accordion: {
      type: Boolean,
      default: function _default() {
        return getConfig().menu.accordion;
      }
    },
    collapsed: {
      type: Boolean,
      default: null
    },
    collapseFixed: Boolean,
    loading: Boolean,
    options: {
      type: Array,
      default: function _default() {
        return [];
      }
    },
    size: {
      type: String,
      default: function _default() {
        return getConfig().menu.size || getConfig().size;
      }
    },
    menuConfig: Object
  },
  inject: {
    $xeLayoutAside: {
      default: null
    }
  },
  data: function data() {
    var reactData = {
      initialized: false,
      isEnterCollapse: false,
      collapseStyle: {},
      collapseZindex: 0,
      activeName: null,
      menuList: [],
      itemHeight: 1
    };
    return {
      xID: _xeUtils.default.uniqueId(),
      reactData: reactData
    };
  },
  computed: Object.assign(Object.assign({}, {}), {
    computeMenuOpts: function computeMenuOpts() {
      var $xeMenu = this;
      var props = $xeMenu;
      return Object.assign({}, getConfig().tree.menuConfig, props.menuConfig);
    },
    computeIsCollapsed: function computeIsCollapsed() {
      var $xeMenu = this;
      var $xeLayoutAside = $xeMenu.$xeLayoutAside;
      var collapsed = $xeMenu.collapsed;
      if (_xeUtils.default.isBoolean(collapsed)) {
        return collapsed;
      }
      if ($xeLayoutAside) {
        return !!$xeLayoutAside.collapsed;
      }
      return false;
    },
    computeCollapseWidth: function computeCollapseWidth() {
      var $xeMenu = this;
      var $xeLayoutAside = $xeMenu.$xeLayoutAside;
      var collapseWidth = '';
      if ($xeLayoutAside) {
        collapseWidth = $xeLayoutAside.collapseWidth || '';
      }
      return collapseWidth;
    },
    computeCollapseEnterWidth: function computeCollapseEnterWidth() {
      var $xeMenu = this;
      var $xeLayoutAside = $xeMenu.$xeLayoutAside;
      var width = '';
      if ($xeLayoutAside) {
        width = $xeLayoutAside.width || '';
      }
      return width;
    }
  }),
  methods: {
    //
    // Method
    //
    dispatchEvent: function dispatchEvent(type, params, evnt) {
      var $xeMenu = this;
      $xeMenu.$emit(type, (0, _ui.createEvent)(evnt, {
        $menu: $xeMenu
      }, params));
    },
    emitModel: function emitModel(value) {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var _events = $xeMenu._events;
      reactData.activeName = value;
      $xeMenu.$emit('input', value);
      if (_events && _events.modelValue) {
        $xeMenu.$emit('modelValue', value);
      } else {
        $xeMenu.$emit('model-value', value);
      }
    },
    callSlot: function callSlot(slotFunc, params, h) {
      var $xeMenu = this;
      var slots = $xeMenu.$scopedSlots;
      if (slotFunc) {
        if (_xeUtils.default.isString(slotFunc)) {
          slotFunc = slots[slotFunc] || null;
        }
        if (_xeUtils.default.isFunction(slotFunc)) {
          return (0, _vn.getSlotVNs)(slotFunc.call($xeMenu, params, h));
        }
      }
      return [];
    },
    getMenuTitle: function getMenuTitle(item) {
      return "".concat(item.title || item.name);
    },
    updateZindex: function updateZindex() {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      if (reactData.collapseZindex < (0, _utils.getLastZIndex)()) {
        reactData.collapseZindex = (0, _utils.nextZIndex)();
      }
    },
    updateActiveMenu: function updateActiveMenu(isDefExpand) {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var activeName = reactData.activeName;
      _xeUtils.default.eachTree(reactData.menuList, function (item, index, items, path, parent, nodes) {
        if (item.itemKey === activeName) {
          nodes.forEach(function (obj) {
            obj.isActive = true;
            if (isDefExpand) {
              obj.isExpand = true;
            }
          });
          item.isExactActive = true;
        } else {
          item.isExactActive = false;
          item.isActive = false;
        }
      }, {
        children: 'childList'
      });
    },
    updateMenuConfig: function updateMenuConfig() {
      var $xeMenu = this;
      var props = $xeMenu;
      var reactData = $xeMenu.reactData;
      var options = props.options,
        expandAll = props.expandAll;
      reactData.menuList = _xeUtils.default.mapTree(options, function (item, index, items, path, parent) {
        var objItem = Object.assign(Object.assign({}, item), {
          parentKey: parent ? parent.name || path.slice(0, path.length - 1).join(',') : '',
          level: path.length,
          itemKey: item.name || path.join(','),
          isExactActive: false,
          isActive: false,
          isExpand: _xeUtils.default.isBoolean(item.expanded) ? item.expanded : !!expandAll,
          hasChild: item.children && item.children.length > 0
        });
        return objItem;
      }, {
        children: 'children',
        mapChildren: 'childList'
      });
    },
    updateCollapseStyle: function updateCollapseStyle() {
      var $xeMenu = this;
      var props = $xeMenu;
      var reactData = $xeMenu.reactData;
      var collapseFixed = props.collapseFixed;
      if (collapseFixed) {
        $xeMenu.$nextTick(function () {
          var isEnterCollapse = reactData.isEnterCollapse;
          var isCollapsed = $xeMenu.computeIsCollapsed;
          var collapseEnterWidth = $xeMenu.computeCollapseEnterWidth;
          var collapseWidth = $xeMenu.computeCollapseWidth;
          var el = $xeMenu.$refs.refElem;
          if (el) {
            var clientRect = el.getBoundingClientRect();
            var parentNode = el.parentNode;
            reactData.collapseStyle = isCollapsed ? {
              top: (0, _dom.toCssUnit)(clientRect.top),
              left: (0, _dom.toCssUnit)(clientRect.left),
              height: (0, _dom.toCssUnit)(parentNode.clientHeight),
              width: isEnterCollapse ? collapseEnterWidth ? (0, _dom.toCssUnit)(collapseEnterWidth) : '' : collapseWidth ? (0, _dom.toCssUnit)(collapseWidth) : '',
              zIndex: reactData.collapseZindex
            } : {};
          }
        });
      }
    },
    handleCollapseMenu: function handleCollapseMenu() {
      var $xeMenu = this;
      var props = $xeMenu;
      var reactData = $xeMenu.reactData;
      var collapseFixed = props.collapseFixed;
      if (collapseFixed) {
        var initialized = reactData.initialized;
        var isCollapsed = $xeMenu.computeIsCollapsed;
        if (isCollapsed) {
          if (!initialized) {
            reactData.initialized = true;
            $xeMenu.$nextTick(function () {
              var collapseEl = $xeMenu.$refs.refCollapseElem;
              if (collapseEl) {
                document.body.appendChild(collapseEl);
              }
            });
          }
        }
        reactData.isEnterCollapse = false;
        $xeMenu.updateZindex();
        $xeMenu.updateCollapseStyle();
      }
    },
    handleClickIconCollapse: function handleClickIconCollapse(evnt, item, itemList) {
      var $xeMenu = this;
      var props = $xeMenu;
      var accordion = props.accordion;
      var hasChild = item.hasChild,
        isExpand = item.isExpand;
      if (hasChild) {
        evnt.stopPropagation();
        evnt.preventDefault();
        if (accordion) {
          itemList.forEach(function (obj) {
            if (obj !== item) {
              obj.isExpand = false;
            }
          });
        }
        item.isExpand = !isExpand;
      }
    },
    handleContextmenuEvent: function handleContextmenuEvent(evnt, item) {
      var $xeMenu = this;
      var props = $xeMenu;
      var menuConfig = props.menuConfig;
      var menuOpts = $xeMenu.computeMenuOpts;
      if (menuConfig ? (0, _utils.isEnableConf)(menuOpts) : menuOpts.enabled) {
        var options = menuOpts.options,
          visibleMethod = menuOpts.visibleMethod;
        if (!visibleMethod || visibleMethod({
          $menu: $xeMenu,
          options: options,
          currentMenu: item
        })) {
          if (_ui.VxeUI.contextMenu) {
            _ui.VxeUI.contextMenu.openByEvent(evnt, {
              options: options,
              events: {
                optionClick: function optionClick(eventParams) {
                  var option = eventParams.option;
                  var gMenuOpts = menus.get(option.code);
                  var mmMethod = gMenuOpts ? gMenuOpts.menuMenuMethod : null;
                  var params = {
                    menu: option,
                    currentMenu: item,
                    $event: evnt,
                    $menu: $xeMenu
                  };
                  if (mmMethod) {
                    mmMethod(params, evnt);
                  }
                  $xeMenu.dispatchEvent('menu-click', params, eventParams.$event);
                }
              }
            });
          }
        }
      }
      $xeMenu.dispatchEvent('option-menu', {
        currentMenu: item
      }, evnt);
    },
    handleClickMenu: function handleClickMenu(evnt, item, itemList) {
      var $xeMenu = this;
      var itemKey = item.itemKey,
        routerLink = item.routerLink,
        hasChild = item.hasChild;
      if (routerLink) {
        $xeMenu.emitModel(itemKey);
      } else {
        if (hasChild) {
          $xeMenu.handleClickIconCollapse(evnt, item, itemList);
        } else {
          $xeMenu.emitModel(itemKey);
        }
      }
      var params = {
        currentMenu: item,
        // 已废弃
        menu: item
      };
      $xeMenu.dispatchEvent('click', params, evnt);
    },
    handleMenuMouseenter: function handleMenuMouseenter() {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var collapseStyle = reactData.collapseStyle;
      var collapseEnterWidth = $xeMenu.computeCollapseEnterWidth;
      reactData.collapseStyle = Object.assign({}, collapseStyle, {
        width: collapseEnterWidth ? (0, _dom.toCssUnit)(collapseEnterWidth) : ''
      });
      reactData.isEnterCollapse = true;
    },
    handleMenuMouseover: function handleMenuMouseover() {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var isEnterCollapse = reactData.isEnterCollapse;
      if (!isEnterCollapse) {
        $xeMenu.handleMenuMouseenter();
      }
    },
    handleMenuMouseleave: function handleMenuMouseleave() {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var collapseStyle = reactData.collapseStyle;
      var el = this.$refs.refElem;
      reactData.collapseStyle = Object.assign({}, collapseStyle, {
        width: el ? (0, _dom.toCssUnit)(el.offsetWidth) : ''
      });
      reactData.isEnterCollapse = false;
    },
    //
    //
    // Render
    //
    renderMenuTitle: function renderMenuTitle(h, item, itemList) {
      var $xeMenu = this;
      var slots = $xeMenu.$scopedSlots;
      var icon = item.icon,
        isExpand = item.isExpand,
        hasChild = item.hasChild;
      var itemSlots = item.slots || {};
      var optionSlot = itemSlots.default || slots.option;
      var titleSlot = itemSlots.title || slots.optionTitle || slots['option-title'];
      var iconSlot = itemSlots.icon || slots.optionIcon || slots['option-icon'];
      var title = $xeMenu.getMenuTitle(item);
      var isCollapsed = $xeMenu.computeIsCollapsed;
      var params = {
        currentMenu: item,
        collapsed: isCollapsed,
        // 已废弃
        option: item
      };
      return [optionSlot ? (0, _ui.renderEmptyElement)($xeMenu) : h('div', {
        class: 'vxe-menu--item-link-icon'
      }, iconSlot ? $xeMenu.callSlot(iconSlot, params, h) : icon ? [h('i', {
        class: icon
      })] : []), optionSlot ? h('div', {
        class: 'vxe-menu--item-custom-title'
      }, $xeMenu.callSlot(optionSlot, params, h)) : h('div', {
        class: 'vxe-menu--item-link-title',
        attrs: {
          title: title
        }
      }, titleSlot ? $xeMenu.callSlot(titleSlot, params, h) : title), hasChild ? h('div', {
        class: 'vxe-menu--item-link-collapse',
        on: {
          click: function click(evnt) {
            $xeMenu.handleClickIconCollapse(evnt, item, itemList);
          }
        }
      }, [h('i', {
        class: isExpand ? getIcon().MENU_ITEM_EXPAND_OPEN : getIcon().MENU_ITEM_EXPAND_CLOSE
      })]) : (0, _ui.renderEmptyElement)($xeMenu)];
    },
    renderDefaultChildren: function renderDefaultChildren(h, item, itemList) {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      var itemKey = item.itemKey,
        level = item.level,
        hasChild = item.hasChild,
        isActive = item.isActive,
        isExactActive = item.isExactActive,
        isExpand = item.isExpand,
        routerLink = item.routerLink,
        childList = item.childList;
      var isEnterCollapse = reactData.isEnterCollapse;
      var isCollapsed = $xeMenu.computeIsCollapsed;
      if (item.permissionCode) {
        if (!_ui.permission.checkVisible(item.permissionCode)) {
          return (0, _ui.renderEmptyElement)($xeMenu);
        }
      }
      return h('div', {
        key: itemKey,
        class: ['vxe-menu--item-wrapper', "vxe-menu--item-level".concat(level), {
          'is--exact-active': isExactActive,
          'is--active': isActive,
          'is--expand': (!isCollapsed || isEnterCollapse) && isExpand
        }]
      }, [routerLink ? h('router-link', {
        class: 'vxe-menu--item-link',
        props: {
          custom: true,
          to: routerLink
        },
        on: {
          contextmenu: function contextmenu(evnt) {
            $xeMenu.handleContextmenuEvent(evnt, item);
          },
          click: function click(evnt) {
            $xeMenu.handleClickMenu(evnt, item, itemList);
          }
        }
      }, $xeMenu.renderMenuTitle(h, item, itemList)) : h('div', {
        class: 'vxe-menu--item-link',
        on: {
          contextmenu: function contextmenu(evnt) {
            $xeMenu.handleContextmenuEvent(evnt, item);
          },
          click: function click(evnt) {
            $xeMenu.handleClickMenu(evnt, item, itemList);
          }
        }
      }, $xeMenu.renderMenuTitle(h, item, itemList)), hasChild ? h('div', {
        class: 'vxe-menu--item-group'
      }, childList.map(function (child) {
        return $xeMenu.renderDefaultChildren(h, child, childList);
      })) : (0, _ui.renderEmptyElement)($xeMenu)]);
    },
    renderCollapseChildren: function renderCollapseChildren(h, item, itemList) {
      var $xeMenu = this;
      var itemKey = item.itemKey,
        level = item.level,
        hasChild = item.hasChild,
        isActive = item.isActive,
        isExactActive = item.isExactActive,
        routerLink = item.routerLink,
        childList = item.childList;
      if (item.permissionCode) {
        if (!_ui.permission.checkVisible(item.permissionCode)) {
          return (0, _ui.renderEmptyElement)($xeMenu);
        }
      }
      return h('div', {
        key: itemKey,
        class: ['vxe-menu--item-wrapper', "vxe-menu--item-level".concat(level), {
          'is--exact-active': isExactActive,
          'is--active': isActive
        }]
      }, [routerLink ? h('router-link', {
        class: 'vxe-menu--item-link',
        props: {
          custom: true,
          to: routerLink
        },
        on: {
          contextmenu: function contextmenu(evnt) {
            $xeMenu.handleContextmenuEvent(evnt, item);
          },
          click: function click(evnt) {
            $xeMenu.handleClickMenu(evnt, item, itemList);
          }
        }
      }, $xeMenu.renderMenuTitle(h, item, itemList)) : h('div', {
        class: 'vxe-menu--item-link',
        on: {
          contextmenu: function contextmenu(evnt) {
            $xeMenu.handleContextmenuEvent(evnt, item);
          },
          click: function click(evnt) {
            $xeMenu.handleClickMenu(evnt, item, itemList);
          }
        }
      }, $xeMenu.renderMenuTitle(h, item, itemList)), hasChild ? h('div', {
        class: 'vxe-menu--item-group'
      }, childList.map(function (child) {
        return $xeMenu.renderDefaultChildren(h, child, childList);
      })) : (0, _ui.renderEmptyElement)($xeMenu)]);
    },
    renderVN: function renderVN(h) {
      var $xeMenu = this;
      var props = $xeMenu;
      var reactData = $xeMenu.reactData;
      var loading = props.loading,
        collapseFixed = props.collapseFixed;
      var initialized = reactData.initialized,
        menuList = reactData.menuList,
        collapseStyle = reactData.collapseStyle,
        isEnterCollapse = reactData.isEnterCollapse;
      var vSize = $xeMenu.computeSize;
      var isCollapsed = $xeMenu.computeIsCollapsed;
      var ons = {};
      if (collapseFixed) {
        ons = {
          mouseenter: $xeMenu.handleMenuMouseenter,
          mouseover: $xeMenu.handleMenuMouseover,
          mouseleave: $xeMenu.handleMenuMouseleave
        };
      }
      return h('div', {
        ref: 'refElem',
        class: ['vxe-menu', _defineProperty(_defineProperty(_defineProperty({}, "size--".concat(vSize), vSize), 'is--collapsed', isCollapsed), 'is--loading', loading)]
      }, [h('div', {
        class: 'vxe-menu--item-list'
      }, menuList.map(function (child) {
        return isCollapsed ? $xeMenu.renderCollapseChildren(h, child, menuList) : $xeMenu.renderDefaultChildren(h, child, menuList);
      })), initialized ? h('div', {
        ref: 'refCollapseElem',
        class: ['vxe-menu--collapse-wrapper', _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "size--".concat(vSize), vSize), 'is--collapsed', isCollapsed), 'is--enter', isEnterCollapse), 'is--loading', loading)],
        style: collapseStyle,
        on: ons
      }, [isCollapsed ? h('div', {
        class: 'vxe-menu--item-list'
      }, menuList.map(function (child) {
        return $xeMenu.renderDefaultChildren(h, child, menuList);
      })) : (0, _ui.renderEmptyElement)($xeMenu)]) : (0, _ui.renderEmptyElement)($xeMenu),
      /**
       * 加载中
       */
      h(_loading.default, {
        class: 'vxe-list-view--loading',
        props: {
          value: loading
        }
      })]);
    }
  },
  watch: {
    value: function value(val) {
      var $xeMenu = this;
      var reactData = $xeMenu.reactData;
      reactData.activeName = val;
    },
    options: function options() {
      var $xeMenu = this;
      $xeMenu.updateMenuConfig();
      $xeMenu.updateActiveMenu(true);
    },
    'reactData.activeName': function reactDataActiveName() {
      var $xeMenu = this;
      $xeMenu.updateActiveMenu(true);
    },
    computeIsCollapsed: function computeIsCollapsed() {
      var $xeMenu = this;
      $xeMenu.handleCollapseMenu();
    }
  },
  mounted: function mounted() {
    var $xeMenu = this;
    var props = $xeMenu;
    var menuConfig = props.menuConfig;
    var VxeUIContextMenu = _ui.VxeUI.getComponent('VxeContextMenu');
    if (menuConfig && !VxeUIContextMenu) {
      errLog('vxe.error.reqComp', ['vxe-context-menu']);
    }
    _ui.globalEvents.on($xeMenu, 'resize', $xeMenu.updateCollapseStyle);
    $xeMenu.updateCollapseStyle();
  },
  beforeDestroy: function beforeDestroy() {
    var $xeMenu = this;
    _ui.globalEvents.off($xeMenu, 'resize');
    var collapseEl = $xeMenu.$refs.refCollapseElem;
    if (collapseEl) {
      var parentNode = collapseEl.parentNode;
      if (parentNode) {
        parentNode.removeChild(collapseEl);
      }
    }
  },
  created: function created() {
    var $xeMenu = this;
    var props = $xeMenu;
    var reactData = $xeMenu.reactData;
    reactData.initialized = !!props.collapsed;
    reactData.activeName = props.value;
    $xeMenu.updateMenuConfig();
    $xeMenu.updateActiveMenu(true);
  },
  render: function render(h) {
    return this.renderVN(h);
  }
});
/* define-vxe-component end */