// Thanks @stimulus: // https://github.com/stimulusjs/stimulus/blob/master/packages/%40stimulus/core/src/application.ts export function domReady() { return new Promise(resolve => { if (document.readyState == "loading") { document.addEventListener("DOMContentLoaded", resolve) } else { resolve() } }) } export function arrayUnique(array) { var a = array.concat(); for(var i=0; i { const name = replaceAtAndColonWithStandardSyntax(attr.name) const typeMatch = name.match(/x-(on|bind|data|text|html|model|if|show|cloak|transition|ref)/) const valueMatch = name.match(/:([a-zA-Z\-:]+)/) const modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || [] return { type: typeMatch ? typeMatch[1] : null, value: valueMatch ? valueMatch[1] : null, modifiers: modifiers.map(i => i.replace('.', '')), expression: attr.value, } }) .filter(i => { // If no type is passed in for filtering, bypassfilter if (! type) return true return i.type === type }) } export function replaceAtAndColonWithStandardSyntax(name) { if (name.startsWith('@')) { return name.replace('@', 'x-on:') } else if (name.startsWith(':')) { return name.replace(':', 'x-bind:') } return name } export function transitionIn(el, callback, forceSkip = false) { if (forceSkip) return callback() const attrs = getXAttrs(el, 'transition') if (attrs.length < 1) return callback() const enter = (attrs.find(i => i.value === 'enter') || { expression: '' }).expression.split(' ').filter(i => i !== '') const enterStart = (attrs.find(i => i.value === 'enter-start') || { expression: '' }).expression.split(' ').filter(i => i !== '') const enterEnd = (attrs.find(i => i.value === 'enter-end') || { expression: '' }).expression.split(' ').filter(i => i !== '') transition(el, enter, enterStart, enterEnd, callback, () => {}) } export function transitionOut(el, callback, forceSkip = false) { if (forceSkip) return callback() const attrs = getXAttrs(el, 'transition') if (attrs.length < 1) return callback() const leave = (attrs.find(i => i.value === 'leave') || { expression: '' }).expression.split(' ').filter(i => i !== '') const leaveStart = (attrs.find(i => i.value === 'leave-start') || { expression: '' }).expression.split(' ').filter(i => i !== '') const leaveEnd = (attrs.find(i => i.value === 'leave-end') || { expression: '' }).expression.split(' ').filter(i => i !== '') transition(el, leave, leaveStart, leaveEnd, () => {}, callback) } export function transition(el, classesDuring, classesStart, classesEnd, hook1, hook2) { el.classList.add(...classesStart) el.classList.add(...classesDuring) requestAnimationFrame(() => { const duration = Number(getComputedStyle(el).transitionDuration.replace('s', '')) * 1000 hook1() requestAnimationFrame(() => { el.classList.remove(...classesStart) el.classList.add(...classesEnd) setTimeout(() => { hook2() // Adding an "isConnected" check, in case the callback // removed the element from the DOM. if (el.isConnected) { el.classList.remove(...classesDuring) el.classList.remove(...classesEnd) } }, duration); }) }); }