/**
 * tdesign v0.41.7
 * (c) 2022 tdesign
 * @license MIT
 */

import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
import _defineProperty from '@babel/runtime/helpers/defineProperty';
import _regeneratorRuntime from '@babel/runtime/regenerator';
import Vue from 'vue';
import ClASSNAMES from '../utils/classnames.js';
import { ANCHOR_SHARP_REGEXP, getOffsetTop } from './utils.js';
import { off, getScrollContainer, on, getScroll, scrollTo } from '../utils/dom.js';
import props from './props.js';
import { renderTNodeJSX } from '../utils/render-tnode.js';
import { Affix } from '../affix/index.js';
import { COMPONENT_NAME } from './constant.js';
import '../config.js';
import 'raf';
import 'lodash/isString';
import '../utils/easing.js';
import '@babel/runtime/helpers/typeof';
import '../affix/affix.js';
import 'lodash/isFunction';
import '../affix/props.js';
import '../utils/withInstall.js';
import 'lodash/capitalize';
import './style/index.js';
import '../affix/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 ANCHOR_LINE_CLASSNAME = "".concat(COMPONENT_NAME, "__line");
var ANCHOR_LINE_CURSOR_CLASSNAME = "".concat(COMPONENT_NAME, "__line-cursor");
var _Anchor = Vue.extend({
  name: "TAnchor",
  props: _objectSpread({}, props),
  provide: function provide() {
    return {
      tAnchor: this
    };
  },
  data: function data() {
    return {
      links: [],
      active: "",
      activeLineStyle: false
    };
  },
  watch: {
    attach: function attach() {
      if (this.scrollContainer) {
        off(this.scrollContainer, "scroll", this.handleScroll);
      }

      this.getScrollContainer();
    }
  },
  methods: {
    getScrollContainer: function getScrollContainer$1() {
      var container = this.container;
      this.scrollContainer = getScrollContainer(container);
      on(this.scrollContainer, "scroll", this.handleScroll);
      this.handleScroll();
    },
    getAnchorTarget: function getAnchorTarget(link) {
      var matcher = link.match(ANCHOR_SHARP_REGEXP);

      if (!matcher) {
        return;
      }

      var anchor = document.getElementById(matcher[1]);

      if (!anchor) {
        return;
      }

      return anchor;
    },
    registerLink: function registerLink(link) {
      var links = this.links;

      if (!ANCHOR_SHARP_REGEXP.test(link) || links.indexOf(link) !== -1) {
        return;
      }

      links.push(link);
    },
    unregisterLink: function unregisterLink(link) {
      this.links = this.links.filter(function (each) {
        return each !== link;
      });
    },
    setCurrentActiveLink: function setCurrentActiveLink(link) {
      var _this = this;

      return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
        var active;
        return _regeneratorRuntime.wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                active = _this.active;

                if (!(active === link)) {
                  _context.next = 3;
                  break;
                }

                return _context.abrupt("return");

              case 3:
                _this.active = link;

                _this.emitChange(link, active);

                _context.next = 7;
                return Vue.nextTick();

              case 7:
                _this.updateActiveLine();

              case 8:
              case "end":
                return _context.stop();
            }
          }
        }, _callee);
      }))();
    },
    updateActiveLine: function updateActiveLine() {
      var ele = this.$el.querySelector(".".concat(ClASSNAMES.STATUS.active, ">a"));

      if (!ele) {
        this.activeLineStyle = false;
        return;
      }

      var top = ele.offsetTop,
          height = ele.offsetHeight;
      this.activeLineStyle = {
        top: "".concat(top, "px"),
        height: "".concat(height, "px"),
        opacity: 1
      };
    },
    emitChange: function emitChange(currentLink, prevLink) {
      this.$emit("change", currentLink, prevLink);

      if (this.onChange) {
        this.onChange(currentLink, prevLink);
      }
    },
    handleLinkClick: function handleLinkClick(link) {
      this.$emit("click", link);

      if (this.onClick) {
        this.onClick(link);
      }
    },
    handleScrollTo: function handleScrollTo(link) {
      var _this2 = this;

      return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
        var anchor, scrollContainer, targetOffset, scrollTop, offsetTop, top;
        return _regeneratorRuntime.wrap(function _callee2$(_context2) {
          while (1) {
            switch (_context2.prev = _context2.next) {
              case 0:
                anchor = _this2.getAnchorTarget(link);

                _this2.setCurrentActiveLink(link);

                if (anchor) {
                  _context2.next = 4;
                  break;
                }

                return _context2.abrupt("return");

              case 4:
                _this2.handleScrollLock = true;
                scrollContainer = _this2.scrollContainer, targetOffset = _this2.targetOffset;
                scrollTop = getScroll(scrollContainer);
                offsetTop = getOffsetTop(anchor, scrollContainer);
                top = scrollTop + offsetTop - targetOffset;
                _context2.next = 11;
                return scrollTo(top, {
                  container: scrollContainer
                });

              case 11:
                _this2.handleScrollLock = false;

              case 12:
              case "end":
                return _context2.stop();
            }
          }
        }, _callee2);
      }))();
    },
    handleScroll: function handleScroll() {
      var _this3 = this;

      if (this.handleScrollLock) return;
      var links = this.links,
          bounds = this.bounds,
          targetOffset = this.targetOffset;
      var filters = [];
      var active = "";
      links.forEach(function (link) {
        var anchor = _this3.getAnchorTarget(link);

        if (!anchor) {
          return;
        }

        var top = getOffsetTop(anchor, _this3.scrollContainer);

        if (top < bounds + targetOffset) {
          filters.push({
            link: link,
            top: top
          });
        }
      });

      if (filters.length) {
        var latest = filters.reduce(function (prev, cur) {
          return prev.top > cur.top ? prev : cur;
        });
        active = latest.link;
      }

      this.setCurrentActiveLink(active);
    },
    renderCursor: function renderCursor() {
      var h = this.$createElement;
      var titleContent = renderTNodeJSX(this, "cursor");
      return titleContent || h("div", {
        "class": ANCHOR_LINE_CURSOR_CLASSNAME
      });
    }
  },
  mounted: function mounted() {
    var _this4 = this;

    return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
      var active;
      return _regeneratorRuntime.wrap(function _callee3$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              active = _this4.active;

              _this4.getScrollContainer();

              if (!active) {
                _context3.next = 6;
                break;
              }

              _context3.next = 5;
              return Vue.nextTick();

            case 5:
              _this4.handleScrollTo(active);

            case 6:
            case "end":
              return _context3.stop();
          }
        }
      }, _callee3);
    }))();
  },
  destroyed: function destroyed() {
    if (!this.scrollContainer) return;
    off(this.scrollContainer, "scroll", this.handleScroll);
  },
  render: function render() {
    var h = arguments[0];
    var children = this.$scopedSlots["default"],
        size = this.size,
        affixProps = this.affixProps,
        activeLineStyle = this.activeLineStyle;
    var className = [COMPONENT_NAME, ClASSNAMES.SIZE[size]];
    var content = h("div", {
      "class": className
    }, [h("div", {
      "class": ANCHOR_LINE_CLASSNAME
    }, [h("div", {
      "class": "".concat(ANCHOR_LINE_CURSOR_CLASSNAME, "-wrapper"),
      "style": activeLineStyle
    }, [this.renderCursor()])]), children && children(null)]);

    if (affixProps) {
      return h(Affix, {
        "props": _objectSpread({}, affixProps)
      }, [content]);
    }

    return content;
  }
});

export { _Anchor as default };
//# sourceMappingURL=anchor.js.map
