"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 _vn = require("../../ui/src/vn");
var _loading = _interopRequireDefault(require("../../loading/src/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 browseObj = _xeUtils.default.browse();
function createReactData() {
  return {
    scrollYLoad: false,
    bodyHeight: 0,
    customHeight: 0,
    customMaxHeight: 0,
    parentHeight: 0,
    topSpaceHeight: 0,
    items: []
  };
}
function createInternalData() {
  return {
    resizeObserver: undefined,
    fullData: [],
    lastScrollLeft: 0,
    lastScrollTop: 0,
    scrollYStore: {
      startIndex: 0,
      endIndex: 0,
      visibleSize: 0,
      offsetSize: 0,
      rowHeight: 0
    }
  };
}
var _default2 = exports.default = /* define-vxe-component start */(0, _comp.defineVxeComponent)({
  name: 'VxeList',
  mixins: [_ui.globalMixins.sizeMixin],
  props: {
    data: Array,
    height: [Number, String],
    maxHeight: [Number, String],
    loading: Boolean,
    className: [String, Function],
    size: {
      type: String,
      default: function _default() {
        return (0, _ui.getConfig)().list.size || (0, _ui.getConfig)().size;
      }
    },
    autoResize: {
      type: Boolean,
      default: function _default() {
        return (0, _ui.getConfig)().list.autoResize;
      }
    },
    syncResize: [Boolean, String, Number],
    virtualYConfig: Object,
    scrollY: Object
  },
  data: function data() {
    var xID = _xeUtils.default.uniqueId();
    var reactData = createReactData();
    var internalData = createInternalData();
    return {
      xID: xID,
      reactData: reactData,
      internalData: internalData
    };
  },
  computed: Object.assign(Object.assign({}, {}), {
    computeSYOpts: function computeSYOpts() {
      var $xeList = this;
      var props = $xeList;
      return Object.assign({}, (0, _ui.getConfig)().list.virtualYConfig || (0, _ui.getConfig)().list.scrollY, props.virtualYConfig || props.scrollY);
    },
    computeStyles: function computeStyles() {
      var $xeList = this;
      var props = $xeList;
      var reactData = $xeList.reactData;
      var height = props.height,
        maxHeight = props.maxHeight;
      var customHeight = reactData.customHeight,
        customMaxHeight = reactData.customMaxHeight;
      var style = {};
      if (height) {
        style.height = "".concat(customHeight, "px");
      } else if (maxHeight) {
        style.height = 'auto';
        style.maxHeight = "".concat(customMaxHeight, "px");
      }
      return style;
    }
  }),
  methods: {
    //
    // Method
    //
    dispatchEvent: function dispatchEvent(type, params, evnt) {
      var $xeList = this;
      $xeList.$emit(type, (0, _ui.createEvent)(evnt, {
        $list: $xeList
      }, params));
    },
    callSlot: function callSlot(slotFunc, params, h) {
      var $xeList = this;
      var slots = $xeList.$scopedSlots;
      if (slotFunc) {
        if (_xeUtils.default.isString(slotFunc)) {
          slotFunc = slots[slotFunc] || null;
        }
        if (_xeUtils.default.isFunction(slotFunc)) {
          return (0, _vn.getSlotVNs)(slotFunc.call($xeList, params, h));
        }
      }
      return [];
    },
    /**
       * 加载数据
       * @param {Array} datas 数据
       */
    loadData: function loadData(datas) {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var internalData = $xeList.internalData;
      var scrollYStore = internalData.scrollYStore;
      var sYOpts = $xeList.computeSYOpts;
      var fullData = datas || [];
      Object.assign(scrollYStore, {
        startIndex: 0,
        endIndex: 1,
        visibleSize: 0
      });
      internalData.fullData = fullData;
      // 如果gt为0，则总是启用
      reactData.scrollYLoad = !!sYOpts.enabled && sYOpts.gt > -1 && (sYOpts.gt === 0 || sYOpts.gt <= fullData.length);
      $xeList.handleData();
      return $xeList.computeScrollLoad().then(function () {
        $xeList.refreshScroll();
      });
    },
    /**
     * 重新加载数据
     * @param {Array} datas 数据
     */
    reloadData: function reloadData(datas) {
      var $xeList = this;
      $xeList.clearScroll();
      return $xeList.loadData(datas);
    },
    calcTableHeight: function calcTableHeight(key) {
      var $xeList = this;
      var props = $xeList;
      var reactData = $xeList.reactData;
      var parentHeight = reactData.parentHeight;
      var val = props[key];
      var num = 0;
      if (val) {
        if (val === '100%' || val === 'auto') {
          num = parentHeight;
        } else {
          if ((0, _dom.isScale)(val)) {
            num = Math.floor((_xeUtils.default.toInteger(val) || 1) / 100 * parentHeight);
          } else {
            num = _xeUtils.default.toNumber(val);
          }
          num = Math.max(40, num);
        }
      }
      return num;
    },
    updateHeight: function updateHeight() {
      var $xeList = this;
      var reactData = $xeList.reactData;
      reactData.customHeight = $xeList.calcTableHeight('height');
      reactData.customMaxHeight = $xeList.calcTableHeight('maxHeight');
    },
    updateYSpace: function updateYSpace() {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var internalData = $xeList.internalData;
      var scrollYLoad = reactData.scrollYLoad;
      var scrollYStore = internalData.scrollYStore,
        fullData = internalData.fullData;
      reactData.bodyHeight = scrollYLoad ? fullData.length * scrollYStore.rowHeight : 0;
      reactData.topSpaceHeight = scrollYLoad ? Math.max(scrollYStore.startIndex * scrollYStore.rowHeight, 0) : 0;
    },
    handleData: function handleData() {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var internalData = $xeList.internalData;
      var scrollYLoad = reactData.scrollYLoad;
      var fullData = internalData.fullData,
        scrollYStore = internalData.scrollYStore;
      reactData.items = scrollYLoad ? fullData.slice(scrollYStore.startIndex, scrollYStore.endIndex) : fullData.slice(0);
      return $xeList.$nextTick();
    },
    updateYData: function updateYData() {
      var $xeList = this;
      $xeList.handleData();
      $xeList.updateYSpace();
    },
    computeScrollLoad: function computeScrollLoad() {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var internalData = $xeList.internalData;
      return $xeList.$nextTick().then(function () {
        var scrollYLoad = reactData.scrollYLoad;
        var scrollYStore = internalData.scrollYStore;
        var virtualBodyElem = $xeList.$refs.refVirtualBody;
        var sYOpts = $xeList.computeSYOpts;
        var rowHeight = 0;
        var firstItemElem;
        if (virtualBodyElem) {
          if (sYOpts.sItem) {
            firstItemElem = virtualBodyElem.querySelector(sYOpts.sItem);
          }
          if (!firstItemElem) {
            firstItemElem = virtualBodyElem.children[0];
          }
        }
        if (firstItemElem) {
          rowHeight = firstItemElem.offsetHeight;
        }
        rowHeight = Math.max(12, rowHeight);
        scrollYStore.rowHeight = rowHeight;
        // 计算 Y 逻辑
        if (scrollYLoad) {
          var scrollBodyElem = $xeList.$refs.refVirtualWrapper;
          var visibleYSize = Math.max(8, Math.ceil(scrollBodyElem.clientHeight / rowHeight));
          var offsetYSize = sYOpts.oSize ? _xeUtils.default.toNumber(sYOpts.oSize) : browseObj.edge ? 10 : 0;
          scrollYStore.offsetSize = offsetYSize;
          scrollYStore.visibleSize = visibleYSize;
          scrollYStore.endIndex = Math.max(scrollYStore.startIndex + visibleYSize + offsetYSize, scrollYStore.endIndex);
          $xeList.updateYData();
        } else {
          $xeList.updateYSpace();
        }
      });
    },
    /**
     * 清除滚动条
     */
    clearScroll: function clearScroll() {
      var $xeList = this;
      var scrollBodyElem = $xeList.$refs.refVirtualWrapper;
      if (scrollBodyElem) {
        scrollBodyElem.scrollTop = 0;
      }
      return $xeList.$nextTick();
    },
    /**
     * 如果有滚动条，则滚动到对应的位置
     */
    scrollTo: function scrollTo(scrollLeft, scrollTop) {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var scrollBodyElem = $xeList.$refs.refVirtualWrapper;
      if (scrollLeft) {
        if (!_xeUtils.default.isNumber(scrollLeft)) {
          scrollTop = scrollLeft.top;
          scrollLeft = scrollLeft.left;
        }
      }
      if (_xeUtils.default.isNumber(scrollLeft)) {
        scrollBodyElem.scrollLeft = scrollLeft;
      }
      if (_xeUtils.default.isNumber(scrollTop)) {
        scrollBodyElem.scrollTop = scrollTop;
      }
      if (reactData.scrollYLoad) {
        return new Promise(function (resolve) {
          setTimeout(function () {
            $xeList.$nextTick(function () {
              resolve();
            });
          }, 50);
        });
      }
      return $xeList.$nextTick();
    },
    /**
     * 刷新滚动条
     */
    refreshScroll: function refreshScroll() {
      var $xeList = this;
      var internalData = $xeList.internalData;
      var lastScrollLeft = internalData.lastScrollLeft,
        lastScrollTop = internalData.lastScrollTop;
      return $xeList.clearScroll().then(function () {
        if (lastScrollLeft || lastScrollTop) {
          internalData.lastScrollLeft = 0;
          internalData.lastScrollTop = 0;
          return scrollTo(lastScrollLeft, lastScrollTop);
        }
      });
    },
    /**
     * 重新计算列表
     */
    recalculate: function recalculate() {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var el = $xeList.$refs.refElem;
      if (el) {
        var parentEl = el.parentElement;
        reactData.parentHeight = parentEl ? parentEl.clientHeight : 0;
        $xeList.updateHeight();
        if (el.clientWidth && el.clientHeight) {
          return $xeList.computeScrollLoad();
        }
      }
      return $xeList.$nextTick();
    },
    loadYData: function loadYData(evnt) {
      var $xeList = this;
      var internalData = $xeList.internalData;
      var scrollYStore = internalData.scrollYStore;
      var startIndex = scrollYStore.startIndex,
        endIndex = scrollYStore.endIndex,
        visibleSize = scrollYStore.visibleSize,
        offsetSize = scrollYStore.offsetSize,
        rowHeight = scrollYStore.rowHeight;
      var scrollBodyElem = evnt.target;
      var scrollTop = scrollBodyElem.scrollTop;
      var toVisibleIndex = Math.floor(scrollTop / rowHeight);
      var offsetStartIndex = Math.max(0, toVisibleIndex - 1 - offsetSize);
      var offsetEndIndex = toVisibleIndex + visibleSize + offsetSize;
      if (toVisibleIndex <= startIndex || toVisibleIndex >= endIndex - visibleSize - 1) {
        if (startIndex !== offsetStartIndex || endIndex !== offsetEndIndex) {
          scrollYStore.startIndex = offsetStartIndex;
          scrollYStore.endIndex = offsetEndIndex;
          $xeList.updateYData();
        }
      }
    },
    scrollEvent: function scrollEvent(evnt) {
      var $xeList = this;
      var reactData = $xeList.reactData;
      var internalData = $xeList.internalData;
      var scrollBodyElem = evnt.target;
      var scrollTop = scrollBodyElem.scrollTop;
      var scrollLeft = scrollBodyElem.scrollLeft;
      var isX = scrollLeft !== internalData.lastScrollLeft;
      var isY = scrollTop !== internalData.lastScrollTop;
      internalData.lastScrollTop = scrollTop;
      internalData.lastScrollLeft = scrollLeft;
      if (reactData.scrollYLoad) {
        $xeList.loadYData(evnt);
      }
      $xeList.dispatchEvent('scroll', {
        scrollLeft: scrollLeft,
        scrollTop: scrollTop,
        isX: isX,
        isY: isY
      }, evnt);
    },
    //
    // Render
    //
    renderVN: function renderVN(h) {
      var $xeList = this;
      var props = $xeList;
      var reactData = $xeList.reactData;
      var slots = $xeList.$scopedSlots;
      var className = props.className,
        loading = props.loading;
      var bodyHeight = reactData.bodyHeight,
        topSpaceHeight = reactData.topSpaceHeight,
        items = reactData.items;
      var defaultSlot = slots.default;
      var vSize = $xeList.computeSize;
      var styles = $xeList.computeStyles;
      return h('div', {
        ref: 'refElem',
        class: ['vxe-list', className ? _xeUtils.default.isFunction(className) ? className({
          $list: $xeList
        }) : className : '', _defineProperty(_defineProperty({}, "size--".concat(vSize), vSize), 'is--loading', loading)]
      }, [h('div', {
        ref: 'refVirtualWrapper',
        class: 'vxe-list--virtual-wrapper',
        style: styles,
        on: {
          scroll: $xeList.scrollEvent
        }
      }, [h('div', {
        class: 'vxe-list--y-space',
        style: {
          height: bodyHeight ? "".concat(bodyHeight, "px") : ''
        }
      }), h('div', {
        ref: 'refVirtualBody',
        class: 'vxe-list--body',
        style: {
          marginTop: topSpaceHeight ? "".concat(topSpaceHeight, "px") : ''
        }
      }, defaultSlot ? $xeList.callSlot(defaultSlot, {
        items: items
      }, h) : [])]),
      /**
       * 加载中
       */
      h(_loading.default, {
        class: 'vxe-list--loading',
        props: {
          value: loading
        }
      })]);
    }
  },
  watch: {
    data: function data() {
      var $xeList = this;
      var props = $xeList;
      $xeList.loadData(props.data || []);
    },
    height: function height() {
      var $xeList = this;
      $xeList.recalculate();
    },
    maxHeight: function maxHeight() {
      var $xeList = this;
      $xeList.recalculate();
    },
    syncResize: function syncResize(val) {
      var $xeList = this;
      if (val) {
        $xeList.recalculate();
        $xeList.$nextTick(function () {
          return setTimeout(function () {
            return $xeList.recalculate();
          });
        });
      }
    }
  },
  created: function created() {
    var $xeList = this;
    var props = $xeList;
    $xeList.loadData(props.data || []);
  },
  mounted: function mounted() {
    var $xeList = this;
    var props = $xeList;
    var internalData = $xeList.internalData;
    $xeList.recalculate();
    if (props.autoResize) {
      var el = $xeList.$refs.refElem;
      var resizeObserver = _ui.globalResize.create(function () {
        return $xeList.recalculate();
      });
      resizeObserver.observe(el);
      if (el) {
        resizeObserver.observe(el.parentElement);
      }
      internalData.resizeObserver = resizeObserver;
    }
    _ui.globalEvents.on($xeList, 'resize', $xeList.recalculate);
  },
  activated: function activated() {
    var $xeList = this;
    $xeList.recalculate().then(function () {
      return $xeList.refreshScroll();
    });
  },
  beforeDestroy: function beforeDestroy() {
    var $xeList = this;
    var reactData = $xeList.reactData;
    var internalData = $xeList.internalData;
    var resizeObserver = internalData.resizeObserver;
    if (resizeObserver) {
      resizeObserver.disconnect();
    }
    _ui.globalEvents.off($xeList, 'resize');
    _xeUtils.default.assign(reactData, createReactData());
    _xeUtils.default.assign(internalData, createInternalData());
  },
  render: function render(h) {
    return this.renderVN(h);
  }
});
/* define-vxe-component end */