'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const index = require('./index-292cc870.js');

class Movinwords {
    constructor(opts = {}) {
        this._el = null;
        this._words = [];
        this._pausedProps = {};
        this._currentLetterIndex = 0;
        this._started = false;
        this._paused = false;
        this._visible = '--v';
        this._events = {};
        this._eventNames = [
            'start',
            'end',
            'wordTransitionStart',
            'wordTransitionEnd',
            'letterTransitionStart',
            'letterTransitionEnd'
        ];
        this._classNames = {
            base: 'mw',
            word: 'mw-w',
            letter: 'mw-l',
            reverse: 'mw-r',
            animateLetters: 'mw-al'
        };
        this._options = Object.assign({ el: '', sentence: '', autostart: true, duration: 1000, delay: 100, offset: 20, animateLetters: false, reverseTransition: false, reverseOrder: false, transition: 'fadeIn', pausableProps: ['opacity', 'transform'], wordSpacing: 0, letterSpacing: 0, highlight: {
                classname: 'highlight',
                tag: 'strong',
                words: []
            }, events: {}, eventsTransitionProperty: 'opacity', intersectionStart: false, intersectionOptions: {
                root: null,
                threshold: 0,
                rootMargin: '0px'
            } }, opts);
        if (!this._options.el) {
            throw new Error('No element provided.');
        }
        if (typeof this._options.el === 'string') {
            this._el = document.querySelector(this._options.el);
        }
        if (this._options.el instanceof HTMLElement) {
            this._el = this._options.el;
        }
        if (this._el) {
            this._registerEvents();
            this._getSentences();
            if (this._options.autostart) {
                this.start();
            }
        }
    }
    _registerEvents() {
        const registeredEvents = this._options.events;
        for (const eventName in registeredEvents) {
            if (registeredEvents.hasOwnProperty(eventName) &&
                this._isAllowedEvent(eventName)) {
                this._addEventListener(eventName, registeredEvents[eventName]);
            }
        }
    }
    _addEventListener(event, callback) {
        if (typeof event !== 'string' || typeof callback !== 'function') {
            return false;
        }
        if (this._events[event] === undefined) {
            this._events[event] = {
                listeners: []
            };
        }
        this._events[event].listeners.push(callback);
    }
    _emitEvent(event, details) {
        if (this._events[event] === undefined) {
            return false;
        }
        this._events[event].listeners.forEach(listener => listener(details));
    }
    _isAllowedEvent(eventName) {
        return this._eventNames.includes(eventName);
    }
    _isEmptyArray(arr) {
        if (Array.isArray(arr) && arr) {
            return !arr.length;
        }
    }
    _isHighlightedWord(word) {
        const highlightedWordsArr = this._options.highlight.words;
        return (highlightedWordsArr && !this._isEmptyArray(highlightedWordsArr) && highlightedWordsArr.includes(word));
    }
    _isLastLetterOfWord(index, total) {
        return index === total - 1;
    }
    _isLastWordOfSentence(wordStr) {
        let output = false;
        for (const [index, word] of this._words.entries()) {
            if ((wordStr === word) && (index + 1 === this._words.length)) {
                output = true;
            }
        }
        return output;
    }
    _setCSSVariables(sentence) {
        sentence.style.setProperty('--mw-word-spacing', String(this._getSpacing(sentence)));
        sentence.style.setProperty('--mw-letter-spacing', String(this._getSpacing(sentence, 'letter')));
        sentence.style.setProperty('--mw-duration', `${this._options.duration}ms`);
        sentence.style.setProperty('--mw-delay', `${this._options.delay}ms`);
        sentence.style.setProperty('--mw-offset', String(this._options.offset));
    }
    _getWordIndex(index, words) {
        const realIndex = index + 1;
        return this._options.reverseOrder
            ? words.length - realIndex
            : realIndex;
    }
    _getSpacing(sentence, type = 'word') {
        const spacing = type === 'word'
            ? this._options.wordSpacing
            : this._options.letterSpacing;
        if (spacing) {
            return spacing;
        }
        return type === 'word'
            ? parseInt(window.getComputedStyle(sentence, null).getPropertyValue('font-size')) * 0.4
            : 0;
    }
    _getWordsArray(sentence) {
        if (sentence.textContent) {
            this._words = sentence.textContent.replace(/(?:\r\n|\r|\n)/g, ' :br: ').trim().split(' ');
        }
        return this._words;
    }
    _getLettersArray(word) {
        return word.textContent
            ? [...word.textContent]
            : [];
    }
    _getSentences() {
        if (this._el) {
            if (this._options.sentence) {
                this._el.innerHTML = this._options.sentence;
            }
            this._el.classList.add(this._classNames.base);
            this._el.classList.add(this._options.transition);
            if (this._options.reverseTransition) {
                this._el.classList.add(this._classNames.reverse);
            }
            if (this._options.animateLetters) {
                this._el.classList.add(this._classNames.animateLetters);
            }
        }
    }
    _parseSentences() {
        if (this._el) {
            this._setCSSVariables(this._el);
            this._createAndAppendWordTags(this._el);
            this._createAndAppendLetterTags(this._el);
            setTimeout(() => {
                if (this._el) {
                    this._el.classList.add(this._visible);
                    delete this._el.dataset[this._classNames.base];
                }
            }, 100);
        }
    }
    _appendTags(el, tagsArr) {
        el.innerHTML = '';
        for (const tag of tagsArr) {
            el.appendChild(tag);
        }
    }
    _createTag(options) {
        var _a;
        const tagEl = document.createElement(options.tag);
        tagEl.className = options.className;
        tagEl.textContent = options.text;
        for (const varName in options.vars) {
            if (varName) {
                const vars = (_a = options.vars[varName]) !== null && _a !== void 0 ? _a : null;
                tagEl.style.setProperty(`--mw-${varName}`, String(vars));
            }
        }
        return tagEl;
    }
    _createAndAppendWordTags(sentence) {
        const wordTagsArr = this._createWordTags(sentence);
        this._appendTags(sentence, wordTagsArr);
    }
    _createAndAppendLetterTags(sentence) {
        const words = sentence.querySelectorAll(`.${this._classNames.word}`);
        words.forEach((word, index) => {
            const letterTagsArr = this._createLetterTags(word, this._getWordIndex(index, words));
            this._appendTags(word, letterTagsArr);
        });
    }
    _createWordTags(sentence) {
        const wordTagsArr = [];
        const words = this._getWordsArray(sentence);
        for (const word of words) {
            let tag = 'span';
            let className = this._classNames.word;
            if (this._isHighlightedWord(word)) {
                className += ` ${this._options.highlight.classname}`;
                tag = this._options.highlight.tag;
            }
            if (word == ':br:') {
                wordTagsArr.push(this._createTag({
                    tag: 'br',
                    className: 'mv-n',
                    text: '',
                    vars: {}
                }));
            }
            else if (word != '') {
                wordTagsArr.push(this._createTag({
                    tag,
                    className,
                    text: word,
                    vars: {}
                }));
            }
        }
        return wordTagsArr;
    }
    _createLetterElement(letter, letters, index, wordIndex) {
        const payload = {
            tag: 'span',
            className: `${this._classNames.letter}`,
            text: letter,
            vars: {
                t: undefined,
                w: wordIndex,
                l: index
            }
        };
        if (this._options.animateLetters &&
            typeof payload.vars === 'object' &&
            !Array.isArray(payload.vars)) {
            payload.vars.t = letters.length;
            payload.vars.l = this._currentLetterIndex++;
        }
        return this._createTag(payload);
    }
    _addLetterEventListeners(word, letterEl) {
        const payload = Object.assign(Object.assign({}, this._options), { word: {
                el: word,
                text: word.textContent
            } });
        const ontransitionstart = (event) => {
            if (event.propertyName === this._options.eventsTransitionProperty) {
                this._emitEvent(`wordTransitionStart`, payload);
            }
        };
        const ontransitionend = (event) => {
            if (event.propertyName === this._options.eventsTransitionProperty) {
                this._emitEvent(`wordTransitionEnd`, payload);
                if (word.textContent && this._isLastWordOfSentence(word.textContent)) {
                    this._emitEvent('end', this._options);
                }
            }
        };
        const ondisconnected = () => {
            console.log('disconnect the words');
            letterEl.removeEventListener('transitionstart', ontransitionstart);
            letterEl.removeEventListener('transitionend', ontransitionend);
            this._el.removeEventListener('disconnected', ondisconnected);
        };
        letterEl.addEventListener('transitionstart', ontransitionstart);
        letterEl.addEventListener('transitionend', ontransitionend);
        this._el.addEventListener('disconnected', ondisconnected);
    }
    _createLetterTags(word, wordIndex) {
        const letterTagsArr = [];
        const letters = this._getLettersArray(word);
        for (const [index, letter] of letters.entries()) {
            const letterEl = this._createLetterElement(letter, letters, index, wordIndex);
            if (this._isLastLetterOfWord(index, letters.length)) {
                this._addLetterEventListeners(word, letterEl);
            }
            letterTagsArr.push(letterEl);
        }
        return letterTagsArr;
    }
    _triggerStart() {
        this._started = true;
        this._emitEvent('start', this._options);
        this._parseSentences();
    }
    _triggerStartOnIntersection() {
        if ('IntersectionObserver' in window &&
            'IntersectionObserverEntry' in window &&
            'intersectionRatio' in window.IntersectionObserverEntry.prototype &&
            this._options.el) {
            const observer = new IntersectionObserver((elements) => {
                elements.forEach((el) => {
                    if (el.isIntersecting) {
                        this._triggerStart();
                    }
                });
            }, this._options.intersectionOptions);
            if (this._el) {
                observer.observe(this._el);
            }
        }
    }
    pause() {
        if (!this._paused && this._el) {
            const elements = document.querySelectorAll(`.${this._classNames.letter}`);
            elements.forEach((el, index) => {
                const htmlEl = el;
                this._pausedProps[index] = {};
                const computedStyle = window.getComputedStyle(el);
                for (const prop of this._options.pausableProps) {
                    this._pausedProps[index][prop] = computedStyle[prop];
                    htmlEl.style[prop] = computedStyle[prop];
                }
            });
            this._paused = true;
        }
    }
    resume() {
        if (this._paused && this._el) {
            const elements = document.querySelectorAll(`.${this._classNames.letter}`);
            elements.forEach((el) => {
                const htmlEl = el;
                for (const prop of this._options.pausableProps) {
                    htmlEl.style[prop] = '';
                }
            });
            this._paused = false;
        }
    }
    start() {
        if (!this._started) {
            if (this._options.intersectionStart) {
                this._triggerStartOnIntersection();
            }
            else {
                this._triggerStart();
            }
        }
    }
}
if (typeof window !== 'undefined') {
    window.Movinwords = Movinwords;
}

