<!--
    Mixin that provides size watch capabilities using the ResizeObserver api.
-->

<script>
import { debounce } from 'throttle-debounce';

export default {
    data() {
        return {
            resizing: false,
        };
    },
    computed: {
        // return something other than 0 to enable debounced resize (only evaluated in mounted in
        // the current implementation)
        resizeDebounceValue() {
            return 0;
        },

        // the element to observe for size changes, defaults to this.$el (only evaluated in mounted
        // in the current implementation)
        observeElementValue() {
            if (this.$el instanceof Element || this.$el instanceof SVGElement) {
                return this.$el;
            } else {
                return null;
            }
        },
    },
    mounted() {
        if (!this.resize) {
            return;
        }

        const resizeDebouncedFn = this.resizeDebounceValue
            ? debounce(this.resizeDebounceValue, e => {
                  try {
                      this.resize(e);
                  } catch (e) {
                      console.error('Resize: ' + e);
                  }
                  this.resizing = false;
              })
            : null;

        const resizeFn = () => {
            // debounced version
            if (resizeDebouncedFn) {
                if (!this.resizing) {
                    this.resizing = true;
                    if (this.resizeStarted) {
                        this.resizeStarted();
                    }
                }
                resizeDebouncedFn();
            }

            // regular version
            else {
                try {
                    this.resize();
                } catch (e) {
                    console.error('Resize: ' + e);
                }
            }
        };

        this.resizeObserver = new ResizeObserver(resizeFn);

        if (
            this.observeElementValue &&
            (this.observeElementValue instanceof Element ||
                this.observeElementValue instanceof SVGElement)
        ) {
            this.resizeObserver.observe(this.observeElementValue);
        } else {
            const name = this.bem ? this.bem() : 'PxBaseResize';
            console.warn(
                `${name}: Could not call ResizeObserver.observe because observeElementValue is not an element: ${this.observeElementValue}`,
            );
        }
    },
    beforeUnmount() {
        if (this.resizeObserver) {
            this.resizeObserver.disconnect();
            delete this.resizeObserver;
        }
    },
};
</script>
