/**
 * ldesign v0.2.2
 * (c) 2022年9月20日 swimly
 * @license MIT
 */

import _typeof from '@babel/runtime/helpers/typeof';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import { createPopper } from '@popperjs/core';
import { s as setStyle } from '../../chunks/set-style.js';
import { on, off, once } from '../../utils/dom.js';
import { renderContent, renderLNodeJSX } from '../../utils/render-node.js';
import { getIEVersion } from '../../utils/helper.js';
import popupProps from './props.js';
import LContainer from './container.js';
import { getClassPrefixMixins } from '../config-provider/config-receiver.js';
import mixins from '../../utils/mixins.js';
import 'vue';
import 'raf';
import 'lodash/isString';
import '../../utils/easing.js';
import 'lodash/camelCase';
import 'lodash/kebabCase';
import '@babel/runtime/helpers/objectWithoutProperties';
import '@babel/runtime/helpers/slicedToArray';
import 'lodash/mergeWith';
import 'lodash';
import '../config-provider/context.js';
import '../../chunks/zh_CN.js';
import '../config-provider/type.js';

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; }
var classPrefixMixins = getClassPrefixMixins("popup");
var triggers = ["click", "hover", "focus", "context-menu"];
var injectionKey = "__T_POPUP";

function getPopperPlacement(placement) {
  return placement.replace(/-(left|top)$/, "-start").replace(/-(right|bottom)$/, "-end");
}

function attachListeners(elm) {
  var offs = [];
  return {
    add: function add(type, listener) {
      on(elm, type, listener);
      offs.push(function () {
        off(elm, type, listener);
      });
    },
    clean: function clean() {
      offs.forEach(function (handler) {
        return handler === null || handler === void 0 ? void 0 : handler();
      });
      offs.length = 0;
    }
  };
}

