angularjs-rails 1.2.7 → 1.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9d9ac90904b1e170ac32c2d76876dd40aa82cbf0
4
- data.tar.gz: 44e31d21d4fb9ebf89e7b862f1bb577459ca1b6d
3
+ metadata.gz: 087ea383ebafbfe0b11828d89862a2a5034f6142
4
+ data.tar.gz: 32d02bdeb0c4c6e5d2c3734251df42eb2421d50f
5
5
  SHA512:
6
- metadata.gz: 64e6a0c25a45fd978306e1121ca67cfc63af74d3d8bbcf45c9f00b722380737363f52eff40caed62760ff0ae88c5b4d56e0f1924f77fb1310ab843d77e969e19
7
- data.tar.gz: 194046bb67a6b5fb4c97ced2a850bda0cd5cd9ac948172a50963743e97c2f74d920921fec493a4c4d060d2adbd1a28e948820872430aebdb50e4d5ef3be901fa
6
+ metadata.gz: 7d7833ac6d9a8223ea754017f0e0fcc06dd4d490e8a43b4882762609823b8495fb8d7df96074ab8b59e17ee80b50354b1db144a65ee81f6b062bfde7288e399f
7
+ data.tar.gz: 2a9bab997d585834d27b3a0b29fe8e8bdee2a1900dfe4926174de5b6d71987ca97a1062c4cc0def90b95cac6ee7bb0e200b4e73e8480dfbd8bcee3d9566caed3
@@ -1,6 +1,6 @@
1
1
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.2.7"
3
+ VERSION = "1.2.9"
4
4
  UNSTABLE_VERSION = "1.1.5"
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.7
2
+ * @license AngularJS v1.2.9
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -254,6 +254,26 @@ angular.module('ngAnimate', ['ng'])
254
254
  * Please visit the {@link ngAnimate `ngAnimate`} module overview page learn more about how to use animations in your application.
255
255
  *
256
256
  */
