/* If you add a vgrow attribute to your textarea then it will automatically grow
 * to include all content, up to the CSS max-height (if any is specified). */
(function() {
    class VGrow {
        constructor() {
            this.observer = new MutationObserver(this.observeMutations.bind(this));
            this.observe();
            this.initializeTextareas();
        }

        initializeTextareas() {
            const textareas = document.querySelectorAll('textarea[vgrow]');
            for (const textarea of textareas) {
                this.initializeTextarea(textarea);
            }
        }

        initializeTextarea(textarea) {
            this.adjustTextareaHeight(textarea);
            textarea.addEventListener('input', (event) => {
                this.adjustTextareaHeight(event.target);
            });
        }

        adjustTextareaHeight(textarea) {
            const computedStyle = window.getComputedStyle(textarea);
            const maxHeight = parseInt(computedStyle.maxHeight, 10);

            // Reset the textarea height to auto to shrink it (if needed)
            // (this messes up scroll, so we restore it later)
            const scrollY = window.scrollY;
            textarea.style.height = 'auto';

            if (maxHeight && textarea.scrollHeight > maxHeight) {
                textarea.style.height = `${maxHeight}px`;
                textarea.style.overflowY = 'auto';
            } else {
                textarea.style.height = `${textarea.scrollHeight}px`;
            }

            // Restore scroll
            window.scrollTo(0, scrollY);
        }

        observe() {
            this.observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        }

        observeMutations(mutationsList, observer) {
            for (const mutation of mutationsList) {
                if (mutation.type === 'childList' && mutation.addedNodes.length) {
                    mutation.addedNodes.forEach((node) => {
                        if (node.nodeName === 'TEXTAREA' && node.hasAttribute('vgrow')) {
                            this.initializeTextarea(node);
                        }
                    });
                }
            }
        }
    }

    document.addEventListener('DOMContentLoaded', () => {
        new VGrow();
    });

})();