var LPopup = mixins(classPrefixMixins).extend({
  name: "LPopup",
  components: {
    LContainer: LContainer
  },
  provide: function provide() {
    return _defineProperty({}, injectionKey, this);
  },
  inject: {
    popup: {
      from: injectionKey,
      "default": void 0
    }
  },
  props: _objectSpread(_objectSpread({}, popupProps), {}, {
    expandAnimation: {
      type: Boolean
    },
    updateScrollTop: {
      type: Function
    }
  }),
  data: function data() {
    return {
      popper: null,
      timeout: null,
      hasDocumentEvent: false,
      visibleState: 0,
      mouseInRange: false,
      contentClicked: false
    };
  },
  computed: {
    overlayClasses: function overlayClasses() {
      var _ref2;

      return ["".concat(this.componentName, "__content"), (_ref2 = {}, _defineProperty(_ref2, "".concat(this.componentName, "__content--text"), this.content === "string"), _defineProperty(_ref2, "".concat(this.componentName, "__content--arrow"), this.showArrow), _defineProperty(_ref2, this.commonStatusClassName.disabled, this.disabled), _ref2), this.overlayInnerClassName];
    },
    hasTrigger: function hasTrigger() {
      var _this = this;

      return triggers.reduce(function (map, trigger) {
        return _objectSpread(_objectSpread({}, map), {}, _defineProperty({}, trigger, _this.trigger.includes(trigger)));
      }, {});
    },
    normalizedDelay: function normalizedDelay() {
      var _this$delay, _delay$;

      var delay = [].concat((_this$delay = this.delay) !== null && _this$delay !== void 0 ? _this$delay : [250, 150]);
      return {
        open: delay[0],
        close: (_delay$ = delay[1]) !== null && _delay$ !== void 0 ? _delay$ : delay[0]
      };
    }
  },
  watch: {
    visible: function visible(_visible) {
      var _this2 = this;

      var hasTrigger = this.hasTrigger,
          triggerEl = this.$el;

      if (_visible) {
        this.preventClosing(true);

        if (!this.hasDocumentEvent) {
          on(document, "click", this.handleDocumentClick, true);
          this.hasDocumentEvent = true;
        }

        if (triggerEl && hasTrigger.focus) {
          once(triggerEl, "keydown", function (ev) {
            if (ev.code === "Escape") {
              _this2.handleClose({
                trigger: "keydown-esc"
              });
            }
          });
        }

        this.$nextTick(function () {
          _this2.popupMounted();
        });
      } else {
        this.preventClosing(false);
        off(document, "click", this.handleDocumentClick, true);
        this.hasDocumentEvent = false;
        this.mouseInRange = false;
      }
    },
    overlayInnerStyle: function overlayInnerStyle() {
      this.updateOverlayInnerStyle();
      this.updatePopper();
    },
    placement: function placement() {
      var _this$popper;

      (_this$popper = this.popper) === null || _this$popper === void 0 ? void 0 : _this$popper.destroy();
      this.popper = null;
      this.updatePopper();
    },
    contentClicked: function contentClicked(clicked) {
      if (this.popup) {
        this.popup.contentClicked = clicked;
      }
    }
  },
  mounted: function mounted() {
    var _this3 = this;

    var trigger = attachListeners(this.$el);

    var updateTrigger = function updateTrigger() {
      trigger.clean();
      var hasTrigger = _this3.hasTrigger;

      if (hasTrigger.hover) {
        trigger.add("mouseenter", function () {
          return _this3.handleOpen({
            trigger: "trigger-element-hover"
          });
        });
        trigger.add("mouseleave", function () {
          return _this3.handleClose({
            trigger: "trigger-element-hover"
          });
        });
      } else if (hasTrigger.focus) {
        trigger.add("focusin", function () {
          return _this3.handleOpen({
            trigger: "trigger-element-focus"
          });
        });
        trigger.add("focusout", function () {
          return _this3.handleClose({
            trigger: "trigger-element-blur"
          });
        });
      } else if (hasTrigger.click) {
        trigger.add("click", function (e) {
          _this3.handleToggle({
            e: e,
            trigger: "trigger-element-click"
          });

          if (getIEVersion() < 11) {
            _this3.handleDocumentClick(e);
          }
        });
      } else if (hasTrigger["context-menu"]) {
        trigger.add("contextmenu", function (e) {
          e.preventDefault();
          e.button === 2 && _this3.handleToggle({
            trigger: "context-menu"
          });
        });
      }
    };

    updateTrigger();
    this.$watch("trigger", updateTrigger);
  },
  updated: function updated() {
    var _this$$refs$container;

    (_this$$refs$container = this.$refs.container) === null || _this$$refs$container === void 0 ? void 0 : _this$$refs$container.updateContent();
  },
  beforeDestroy: function beforeDestroy() {
    if (this.visible) {
      var _this$popup;

      (_this$popup = this.popup) === null || _this$popup === void 0 ? void 0 : _this$popup.preventClosing(false);
    }

    this.destroyPopper();
    off(document, "click", this.handleDocumentClick, true);
    clearTimeout(this.timeout);
  },
  methods: {
    updatePopper: function updatePopper() {
      var _this4 = this;

      var triggerEl = this.$el;
      var popperEl = this.$refs.popper;
      if (!popperEl || !this.visible) return;

      if (this.popper) {
        this.popper.update();
        return;
      }

      this.popper = createPopper(triggerEl, popperEl, {
        modifiers: getIEVersion() > 9 ? [] : [{
          name: "computeStyles",
          options: {
            gpuAcceleration: false
          }
        }],
        placement: getPopperPlacement(this.placement),
        onFirstUpdate: function onFirstUpdate() {
          _this4.$nextTick(_this4.updatePopper);
        }
      });
    },
    popupMounted: function popupMounted() {
      var _this$$refs;

      var overlayEl = (_this$$refs = this.$refs) === null || _this$$refs === void 0 ? void 0 : _this$$refs.overlay;

      if (overlayEl) {
        var _this$updateScrollTop;

        (_this$updateScrollTop = this.updateScrollTop) === null || _this$updateScrollTop === void 0 ? void 0 : _this$updateScrollTop.call(this, overlayEl);
      }
    },
    getOverlayStyle: function getOverlayStyle() {
      var _this$$refs2;

      var overlayStyle = this.overlayStyle;
      var triggerEl = this.$el;
      var overlayEl = (_this$$refs2 = this.$refs) === null || _this$$refs2 === void 0 ? void 0 : _this$$refs2.overlay;
      if (!triggerEl || !overlayEl) return;

      if (typeof overlayStyle === "function") {
        return overlayStyle(triggerEl, overlayEl);
      }

      if (_typeof(overlayStyle) === "object") {
        return overlayStyle;
      }
    },
    updateOverlayInnerStyle: function updateOverlayInnerStyle() {
      var _this$$refs3;

      var overlayInnerStyle = this.overlayInnerStyle;
      var triggerEl = this.$el;
      var overlayEl = (_this$$refs3 = this.$refs) === null || _this$$refs3 === void 0 ? void 0 : _this$$refs3.overlay;
      if (!triggerEl || !overlayEl) return;

      if (typeof overlayInnerStyle === "function") {
        setStyle(overlayEl, overlayInnerStyle(triggerEl, overlayEl));
      } else if (_typeof(overlayInnerStyle) === "object") {
        setStyle(overlayEl, overlayInnerStyle);
      }
    },
    destroyPopper: function destroyPopper() {
      if (this.popper) {
        this.popper.destroy();
        this.popper = null;
      }

      if (this.destroyOnClose) {
        var _this$$refs$container2;

        (_this$$refs$container2 = this.$refs.container) === null || _this$$refs$container2 === void 0 ? void 0 : _this$$refs$container2.unmountContent();
      }
    },
    handleToggle: function handleToggle(context) {
      this.emitPopVisible(!this.visible, context);
    },
    handleOpen: function handleOpen(context) {
      var _this5 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this5.emitPopVisible(true, context);
      }, this.hasTrigger.click ? 0 : this.normalizedDelay.open);
    },
    handleClose: function handleClose(context) {
      var _this6 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this6.emitPopVisible(false, context);
      }, this.hasTrigger.click ? 0 : this.normalizedDelay.close);
    },
    handleDocumentClick: function handleDocumentClick(ev) {
      var _this7 = this;

      if (this.contentClicked) {
        setTimeout(function () {
          _this7.contentClicked = false;
        });
        return;
      }

      var triggerEl = this.$el;
      if (triggerEl.contains(ev.target)) return;
      this.visibleState = 0;
      this.emitPopVisible(false, {
        trigger: "document"
      });
    },
    emitPopVisible: function emitPopVisible(visible, context) {
      if (this.disabled || visible === this.visible) return;
      if (!visible && this.visibleState > 1) return;
      if (visible && this.mouseInRange) return;
      this.$emit("visible-change", visible, context);

      if (typeof this.onVisibleChange === "function") {
        this.onVisibleChange(visible, context);
      }
    },
    onMouseEnter: function onMouseEnter() {
      this.mouseInRange = true;
      this.handleOpen({});
    },
    onMouseLeave: function onMouseLeave(ev) {
      if (this.visibleState > 1) {
        var rect = this.$refs.popper.getBoundingClientRect();
        if (ev.x > rect.x && ev.x < rect.x + rect.width && ev.y > rect.y && ev.y < rect.y + rect.height) return;
      }

      this.mouseInRange = false;
      this.handleClose({});
      var parent = this.popup;

      if (parent !== null && parent !== void 0 && parent.mouseInRange) {
        parent.onMouseLeave(ev);
      }
    },
    onBeforeEnter: function onBeforeEnter() {
      if (this.visible) {
        this.updatePopper();
      }
    },
    onAfterEnter: function onAfterEnter() {
      if (this.visible) {
        this.updatePopper();
      }
    },
    preventClosing: function preventClosing(preventing) {
      var parent = this.popup;
      parent === null || parent === void 0 ? void 0 : parent.preventClosing(preventing);

      if (preventing) {
        this.visibleState += 1;
      } else if (this.visibleState) {
        this.visibleState -= 1;

        if (!this.visibleState) {
          this.emitPopVisible(false, {});

          if (parent !== null && parent !== void 0 && parent.hasTrigger.hover && !(parent !== null && parent !== void 0 && parent.mouseInRange)) {
            parent.emitPopVisible(false, {});
          }
        }
      }
    }
  },
  render: function render(h) {
    var _this8 = this;

    var visible = this.visible,
        destroyOnClose = this.destroyOnClose,
        hasTrigger = this.hasTrigger,
        onScroll = this.onScroll;
    var ref = renderContent(this, "default", "triggerElement");
    var content = renderLNodeJSX(this, "content");
    var hidePopup = this.hideEmptyPopup && ["", void 0, null].includes(content);
    var overlay = visible || !destroyOnClose ? h("div", {
      "class": [this.componentName, this.overlayClassName],
      ref: "popper",
      style: [hidePopup && {
        visibility: "hidden",
        pointerEvents: "none"
      }, {
        zIndex: this.zIndex
      }, this.getOverlayStyle()],
      directives: destroyOnClose ? void 0 : [{
        name: "show",
        rawName: "v-show",
        value: visible && !hidePopup,
        expression: "visible"
      }],
      on: _objectSpread({
        mousedown: function mousedown() {
          _this8.contentClicked = true;
        }
      }, hasTrigger.hover && {
        mouseenter: this.onMouseEnter,
        mouseleave: this.onMouseLeave
      })
    }, [h("div", {
      "class": this.overlayClasses,
      ref: "overlay",
      on: onScroll ? {
        scroll: function scroll(e) {
          onScroll({
            e: e
          });
        }
      } : void 0
    }, [content, this.showArrow && h("div", {
      "class": "".concat(this.componentName, "__arrow")
    })])]) : null;
    return h("l-container", {
      "ref": "container",
      "on": {
        "contentMounted": function contentMounted() {
          if (visible) {
            _this8.updatePopper();

            _this8.updateOverlayInnerStyle();
          }
        },
        "resize": function resize() {
          if (visible) {
            _this8.updatePopper();
          }
        }
      },
      "attrs": {
        "parent": this,
        "visible": visible,
        "attach": this.attach
      }
    }, [h("transition", {
      "slot": "content",
      "attrs": {
        "name": this.expandAnimation ? "".concat(this.componentName, "--animation-expand") : "".concat(this.componentName, "--animation"),
        "appear": true
      },
      "on": {
        "beforeEnter": this.onBeforeEnter,
        "afterEnter": this.onAfterEnter,
        "afterLeave": this.destroyPopper
      }
    }, [overlay]), ref]);
  }
});

export { LPopup as default };
//# sourceMappingURL=popup.js.map