const styleCss = "[data-mw],.mw{opacity:0}.mw.--v{opacity:1}.mw .mw-w{--mw-offset-sanitized:calc(var(--mw-offset) * 1px);--mw-offset-sanitized-negative:calc(-1 * var(--mw-offset-sanitized));white-space:nowrap;display:-ms-inline-flexbox;display:inline-flex;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.mw .mv-n{display:block}.mw .mw-w:not(:last-child){margin-right:calc(var(--mw-word-spacing) * 1px)}.mw .mw-l{position:relative;display:inline-block;-webkit-transition-duration:var(--mw-duration);transition-duration:var(--mw-duration)}.mw .mw-l:not(:last-child){margin-right:calc(var(--mw-letter-spacing) * 1px)}.mw:not(.mw-al) .mw-l{-webkit-transition-delay:calc(var(--mw-delay) * var(--mw-w));transition-delay:calc(var(--mw-delay) * var(--mw-w))}.mw.mw-al .mw-l{-webkit-transition-delay:calc(var(--mw-delay) * var(--mw-l));transition-delay:calc(var(--mw-delay) * var(--mw-l))}.mw.fadeIn .mw-l{opacity:0;-webkit-transition-property:opacity;transition-property:opacity;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;will-change:opacity}.mw.slideInLeft .mw-l{-webkit-transform:translateX(var(--mw-offset-sanitized-negative));transform:translateX(var(--mw-offset-sanitized-negative))}.mw.slideInRight .mw-l{-webkit-transform:translateX(var(--mw-offset-sanitized));transform:translateX(var(--mw-offset-sanitized))}.mw.slideInTop .mw-l,.mw.revealInTop .mw-l{-webkit-transform:translateY(var(--mw-offset-sanitized-negative));transform:translateY(var(--mw-offset-sanitized-negative))}.mw.slideInBottom .mw-l,.mw.revealInBottom .mw-l{-webkit-transform:translateY(var(--mw-offset-sanitized));transform:translateY(var(--mw-offset-sanitized))}.mw.slideInTop .mw-l,.mw.slideInBottom .mw-l,.mw.slideInLeft .mw-l,.mw.slideInRight .mw-l,.mw.revealInTop .mw-l,.mw.revealInBottom .mw-l{opacity:0;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:opacity, transform;transition-property:opacity, transform, -webkit-transform;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;will-change:opacity, transform}.mw.fadeIn.--v .mw-l,.mw.slideInTop.--v .mw-l,.mw.slideInBottom.--v .mw-l,.mw.slideInLeft.--v .mw-l,.mw.slideInRight.--v .mw-l,.mw.revealInTop.--v .mw-l,.mw.revealInBottom.--v .mw-l{opacity:1}.mw.slideInTop.--v .mw-l,.mw.slideInBottom.--v .mw-l,.mw.revealInTop.--v .mw-l,.mw.revealInBottom.--v .mw-l{-webkit-transform:translateY(0);transform:translateY(0)}.mw.slideInLeft.--v .mw-l,.mw.slideInRight.--v .mw-l{-webkit-transform:translateX(0);transform:translateX(0)}.mw.revealInTop.--v .mw-w,.mw.revealInBottom.--v .mw-w{overflow:hidden}.mw.mw-r.fadeIn .mw-l,.mw.mw-r.slideInTop .mw-l,.mw.mw-r.slideInBottom .mw-l,.mw.mw-r.slideInLeft .mw-l,.mw.mw-r.slideInRight .mw-l,.mw.mw-r.revealInTop .mw-l,.mw.mw-r.revealInBottom .mw-l{opacity:1}.mw.mw-r.slideInTop .mw-l,.mw.mw-r.slideInBottom .mw-l,.mw.mw-r.revealInTop .mw-l,.mw.mw-r.revealInBottom .mw-l{-webkit-transform:translateY(0);transform:translateY(0)}.mw.mw-r.slideInLeft .mw-l,.mw.mw-r.slideInRight .mw-l{-webkit-transform:translateX(0);transform:translateX(0)}.mw.mw-r.revealInTop .mw-w,.mw.mw-r.revealInBottom .mw-w{overflow:hidden}.mw.mw-r.slideInLeft.--v .mw-l{-webkit-transform:translateX(var(--mw-offset-sanitized-negative));transform:translateX(var(--mw-offset-sanitized-negative))}.mw.mw-r.slideInRight.--v .mw-l{-webkit-transform:translateX(var(--mw-offset-sanitized));transform:translateX(var(--mw-offset-sanitized))}.mw.mw-r.slideInTop.--v .mw-l,.mw.mw-r.revealInTop.--v .mw-l{-webkit-transform:translateY(var(--mw-offset-sanitized-negative));transform:translateY(var(--mw-offset-sanitized-negative))}.mw.mw-r.slideInBottom.--v .mw-l,.mw.mw-r.revealInBottom.--v .mw-l{-webkit-transform:translateY(var(--mw-offset-sanitized));transform:translateY(var(--mw-offset-sanitized))}.mw.mw-r.fadeIn.--v .mw-l,.mw.mw-r.slideInTop.--v .mw-l,.mw.mw-r.slideInBottom.--v .mw-l,.mw.mw-r.slideInLeft.--v .mw-l,.mw.mw-r.slideInRight.--v .mw-l,.mw.mw-r.revealInTop.--v .mw-l,.mw.mw-r.revealInBottom.--v .mw-l{opacity:0}";
const XMovinwordsStyle0 = styleCss;

