/** * -------------------------------------------------------------------------- * Bootstrap (v5.1.3): util/index.js * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) * -------------------------------------------------------------------------- */ const MILLISECONDS_MULTIPLIER = 1000 const TRANSITION_END = 'transitionend' /** * Trick to restart an element's animation * * @param {HTMLElement} element * @return void * * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation */ const reflow = element => { // eslint-disable-next-line no-unused-expressions element.offsetHeight } const execute = callback => { if (typeof callback === 'function') { callback() } } const getTransitionDurationFromElement = element => { if (!element) { return 0 } // Get transition-duration of the element let { transitionDuration, transitionDelay } = window.getComputedStyle(element) const floatTransitionDuration = Number.parseFloat(transitionDuration) const floatTransitionDelay = Number.parseFloat(transitionDelay) // Return 0 if element or transition duration is not found if (!floatTransitionDuration && !floatTransitionDelay) { return 0 } // If multiple durations are defined, take the first transitionDuration = transitionDuration.split(',')[0] transitionDelay = transitionDelay.split(',')[0] return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER } const triggerTransitionEnd = element => { // eslint-disable-next-line no-undef element.dispatchEvent(new Event(TRANSITION_END)) } const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { if (!waitForTransition) { execute(callback) return } const durationPadding = 5 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding let called = false const handler = ({ target }) => { if (target !== transitionElement) { return } called = true transitionElement.removeEventListener(TRANSITION_END, handler) execute(callback) } transitionElement.addEventListener(TRANSITION_END, handler) setTimeout(() => { if (!called) { triggerTransitionEnd(transitionElement) } }, emulatedDuration) } export { getTransitionDurationFromElement, triggerTransitionEnd, reflow, execute, executeAfterTransition }