123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import _extends from 'babel-runtime/helpers/extends';
- import _typeof from 'babel-runtime/helpers/typeof';
- import PropTypes from '../_util/vue-types';
- import { alignElement, alignPoint } from 'dom-align';
- import addEventListener from '../vc-util/Dom/addEventListener';
- import { isWindow, buffer, isSamePoint, isSimilarValue, restoreFocus } from './util';
- import { cloneElement } from '../_util/vnode.js';
- import clonedeep from 'lodash/cloneDeep';
- import { getSlot, getListeners } from '../_util/props-util';
- function getElement(func) {
- if (typeof func !== 'function' || !func) return null;
- return func();
- }
- function getPoint(point) {
- if ((typeof point === 'undefined' ? 'undefined' : _typeof(point)) !== 'object' || !point) return null;
- return point;
- }
- export default {
- props: {
- childrenProps: PropTypes.object,
- align: PropTypes.object.isRequired,
- target: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).def(function () {
- return window;
- }),
- monitorBufferTime: PropTypes.number.def(50),
- monitorWindowResize: PropTypes.bool.def(false),
- disabled: PropTypes.bool.def(false)
- },
- data: function data() {
- this.aligned = false;
- return {};
- },
- mounted: function mounted() {
- var _this = this;
- this.$nextTick(function () {
- _this.prevProps = _extends({}, _this.$props);
- var props = _this.$props;
- // if parent ref not attached .... use document.getElementById
- !_this.aligned && _this.forceAlign();
- if (!props.disabled && props.monitorWindowResize) {
- _this.startMonitorWindowResize();
- }
- });
- },
- updated: function updated() {
- var _this2 = this;
- this.$nextTick(function () {
- var prevProps = _this2.prevProps;
- var props = _this2.$props;
- var reAlign = false;
- if (!props.disabled) {
- var source = _this2.$el;
- var sourceRect = source ? source.getBoundingClientRect() : null;
- if (prevProps.disabled) {
- reAlign = true;
- } else {
- var lastElement = getElement(prevProps.target);
- var currentElement = getElement(props.target);
- var lastPoint = getPoint(prevProps.target);
- var currentPoint = getPoint(props.target);
- if (isWindow(lastElement) && isWindow(currentElement)) {
- // Skip if is window
- reAlign = false;
- } else if (lastElement !== currentElement || // Element change
- lastElement && !currentElement && currentPoint || // Change from element to point
- lastPoint && currentPoint && currentElement || // Change from point to element
- currentPoint && !isSamePoint(lastPoint, currentPoint)) {
- reAlign = true;
- }
- // If source element size changed
- var preRect = _this2.sourceRect || {};
- if (!reAlign && source && (!isSimilarValue(preRect.width, sourceRect.width) || !isSimilarValue(preRect.height, sourceRect.height))) {
- reAlign = true;
- }
- }
- _this2.sourceRect = sourceRect;
- }
- if (reAlign) {
- _this2.forceAlign();
- }
- if (props.monitorWindowResize && !props.disabled) {
- _this2.startMonitorWindowResize();
- } else {
- _this2.stopMonitorWindowResize();
- }
- _this2.prevProps = _extends({}, _this2.$props, { align: clonedeep(_this2.$props.align) });
- });
- },
- beforeDestroy: function beforeDestroy() {
- this.stopMonitorWindowResize();
- },
- methods: {
- startMonitorWindowResize: function startMonitorWindowResize() {
- if (!this.resizeHandler) {
- this.bufferMonitor = buffer(this.forceAlign, this.$props.monitorBufferTime);
- this.resizeHandler = addEventListener(window, 'resize', this.bufferMonitor);
- }
- },
- stopMonitorWindowResize: function stopMonitorWindowResize() {
- if (this.resizeHandler) {
- this.bufferMonitor.clear();
- this.resizeHandler.remove();
- this.resizeHandler = null;
- }
- },
- forceAlign: function forceAlign() {
- var _$props = this.$props,
- disabled = _$props.disabled,
- target = _$props.target,
- align = _$props.align;
- if (!disabled && target) {
- var source = this.$el;
- var listeners = getListeners(this);
- var result = void 0;
- var element = getElement(target);
- var point = getPoint(target);
- // IE lose focus after element realign
- // We should record activeElement and restore later
- var activeElement = document.activeElement;
- if (element) {
- result = alignElement(source, element, align);
- } else if (point) {
- result = alignPoint(source, point, align);
- }
- restoreFocus(activeElement, source);
- this.aligned = true;
- listeners.align && listeners.align(source, result);
- }
- }
- },
- render: function render() {
- var childrenProps = this.$props.childrenProps;
- var child = getSlot(this)[0];
- if (child && childrenProps) {
- return cloneElement(child, { props: childrenProps });
- }
- return child;
- }
- };
|