257
+ .factory('$$animateReflow', ['$window', '$timeout', function($window, $timeout) {
258
+ var requestAnimationFrame = $window.requestAnimationFrame ||
259
+ $window.webkitRequestAnimationFrame ||
260
+ function(fn) {
261
+ return $timeout(fn, 10, false);
262
+ };
263
+
264
+ var cancelAnimationFrame = $window.cancelAnimationFrame ||
265
+ $window.webkitCancelAnimationFrame ||
266
+ function(timer) {
267
+ return $timeout.cancel(timer);
268
+ };
269
+ return function(fn) {
270
+ var id = requestAnimationFrame(fn);
271
+ return function() {
272
+ cancelAnimationFrame(id);
273
+ };
274
+ };
275
+ }])
276
+
257
277
  .config(['$provide', '$animateProvider', function($provide, $animateProvider) {
258
278
  var noop = angular.noop;
259
279
  var forEach = angular.forEach;
@@ -301,6 +321,10 @@ angular.module('ngAnimate', ['ng'])
301
321
  return classNameFilter.test(className);
302
322
  };
303
323
 
324
+ function async(fn) {
325
+ return $timeout(fn, 0, false);
326
+ }
327
+
304
328
  function lookup(name) {
305
329
  if (name) {
306
330
  var matches = [],
@@ -592,6 +616,8 @@ angular.module('ngAnimate', ['ng'])
592
616
  //best to catch this early on to prevent any animation operations from occurring
593
617
  if(!node || !isAnimatableClassName(classes)) {
594
618
  fireDOMOperation();
619
+ fireBeforeCallbackAsync();
620
+ fireAfterCallbackAsync();
595
621
  closeAnimation();
596
622
  return;
597
623
  }
@@ -611,6 +637,8 @@ angular.module('ngAnimate', ['ng'])
611
637
  //NOTE: IE8 + IE9 should close properly (run closeAnimation()) in case a NO animation is not found.
612
638
  if (animationsDisabled(element, parentElement) || matches.length === 0) {
613
639
  fireDOMOperation();
640
+ fireBeforeCallbackAsync();
641
+ fireAfterCallbackAsync();
614
642
  closeAnimation();
615
643
  return;
616
644
  }
@@ -649,14 +677,17 @@ angular.module('ngAnimate', ['ng'])
649
677
  //animation do it's thing and close this one early
650
678
  if(animations.length === 0) {
651
679
  fireDOMOperation();
680
+ fireBeforeCallbackAsync();
681
+ fireAfterCallbackAsync();
652
682
  fireDoneCallbackAsync();
653
683
  return;
654
684
  }
655
685
 
686
+ var ONE_SPACE = ' ';
656
687
  //this value will be searched for class-based CSS className lookup. Therefore,
657
688
  //we prefix and suffix the current className value with spaces to avoid substring
658
689
  //lookups of className tokens
659
- var futureClassName = ' ' + currentClassName + ' ';
690
+ var futureClassName = ONE_SPACE + currentClassName + ONE_SPACE;
660
691
  if(ngAnimateState.running) {
661
692
  //if an animation is currently running on the element then lets take the steps
662
693
  //to cancel that animation and fire any required callbacks
@@ -664,12 +695,23 @@ angular.module('ngAnimate', ['ng'])
664
695
  cleanup(element);
665
696
  cancelAnimations(ngAnimateState.animations);
666
697
 
698
+ //in the event that the CSS is class is quickly added and removed back
699
+ //then we don't want to wait until after the reflow to add/remove the CSS
700
+ //class since both class animations may run into a race condition.
701
+ //The code below will check to see if that is occurring and will
702
+ //immediately remove the former class before the reflow so that the
703
+ //animation can snap back to the original animation smoothly
704
+ var isFullyClassBasedAnimation = isClassBased && !ngAnimateState.structural;
705
+ var isRevertingClassAnimation = isFullyClassBasedAnimation &&
706
+ ngAnimateState.className == className &&
707
+ animationEvent != ngAnimateState.event;
708
+
667
709
  //if the class is removed during the reflow then it will revert the styles temporarily
668
710
  //back to the base class CSS styling causing a jump-like effect to occur. This check
669
711
  //here ensures that the domOperation is only performed after the reflow has commenced
670
- if(ngAnimateState.beforeComplete) {
712
+ if(ngAnimateState.beforeComplete || isRevertingClassAnimation) {
671
713
  (ngAnimateState.done || noop)(true);
672
- } else if(isClassBased && !ngAnimateState.structural) {
714
+ } else if(isFullyClassBasedAnimation) {
673
715
  //class-based animations will compare element className values after cancelling the
674
716
  //previous animation to see if the element properties already contain the final CSS
675
717
  //class and if so then the animation will be skipped. Since the domOperation will
@@ -677,8 +719,8 @@ angular.module('ngAnimate', ['ng'])
677
719
  //will be invalid. Therefore the same string manipulation that would occur within the
678
720
  //DOM operation will be performed below so that the class comparison is valid...
679
721
  futureClassName = ngAnimateState.event == 'removeClass' ?
680
- futureClassName.replace(ngAnimateState.className, '') :
681
- futureClassName + ngAnimateState.className + ' ';
722
+ futureClassName.replace(ONE_SPACE + ngAnimateState.className + ONE_SPACE, ONE_SPACE) :
723
+ futureClassName + ngAnimateState.className + ONE_SPACE;
682
724
  }
683
725
  }
684
726
 
@@ -686,10 +728,12 @@ angular.module('ngAnimate', ['ng'])
686
728
  //(on addClass) or doesn't contain (on removeClass) the className being animated.
687
729
  //The reason why this is being called after the previous animations are cancelled
688
730
  //is so that the CSS classes present on the element can be properly examined.
689
- var classNameToken = ' ' + className + ' ';
731
+ var classNameToken = ONE_SPACE + className + ONE_SPACE;
690
732
  if((animationEvent == 'addClass' && futureClassName.indexOf(classNameToken) >= 0) ||
691
733
  (animationEvent == 'removeClass' && futureClassName.indexOf(classNameToken) == -1)) {
692
734
  fireDOMOperation();
735
+ fireBeforeCallbackAsync();
736
+ fireAfterCallbackAsync();
693
737
  fireDoneCallbackAsync();
694
738
  return;
695
739
  }
@@ -730,6 +774,10 @@ angular.module('ngAnimate', ['ng'])
730
774
  }
731
775
 
732
776
  function invokeRegisteredAnimationFns(animations, phase, allAnimationFnsComplete) {
777
+ phase == 'after' ?
778
+ fireAfterCallbackAsync() :
779
+ fireBeforeCallbackAsync();
780
+
733
781
  var endFnName = phase + 'End';
734
782
  forEach(animations, function(animation, index) {
735
783
  var animationPhaseCompleted = function() {
@@ -766,8 +814,27 @@ angular.module('ngAnimate', ['ng'])
766
814
  }
767
815
  }
768
816
 
817
+ function fireDOMCallback(animationPhase) {
818
+ element.triggerHandler('$animate:' + animationPhase, {
819
+ event : animationEvent,
820
+ className : className
821
+ });
822
+ }
823
+
824
+ function fireBeforeCallbackAsync() {
825
+ async(function() {
826
+ fireDOMCallback('before');
827
+ });
828
+ }
829
+
830
+ function fireAfterCallbackAsync() {
831
+ async(function() {
832
+ fireDOMCallback('after');
833
+ });
834
+ }
835
+
769
836
  function fireDoneCallbackAsync() {
770
- doneCallback && $timeout(doneCallback, 0, false);
837
+ doneCallback && async(doneCallback);
771
838
  }
772
839
 
773
840
  //it is less complicated to use a flag than managing and cancelling
@@ -791,9 +858,9 @@ angular.module('ngAnimate', ['ng'])
791
858
  if(isClassBased) {
792
859
  cleanup(element);
793
860
  } else {
794
- data.closeAnimationTimeout = $timeout(function() {
861
+ data.closeAnimationTimeout = async(function() {
795
862
  cleanup(element);
796
- }, 0, false);
863
+ });
797
864
  element.data(NG_ANIMATE_STATE, data);
798
865
  }
799
866
  }
@@ -817,10 +884,10 @@ angular.module('ngAnimate', ['ng'])
817
884
  function cancelAnimations(animations) {
818
885
  var isCancelledFlag = true;
819
886
  forEach(animations, function(animation) {
820
- if(!animations.beforeComplete) {
887
+ if(!animation.beforeComplete) {
821
888
  (animation.beforeEnd || noop)(isCancelledFlag);
822
889
  }
823
- if(!animations.afterComplete) {
890
+ if(!animation.afterComplete) {
824
891
  (animation.afterEnd || noop)(isCancelledFlag);
825
892
  }
826
893
  });
@@ -866,7 +933,8 @@ angular.module('ngAnimate', ['ng'])
866
933
  }
867
934
  }]);
868
935
 
869
- $animateProvider.register('', ['$window', '$sniffer', '$timeout', function($window, $sniffer, $timeout) {
936
+ $animateProvider.register('', ['$window', '$sniffer', '$timeout', '$$animateReflow',
937
+ function($window, $sniffer, $timeout, $$animateReflow) {
870
938
  // Detect proper transitionend/animationend event names.
871
939
  var CSS_PREFIX = '', TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT;
872
940
 
@@ -911,11 +979,13 @@ angular.module('ngAnimate', ['ng'])
911
979
  var parentCounter = 0;
912
980
  var animationReflowQueue = [];
913
981
  var animationElementQueue = [];
914
- var animationTimer;
982
+ var cancelAnimationReflow;
915
983
  var closingAnimationTime = 0;
916
984
  var timeOut = false;
917
985
  function afterReflow(element, callback) {
918
- $timeout.cancel(animationTimer);
986
+ if(cancelAnimationReflow) {
987
+ cancelAnimationReflow();
988
+ }
919
989
 
920
990
  animationReflowQueue.push(callback);
921
991
 
@@ -924,15 +994,19 @@ angular.module('ngAnimate', ['ng'])
924
994
  animationElementQueue.push(element);
925
995
 
926
996
  var elementData = element.data(NG_ANIMATE_CSS_DATA_KEY);
927
- closingAnimationTime = Math.max(closingAnimationTime,
928
- (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER * ONE_SECOND);
997
+
998
+ var stagger = elementData.stagger;
999
+ var staggerTime = elementData.itemIndex * (Math.max(stagger.animationDelay, stagger.transitionDelay) || 0);
1000
+
1001
+ var animationTime = (elementData.maxDelay + elementData.maxDuration) * CLOSING_TIME_BUFFER;
1002
+ closingAnimationTime = Math.max(closingAnimationTime, (staggerTime + animationTime) * ONE_SECOND);
929
1003
 
930
1004
  //by placing a counter we can avoid an accidental
931
1005
  //race condition which may close an animation when
932
1006
  //a follow-up animation is midway in its animation
933
1007
  elementData.animationCount = animationCounter;
934
1008
 
935
- animationTimer = $timeout(function() {
1009
+ cancelAnimationReflow = $$animateReflow(function() {
936
1010
  forEach(animationReflowQueue, function(fn) {
937
1011
  fn();
938
1012
  });
@@ -953,11 +1027,11 @@ angular.module('ngAnimate', ['ng'])
953
1027
 
954
1028
  animationReflowQueue = [];
955
1029
  animationElementQueue = [];
956
- animationTimer = null;
1030
+ cancelAnimationReflow = null;
957
1031
  lookupCache = {};
958
1032
  closingAnimationTime = 0;
959
1033
  animationCounter++;
960
- }, 10, false);
1034
+ });
961
1035
  }
962
1036
 
963
1037
  function closeAllAnimations(elements, count) {
@@ -1048,13 +1122,13 @@ angular.module('ngAnimate', ['ng'])
1048
1122
  return parentID + '-' + extractElementNode(element).className;
1049
1123
  }
1050
1124
 
1051
- function animateSetup(element, className) {
1125
+ function animateSetup(element, className, calculationDecorator) {
1052
1126
  var cacheKey = getCacheKey(element);
1053
1127
  var eventCacheKey = cacheKey + ' ' + className;
1054
1128
  var stagger = {};
1055
- var ii = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
1129
+ var itemIndex = lookupCache[eventCacheKey] ? ++lookupCache[eventCacheKey].total : 0;
1056
1130
 
1057
- if(ii > 0) {
1131
+ if(itemIndex > 0) {
1058
1132
  var staggerClassName = className + '-stagger';
1059
1133
  var staggerCacheKey = cacheKey + ' ' + staggerClassName;
1060
1134
  var applyClasses = !lookupCache[staggerCacheKey];
@@ -1066,9 +1140,16 @@ angular.module('ngAnimate', ['ng'])
1066
1140
  applyClasses && element.removeClass(staggerClassName);
1067
1141
  }
1068
1142
 
1143
+ /* the animation itself may need to add/remove special CSS classes
1144
+ * before calculating the anmation styles */
1145
+ calculationDecorator = calculationDecorator ||
1146
+ function(fn) { return fn(); };
1147
+
1069
1148
  element.addClass(className);
1070
1149
 
1071
- var timings = getElementAnimationDetails(element, eventCacheKey);
1150
+ var timings = calculationDecorator(function() {
1151
+ return getElementAnimationDetails(element, eventCacheKey);
1152
+ });
1072
1153
 
1073
1154
  /* there is no point in performing a reflow if the animation
1074
1155
  timeout is empty (this would cause a flicker bug normally
@@ -1100,7 +1181,7 @@ angular.module('ngAnimate', ['ng'])
1100
1181
  classes : className + ' ' + activeClassName,
1101
1182
  timings : timings,
1102
1183
  stagger : stagger,
1103
- ii : ii
1184
+ itemIndex : itemIndex
1104
1185
  });
1105
1186
 
1106
1187
  return true;
@@ -1145,7 +1226,7 @@ angular.module('ngAnimate', ['ng'])
1145
1226
  var maxDelayTime = Math.max(timings.transitionDelay, timings.animationDelay) * ONE_SECOND;
1146
1227
  var startTime = Date.now();
1147
1228
  var css3AnimationEvents = ANIMATIONEND_EVENT + ' ' + TRANSITIONEND_EVENT;
1148
- var ii = elementData.ii;
1229
+ var itemIndex = elementData.itemIndex;
1149
1230
 
1150
1231
  var style = '', appliedStyles = [];
1151
1232
  if(timings.transitionDuration > 0) {
@@ -1158,17 +1239,17 @@ angular.module('ngAnimate', ['ng'])
1158
1239
  }
1159
1240
  }
1160
1241
 
1161
- if(ii > 0) {
1242
+ if(itemIndex > 0) {
1162
1243
  if(stagger.transitionDelay > 0 && stagger.transitionDuration === 0) {
1163
1244
  var delayStyle = timings.transitionDelayStyle;
1164
1245
  style += CSS_PREFIX + 'transition-delay: ' +
1165
- prepareStaggerDelay(delayStyle, stagger.transitionDelay, ii) + '; ';
1246
+ prepareStaggerDelay(delayStyle, stagger.transitionDelay, itemIndex) + '; ';
1166
1247
  appliedStyles.push(CSS_PREFIX + 'transition-delay');
1167
1248
  }
1168
1249
 
1169
1250
  if(stagger.animationDelay > 0 && stagger.animationDuration === 0) {
1170
1251
  style += CSS_PREFIX + 'animation-delay: ' +
1171
- prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, ii) + '; ';
1252
+ prepareStaggerDelay(timings.animationDelayStyle, stagger.animationDelay, itemIndex) + '; ';
1172
1253
  appliedStyles.push(CSS_PREFIX + 'animation-delay');
1173
1254
  }
1174
1255
  }
@@ -1233,8 +1314,8 @@ angular.module('ngAnimate', ['ng'])
1233
1314
  return style;
1234
1315
  }
1235
1316
 
1236
- function animateBefore(element, className) {
1237
- if(animateSetup(element, className)) {
1317
+ function animateBefore(element, className, calculationDecorator) {
1318
+ if(animateSetup(element, className, calculationDecorator)) {
1238
1319
  return function(cancelled) {
1239
1320
  cancelled && animateClose(element, className);
1240
1321
  };
@@ -1329,7 +1410,18 @@ angular.module('ngAnimate', ['ng'])
1329
1410
  },
1330
1411
 
1331
1412
  beforeAddClass : function(element, className, animationCompleted) {
1332
- var cancellationMethod = animateBefore(element, suffixClasses(className, '-add'));
1413
+ var cancellationMethod = animateBefore(element, suffixClasses(className, '-add'), function(fn) {
1414
+
1415
+ /* when a CSS class is added to an element then the transition style that
1416
+ * is applied is the transition defined on the element when the CSS class
1417
+ * is added at the time of the animation. This is how CSS3 functions
1418
+ * outside of ngAnimate. */
1419
+ element.addClass(className);
1420
+ var timings = fn();
1421
+ element.removeClass(className);
1422
+ return timings;
1423
+ });
1424
+
1333
1425
  if(cancellationMethod) {
1334
1426
  afterReflow(element, function() {
1335
1427
  unblockTransitions(element);
@@ -1346,7 +1438,18 @@ angular.module('ngAnimate', ['ng'])
1346
1438
  },
1347
1439
 
1348
1440
  beforeRemoveClass : function(element, className, animationCompleted) {
1349
- var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove'));
1441
+ var cancellationMethod = animateBefore(element, suffixClasses(className, '-remove'), function(fn) {
1442
+ /* when classes are removed from an element then the transition style
1443
+ * that is applied is the transition defined on the element without the
1444
+ * CSS class being there. This is how CSS3 functions outside of ngAnimate.
1445
+ * http://plnkr.co/edit/j8OzgTNxHTb4n3zLyjGW?p=preview */
1446
+ var klass = element.attr('class');
1447
+ element.removeClass(className);
1448
+ var timings = fn();
1449
+ element.attr('class', klass);
1450
+ return timings;
1451
+ });
1452
+
1350
1453
  if(cancellationMethod) {
1351
1454
  afterReflow(element, function() {
1352
1455
  unblockTransitions(element);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.7
2
+ * @license AngularJS v1.2.9
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.7
2
+ * @license AngularJS v1.2.9
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.2.7/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.9/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.7
2
+ * @license AngularJS v1.2.9
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -763,6 +763,36 @@ angular.mock.TzDate = function (offset, timestamp) {
763
763
  angular.mock.TzDate.prototype = Date.prototype;
764
764
  /* jshint +W101 */
765
765
 
766
+ // TODO(matias): remove this IMMEDIATELY once we can properly detect the
767
+ // presence of a registered module
768
+ var animateLoaded;
769
+ try {
770
+ angular.module('ngAnimate');
771
+ animateLoaded = true;
772
+ } catch(e) {}
773
+
774
+ if(animateLoaded) {
775
+ angular.module('ngAnimate').config(['$provide', function($provide) {
776
+ var reflowQueue = [];
777
+ $provide.value('$$animateReflow', function(fn) {
778
+ reflowQueue.push(fn);
779
+ return angular.noop;
780
+ });
781
+ $provide.decorator('$animate', function($delegate) {
782
+ $delegate.triggerReflow = function() {
783
+ if(reflowQueue.length === 0) {
784
+ throw new Error('No animation reflows present');
785
+ }
786
+ angular.forEach(reflowQueue, function(fn) {
787
+ fn();
788
+ });
789
+ reflowQueue = [];
790
+ };
791
+ return $delegate;
792
+ });
793
+ }]);
794
+ }
795
+
766
796
  angular.mock.animate = angular.module('mock.animate', ['ng'])
767
797
 
768
798
  .config(['$provide', function($provide) {
@@ -1920,7 +1950,6 @@ angular.mock.clearDataCache = function() {
1920
1950
  };
1921
1951
 
1922
1952
 
1923
-
1924
1953
  if(window.jasmine || window.mocha) {
1925
1954
 
1926
1955
  var currentSpec = null,
@@ -2086,6 +2115,20 @@ if(window.jasmine || window.mocha) {
2086
2115
  *
2087
2116
  * @param {...Function} fns any number of functions which will be injected using the injector.
2088
2117
  */
2118
+
2119
+
2120
+
2121
+ var ErrorAddingDeclarationLocationStack = function(e, errorForStack) {
2122
+ this.message = e.message;
2123
+ this.name = e.name;
2124
+ if (e.line) this.line = e.line;
2125
+ if (e.sourceId) this.sourceId = e.sourceId;
2126
+ if (e.stack && errorForStack)
2127
+ this.stack = e.stack + '\n' + errorForStack.stack;
2128
+ if (e.stackArray) this.stackArray = e.stackArray;
2129
+ };
2130
+ ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString;
2131
+
2089
2132
  window.inject = angular.mock.inject = function() {
2090
2133
  var blockFns = Array.prototype.slice.call(arguments, 0);
2091
2134
  var errorForStack = new Error('Declaration Location');
@@ -2106,7 +2149,9 @@ if(window.jasmine || window.mocha) {
2106
2149
  injector.invoke(blockFns[i] || angular.noop, this);
2107
2150
  /* jshint +W040 */
2108
2151
  } catch (e) {
2109
- if(e.stack && errorForStack) e.stack += '\n' + errorForStack.stack;
2152
+ if (e.stack && errorForStack) {
2153
+ throw new ErrorAddingDeclarationLocationStack(e, errorForStack);
2154
+ }
2110
2155
  throw e;
2111
2156
  } finally {
2112
2157
  errorForStack = null;