const XMovinwords = class {
    constructor(hostRef) {
        index.registerInstance(this, hostRef);
        this.onTypingStart = index.createEvent(this, "typingstart", 7);
        this.onTypingEnd = index.createEvent(this, "typingend", 7);
        /**
         * Drawer state of the content
         */
        this.movinInstance = null;
        this.sentence = undefined;
        this.highlight = '';
    }
    /**
     * Watcher hook on sentence change
     */
    watchSentenceHandler() {
        if (this.el) {
            this.el.dispatchEvent(new CustomEvent('disconnected'));
            this.el.classList.remove('--v');
            this.movinInstance = new Movinwords({
                el: this.el,
                sentence: this.sentence,
                events: {
                    start: () => {
                        this.onTypingStart.emit();
                    },
                    end: () => {
                        this.onTypingEnd.emit();
                    },
                },
                highlight: {
                    classname: 'highlight',
                    tag: 'strong',
                    words: this.highlight.split(',').map((word) => word.trim()),
                },
            });
            this.movinInstance.start();
        }
    }
    /**
     * On element is mounted
     */
    componentDidLoad() {
        this.movinInstance = new Movinwords({
            el: this.el,
            autostart: true,
            sentence: this.sentence,
            events: {
                start: () => {
                    this.onTypingStart.emit();
                },
                end: () => {
                    this.onTypingEnd.emit();
                },
            },
            highlight: {
                classname: 'highlight',
                tag: 'strong',
                words: this.highlight.split(',').map((word) => word.trim()),
            },
        });
    }
    /**
     * On element is destroyed
     */
    disconnectedCallback() {
        this.el.dispatchEvent(new CustomEvent('disconnected'));
    }
    /**
     * Render component
     */
    render() {
        return index.h(index.Host, { key: 'acf9386b1e9b134d96babcd475eac2d656dce6f3' }, index.h("slot", { key: 'b2bb0168dbc686be52f7dce262f95dfe5b31a26d' }));
    }
    get el() { return index.getElement(this); }
    static get watchers() { return {
        "sentence": ["watchSentenceHandler"]
    }; }
};
XMovinwords.style = XMovinwordsStyle0;

exports.x_movinwords = XMovinwords;
