/**
 * from Ant Design Vue 1.6.2 rc-resize-observer
 * @author xiufu.wang
 */
import ResizeObserver from 'resize-observer-polyfill';

export default {
    name: 'ProResizeObserver',
    componentName: 'ProResizeObserver',
    components: {},
    computed: {},
    data() {
        this.currentElement = null;
        this.resizeObserver = null;
        return {
            width: 0,
            height: 0,
        };
    },
    mounted() {
        this.onComponentUpdated();
    },

    updated() {
        this.onComponentUpdated();
    },
    beforeDestroy() {
        this.destroyObserver();
    },
    methods: {
        onComponentUpdated() {
            const { disabled } = this;

            // Unregister if disabled
            if (disabled) {
                this.destroyObserver();
                return;
            }

            // Unregister if element changed
            const element = this.$el;
            const elementChanged = element !== this.currentElement;
            if (elementChanged) {
                this.destroyObserver();
                this.currentElement = element;
            }

            if (!this.resizeObserver && element) {
                this.resizeObserver = new ResizeObserver(this.onResize);
                this.resizeObserver.observe(element);
            }
        },

        onResize(entries) {
            const { target } = entries[0];
            const { width, height } = target.getBoundingClientRect();
            /**
             * Resize observer trigger when content size changed.
             * In most case we just care about element size,
             * let's use `boundary` instead of `contentRect` here to avoid shaking.
             */
            const fixedWidth = Math.floor(width);
            const fixedHeight = Math.floor(height);

            if (this.width !== fixedWidth || this.height !== fixedHeight) {
                const size = { width: fixedWidth, height: fixedHeight };
                this.width = fixedWidth;
                this.fixedHeight = fixedHeight;
                this.$emit('resize', size);
            }
        },

        destroyObserver() {
            if (this.resizeObserver) {
                this.resizeObserver.disconnect();
                this.resizeObserver = null;
            }
        },
    },

    render() {
        return this.$slots.default[0];
    }
}