all files / app/animation/ animateChange.service.js

100% Statements 34/34
66.67% Branches 4/6
100% Functions 12/12
100% Lines 34/34
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153                          108×                                                   31×   31×     31×   31×   22×   22×           22×     22×     22×     22×             30× 30×                                   24×   24×   24×   24×   24× 24×   24×                                                                        
/**
 * @ngdoc service
 * @name app.animation.animateChange
 * @description
 * Methods to animate some elements in a view by controlling a sequence of
 * delays and state changes.
 */
(function () {
  'use strict';
 
  angular
    .module('app.animation')
    .factory('animateChange', factory);
 
  /** @ngInject */
  function factory(animationTimers, $q) {
    return {
      promiseHideThenShow: promiseHideThenShow,
      hideThenShow: hideThenShow,
      toggleShow: toggleShow
    };
 
    /**
     * @ngdoc function
     * @name promiseHideThenShow
     * @methodOf app.animation.animateChange
     * @description
     * Given a promise and some callbacks,
     * animate the elements before and after making a change.
     * @param {Object} promise
     * A promise to complete before make a change
     * @param {Function} change
     * Function to make the change
     * @param {Object} hideAndShow
     * Contains Function members: hideChanging, hideChanged, showChanged and reset.
     * @param {Function} reject
     * Function called when promise is rejected
     * @param {Function} final
     * Function called when promise is finalized
     */
    function promiseHideThenShow(promise, change, hideAndShow, reject, final) {
 
      // Delay to let changing data hide
      var timerPromise = animationTimers.delayOut();
 
      var all = $q.all({timer: timerPromise, promise: promise});
 
      // Set flags so that changing values will be hidden
      hideAndShow.hideChanging();
 
      all.then(
        function (hash) {
          var response = hash.promise;
 
          change(response);
          // Note: There must not be a digest between change() and hideChanged().
          // Otherwise, the changed elements will be rendered without animation.
 
          // Set flags so that new elements will be hidden, initially.
          // Flags also enable ng-class.
          hideAndShow.hideChanged();
 
          // Let ng-class be processed
          animationTimers.digest().then(function () {
 
            // Show new elements
            hideAndShow.showChanged();
 
            // Reset flags after new elements have shown
            animationTimers.delayIn().then(hideAndShow.reset);
          });
 
        },
        function (response) {
          Eif (reject)
            reject(response);
          hideAndShow.reset();
        }).finally(
        function () {
          Eif (final) {
            final();
          }
        });
    }
 
    /**
     * @ngdoc function
     * @name hideThenShow
     * @methodOf app.animation.animateChange
     * @description
     * Given a change function and some other callbacks,
     * animate the elements before and after making a change.
     * @param {Function} change
     * function to make the change
     * @param {Object} hideAndShow
     * Contains Function members: hideChanging, hideChanged, showChanged and reset.
     */
    function hideThenShow(change, hideAndShow) {
 
      hideAndShow.hideChanging();
 
      animationTimers.delayOut().then(function () {
 
        change();
 
        hideAndShow.hideChanged();
 
        animationTimers.digest().then(function () {
          hideAndShow.showChanged();
 
          animationTimers.delayIn().then(
            hideAndShow.reset);
        });
      });
    }
 
    /**
     * @ngdoc function
     * @name toggleShow
     * @methodOf app.animation.animateChange
     * @description
     * Given a toggle function and two other callbacks, animate the
     * elements that are to be shown or hidden by toggling a setting.
     * @param {Function} toggle
     * Function to toggle a setting
     * @param {Function} enableNgClass
     * Function to set flags to enable animation
     * @param {Function} reset
     * Function to set flags to disable animation
     */
    function toggleShow(toggle, enableNgClass, reset) {
      // Set flags to enable  ng-class
      enableNgClass();
 
      // Eval ng-class
      animationTimers.digest().then(function () {
 
        // Change setting
        var show = toggle();
 
        // Wait for new elements to finish showing or hiding then
        // reset flags
        var delay = show ? animationTimers.delayIn : animationTimers.delayOut;
        delay().then(reset);
      });
    }
  }
})();