"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 _utils = require("../../ui/src/utils");
var _dom = require("../../ui/src/dom");
var _vn = require("../../ui/src/vn");
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 _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
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); }
function createReactData() {
  return {
    target: null,
    isUpdate: false,
    visible: false,
    tipPos: null,
    tipContent: '',
    tipActive: false,
    tipTarget: null,
    tipZindex: 0,
    tipStore: {
      style: {},
      placement: '',
      arrowStyle: {}
    }
  };
}
function createInternalData() {
  return {
    // showDelayTip: undefined
  };
}
var _default2 = exports.default = /* define-vxe-component start */(0, _comp.defineVxeComponent)({
  name: 'VxeTooltip',
  mixins: [_ui.globalMixins.sizeMixin],
  props: {
    value: Boolean,
    size: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.size || (0, _ui.getConfig)().size;
      }
    },
    selector: String,
    trigger: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.trigger || 'hover';
      }
    },
    theme: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.theme || 'dark';
      }
    },
    content: {
      type: [String, Number],
      default: null
    },
    useHtml: {
      type: Boolean,
      default: function _default() {
        return _xeUtils.default.isBoolean((0, _ui.getConfig)().tooltip.useHtml) ? (0, _ui.getConfig)().tooltip.useHtml : null;
      }
    },
    // 已废弃，请使用 useHtml
    useHTML: {
      type: Boolean,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.useHTML;
      }
    },
    zIndex: [String, Number],
    popupClassName: [String, Function],
    width: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.Width;
      }
    },
    height: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.height;
      }
    },
    minWidth: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.minWidth;
      }
    },
    minHeight: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.minHeight;
      }
    },
    maxWidth: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.maxWidth;
      }
    },
    maxHeight: {
      type: [String, Number],
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.maxHeight;
      }
    },
    placement: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.placement;
      }
    },
    defaultPlacement: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.defaultPlacement;
      }
    },
    isArrow: {
      type: Boolean,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.isArrow;
      }
    },
    enterable: {
      type: Boolean,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.enterable;
      }
    },
    enterDelay: {
      type: Number,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.enterDelay;
      }
    },
    leaveDelay: {
      type: Number,
      default: function _default() {
        return (0, _ui.getConfig)().tooltip.leaveDelay;
      }
    }
  },
  data: function data() {
    var xID = _xeUtils.default.uniqueId();
    var reactData = createReactData();
    return Object.assign(Object.assign({}, {}), {
      xID: xID,
      reactData: reactData
    });
  },
  computed: Object.assign(Object.assign({}, {}), {
    computeWrapperStyle: function computeWrapperStyle() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var width = props.width,
        height = props.height,
        minHeight = props.minHeight,
        minWidth = props.minWidth,
        maxHeight = props.maxHeight,
        maxWidth = props.maxWidth;
      var stys = {};
      if (width) {
        stys.width = (0, _dom.toCssUnit)(width);
      }
      if (height) {
        stys.height = (0, _dom.toCssUnit)(height);
      }
      if (minWidth) {
        stys.minWidth = (0, _dom.toCssUnit)(minWidth);
      }
      if (minHeight) {
        stys.minHeight = (0, _dom.toCssUnit)(minHeight);
      }
      if (maxWidth) {
        stys.maxWidth = (0, _dom.toCssUnit)(maxWidth);
      }
      if (maxHeight) {
        stys.maxHeight = (0, _dom.toCssUnit)(maxHeight);
      }
      return stys;
    }
  }),
  methods: {
    //
    // Method
    //
    dispatchEvent: function dispatchEvent(type, params, evnt) {
      var $xeTooltip = this;
      $xeTooltip.$emit(type, (0, _ui.createEvent)(evnt, {
        $tooltip: $xeTooltip
      }, params));
    },
    emitModel: function emitModel(value) {
      var $xeTooltip = this;
      var _events = $xeTooltip._events;
      $xeTooltip.$emit('input', value);
      if (_events && _events.modelValue) {
        $xeTooltip.$emit('modelValue', value);
      } else {
        $xeTooltip.$emit('model-value', value);
      }
    },
    getSelectorEl: function getSelectorEl() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var selector = props.selector;
      if (selector) {
        if (_xeUtils.default.isElement(selector)) {
          return selector;
        }
        if (_xeUtils.default.isString(selector)) {
          return document.querySelector(selector);
        }
      }
      return null;
    },
    openByEvent: function openByEvent(evnt, target, content) {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      return $xeTooltip.handleVisible(target || reactData.target || $xeTooltip.getSelectorEl(), content, evnt);
    },
    open: function open(target, content) {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      return $xeTooltip.handleVisible(target || reactData.target || $xeTooltip.getSelectorEl(), content);
    },
    close: function close() {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      reactData.tipPos = null;
      reactData.tipTarget = null;
      reactData.tipActive = false;
      Object.assign(reactData.tipStore, {
        style: {},
        placement: '',
        arrowStyle: null
      });
      $xeTooltip.updateValue(false);
      return $xeTooltip.$nextTick();
    },
    toVisible: function toVisible(target, content) {
      var $xeTooltip = this;
      return $xeTooltip.handleVisible(target, content);
    },
    updatePlacement: function updatePlacement() {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      var visible = reactData.visible,
        tipTarget = reactData.tipTarget;
      var el = $xeTooltip.$refs.refElem;
      if (visible && tipTarget && el) {
        $xeTooltip.updateTipStyle();
      }
      return $xeTooltip.$nextTick().then(function () {
        var tipTarget = reactData.tipTarget;
        el = $xeTooltip.$refs.refElem;
        if (tipTarget && el) {
          $xeTooltip.updateTipStyle();
          return $xeTooltip.$nextTick().then(function () {
            $xeTooltip.updateTipStyle();
          });
        }
      });
    },
    isActived: function isActived() {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      return reactData.tipActive;
    },
    setActived: function setActived(active) {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      reactData.tipActive = !!active;
    },
    updateTipStyle: function updateTipStyle() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      var isArrow = props.isArrow,
        placement = props.placement,
        defaultPlacement = props.defaultPlacement;
      var targetElem = reactData.tipTarget,
        tipStore = reactData.tipStore,
        tipPos = reactData.tipPos;
      var top = '';
      var left = '';
      var panelPlacement = 'bottom';
      var arrowLeft = '';
      var panelElem = $xeTooltip.$refs.refElem;
      if (panelElem && targetElem) {
        var documentElement = document.documentElement;
        var bodyElem = document.body;
        var targetWidth = targetElem.offsetWidth;
        var targetHeight = targetElem.offsetHeight;
        var panelHeight = panelElem.offsetHeight;
        var panelWidth = panelElem.offsetWidth;
        var targetRect = targetElem.getBoundingClientRect();
        var visibleHeight = documentElement.clientHeight || bodyElem.clientHeight;
        var visibleWidth = documentElement.clientWidth || bodyElem.clientWidth;
        var marginSize = 6;
        left = targetRect.left;
        top = targetRect.top + targetHeight;
        if (tipPos && (tipPos.oLeft || tipPos.oTop)) {
          if (isArrow) {
            left = left + Math.max(8, Math.min(targetWidth - 8, tipPos.oLeft)) - panelWidth / 2;
          } else {
            left = tipPos.x + 1;
            top = tipPos.y + 1;
          }
        } else {
          left = targetRect.left + (targetWidth - panelWidth) / 2;
        }
        if (placement === 'top') {
          panelPlacement = 'top';
          top = targetRect.top - panelHeight;
        } else if (!placement) {
          if (defaultPlacement === 'top') {
            panelPlacement = 'top';
            top = targetRect.top - panelHeight;
            // 如果上面不够放，则向下
            if (top < marginSize) {
              panelPlacement = 'bottom';
              top = targetRect.top + targetHeight;
            }
            // 如果下面不够放，则向上（优先）
            if (top + panelHeight + marginSize > visibleHeight) {
              panelPlacement = 'top';
              top = targetRect.top - panelHeight;
            }
          } else {
            // 如果下面不够放，则向上
            if (top + panelHeight + marginSize > visibleHeight) {
              panelPlacement = 'top';
              top = targetRect.top - panelHeight;
            }
            // 如果上面不够放，则向下（优先）
            if (top < marginSize) {
              panelPlacement = 'bottom';
              top = targetRect.top + targetHeight;
            }
          }
        }
        // 如果溢出右边
        if (left + panelWidth + marginSize > visibleWidth) {
          left -= left + panelWidth + marginSize - visibleWidth;
        }
        // 如果溢出左边
        if (left < marginSize) {
          left = marginSize;
        }
        // 箭头
        if (left === targetRect.left) {
          if (targetWidth <= panelWidth) {
            arrowLeft = targetWidth / 2;
          }
        } else if (left < targetRect.left) {
          if (left + panelWidth > targetRect.left + targetWidth) {
            arrowLeft = targetRect.left - left + targetWidth / 2;
          } else {
            arrowLeft = targetRect.left - left + (panelWidth - (targetRect.left - left)) / 2;
          }
        }
        tipStore.placement = panelPlacement;
        tipStore.style.top = "".concat(top, "px");
        tipStore.style.left = "".concat(left, "px");
        tipStore.arrowStyle.left = "".concat(arrowLeft, "px");
      }
    },
    updateValue: function updateValue(value) {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      if (value !== reactData.visible) {
        reactData.visible = value;
        reactData.isUpdate = true;
        $xeTooltip.emitModel(value);
      }
    },
    updateZindex: function updateZindex() {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      if (reactData.tipZindex < (0, _utils.getLastZIndex)()) {
        reactData.tipZindex = (0, _utils.nextZIndex)();
      }
    },
    clickEvent: function clickEvent() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      if (reactData.visible) {
        $xeTooltip.close();
      } else {
        $xeTooltip.handleVisible(reactData.target || $xeTooltip.getSelectorEl(), props.content);
      }
    },
    targetMouseenterEvent: function targetMouseenterEvent() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      $xeTooltip.handleVisible(reactData.target || $xeTooltip.getSelectorEl(), props.content);
    },
    targetMouseleaveEvent: function targetMouseleaveEvent() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      var trigger = props.trigger,
        enterable = props.enterable,
        leaveDelay = props.leaveDelay;
      reactData.tipActive = false;
      if (enterable && trigger === 'hover') {
        setTimeout(function () {
          if (!reactData.tipActive) {
            $xeTooltip.close();
          }
        }, leaveDelay);
      } else {
        $xeTooltip.close();
      }
    },
    wrapperMouseenterEvent: function wrapperMouseenterEvent() {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      reactData.tipActive = true;
    },
    wrapperMouseleaveEvent: function wrapperMouseleaveEvent() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      var trigger = props.trigger,
        enterable = props.enterable,
        leaveDelay = props.leaveDelay;
      reactData.tipActive = false;
      if (enterable && trigger === 'hover') {
        setTimeout(function () {
          if (!reactData.tipActive) {
            $xeTooltip.close();
          }
        }, leaveDelay);
      }
    },
    showTip: function showTip() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      var tipStore = reactData.tipStore;
      var el = $xeTooltip.$refs.refElem;
      if (el) {
        var parentNode = el.parentNode;
        if (!parentNode) {
          document.body.appendChild(el);
        }
      }
      $xeTooltip.updateValue(true);
      $xeTooltip.updateZindex();
      tipStore.placement = 'top';
      tipStore.style = {
        width: 'auto',
        left: 0,
        top: 0,
        zIndex: props.zIndex || reactData.tipZindex
      };
      tipStore.arrowStyle = {
        left: '50%'
      };
      return $xeTooltip.updatePlacement();
    },
    handleDelayFn: function handleDelayFn() {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      var internalData = $xeTooltip.internalData;
      internalData.showDelayTip = _xeUtils.default.debounce(function () {
        if (reactData.tipActive) {
          $xeTooltip.showTip();
        }
      }, props.enterDelay, {
        leading: false,
        trailing: true
      });
    },
    handleVisible: function handleVisible(target, content, evnt) {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var slots = $xeTooltip.$scopedSlots;
      var reactData = $xeTooltip.reactData;
      var internalData = $xeTooltip.internalData;
      var contentSlot = slots.content;
      if (!contentSlot && (content === '' || _xeUtils.default.eqNull(content))) {
        return $xeTooltip.$nextTick();
      }
      if (target) {
        var showDelayTip = internalData.showDelayTip;
        var trigger = props.trigger,
          enterDelay = props.enterDelay;
        if (evnt) {
          reactData.tipPos = {
            x: evnt.clientX,
            y: evnt.clientY,
            oLeft: evnt.offsetX,
            oTop: evnt.offsetY
          };
        } else {
          reactData.tipPos = null;
        }
        reactData.tipActive = true;
        reactData.tipTarget = target;
        reactData.tipContent = content;
        if (reactData.visible) {
          return $xeTooltip.updatePlacement();
        }
        if (enterDelay && trigger === 'hover') {
          if (showDelayTip) {
            showDelayTip();
          }
        } else {
          return $xeTooltip.showTip();
        }
      }
      return $xeTooltip.$nextTick();
    },
    wheelEvent: function wheelEvent(evnt) {
      evnt.stopPropagation();
    },
    //
    // Render
    //
    renderContent: function renderContent(h) {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var slots = $xeTooltip.$scopedSlots;
      var reactData = $xeTooltip.reactData;
      var useHtml = props.useHtml,
        useHTML = props.useHTML;
      var tipContent = reactData.tipContent;
      var wrapperStyle = $xeTooltip.computeWrapperStyle;
      var contentSlot = slots.content;
      var contVNs = [];
      if (contentSlot) {
        contVNs.push(h('div', {
          key: 'ct'
        }, (0, _vn.getSlotVNs)(contentSlot({}))));
      } else if (_xeUtils.default.isBoolean(useHtml) ? useHtml : useHTML) {
        contVNs.push(h('div', {
          key: 'ch',
          domProps: {
            innerHTML: tipContent
          }
        }));
      } else {
        contVNs.push(h('span', {
          key: 'cd'
        }, "".concat(tipContent)));
      }
      return h('div', {
        key: 3,
        ref: 'contentWrapperfElem',
        class: 'vxe-tooltip--content',
        style: wrapperStyle
      }, contVNs);
    },
    renderVN: function renderVN(h) {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var slots = $xeTooltip.$scopedSlots;
      var reactData = $xeTooltip.reactData;
      var popupClassName = props.popupClassName,
        theme = props.theme,
        isArrow = props.isArrow,
        enterable = props.enterable;
      var tipActive = reactData.tipActive,
        visible = reactData.visible,
        tipStore = reactData.tipStore;
      var defaultSlot = slots.default;
      var vSize = $xeTooltip.computeSize;
      var ons;
      if (enterable) {
        ons = {
          mouseenter: $xeTooltip.wrapperMouseenterEvent,
          mouseleave: $xeTooltip.wrapperMouseleaveEvent
        };
      }
      return h('div', {
        ref: 'refElem',
        class: ['vxe-tooltip--wrapper', "theme--".concat(theme), popupClassName ? _xeUtils.default.isFunction(popupClassName) ? popupClassName({
          $tooltip: $xeTooltip
        }) : popupClassName : '', _defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty(_defineProperty({}, "size--".concat(vSize), vSize), "placement--".concat(tipStore.placement), tipStore.placement), 'is--enterable', enterable), 'is--visible', visible), 'is--arrow', isArrow), 'is--active', tipActive)],
        style: tipStore.style,
        on: ons
      }, [h('div', {
        key: 'tby',
        class: 'vxe-tooltip--body'
      }, [$xeTooltip.renderContent(h), h('div', {
        class: 'vxe-tooltip--arrow',
        style: tipStore.arrowStyle
      })])].concat(_toConsumableArray(defaultSlot ? (0, _vn.getSlotVNs)(defaultSlot({})) : [])));
    }
  },
  watch: {
    content: function content(val) {
      var $xeTooltip = this;
      var reactData = $xeTooltip.reactData;
      reactData.tipContent = val;
    },
    value: function value(val) {
      var $xeTooltip = this;
      var props = $xeTooltip;
      var reactData = $xeTooltip.reactData;
      if (!reactData.isUpdate) {
        if (val) {
          $xeTooltip.handleVisible(reactData.target || $xeTooltip.getSelectorEl(), props.content);
        } else {
          $xeTooltip.close();
        }
      }
      reactData.isUpdate = false;
    },
    enterDelay: function enterDelay() {
      var $xeTooltip = this;
      $xeTooltip.handleDelayFn();
    }
  },
  created: function created() {
    var $xeTooltip = this;
    $xeTooltip.internalData = createInternalData();
    $xeTooltip.handleDelayFn();
  },
  mounted: function mounted() {
    var $xeTooltip = this;
    var props = $xeTooltip;
    var reactData = $xeTooltip.reactData;
    var contentWrapperfEl = $xeTooltip.$refs.contentWrapperfElem;
    if (contentWrapperfEl) {
      contentWrapperfEl.addEventListener('wheel', $xeTooltip.wheelEvent, {
        passive: false
      });
    }
    $xeTooltip.$nextTick(function () {
      var trigger = props.trigger,
        content = props.content;
      var wrapperElem = $xeTooltip.$refs.refElem;
      if (wrapperElem) {
        var parentNode = wrapperElem.parentNode;
        if (parentNode) {
          reactData.tipContent = content;
          reactData.tipZindex = (0, _utils.nextZIndex)();
          _xeUtils.default.arrayEach(wrapperElem.children, function (elem, index) {
            if (index) {
              parentNode.insertBefore(elem, wrapperElem);
              if (!reactData.target) {
                reactData.target = elem;
              }
            }
          });
          parentNode.removeChild(wrapperElem);
          var target = reactData.target;
          if (target) {
            if (trigger === 'hover') {
              target.onmouseenter = $xeTooltip.targetMouseenterEvent;
              target.onmouseleave = $xeTooltip.targetMouseleaveEvent;
            } else if (trigger === 'click') {
              target.onclick = $xeTooltip.clickEvent;
            }
          }
          if (props.value) {
            $xeTooltip.handleVisible(target || $xeTooltip.getSelectorEl(), content);
          }
        }
      }
    });
  },
  beforeDestroy: function beforeDestroy() {
    var $xeTooltip = this;
    var reactData = $xeTooltip.reactData;
    var target = reactData.target;
    var wrapperElem = $xeTooltip.$refs.refElem;
    if (target) {
      target.onmouseenter = null;
      target.onmouseleave = null;
      target.onclick = null;
    }
    var contentWrapperfEl = $xeTooltip.$refs.contentWrapperfElem;
    if (contentWrapperfEl) {
      contentWrapperfEl.removeEventListener('wheel', $xeTooltip.wheelEvent);
    }
    if (wrapperElem) {
      var parentNode = wrapperElem.parentNode;
      if (parentNode) {
        parentNode.removeChild(wrapperElem);
      }
    }
  },
  destroyed: function destroyed() {
    var $xeTooltip = this;
    var reactData = $xeTooltip.reactData;
    var internalData = $xeTooltip.internalData;
    _xeUtils.default.assign(reactData, createReactData());
    _xeUtils.default.assign(internalData, createInternalData());
  },
  render: function render(h) {
    return this.renderVN(h);
  }
});
/* define-vxe-component end */