# All files / lib transition.js

98.13% Statements 105/107
96.96% Branches 32/33
100% Functions 3/3
98.13% Lines 105/107

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    1082x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    51x
    48x
    4x
    4x
    44x
    48x
    1x
    1x
    48x
    51x
    51x
    51x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    429x
    427x
    427x
    2x
    2x
    427x
    427x
    427x
    429x
    288x
    288x
    139x
    139x
    4x
    4x
    135x
    135x
    135x
    675x
    675x
    135x
    429x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    482x
    482x
    482x
    482x
    482x
    482x

    482x
    482x
    482x
    482x
    482x
    482x
    429x
    429x
    482x
    482x
    482x
    482x
    53x
    53x
    53x
    53x
    53x
    27x
    27x
    482x
    482x
    482x
    482x
    482x
    21x
    2x
    21x
    21x
    53x
    53x
    482x
     import process from './util/process';
    import {
      TransitionCache,
      NodeCache,
      NODE_TYPE,
      VTree,
      TransitionStateNames,
      TransitionStateName,
    } from './util/types';

    /**
     *
     * @param {TransitionStateName} stateName
     * @param {Function} callback
     * @return {void}
     */
    export function addTransitionState(stateName, callback) {
      if (process.env.NODE_ENV !== 'production') {
        if (!TransitionStateNames.includes(stateName)) {
          throw new Error(`Invalid state name '${stateName}'`);
        }

        if (!callback) {
          throw new Error('Missing transition state callback');
        }
      }

      TransitionCache.get(stateName)?.add(callback);
    }

    /**
     *
     * @param {TransitionStateName=} stateName
     * @param {Function=} callback
     * @return {void}
     */
    export function removeTransitionState(stateName, callback) {
      if (process.env.NODE_ENV !== 'production') {
        // Only validate the stateName if the caller provides one.
        if (stateName && !TransitionStateNames.includes(stateName)) {
          throw new Error(`Invalid state name '${stateName}'`);
        }
      }

      // Remove all specific transition callbacks.
      if (!callback && stateName) {
        TransitionCache.get(stateName)?.clear();
      }
      // Remove a single distinct transition callback.
      else if (stateName && callback) {
        TransitionCache.get(stateName)?.delete(callback);
      }
      // Remove all transition callbacks.
      else {
        for (let i = 0; i < TransitionStateNames.length; i++) {
          TransitionCache.get(TransitionStateNames[i])?.clear();
        }
      }
    }

    /**
     *
     * @param {TransitionStateName} setName
     * @param  {...any} args
     *
     * @return {Promise<any>[]}
     */
    export function runTransitions(setName, ...args) {
      const set = TransitionCache.get(setName);

      /** @type {Promise<any>[]} */
      const promises = [];

      if (!set) {
        return promises;
      }

      const vTree = args[0];
      const isElement = vTree.nodeType === NODE_TYPE.ELEMENT;

      // Filter out text nodes and fragments from transition callbacks.
      if (!set.size || (setName !== 'textChanged' && !isElement)) {
        return promises;
      }

      // Run each transition callback, but only if the passed args are an
      // Element.
      set.forEach(callback => {
        const nodes = args.map(x => NodeCache.get(x) || x);
        const retVal = callback(...nodes);

        // Is a `thennable` object or Native Promise.
        if (typeof retVal === 'object' && retVal.then) {
          promises.push(retVal);
        }
      });

      // For attached and detached transitions, dig into children to ensure
      // all are run with this.
      if (setName === 'attached' || setName === 'detached') {
        vTree.childNodes.forEach((/** @type {VTree} */ childTree) => {
          promises.push(...runTransitions(setName, childTree, ...args.slice(1)));
        });
      }

      return promises;
    }