/**
 * tdesign v0.32.0
 * (c) 2021 tdesign
 * @license MIT
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _typeof = require('@babel/runtime/helpers/typeof');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var Vue = require('vue');
var core = require('@popperjs/core');
var _commonjsHelpers = require('../_chunks/dep-939cdc39.js');
var config = require('../config.js');
var utils_classnames = require('../utils/classnames.js');
var utils_dom = require('../utils/dom.js');
var popup_props = require('./props.js');
var utils_renderTnode = require('../utils/render-tnode.js');
var utils_setStyle = require('../utils/set-style.js');
require('raf');
require('lodash/isString');
require('../utils/easing.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue);

var ResizeSensor = _commonjsHelpers.createCommonjsModule(function (module, exports) {
  /**
   * Copyright Marc J. Schmidt. See the LICENSE file at the top-level
   * directory of this distribution and at
   * https://github.com/marcj/css-element-queries/blob/master/LICENSE.
   */

  (function (root, factory) {
    {
      module.exports = factory();
    }
  })(typeof window !== 'undefined' ? window : _commonjsHelpers.commonjsGlobal, function () {
    // Make sure it does not throw in a SSR (Server Side Rendering) situation
    if (typeof window === "undefined") {
      return null;
    } // https://github.com/Semantic-Org/Semantic-UI/issues/3855
    // https://github.com/marcj/css-element-queries/issues/257


    var globalWindow = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); // Only used for the dirty checking, so the event callback count is limited to max 1 call per fps per sensor.
    // In combination with the event based resize sensor this saves cpu time, because the sensor is too fast and
    // would generate too many unnecessary events.

    var requestAnimationFrame = globalWindow.requestAnimationFrame || globalWindow.mozRequestAnimationFrame || globalWindow.webkitRequestAnimationFrame || function (fn) {
      return globalWindow.setTimeout(fn, 20);
    };

    var cancelAnimationFrame = globalWindow.cancelAnimationFrame || globalWindow.mozCancelAnimationFrame || globalWindow.webkitCancelAnimationFrame || function (timer) {
      globalWindow.clearTimeout(timer);
    };
    /**
     * Iterate over each of the provided element(s).
     *
     * @param {HTMLElement|HTMLElement[]} elements
     * @param {Function}                  callback
     */


    function forEachElement(elements, callback) {
      var elementsType = Object.prototype.toString.call(elements);
      var isCollectionTyped = '[object Array]' === elementsType || '[object NodeList]' === elementsType || '[object HTMLCollection]' === elementsType || '[object Object]' === elementsType || 'undefined' !== typeof jQuery && elements instanceof jQuery //jquery
      || 'undefined' !== typeof Elements && elements instanceof Elements //mootools
      ;
      var i = 0,
          j = elements.length;

      if (isCollectionTyped) {
        for (; i < j; i++) {
          callback(elements[i]);
        }
      } else {
        callback(elements);
      }
    }
    /**
    * Get element size
    * @param {HTMLElement} element
    * @returns {Object} {width, height}
    */


    function getElementSize(element) {
      if (!element.getBoundingClientRect) {
        return {
          width: element.offsetWidth,
          height: element.offsetHeight
        };
      }

      var rect = element.getBoundingClientRect();
      return {
        width: Math.round(rect.width),
        height: Math.round(rect.height)
      };
    }
    /**
     * Apply CSS styles to element.
     *
     * @param {HTMLElement} element
     * @param {Object} style
     */


    function setStyle(element, style) {
      Object.keys(style).forEach(function (key) {
        element.style[key] = style[key];
      });
    }
    /**
     * Class for dimension change detection.
     *
     * @param {Element|Element[]|Elements|jQuery} element
     * @param {Function} callback
     *
     * @constructor
     */


    var ResizeSensor = function ResizeSensor(element, callback) {
      //Is used when checking in reset() only for invisible elements
      var lastAnimationFrameForInvisibleCheck = 0;
      /**
       *
       * @constructor
       */

      function EventQueue() {
        var q = [];

        this.add = function (ev) {
          q.push(ev);
        };

        var i, j;

        this.call = function (sizeInfo) {
          for (i = 0, j = q.length; i < j; i++) {
            q[i].call(this, sizeInfo);
          }
        };

        this.remove = function (ev) {
          var newQueue = [];

          for (i = 0, j = q.length; i < j; i++) {
            if (q[i] !== ev) newQueue.push(q[i]);
          }

          q = newQueue;
        };

        this.length = function () {
          return q.length;
        };
      }
      /**
       *
       * @param {HTMLElement} element
       * @param {Function}    resized
       */


      function attachResizeEvent(element, resized) {
        if (!element) return;

        if (element.resizedAttached) {
          element.resizedAttached.add(resized);
          return;
        }

        element.resizedAttached = new EventQueue();
        element.resizedAttached.add(resized);
        element.resizeSensor = document.createElement('div');
        element.resizeSensor.dir = 'ltr';
        element.resizeSensor.className = 'resize-sensor';
        var style = {
          pointerEvents: 'none',
          position: 'absolute',
          left: '0px',
          top: '0px',
          right: '0px',
          bottom: '0px',
          overflow: 'hidden',
          zIndex: '-1',
          visibility: 'hidden',
          maxWidth: '100%'
        };
        var styleChild = {
          position: 'absolute',
          left: '0px',
          top: '0px',
          transition: '0s'
        };
        setStyle(element.resizeSensor, style);
        var expand = document.createElement('div');
        expand.className = 'resize-sensor-expand';
        setStyle(expand, style);
        var expandChild = document.createElement('div');
        setStyle(expandChild, styleChild);
        expand.appendChild(expandChild);
        var shrink = document.createElement('div');
        shrink.className = 'resize-sensor-shrink';
        setStyle(shrink, style);
        var shrinkChild = document.createElement('div');
        setStyle(shrinkChild, styleChild);
        setStyle(shrinkChild, {
          width: '200%',
          height: '200%'
        });
        shrink.appendChild(shrinkChild);
        element.resizeSensor.appendChild(expand);
        element.resizeSensor.appendChild(shrink);
        element.appendChild(element.resizeSensor);
        var computedStyle = window.getComputedStyle(element);
        var position = computedStyle ? computedStyle.getPropertyValue('position') : null;

        if ('absolute' !== position && 'relative' !== position && 'fixed' !== position && 'sticky' !== position) {
          element.style.position = 'relative';
        }

        var dirty = false; //last request animation frame id used in onscroll event

        var rafId = 0;
        var size = getElementSize(element);
        var lastWidth = 0;
        var lastHeight = 0;
        var initialHiddenCheck = true;
        lastAnimationFrameForInvisibleCheck = 0;

        var resetExpandShrink = function resetExpandShrink() {
          var width = element.offsetWidth;
          var height = element.offsetHeight;
          expandChild.style.width = width + 10 + 'px';
          expandChild.style.height = height + 10 + 'px';
          expand.scrollLeft = width + 10;
          expand.scrollTop = height + 10;
          shrink.scrollLeft = width + 10;
          shrink.scrollTop = height + 10;
        };

        var reset = function reset() {
          // Check if element is hidden
          if (initialHiddenCheck) {
            var invisible = element.offsetWidth === 0 && element.offsetHeight === 0;

            if (invisible) {
              // Check in next frame
              if (!lastAnimationFrameForInvisibleCheck) {
                lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function () {
                  lastAnimationFrameForInvisibleCheck = 0;
                  reset();
                });
              }

              return;
            } else {
              // Stop checking
              initialHiddenCheck = false;
            }
          }

          resetExpandShrink();
        };

        element.resizeSensor.resetSensor = reset;

        var onResized = function onResized() {
          rafId = 0;
          if (!dirty) return;
          lastWidth = size.width;
          lastHeight = size.height;

          if (element.resizedAttached) {
            element.resizedAttached.call(size);
          }
        };

        var onScroll = function onScroll() {
          size = getElementSize(element);
          dirty = size.width !== lastWidth || size.height !== lastHeight;

          if (dirty && !rafId) {
            rafId = requestAnimationFrame(onResized);
          }

          reset();
        };

        var addEvent = function addEvent(el, name, cb) {
          if (el.attachEvent) {
            el.attachEvent('on' + name, cb);
          } else {
            el.addEventListener(name, cb);
          }
        };

        addEvent(expand, 'scroll', onScroll);
        addEvent(shrink, 'scroll', onScroll); // Fix for custom Elements and invisible elements

        lastAnimationFrameForInvisibleCheck = requestAnimationFrame(function () {
          lastAnimationFrameForInvisibleCheck = 0;
          reset();
        });
      }

      forEachElement(element, function (elem) {
        attachResizeEvent(elem, callback);
      });

      this.detach = function (ev) {
        // clean up the unfinished animation frame to prevent a potential endless requestAnimationFrame of reset
        if (!lastAnimationFrameForInvisibleCheck) {
          cancelAnimationFrame(lastAnimationFrameForInvisibleCheck);
          lastAnimationFrameForInvisibleCheck = 0;
        }

        ResizeSensor.detach(element, ev);
      };

      this.reset = function () {
        element.resizeSensor.resetSensor();
      };
    };

    ResizeSensor.reset = function (element) {
      forEachElement(element, function (elem) {
        elem.resizeSensor.resetSensor();
      });
    };

    ResizeSensor.detach = function (element, ev) {
      forEachElement(element, function (elem) {
        if (!elem) return;

        if (elem.resizedAttached && typeof ev === "function") {
          elem.resizedAttached.remove(ev);
          if (elem.resizedAttached.length()) return;
        }

        if (elem.resizeSensor) {
          if (elem.contains(elem.resizeSensor)) {
            elem.removeChild(elem.resizeSensor);
          }

          delete elem.resizeSensor;
          delete elem.resizedAttached;
        }
      });
    };

    if (typeof MutationObserver !== "undefined") {
      var observer = new MutationObserver(function (mutations) {
        for (var i in mutations) {
          if (mutations.hasOwnProperty(i)) {
            var items = mutations[i].addedNodes;

            for (var j = 0; j < items.length; j++) {
              if (items[j].resizeSensor) {
                ResizeSensor.reset(items[j]);
              }
            }
          }
        }
      });
      document.addEventListener("DOMContentLoaded", function (event) {
        observer.observe(document.body, {
          childList: true,
          subtree: true
        });
      });
    }

    return ResizeSensor;
  });
});

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__default["default"](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 stop = function stop(e) {
  return e.stopPropagation();
};

var name = "".concat(config.prefix, "-popup");
var placementMap = {
  top: "top",
  "top-left": "top-start",
  "top-right": "top-end",
  bottom: "bottom",
  "bottom-left": "bottom-start",
  "bottom-right": "bottom-end",
  left: "left",
  "left-top": "left-start",
  "left-bottom": "left-end",
  right: "right",
  "right-top": "right-start",
  "right-bottom": "right-end"
};
var showTimeout = 250;
var hideTimeout = 150;
var triggers = ["click", "hover", "focus", "context-menu"];
var Popup = Vue__default["default"].extend({
  name: "TPopup",
  provide: function provide() {
    return {
      popup: this
    };
  },
  inject: {
    popup: {
      "default": void 0
    }
  },
  props: _objectSpread(_objectSpread({}, popup_props["default"]), {}, {
    expandAnimation: {
      type: Boolean
    }
  }),
  data: function data() {
    return {
      name: name,
      referenceElm: null,
      resizeSensor: null,
      popper: null,
      timeout: null,
      refOverlayElm: null,
      hasDocumentEvent: false,
      presetMaxHeight: null
    };
  },
  computed: {
    overlayClasses: function overlayClasses() {
      var _ref;

      var base = ["".concat(name, "__content"), (_ref = {}, _defineProperty__default["default"](_ref, "".concat(name, "__content--arrow"), this.showArrow), _defineProperty__default["default"](_ref, utils_classnames["default"].STATUS.disabled, this.disabled), _ref)];
      return base.concat(this.overlayClassName);
    },
    hasTrigger: function hasTrigger() {
      var _this = this;

      return triggers.reduce(function (map, trigger) {
        return _objectSpread(_objectSpread({}, map), {}, _defineProperty__default["default"]({}, trigger, _this.trigger.includes(trigger)));
      }, {});
    }
  },
  watch: {
    visible: function visible(val) {
      var _this2 = this;

      if (val) {
        this.updatePopper();

        if (!this.hasDocumentEvent && (this.hasTrigger["context-menu"] || this.hasTrigger.click)) {
          utils_dom.on(document, "mousedown", this.handleDocumentClick);
          this.hasDocumentEvent = true;
        }

        if (this.referenceElm && this.hasTrigger.focus) {
          utils_dom.once(this.referenceElm, "keydown", function (ev) {
            if (ev.code === "Escape") {
              _this2.handleClose({
                trigger: "keydown-esc"
              });
            }
          });
        }
      } else {
        utils_dom.off(document, "mousedown", this.handleDocumentClick);
        this.hasDocumentEvent = false;
      }
    },
    overlayStyle: function overlayStyle() {
      if (this.popper) {
        this.popper.update();
        this.updateOverlayStyle();
      }
    }
  },
  mounted: function mounted() {
    var _this3 = this;

    if (typeof this.content === "string") {
      this.setOverlayStyle({
        maxWidth: "480px"
      });
    }

    this.referenceElm = this.referenceElm || this.$el;
    if (!this.referenceElm || !this.$refs.popper) return;

    if (this.visible) {
      this.createPopper();
      this.updateOverlayStyle();
    }

    var reference = this.referenceElm;
    var popperElm = this.$refs.popper;
    var offEvents = [];
    this.$on("hook:beforeDestroy", function () {
      offEvents.forEach(function (handler) {
        return handler();
      });
    });

    if (this.hasTrigger.click) {
      offEvents.push(utils_dom.on(reference, "click", function (e) {
        return _this3.handleToggle({
          e: e,
          trigger: "trigger-element-click"
        });
      }));
    }

    if (this.hasTrigger.hover) {
      offEvents.push(utils_dom.on(reference, "mouseenter", function () {
        return _this3.handleOpen({
          trigger: "trigger-element-hover"
        });
      }));
      offEvents.push(utils_dom.on(reference, "mouseleave", function () {
        return _this3.handleClose({
          trigger: "trigger-element-hover"
        });
      }));
      offEvents.push(utils_dom.on(popperElm, "mouseenter", function () {
        return _this3.handleOpen({
          trigger: "trigger-element-hover"
        }, true);
      }));
      offEvents.push(utils_dom.on(popperElm, "mouseleave", function (ev) {
        var parent = _this3.popup;
        var closeParent;

        if (parent !== null && parent !== void 0 && parent.visible) {
          var parentRect = parent.$refs.popper.getBoundingClientRect();
          closeParent = !(ev.x > parentRect.left && ev.x < parentRect.right && ev.y > parentRect.top && ev.y < parentRect.bottom);
        }

        _this3.handleClose({
          trigger: "trigger-element-hover"
        }, closeParent);
      }));
    }

    if (this.hasTrigger.focus) {
      if (reference.querySelector("input,textarea")) {
        offEvents.push(utils_dom.on(reference, "focusin", function () {
          return _this3.handleOpen({
            trigger: "trigger-element-focus"
          });
        }));
        offEvents.push(utils_dom.on(reference, "focusout", function () {
          return _this3.handleClose({
            trigger: "trigger-element-blur"
          });
        }));
      } else {
        offEvents.push(utils_dom.on(reference, "mousedown", function () {
          return _this3.handleOpen({
            trigger: "trigger-element-click"
          });
        }));
        offEvents.push(utils_dom.on(reference, "mouseup", function () {
          return _this3.handleClose({
            trigger: "trigger-element-click"
          });
        }));
      }
    }

    if (this.hasTrigger["context-menu"]) {
      reference.oncontextmenu = function () {
        return false;
      };

      offEvents.push(utils_dom.on(reference, "mousedown", function (e) {
        e.button === 2 && _this3.handleToggle({
          trigger: "context-menu"
        });
      }));
    }
  },
  beforeDestroy: function beforeDestroy() {
    if (this.popper && !this.visible) {
      this.popper.destroy();
      this.popper = null;
    }

    var popperElm = this.$refs.popper;

    if (popperElm && popperElm.parentNode === document.body) {
      popperElm.removeEventListener("click", stop);
      document.body.removeChild(popperElm);
    }
  },
  methods: {
    createPopper: function createPopper() {
      var _this4 = this;

      var currentPlacement = this.placement;
      var popperElm = this.$refs.popper;
      var overlayContainer = utils_dom.getAttach(this.attach);
      overlayContainer.appendChild(popperElm);

      if (this.popper && this.popper.destroy) {
        this.popper.destroy();
      }

      var placement = placementMap[currentPlacement];

      if (this.expandAnimation) {
        popperElm.style.display = "";
        this.presetMaxHeight = parseInt(getComputedStyle(this.getContentElm(popperElm)).maxHeight, 10) || Infinity;
        var referenceElmBottom = innerHeight - this.referenceElm.getBoundingClientRect().bottom;
        var referenceElmTop = this.referenceElm.getBoundingClientRect().top;

        if (referenceElmBottom < popperElm.scrollHeight && referenceElmTop >= popperElm.scrollHeight) {
          placement = /left/.test(currentPlacement) ? "top-start" : "top-end";
        }

        popperElm.style.display = "none";
      }

      this.popper = core.createPopper(this.referenceElm, popperElm, {
        placement: placement,
        onFirstUpdate: function onFirstUpdate() {
          _this4.$nextTick(_this4.updatePopper);
        }
      });
      popperElm.addEventListener("click", stop);
      this.resizeSensor = new ResizeSensor(this.referenceElm, function () {
        _this4.popper && _this4.popper.update();

        _this4.updateOverlayStyle();
      });
    },
    updatePopper: function updatePopper() {
      if (this.popper) {
        this.popper.update();
      } else {
        this.createPopper();
      }
    },
    updateOverlayStyle: function updateOverlayStyle() {
      var overlayStyle = this.overlayStyle;
      var referenceElm = this.$el;
      if (!this.$refs) return;
      var refOverlayElm = this.$refs.overlay;

      if (typeof overlayStyle === "function" && referenceElm && refOverlayElm) {
        var userOverlayStyle = overlayStyle(referenceElm);
        this.setOverlayStyle(userOverlayStyle);
      } else if (_typeof__default["default"](overlayStyle) === "object" && refOverlayElm) {
        this.setOverlayStyle(overlayStyle);
      }
    },
    setOverlayStyle: function setOverlayStyle(styles) {
      if (!this.$refs) return;
      var refOverlayElm = this.$refs.overlay;

      if (_typeof__default["default"](styles) === "object" && refOverlayElm) {
        utils_setStyle["default"](refOverlayElm, styles);
      }
    },
    destroyPopper: function destroyPopper(el) {
      this.resetExpandStyles(el);

      if (this.popper) {
        this.popper.destroy();
        this.popper = null;

        if (this.destroyOnClose) {
          var popperElm = this.$refs.popper;
          popperElm.parentNode.removeChild(popperElm);
        }
      }
    },
    handleToggle: function handleToggle(context) {
      this.emitPopVisible(!this.visible, context);
    },
    handleOpen: function handleOpen(context, openParent) {
      var _this5 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this5.emitPopVisible(true, context);
      }, this.hasTrigger.click ? 0 : showTimeout);

      if (openParent) {
        var _this$popup;

        (_this$popup = this.popup) === null || _this$popup === void 0 ? void 0 : _this$popup.handleOpen(context, true);
      }
    },
    handleClose: function handleClose(context, closeParent) {
      var _this6 = this;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(function () {
        _this6.emitPopVisible(false, context);
      }, this.hasTrigger.click ? 0 : hideTimeout);

      if (closeParent) {
        var _this$popup2;

        (_this$popup2 = this.popup) === null || _this$popup2 === void 0 ? void 0 : _this$popup2.handleClose({
          trigger: "trigger-element-hover"
        }, true);
      }
    },
    handleDocumentClick: function handleDocumentClick(e) {
      var popperElm = this.$refs.popper;
      if (!this.$el || this.$el.contains(e.target) || !popperElm || popperElm.contains(e.target)) return;
      this.emitPopVisible(false, {
        trigger: "document"
      });
    },
    emitPopVisible: function emitPopVisible(val, context) {
      this.$emit("visible-change", val, context);

      if (typeof this.onVisibleChange === "function") {
        this.onVisibleChange(val, context);
      }
    },
    getContentElm: function getContentElm(el) {
      if (this.expandAnimation) {
        var content = el.querySelector(".".concat(name, "__content"));
        return content;
      }

      return null;
    },
    resetExpandStyles: function resetExpandStyles(el) {
      var content = this.getContentElm(el);

      if (content) {
        content.style.overflow = "";

        if (this.presetMaxHeight !== Infinity) {
          content.style.maxHeight = "";
        }
      }
    },
    beforeEnter: function beforeEnter(el) {
      var content = this.getContentElm(el);

      if (content) {
        content.style.overflow = "hidden";
        content.style.maxHeight = "0";
      }
    },
    enter: function enter(el) {
      var content = this.getContentElm(el);

      if (content) {
        var scrollHeight = Math.min(content.scrollHeight, this.presetMaxHeight);
        content.style.maxHeight = "".concat(scrollHeight, "px");
      }
    },
    leave: function leave(el) {
      var content = this.getContentElm(el);
      if (content) content.style.maxHeight = "0";
    },
    beforeLeave: function beforeLeave(el) {
      var content = this.getContentElm(el);

      if (content) {
        content.style.overflow = "hidden";
      }
    }
  },
  render: function render() {
    var h = arguments[0];
    return h("div", {
      "class": "".concat(name, "__reference")
    }, [h("transition", {
      "attrs": {
        "name": "".concat(name, "--animation"),
        "appear": true
      },
      "on": {
        "beforeEnter": this.beforeEnter,
        "enter": this.enter,
        "afterEnter": this.resetExpandStyles,
        "beforeLeave": this.beforeLeave,
        "leave": this.leave,
        "afterLeave": this.destroyPopper
      }
    }, [h("div", {
      "class": name,
      "ref": "popper",
      "directives": [{
        name: "show",
        value: !this.disabled && this.visible
      }],
      "attrs": {
        "role": "tooltip",
        "aria-hidden": this.disabled || !this.visible ? "true" : "false"
      },
      "style": {
        zIndex: this.zIndex
      }
    }, [h("div", {
      "class": this.overlayClasses,
      "ref": "overlay"
    }, [utils_renderTnode.renderTNodeJSX(this, "content"), this.showArrow && h("div", {
      "class": "".concat(name, "__arrow")
    })])])]), utils_renderTnode.renderContent(this, "default", "triggerElement")]);
  }
});

exports["default"] = Popup;
//# sourceMappingURL=popup.js.map
