'use strict';

/* eslint-disable no-restricted-globals */
/* eslint-enable no-restricted-globals */
/**
 * Takes an element and returns its offsetHeight to trigger reflow,
 * which can be used to reset the animation.
 * For more details, {@see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation}
 *
 * Note: we cannot simply invoke `element.offsetHeight` to trigger reflow
 *       as the statement will get erased during VM optimization phase
 *
 * @param {HTMLElement} element - HTMLElement - The element to be measured.
 * return the offsetHeight of the given element
 */
const reflow = (element) => {
  const offsetHeight = element.offsetHeight;
  if (!isNaN(offsetHeight)) {
    element.dataset['vegaReflow'] = offsetHeight.toString();
  }
};
/**
 * Executes a callback after a transition has ended on a given element
 *
 * @param {() => void} callback - The function to execute after the transition ends
 * @param {HTMLElement} element - The element to listen for transitionend event on
 * @param {number} [timeout] - The timeout in milliseconds after which the callback will be executed even if the
 * transitionend event hasn't been fired.
 */
function executeAfterTransition(callback, element, timeout) {
  // timeoutId cannot be number since typescript/jest is taking it as NodeJS.Timeout instead of window.setTimeout
  let timeoutId = 0;
  /**
   * The handler used to listen for transitionend event
   */
  const handler = () => {
    element.removeEventListener('transitionend', handler);
    timeout && clearTimeout(timeoutId);
    callback();
  };
  element.addEventListener('transitionend', handler);
  timeoutId = timeout ? setTimeout(handler, timeout) : 0;
}

exports.executeAfterTransition = executeAfterTransition;
exports.reflow = reflow;
