import * as _vue from "vue";

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

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (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 = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { 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; }

import { Transition } from 'vue';
import PropTypes from '../_util/vue-types';
import Align from '../vc-align';
import PopupInner from './PopupInner';
import LazyRenderBox from './LazyRenderBox';
import animate from '../_util/css-animation';
import BaseMixin from '../_util/BaseMixin';
import { saveRef } from './utils';
import { splitAttrs, findDOMNode } from '../_util/props-util';
export default {
  name: 'VCTriggerPopup',
  mixins: [BaseMixin],
  inheritAttrs: false,
  props: {
    visible: PropTypes.bool,
    getClassNameFromAlign: PropTypes.func,
    getRootDomNode: PropTypes.func,
    align: PropTypes.any,
    destroyPopupOnHide: PropTypes.bool,
    prefixCls: PropTypes.string,
    getContainer: PropTypes.func,
    transitionName: PropTypes.string,
    animation: PropTypes.any,
    maskAnimation: PropTypes.string,
    maskTransitionName: PropTypes.string,
    mask: PropTypes.bool,
    zIndex: PropTypes.number,
    popupClassName: PropTypes.any,
    popupStyle: PropTypes.object.def(function () {
      return {};
    }),
    stretch: PropTypes.string,
    point: PropTypes.shape({
      pageX: PropTypes.number,
      pageY: PropTypes.number
    })
  },
  data: function data() {
    this.domEl = null;
    this.currentAlignClassName = undefined;
    this.savePopupRef = saveRef.bind(this, 'popupInstance');
    this.saveAlignRef = saveRef.bind(this, 'alignInstance');
    return {
      // Used for stretch
      stretchChecked: false,
      targetWidth: undefined,
      targetHeight: undefined
    };
  },
  mounted: function mounted() {
    var _this = this;

    this.$nextTick(function () {
      _this.rootNode = _this.getPopupDomNode();

      _this.setStretchSize();
    });
  },
  // 如添加会导致动画失效，如放开会导致快速输入时闪动 https://github.com/vueComponent/ant-design-vue/issues/1327，
  // 目前方案是保留动画，闪动问题(动画多次执行)进一步定位
  // beforeUpdate() {
  //   if (this.domEl && this.domEl.rcEndListener) {
  //     this.domEl.rcEndListener();
  //     this.domEl = null;
  //   }
  // },
  updated: function updated() {
    var _this2 = this;

    this.$nextTick(function () {
      _this2.setStretchSize();
    });
  },
  methods: {
    onAlign: function onAlign(popupDomNode, align) {
      var props = this.$props;
      var currentAlignClassName = props.getClassNameFromAlign(align); // FIX: https://github.com/react-component/trigger/issues/56
      // FIX: https://github.com/react-component/tooltip/issues/79

      if (this.currentAlignClassName !== currentAlignClassName) {
        this.currentAlignClassName = currentAlignClassName;
        popupDomNode.className = this.getClassName(currentAlignClassName);
      }

      var onaAlign = this.$attrs.onaAlign;
      onaAlign && onaAlign(popupDomNode, align);
    },
    // Record size if stretch needed
    setStretchSize: function setStretchSize() {
      var _this$$props = this.$props,
          stretch = _this$$props.stretch,
          getRootDomNode = _this$$props.getRootDomNode,
          visible = _this$$props.visible;
      var _this$$data = this.$data,
          stretchChecked = _this$$data.stretchChecked,
          targetHeight = _this$$data.targetHeight,
          targetWidth = _this$$data.targetWidth;

      if (!stretch || !visible) {
        if (stretchChecked) {
          this.setState({
            stretchChecked: false
          });
        }

        return;
      }

      var $ele = getRootDomNode();
      if (!$ele) return;
      var height = $ele.offsetHeight;
      var width = $ele.offsetWidth;

      if (targetHeight !== height || targetWidth !== width || !stretchChecked) {
        this.setState({
          stretchChecked: true,
          targetHeight: height,
          targetWidth: width
        });
      }
    },
    getPopupDomNode: function getPopupDomNode() {
      return findDOMNode(this.popupInstance);
    },
    getTargetElement: function getTargetElement() {
      return this.$props.getRootDomNode();
    },
    // `target` on `rc-align` can accept as a function to get the bind element or a point.
    // ref: https://www.npmjs.com/package/rc-align
    getAlignTarget: function getAlignTarget() {
      var point = this.$props.point;

      if (point) {
        return point;
      }

      return this.getTargetElement;
    },
    getMaskTransitionName: function getMaskTransitionName() {
      var props = this.$props;
      var transitionName = props.maskTransitionName;
      var animation = props.maskAnimation;

      if (!transitionName && animation) {
        transitionName = "".concat(props.prefixCls, "-").concat(animation);
      }

      return transitionName;
    },
    getTransitionName: function getTransitionName() {
      var props = this.$props;
      var transitionName = props.transitionName;
      var animation = props.animation;

      if (!transitionName) {
        if (typeof animation === 'string') {
          transitionName = "".concat(animation);
        } else if (animation && animation.props && animation.props.name) {
          transitionName = animation.props.name;
        }
      }

      return transitionName;
    },
    getClassName: function getClassName(currentAlignClassName) {
      return "".concat(this.$props.prefixCls, " ").concat(this.$attrs.class || '', " ").concat(this.$props.popupClassName, " ").concat(currentAlignClassName);
    },
    getPopupElement: function getPopupElement() {
      var _this3 = this,
          _$slots$default;

      var savePopupRef = this.savePopupRef;
      var props = this.$props,
          $attrs = this.$attrs,
          $slots = this.$slots,
          getTransitionName = this.getTransitionName;
      var _this$$data2 = this.$data,
          stretchChecked = _this$$data2.stretchChecked,
          targetHeight = _this$$data2.targetHeight,
          targetWidth = _this$$data2.targetWidth;
      var _$attrs$style = $attrs.style,
          style = _$attrs$style === void 0 ? {} : _$attrs$style;
      var onEvents = splitAttrs($attrs).onEvents;
      var align = props.align,
          visible = props.visible,
          prefixCls = props.prefixCls,
          animation = props.animation,
          popupStyle = props.popupStyle,
          getClassNameFromAlign = props.getClassNameFromAlign,
          destroyPopupOnHide = props.destroyPopupOnHide,
          stretch = props.stretch;
      var className = this.getClassName(this.currentAlignClassName || getClassNameFromAlign(align)); // const hiddenClassName = `${prefixCls}-hidden`

      if (!visible) {
        this.currentAlignClassName = null;
      }

      var sizeStyle = {};

      if (stretch) {
        // Stretch with target
        if (stretch.indexOf('height') !== -1) {
          sizeStyle.height = typeof targetHeight === 'number' ? "".concat(targetHeight, "px") : targetHeight;
        } else if (stretch.indexOf('minHeight') !== -1) {
          sizeStyle.minHeight = typeof targetHeight === 'number' ? "".concat(targetHeight, "px") : targetHeight;
        }

        if (stretch.indexOf('width') !== -1) {
          sizeStyle.width = typeof targetWidth === 'number' ? "".concat(targetWidth, "px") : targetWidth;
        } else if (stretch.indexOf('minWidth') !== -1) {
          sizeStyle.minWidth = typeof targetWidth === 'number' ? "".concat(targetWidth, "px") : targetWidth;
        } // Delay force align to makes ui smooth


        if (!stretchChecked) {
          // sizeStyle.visibility = 'hidden'
          setTimeout(function () {
            if (_this3.alignInstance) {
              _this3.alignInstance.forceAlign();
            }
          }, 0);
        }
      }

      var popupInnerProps = _objectSpread(_objectSpread({
        prefixCls: prefixCls,
        visible: visible,
        // hiddenClassName,
        class: className
      }, onEvents), {}, {
        ref: savePopupRef,
        style: _objectSpread(_objectSpread(_objectSpread(_objectSpread({}, sizeStyle), popupStyle), style), this.getZIndexStyle())
      });

      var transitionProps = {
        appear: true,
        css: false
      };
      var transitionName = getTransitionName();
      var useTransition = !!transitionName;
      var transitionEvent = {
        onBeforeEnter: function onBeforeEnter() {// el.style.display = el.__vOriginalDisplay
          // this.alignInstance.forceAlign();
        },
        onEnter: function onEnter(el, done) {
          // render 后 vue 会移除通过animate动态添加的 class导致动画闪动，延迟两帧添加动画class，可以进一步定位或者重写 transition 组件
          _this3.$nextTick(function () {
            if (_this3.alignInstance) {
              _this3.alignInstance.$nextTick(function () {
                _this3.domEl = el;
                animate(el, "".concat(transitionName, "-enter"), done);
              });
            } else {
              done();
            }
          });
        },
        onBeforeLeave: function onBeforeLeave() {
          _this3.domEl = null;
        },
        onLeave: function onLeave(el, done) {
          animate(el, "".concat(transitionName, "-leave"), done);
        }
      };
      transitionProps = _objectSpread(_objectSpread({}, transitionProps), transitionEvent);

      if (_typeof(animation) === 'object') {
        useTransition = true;
        transitionProps = _objectSpread(_objectSpread({}, transitionProps), animation);
      }

      if (!useTransition) {
        transitionProps = {};
      }

      if (destroyPopupOnHide) {
        return _vue.createVNode(Transition, transitionProps, {
          default: function _default() {
            return [visible ? _vue.createVNode(Align, {
              "target": _this3.getAlignTarget(),
              "key": "popup",
              "ref": _this3.saveAlignRef,
              "monitorWindowResize": true,
              "align": align,
              "onAlign": _this3.onAlign
            }, {
              default: function _default() {
                return [_vue.createVNode(PopupInner, popupInnerProps, {
                  default: function _default() {
                    return [$slots.default && $slots.default()];
                  }
                })];
              }
            }) : null];
          }
        });
      }

      return _vue.createVNode(Transition, transitionProps, {
        default: function _default() {
          return [_vue.withDirectives(_vue.createVNode(Align, {
            "target": _this3.getAlignTarget(),
            "key": "popup",
            "ref": _this3.saveAlignRef,
            "monitorWindowResize": true,
            "disabled": !visible,
            "align": align,
            "onAlign": _this3.onAlign
          }, {
            default: function _default() {
              return [_vue.createVNode(PopupInner, popupInnerProps, {
                default: function _default() {
                  return [(_$slots$default = $slots.default) === null || _$slots$default === void 0 ? void 0 : _$slots$default.call($slots)];
                }
              })];
            }
          }), [[_vue.vShow, visible]])];
        }
      });
    },
    getZIndexStyle: function getZIndexStyle() {
      var style = {};
      var props = this.$props;

      if (props.zIndex !== undefined) {
        style.zIndex = props.zIndex;
      }

      return style;
    },
    getMaskElement: function getMaskElement() {
      var props = this.$props;
      var maskElement = null;

      if (props.mask) {
        var maskTransition = this.getMaskTransitionName();
        maskElement = _vue.withDirectives(_vue.createVNode(LazyRenderBox, {
          "style": this.getZIndexStyle(),
          "key": "mask",
          "class": "".concat(props.prefixCls, "-mask"),
          "visible": props.visible
        }, null), [[_vue.vShow, props.visible]]);

        if (maskTransition) {
          var _maskElement = function () {
            return maskElement;
          }();

          maskElement = _vue.createVNode(Transition, {
            "appear": true,
            "name": maskTransition
          }, {
            default: function _default() {
              return [_maskElement];
            }
          });
        }
      }

      return maskElement;
    }
  },
  render: function render() {
    var getMaskElement = this.getMaskElement,
        getPopupElement = this.getPopupElement;
    return _vue.createVNode("div", null, [getMaskElement(), getPopupElement()]);
  }
};