# All files / lib once-ended.js

80.76% Statements 84/104
75% Branches 9/12
100% Functions 1/1
80.76% Lines 84/104

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
    1052x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    2x
    174x

    174x
    174x
    174x
    174x
    174x
    174x
    174x
    811x
    811x
    811x
    811x
    174x
    174x
    811x
    811x
    811x
    53x
    53x
    53x
    53x
    53x
    53x
    53x
    53x

    53x
    53x
    53x
    53x
    811x
    811x

    811x
    811x
    268x
    268x
    268x
    811x
    811x
    272x
    272x
    272x
    272x
    272x
    272x
    272x
    811x
    811x
    18x
    18x
    18x
    18x
    18x
    18x
    18x
    18x
    18x
    811x
    811x
    26x
    26x
    26x
    26x
    26x
    26x
    26x
    811x
    811x
    2x
     import componentDidMount from './lifecycle/component-did-mount';
    import componentWillUnmount from './lifecycle/component-will-unmount';
    import diff from './util/binding';
    import { Transaction } from './util/types';

    const { NodeCache, PATCH_TYPE, decodeEntities } = diff.Internals;
    const uppercaseEx = /[A-Z]/g;

    /**
     * Once the transaction has ended we can know for certain that DOM operations
     * have completed and can trigger lifecycle methods like componentDidMount or
     * componentWillUnmount.
     *
     * @param {Transaction} transaction
     */
    export default transaction => {
      if (transaction.aborted) {
        return;
      }

      const { patches } = transaction;
      const { length } = patches;

      let i = 0;

      while (true) {
        const patchType = patches[i];

        // Exhausted remaining patches.
        if (i === length) {
          break;
        }

        switch(patchType) {
          case PATCH_TYPE.SET_ATTRIBUTE: {
            const vTree = patches[i + 1];
            const name = patches[i + 2];
            const value = patches[i + 3];

            uppercaseEx.lastIndex = 0;

            // Normalize uppercase attributes.
            if (uppercaseEx.test(name)) {
              uppercaseEx.lastIndex = 0;

              const newName = name.replace(
                uppercaseEx,
                (/** @type {string} */ ch) => `-${ch.toLowerCase()}`,
              );

              if (value && typeof value === 'string') {
                const decodedValue = decodeEntities(value);

                if (NodeCache.has(vTree)) {
                  /** @type {HTMLElement} */(NodeCache.get(vTree)).setAttribute(newName, decodedValue);
                }
              }
            }

            i += 4;
            break;
          }

          case PATCH_TYPE.REMOVE_ATTRIBUTE: {
            i += 3;
            break;
          }

          case PATCH_TYPE.NODE_VALUE: {
            i += 4;
            break;
          }

          case PATCH_TYPE.INSERT_BEFORE: {
            const newTree = patches[i + 2];

            componentDidMount(newTree);

            i += 4;
            break;
          }

          case PATCH_TYPE.REPLACE_CHILD: {
            const newTree = patches[i + 1];
            const oldTree = patches[i + 2];

            componentWillUnmount(oldTree);
            componentDidMount(newTree);

            i += 3;
            break;
          }

          case PATCH_TYPE.REMOVE_CHILD: {
            const vTree = patches[i + 1];

            componentWillUnmount(vTree);

            i += 2;
            break;
          }
        }
      }
    };