@angular/animations 7.1.3 → 7.1.4

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.
Files changed (126) hide show
  1. package/browser/testing.d.ts +1 -1
  2. package/browser.d.ts +1 -1
  3. package/bundles/animations-browser-testing.umd.js +1 -1
  4. package/bundles/animations-browser-testing.umd.min.js +1 -1
  5. package/bundles/animations-browser-testing.umd.min.js.map +1 -1
  6. package/bundles/animations-browser.umd.js +3 -3
  7. package/bundles/animations-browser.umd.js.map +1 -1
  8. package/bundles/animations-browser.umd.min.js +4 -4
  9. package/bundles/animations-browser.umd.min.js.map +1 -1
  10. package/bundles/animations.umd.js +3 -3
  11. package/bundles/animations.umd.js.map +1 -1
  12. package/bundles/animations.umd.min.js +1 -1
  13. package/bundles/animations.umd.min.js.map +1 -1
  14. package/esm2015/animations.externs.js +19 -17
  15. package/esm2015/animations.js +0 -1
  16. package/esm2015/browser/browser.externs.js +28 -20
  17. package/esm2015/browser/browser.js +0 -1
  18. package/esm2015/browser/index.js +1 -2
  19. package/esm2015/browser/public_api.js +1 -2
  20. package/esm2015/browser/src/browser.js +7 -3
  21. package/esm2015/browser/src/dsl/animation.js +6 -5
  22. package/esm2015/browser/src/dsl/animation_ast.js +194 -112
  23. package/esm2015/browser/src/dsl/animation_ast_builder.js +71 -32
  24. package/esm2015/browser/src/dsl/animation_dsl_visitor.js +82 -29
  25. package/esm2015/browser/src/dsl/animation_timeline_builder.js +135 -21
  26. package/esm2015/browser/src/dsl/animation_timeline_instruction.js +24 -23
  27. package/esm2015/browser/src/dsl/animation_transition_expr.js +12 -8
  28. package/esm2015/browser/src/dsl/animation_transition_factory.js +3 -4
  29. package/esm2015/browser/src/dsl/animation_transition_instruction.js +30 -29
  30. package/esm2015/browser/src/dsl/animation_trigger.js +2 -3
  31. package/esm2015/browser/src/dsl/element_instruction_map.js +2 -3
  32. package/esm2015/browser/src/dsl/style_normalization/animation_style_normalizer.js +3 -4
  33. package/esm2015/browser/src/dsl/style_normalization/web_animations_style_normalizer.js +9 -3
  34. package/esm2015/browser/src/private_export.js +9 -3
  35. package/esm2015/browser/src/render/animation_driver.js +9 -3
  36. package/esm2015/browser/src/render/animation_engine_instruction.js +7 -6
  37. package/esm2015/browser/src/render/animation_engine_next.js +7 -7
  38. package/esm2015/browser/src/render/css_keyframes/css_keyframes_driver.js +7 -8
  39. package/esm2015/browser/src/render/css_keyframes/css_keyframes_player.js +3 -4
  40. package/esm2015/browser/src/render/css_keyframes/direct_style_player.js +11 -5
  41. package/esm2015/browser/src/render/css_keyframes/element_animation_style_handler.js +5 -5
  42. package/esm2015/browser/src/render/shared.js +21 -13
  43. package/esm2015/browser/src/render/timeline_animation_engine.js +13 -6
  44. package/esm2015/browser/src/render/transition_animation_engine.js +147 -76
  45. package/esm2015/browser/src/render/web_animations/dom_animation.js +1 -2
  46. package/esm2015/browser/src/render/web_animations/web_animations_driver.js +5 -6
  47. package/esm2015/browser/src/render/web_animations/web_animations_player.js +6 -7
  48. package/esm2015/browser/src/util.js +22 -12
  49. package/esm2015/browser/testing/index.js +1 -2
  50. package/esm2015/browser/testing/public_api.js +1 -2
  51. package/esm2015/browser/testing/src/mock_animation_driver.js +13 -4
  52. package/esm2015/browser/testing/src/testing.js +9 -3
  53. package/esm2015/browser/testing/testing.js +0 -1
  54. package/esm2015/index.js +1 -2
  55. package/esm2015/public_api.js +1 -2
  56. package/esm2015/src/animation_builder.js +2 -3
  57. package/esm2015/src/animation_event.js +40 -39
  58. package/esm2015/src/animation_metadata.js +236 -211
  59. package/esm2015/src/animations.js +7 -3
  60. package/esm2015/src/players/animation_group_player.js +2 -3
  61. package/esm2015/src/players/animation_player.js +111 -106
  62. package/esm2015/src/private_export.js +9 -3
  63. package/esm2015/src/util.js +2 -3
  64. package/esm2015/src/version.js +3 -4
  65. package/esm5/animations.js +0 -1
  66. package/esm5/browser/browser.js +0 -1
  67. package/esm5/browser/index.js +0 -1
  68. package/esm5/browser/public_api.js +0 -1
  69. package/esm5/browser/src/browser.js +0 -1
  70. package/esm5/browser/src/dsl/animation.js +0 -1
  71. package/esm5/browser/src/dsl/animation_ast.js +0 -1
  72. package/esm5/browser/src/dsl/animation_ast_builder.js +0 -1
  73. package/esm5/browser/src/dsl/animation_dsl_visitor.js +0 -1
  74. package/esm5/browser/src/dsl/animation_timeline_builder.js +0 -1
  75. package/esm5/browser/src/dsl/animation_timeline_instruction.js +0 -1
  76. package/esm5/browser/src/dsl/animation_transition_expr.js +0 -1
  77. package/esm5/browser/src/dsl/animation_transition_factory.js +0 -1
  78. package/esm5/browser/src/dsl/animation_transition_instruction.js +0 -1
  79. package/esm5/browser/src/dsl/animation_trigger.js +0 -1
  80. package/esm5/browser/src/dsl/element_instruction_map.js +0 -1
  81. package/esm5/browser/src/dsl/style_normalization/animation_style_normalizer.js +0 -1
  82. package/esm5/browser/src/dsl/style_normalization/web_animations_style_normalizer.js +0 -1
  83. package/esm5/browser/src/private_export.js +0 -1
  84. package/esm5/browser/src/render/animation_driver.js +0 -1
  85. package/esm5/browser/src/render/animation_engine_instruction.js +0 -1
  86. package/esm5/browser/src/render/animation_engine_next.js +0 -1
  87. package/esm5/browser/src/render/css_keyframes/css_keyframes_driver.js +0 -1
  88. package/esm5/browser/src/render/css_keyframes/css_keyframes_player.js +0 -1
  89. package/esm5/browser/src/render/css_keyframes/direct_style_player.js +0 -1
  90. package/esm5/browser/src/render/css_keyframes/element_animation_style_handler.js +0 -1
  91. package/esm5/browser/src/render/shared.js +0 -1
  92. package/esm5/browser/src/render/timeline_animation_engine.js +0 -1
  93. package/esm5/browser/src/render/transition_animation_engine.js +2 -3
  94. package/esm5/browser/src/render/web_animations/dom_animation.js +0 -1
  95. package/esm5/browser/src/render/web_animations/web_animations_driver.js +0 -1
  96. package/esm5/browser/src/render/web_animations/web_animations_player.js +0 -1
  97. package/esm5/browser/src/util.js +2 -3
  98. package/esm5/browser/testing/index.js +0 -1
  99. package/esm5/browser/testing/public_api.js +0 -1
  100. package/esm5/browser/testing/src/mock_animation_driver.js +0 -1
  101. package/esm5/browser/testing/src/testing.js +0 -1
  102. package/esm5/browser/testing/testing.js +0 -1
  103. package/esm5/index.js +0 -1
  104. package/esm5/public_api.js +0 -1
  105. package/esm5/src/animation_builder.js +0 -1
  106. package/esm5/src/animation_event.js +0 -1
  107. package/esm5/src/animation_metadata.js +3 -4
  108. package/esm5/src/animations.js +0 -1
  109. package/esm5/src/players/animation_group_player.js +0 -1
  110. package/esm5/src/players/animation_player.js +0 -1
  111. package/esm5/src/private_export.js +0 -1
  112. package/esm5/src/util.js +0 -1
  113. package/esm5/src/version.js +1 -2
  114. package/fesm2015/animations.js +18 -20
  115. package/fesm2015/animations.js.map +1 -1
  116. package/fesm2015/browser/testing.js +9 -6
  117. package/fesm2015/browser/testing.js.map +1 -1
  118. package/fesm2015/browser.js +377 -160
  119. package/fesm2015/browser.js.map +1 -1
  120. package/fesm5/animations.js +3 -3
  121. package/fesm5/animations.js.map +1 -1
  122. package/fesm5/browser/testing.js +1 -1
  123. package/fesm5/browser.js +3 -3
  124. package/fesm5/browser.js.map +1 -1
  125. package/package.json +2 -2
  126. package/src/animation_metadata.d.ts +2 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v7.1.3
2
+ * @license Angular v7.1.4
3
3
  * (c) 2010-2018 Google, Inc. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -9,7 +9,7 @@ import { Injectable } from '@angular/core';
9
9
 
10
10
  /**
11
11
  * @fileoverview added by tsickle
12
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
12
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
13
13
  */
14
14
  /**
15
15
  * @return {?}
@@ -57,7 +57,7 @@ function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
57
57
  let previousKeyframe = null;
58
58
  keyframes.forEach(kf => {
59
59
  /** @type {?} */
60
- const offset = /** @type {?} */ (kf['offset']);
60
+ const offset = (/** @type {?} */ (kf['offset']));
61
61
  /** @type {?} */
62
62
  const isSameOffset = offset == previousOffset;
63
63
  /** @type {?} */
@@ -127,13 +127,13 @@ function copyAnimationEvent(e, phaseName, player) {
127
127
  /** @type {?} */
128
128
  const totalTime = player.totalTime;
129
129
  /** @type {?} */
130
- const disabled = (/** @type {?} */ (player)).disabled ? true : false;
130
+ const disabled = ((/** @type {?} */ (player))).disabled ? true : false;
131
131
  /** @type {?} */
132
132
  const event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);
133
133
  /** @type {?} */
134
- const data = (/** @type {?} */ (e))['_data'];
134
+ const data = ((/** @type {?} */ (e)))['_data'];
135
135
  if (data != null) {
136
- (/** @type {?} */ (event))['_data'] = data;
136
+ ((/** @type {?} */ (event)))['_data'] = data;
137
137
  }
138
138
  return event;
139
139
  }
@@ -194,17 +194,19 @@ let _matches = (element, selector) => false;
194
194
  let _query = (element, selector, multi) => {
195
195
  return [];
196
196
  };
197
+ // Define utility methods for browsers and platform-server(domino) where Element
198
+ // and utility methods exist.
197
199
  /** @type {?} */
198
200
  const _isNode = isNode();
199
201
  if (_isNode || typeof Element !== 'undefined') {
200
202
  // this is well supported in all browsers
201
- _contains = (elm1, elm2) => { return /** @type {?} */ (elm1.contains(elm2)); };
203
+ _contains = (elm1, elm2) => { return (/** @type {?} */ (elm1.contains(elm2))); };
202
204
  if (_isNode || Element.prototype.matches) {
203
205
  _matches = (element, selector) => element.matches(selector);
204
206
  }
205
207
  else {
206
208
  /** @type {?} */
207
- const proto = /** @type {?} */ (Element.prototype);
209
+ const proto = (/** @type {?} */ (Element.prototype));
208
210
  /** @type {?} */
209
211
  const fn = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector ||
210
212
  proto.oMatchesSelector || proto.webkitMatchesSelector;
@@ -248,16 +250,16 @@ let _IS_WEBKIT = false;
248
250
  function validateStyleProperty(prop) {
249
251
  if (!_CACHED_BODY) {
250
252
  _CACHED_BODY = getBodyNode() || {};
251
- _IS_WEBKIT = /** @type {?} */ ((_CACHED_BODY)).style ? ('WebkitAppearance' in /** @type {?} */ ((_CACHED_BODY)).style) : false;
253
+ _IS_WEBKIT = (/** @type {?} */ (_CACHED_BODY)).style ? ('WebkitAppearance' in (/** @type {?} */ (_CACHED_BODY)).style) : false;
252
254
  }
253
255
  /** @type {?} */
254
256
  let result = true;
255
- if (/** @type {?} */ ((_CACHED_BODY)).style && !containsVendorPrefix(prop)) {
256
- result = prop in /** @type {?} */ ((_CACHED_BODY)).style;
257
+ if ((/** @type {?} */ (_CACHED_BODY)).style && !containsVendorPrefix(prop)) {
258
+ result = prop in (/** @type {?} */ (_CACHED_BODY)).style;
257
259
  if (!result && _IS_WEBKIT) {
258
260
  /** @type {?} */
259
261
  const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.substr(1);
260
- result = camelProp in /** @type {?} */ ((_CACHED_BODY)).style;
262
+ result = camelProp in (/** @type {?} */ (_CACHED_BODY)).style;
261
263
  }
262
264
  }
263
265
  return result;
@@ -294,7 +296,7 @@ function hypenatePropsObject(object) {
294
296
 
295
297
  /**
296
298
  * @fileoverview added by tsickle
297
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
299
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
298
300
  */
299
301
  /**
300
302
  * \@publicApi
@@ -364,7 +366,7 @@ AnimationDriver.NOOP = new NoopAnimationDriver();
364
366
 
365
367
  /**
366
368
  * @fileoverview added by tsickle
367
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
369
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
368
370
  */
369
371
  /** @type {?} */
370
372
  const ONE_SECOND = 1000;
@@ -392,7 +394,7 @@ function resolveTimingValue(value) {
392
394
  if (typeof value == 'number')
393
395
  return value;
394
396
  /** @type {?} */
395
- const matches = (/** @type {?} */ (value)).match(/^(-?[\.\d]+)(m?s)/);
397
+ const matches = ((/** @type {?} */ (value))).match(/^(-?[\.\d]+)(m?s)/);
396
398
  if (!matches || matches.length < 2)
397
399
  return 0;
398
400
  return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
@@ -407,7 +409,6 @@ function _convertTimeValueToMS(value, unit) {
407
409
  case 's':
408
410
  return value * ONE_SECOND;
409
411
  default: // ms or something else
410
- // ms or something else
411
412
  return value;
412
413
  }
413
414
  }
@@ -418,8 +419,9 @@ function _convertTimeValueToMS(value, unit) {
418
419
  * @return {?}
419
420
  */
420
421
  function resolveTiming(timings, errors, allowNegativeValues) {
421
- return timings.hasOwnProperty('duration') ? /** @type {?} */ (timings) :
422
- parseTimeExpression(/** @type {?} */ (timings), errors, allowNegativeValues);
422
+ return timings.hasOwnProperty('duration') ?
423
+ (/** @type {?} */ (timings)) :
424
+ parseTimeExpression((/** @type {?} */ (timings)), errors, allowNegativeValues);
423
425
  }
424
426
  /**
425
427
  * @param {?} exp
@@ -447,7 +449,7 @@ function parseTimeExpression(exp, errors, allowNegativeValues) {
447
449
  /** @type {?} */
448
450
  const delayMatch = matches[3];
449
451
  if (delayMatch != null) {
450
- delay = _convertTimeValueToMS(Math.floor(parseFloat(delayMatch)), matches[4]);
452
+ delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);
451
453
  }
452
454
  /** @type {?} */
453
455
  const easingVal = matches[5];
@@ -456,7 +458,7 @@ function parseTimeExpression(exp, errors, allowNegativeValues) {
456
458
  }
457
459
  }
458
460
  else {
459
- duration = /** @type {?} */ (exp);
461
+ duration = (/** @type {?} */ (exp));
460
462
  }
461
463
  if (!allowNegativeValues) {
462
464
  /** @type {?} */
@@ -542,6 +544,10 @@ function getStyleAttributeString(element, key, value) {
542
544
  * @return {?}
543
545
  */
544
546
  function writeStyleAttribute(element) {
547
+ // Read the style property of the element and manually reflect it to the
548
+ // style attribute. This is needed because Domino on platform-server doesn't
549
+ // understand the full set of allowed CSS properties and doesn't reflect some
550
+ // of them automatically.
545
551
  /** @type {?} */
546
552
  let styleAttrValue = '';
547
553
  for (let i = 0; i < element.style.length; i++) {
@@ -606,7 +612,7 @@ function normalizeAnimationEntry(steps) {
606
612
  return steps[0];
607
613
  return sequence(steps);
608
614
  }
609
- return /** @type {?} */ (steps);
615
+ return (/** @type {?} */ (steps));
610
616
  }
611
617
  /**
612
618
  * @param {?} value
@@ -642,7 +648,7 @@ function extractStyleParams(value) {
642
648
  /** @type {?} */
643
649
  let match;
644
650
  while (match = PARAM_REGEX.exec(val)) {
645
- params.push(/** @type {?} */ (match[1]));
651
+ params.push((/** @type {?} */ (match[1])));
646
652
  }
647
653
  PARAM_REGEX.lastIndex = 0;
648
654
  }
@@ -785,20 +791,21 @@ function visitDslNode(visitor, node, context) {
785
791
  * @return {?}
786
792
  */
787
793
  function computeStyle(element, prop) {
788
- return (/** @type {?} */ (window.getComputedStyle(element)))[prop];
794
+ return ((/** @type {?} */ (window.getComputedStyle(element))))[prop];
789
795
  }
790
796
 
791
797
  /**
792
798
  * @fileoverview added by tsickle
793
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
799
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
794
800
  */
795
- /** *
801
+ /**
796
802
  * @license
797
803
  * Copyright Google Inc. All Rights Reserved.
798
804
  *
799
805
  * Use of this source code is governed by an MIT-style license that can be
800
806
  * found in the LICENSE file at https://angular.io/license
801
- @type {?} */
807
+ * @type {?}
808
+ */
802
809
  const ANY_STATE = '*';
803
810
  /**
804
811
  * @param {?} transitionValue
@@ -809,12 +816,12 @@ function parseTransitionExpr(transitionValue, errors) {
809
816
  /** @type {?} */
810
817
  const expressions = [];
811
818
  if (typeof transitionValue == 'string') {
812
- (/** @type {?} */ (transitionValue))
819
+ ((/** @type {?} */ (transitionValue)))
813
820
  .split(/\s*,\s*/)
814
821
  .forEach(str => parseInnerTransitionStr(str, expressions, errors));
815
822
  }
816
823
  else {
817
- expressions.push(/** @type {?} */ (transitionValue));
824
+ expressions.push((/** @type {?} */ (transitionValue)));
818
825
  }
819
826
  return expressions;
820
827
  }
@@ -832,7 +839,7 @@ function parseInnerTransitionStr(eventStr, expressions, errors) {
832
839
  expressions.push(result);
833
840
  return;
834
841
  }
835
- eventStr = /** @type {?} */ (result);
842
+ eventStr = (/** @type {?} */ (result));
836
843
  }
837
844
  /** @type {?} */
838
845
  const match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
@@ -873,6 +880,10 @@ function parseAnimationAlias(alias, errors) {
873
880
  return '* => *';
874
881
  }
875
882
  }
883
+ // DO NOT REFACTOR ... keep the follow set instantiations
884
+ // with the values intact (closure compiler for some reason
885
+ // removes follow-up lines that add the values outside of
886
+ // the constructor...
876
887
  /** @type {?} */
877
888
  const TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
878
889
  /** @type {?} */
@@ -904,12 +915,48 @@ function makeLambdaFromStates(lhs, rhs) {
904
915
 
905
916
  /**
906
917
  * @fileoverview added by tsickle
907
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
918
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
908
919
  */
909
920
  /** @type {?} */
910
921
  const SELF_TOKEN = ':self';
911
922
  /** @type {?} */
912
923
  const SELF_TOKEN_REGEX = new RegExp(`\s*${SELF_TOKEN}\s*,?`, 'g');
924
+ /*
925
+ * [Validation]
926
+ * The visitor code below will traverse the animation AST generated by the animation verb functions
927
+ * (the output is a tree of objects) and attempt to perform a series of validations on the data. The
928
+ * following corner-cases will be validated:
929
+ *
930
+ * 1. Overlap of animations
931
+ * Given that a CSS property cannot be animated in more than one place at the same time, it's
932
+ * important that this behaviour is detected and validated. The way in which this occurs is that
933
+ * each time a style property is examined, a string-map containing the property will be updated with
934
+ * the start and end times for when the property is used within an animation step.
935
+ *
936
+ * If there are two or more parallel animations that are currently running (these are invoked by the
937
+ * group()) on the same element then the validator will throw an error. Since the start/end timing
938
+ * values are collected for each property then if the current animation step is animating the same
939
+ * property and its timing values fall anywhere into the window of time that the property is
940
+ * currently being animated within then this is what causes an error.
941
+ *
942
+ * 2. Timing values
943
+ * The validator will validate to see if a timing value of `duration delay easing` or
944
+ * `durationNumber` is valid or not.
945
+ *
946
+ * (note that upon validation the code below will replace the timing data with an object containing
947
+ * {duration,delay,easing}.
948
+ *
949
+ * 3. Offset Validation
950
+ * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
951
+ * Offsets within keyframes() are considered valid when:
952
+ *
953
+ * - No offsets are used at all
954
+ * - Each style() entry contains an offset value
955
+ * - Each offset is between 0 and 1
956
+ * - Each offset is greater to or equal than the previous one
957
+ *
958
+ * Otherwise an error will be thrown.
959
+ */
913
960
  /**
914
961
  * @param {?} driver
915
962
  * @param {?} metadata
@@ -937,7 +984,7 @@ class AnimationAstBuilderVisitor {
937
984
  /** @type {?} */
938
985
  const context = new AnimationAstBuilderContext(errors);
939
986
  this._resetContextStyleTimingState(context);
940
- return /** @type {?} */ (visitDslNode(this, normalizeAnimationEntry(metadata), context));
987
+ return (/** @type {?} */ (visitDslNode(this, normalizeAnimationEntry(metadata), context)));
941
988
  }
942
989
  /**
943
990
  * @param {?} context
@@ -970,7 +1017,7 @@ class AnimationAstBuilderVisitor {
970
1017
  this._resetContextStyleTimingState(context);
971
1018
  if (def.type == 0 /* State */) {
972
1019
  /** @type {?} */
973
- const stateDef = /** @type {?} */ (def);
1020
+ const stateDef = (/** @type {?} */ (def));
974
1021
  /** @type {?} */
975
1022
  const name = stateDef.name;
976
1023
  name.toString().split(/\s*,\s*/).forEach(n => {
@@ -981,7 +1028,7 @@ class AnimationAstBuilderVisitor {
981
1028
  }
982
1029
  else if (def.type == 1 /* Transition */) {
983
1030
  /** @type {?} */
984
- const transition = this.visitTransition(/** @type {?} */ (def), context);
1031
+ const transition = this.visitTransition((/** @type {?} */ (def)), context);
985
1032
  queryCount += transition.queryCount;
986
1033
  depCount += transition.depCount;
987
1034
  transitions.push(transition);
@@ -1014,7 +1061,7 @@ class AnimationAstBuilderVisitor {
1014
1061
  styleAst.styles.forEach(value => {
1015
1062
  if (isObject(value)) {
1016
1063
  /** @type {?} */
1017
- const stylesObj = /** @type {?} */ (value);
1064
+ const stylesObj = (/** @type {?} */ (value));
1018
1065
  Object.keys(stylesObj).forEach(prop => {
1019
1066
  extractStyleParams(stylesObj[prop]).forEach(sub => {
1020
1067
  if (!params.hasOwnProperty(sub)) {
@@ -1109,11 +1156,11 @@ class AnimationAstBuilderVisitor {
1109
1156
  /** @type {?} */
1110
1157
  let styleMetadata = metadata.styles ? metadata.styles : style({});
1111
1158
  if (styleMetadata.type == 5 /* Keyframes */) {
1112
- styleAst = this.visitKeyframes(/** @type {?} */ (styleMetadata), context);
1159
+ styleAst = this.visitKeyframes((/** @type {?} */ (styleMetadata)), context);
1113
1160
  }
1114
1161
  else {
1115
1162
  /** @type {?} */
1116
- let styleMetadata = /** @type {?} */ (metadata.styles);
1163
+ let styleMetadata = (/** @type {?} */ (metadata.styles));
1117
1164
  /** @type {?} */
1118
1165
  let isEmpty = false;
1119
1166
  if (!styleMetadata) {
@@ -1159,17 +1206,17 @@ class AnimationAstBuilderVisitor {
1159
1206
  /** @type {?} */
1160
1207
  const styles = [];
1161
1208
  if (Array.isArray(metadata.styles)) {
1162
- (/** @type {?} */ (metadata.styles)).forEach(styleTuple => {
1209
+ ((/** @type {?} */ (metadata.styles))).forEach(styleTuple => {
1163
1210
  if (typeof styleTuple == 'string') {
1164
1211
  if (styleTuple == AUTO_STYLE) {
1165
- styles.push(/** @type {?} */ (styleTuple));
1212
+ styles.push((/** @type {?} */ (styleTuple)));
1166
1213
  }
1167
1214
  else {
1168
1215
  context.errors.push(`The provided style string value ${styleTuple} is not allowed.`);
1169
1216
  }
1170
1217
  }
1171
1218
  else {
1172
- styles.push(/** @type {?} */ (styleTuple));
1219
+ styles.push((/** @type {?} */ (styleTuple)));
1173
1220
  }
1174
1221
  });
1175
1222
  }
@@ -1183,11 +1230,11 @@ class AnimationAstBuilderVisitor {
1183
1230
  styles.forEach(styleData => {
1184
1231
  if (isObject(styleData)) {
1185
1232
  /** @type {?} */
1186
- const styleMap = /** @type {?} */ (styleData);
1233
+ const styleMap = (/** @type {?} */ (styleData));
1187
1234
  /** @type {?} */
1188
1235
  const easing = styleMap['easing'];
1189
1236
  if (easing) {
1190
- collectedEasing = /** @type {?} */ (easing);
1237
+ collectedEasing = (/** @type {?} */ (easing));
1191
1238
  delete styleMap['easing'];
1192
1239
  }
1193
1240
  if (!containsDynamicStyles) {
@@ -1234,7 +1281,7 @@ class AnimationAstBuilderVisitor {
1234
1281
  return;
1235
1282
  }
1236
1283
  /** @type {?} */
1237
- const collectedStyles = context.collectedStyles[/** @type {?} */ ((context.currentQuerySelector))];
1284
+ const collectedStyles = context.collectedStyles[(/** @type {?} */ (context.currentQuerySelector))];
1238
1285
  /** @type {?} */
1239
1286
  const collectedEntry = collectedStyles[prop];
1240
1287
  /** @type {?} */
@@ -1322,7 +1369,7 @@ class AnimationAstBuilderVisitor {
1322
1369
  /** @type {?} */
1323
1370
  const currentTime = context.currentTime;
1324
1371
  /** @type {?} */
1325
- const currentAnimateTimings = /** @type {?} */ ((context.currentAnimateTimings));
1372
+ const currentAnimateTimings = (/** @type {?} */ (context.currentAnimateTimings));
1326
1373
  /** @type {?} */
1327
1374
  const animateDuration = currentAnimateTimings.duration;
1328
1375
  keyframes.forEach((kf, i) => {
@@ -1381,9 +1428,9 @@ class AnimationAstBuilderVisitor {
1381
1428
  */
1382
1429
  visitQuery(metadata, context) {
1383
1430
  /** @type {?} */
1384
- const parentSelector = /** @type {?} */ ((context.currentQuerySelector));
1431
+ const parentSelector = (/** @type {?} */ (context.currentQuerySelector));
1385
1432
  /** @type {?} */
1386
- const options = /** @type {?} */ ((metadata.options || {}));
1433
+ const options = (/** @type {?} */ ((metadata.options || {})));
1387
1434
  context.queryCount++;
1388
1435
  context.currentQuery = metadata;
1389
1436
  const [selector, includeSelf] = normalizeSelector(metadata.selector);
@@ -1476,16 +1523,16 @@ function consumeOffset(styles) {
1476
1523
  styles.forEach(styleTuple => {
1477
1524
  if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) {
1478
1525
  /** @type {?} */
1479
- const obj = /** @type {?} */ (styleTuple);
1480
- offset = parseFloat(/** @type {?} */ (obj['offset']));
1526
+ const obj = (/** @type {?} */ (styleTuple));
1527
+ offset = parseFloat((/** @type {?} */ (obj['offset'])));
1481
1528
  delete obj['offset'];
1482
1529
  }
1483
1530
  });
1484
1531
  }
1485
1532
  else if (isObject(styles) && styles.hasOwnProperty('offset')) {
1486
1533
  /** @type {?} */
1487
- const obj = /** @type {?} */ (styles);
1488
- offset = parseFloat(/** @type {?} */ (obj['offset']));
1534
+ const obj = (/** @type {?} */ (styles));
1535
+ offset = parseFloat((/** @type {?} */ (obj['offset'])));
1489
1536
  delete obj['offset'];
1490
1537
  }
1491
1538
  return offset;
@@ -1506,23 +1553,23 @@ function constructTimingAst(value, errors) {
1506
1553
  /** @type {?} */
1507
1554
  let timings = null;
1508
1555
  if (value.hasOwnProperty('duration')) {
1509
- timings = /** @type {?} */ (value);
1556
+ timings = (/** @type {?} */ (value));
1510
1557
  }
1511
1558
  else if (typeof value == 'number') {
1512
1559
  /** @type {?} */
1513
- const duration = resolveTiming(/** @type {?} */ (value), errors).duration;
1514
- return makeTimingAst(/** @type {?} */ (duration), 0, '');
1560
+ const duration = resolveTiming((/** @type {?} */ (value)), errors).duration;
1561
+ return makeTimingAst((/** @type {?} */ (duration)), 0, '');
1515
1562
  }
1516
1563
  /** @type {?} */
1517
- const strValue = /** @type {?} */ (value);
1564
+ const strValue = (/** @type {?} */ (value));
1518
1565
  /** @type {?} */
1519
1566
  const isDynamic = strValue.split(/\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{');
1520
1567
  if (isDynamic) {
1521
1568
  /** @type {?} */
1522
- const ast = /** @type {?} */ (makeTimingAst(0, 0, ''));
1569
+ const ast = (/** @type {?} */ (makeTimingAst(0, 0, '')));
1523
1570
  ast.dynamic = true;
1524
1571
  ast.strValue = strValue;
1525
- return /** @type {?} */ (ast);
1572
+ return (/** @type {?} */ (ast));
1526
1573
  }
1527
1574
  timings = timings || resolveTiming(strValue, errors);
1528
1575
  return makeTimingAst(timings.duration, timings.delay, timings.easing);
@@ -1535,7 +1582,7 @@ function normalizeAnimationOptions(options) {
1535
1582
  if (options) {
1536
1583
  options = copyObj(options);
1537
1584
  if (options['params']) {
1538
- options['params'] = /** @type {?} */ ((normalizeParams(options['params'])));
1585
+ options['params'] = (/** @type {?} */ (normalizeParams(options['params'])));
1539
1586
  }
1540
1587
  }
1541
1588
  else {
@@ -1555,7 +1602,7 @@ function makeTimingAst(duration, delay, easing) {
1555
1602
 
1556
1603
  /**
1557
1604
  * @fileoverview added by tsickle
1558
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1605
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
1559
1606
  */
1560
1607
  /**
1561
1608
  * @param {?} element
@@ -1583,7 +1630,7 @@ function createTimelineInstruction(element, keyframes, preStyleProps, postStyleP
1583
1630
 
1584
1631
  /**
1585
1632
  * @fileoverview added by tsickle
1586
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1633
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
1587
1634
  */
1588
1635
  class ElementInstructionMap {
1589
1636
  constructor() {
@@ -1630,7 +1677,7 @@ class ElementInstructionMap {
1630
1677
 
1631
1678
  /**
1632
1679
  * @fileoverview added by tsickle
1633
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
1680
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
1634
1681
  */
1635
1682
  /** @type {?} */
1636
1683
  const ONE_FRAME_IN_MILLISECONDS = 1;
@@ -1642,6 +1689,90 @@ const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
1642
1689
  const LEAVE_TOKEN = ':leave';
1643
1690
  /** @type {?} */
1644
1691
  const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
1692
+ /*
1693
+ * The code within this file aims to generate web-animations-compatible keyframes from Angular's
1694
+ * animation DSL code.
1695
+ *
1696
+ * The code below will be converted from:
1697
+ *
1698
+ * ```
1699
+ * sequence([
1700
+ * style({ opacity: 0 }),
1701
+ * animate(1000, style({ opacity: 0 }))
1702
+ * ])
1703
+ * ```
1704
+ *
1705
+ * To:
1706
+ * ```
1707
+ * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]
1708
+ * duration = 1000
1709
+ * delay = 0
1710
+ * easing = ''
1711
+ * ```
1712
+ *
1713
+ * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
1714
+ * combination of prototypical inheritance, AST traversal and merge-sort-like algorithms are used.
1715
+ *
1716
+ * [AST Traversal]
1717
+ * Each of the animation verbs, when executed, will return an string-map object representing what
1718
+ * type of action it is (style, animate, group, etc...) and the data associated with it. This means
1719
+ * that when functional composition mix of these functions is evaluated (like in the example above)
1720
+ * then it will end up producing a tree of objects representing the animation itself.
1721
+ *
1722
+ * When this animation object tree is processed by the visitor code below it will visit each of the
1723
+ * verb statements within the visitor. And during each visit it will build the context of the
1724
+ * animation keyframes by interacting with the `TimelineBuilder`.
1725
+ *
1726
+ * [TimelineBuilder]
1727
+ * This class is responsible for tracking the styles and building a series of keyframe objects for a
1728
+ * timeline between a start and end time. The builder starts off with an initial timeline and each
1729
+ * time the AST comes across a `group()`, `keyframes()` or a combination of the two wihtin a
1730
+ * `sequence()` then it will generate a sub timeline for each step as well as a new one after
1731
+ * they are complete.
1732
+ *
1733
+ * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub
1734
+ * timeline was created (based on one of the cases above) then the parent timeline will attempt to
1735
+ * merge the styles used within the sub timelines into itself (only with group() this will happen).
1736
+ * This happens with a merge operation (much like how the merge works in mergesort) and it will only
1737
+ * copy the most recently used styles from the sub timelines into the parent timeline. This ensures
1738
+ * that if the styles are used later on in another phase of the animation then they will be the most
1739
+ * up-to-date values.
1740
+ *
1741
+ * [How Missing Styles Are Updated]
1742
+ * Each timeline has a `backFill` property which is responsible for filling in new styles into
1743
+ * already processed keyframes if a new style shows up later within the animation sequence.
1744
+ *
1745
+ * ```
1746
+ * sequence([
1747
+ * style({ width: 0 }),
1748
+ * animate(1000, style({ width: 100 })),
1749
+ * animate(1000, style({ width: 200 })),
1750
+ * animate(1000, style({ width: 300 }))
1751
+ * animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere
1752
+ * else
1753
+ * ])
1754
+ * ```
1755
+ *
1756
+ * What is happening here is that the `height` value is added later in the sequence, but is missing
1757
+ * from all previous animation steps. Therefore when a keyframe is created it would also be missing
1758
+ * from all previous keyframes up until where it is first used. For the timeline keyframe generation
1759
+ * to properly fill in the style it will place the previous value (the value from the parent
1760
+ * timeline) or a default value of `*` into the backFill object. Given that each of the keyframe
1761
+ * styles are objects that prototypically inhert from the backFill object, this means that if a
1762
+ * value is added into the backFill then it will automatically propagate any missing values to all
1763
+ * keyframes. Therefore the missing `height` value will be properly filled into the already
1764
+ * processed keyframes.
1765
+ *
1766
+ * When a sub-timeline is created it will have its own backFill property. This is done so that
1767
+ * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
1768
+ * keyframes
1769
+ *
1770
+ * (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
1771
+ *
1772
+ * [Validation]
1773
+ * The code in this file is not responsible for validation. That functionality happens with within
1774
+ * the `AnimationValidatorVisitor` code.
1775
+ */
1645
1776
  /**
1646
1777
  * @param {?} driver
1647
1778
  * @param {?} rootElement
@@ -1679,6 +1810,7 @@ class AnimationTimelineBuilderVisitor {
1679
1810
  context.options = options;
1680
1811
  context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
1681
1812
  visitDslNode(this, ast, context);
1813
+ // this checks to see if an actual animation happened
1682
1814
  /** @type {?} */
1683
1815
  const timelines = context.timelines.filter(timeline => timeline.containsAnimation());
1684
1816
  if (timelines.length && Object.keys(finalStyles).length) {
@@ -1729,7 +1861,7 @@ class AnimationTimelineBuilderVisitor {
1729
1861
  /** @type {?} */
1730
1862
  const startTime = context.currentTimeline.currentTime;
1731
1863
  /** @type {?} */
1732
- const endTime = this._visitSubInstructions(elementInstructions, innerContext, /** @type {?} */ (innerContext.options));
1864
+ const endTime = this._visitSubInstructions(elementInstructions, innerContext, (/** @type {?} */ (innerContext.options)));
1733
1865
  if (startTime != endTime) {
1734
1866
  // we do this on the upper context because we created a sub context for
1735
1867
  // the sub child animations
@@ -1762,6 +1894,8 @@ class AnimationTimelineBuilderVisitor {
1762
1894
  const startTime = context.currentTimeline.currentTime;
1763
1895
  /** @type {?} */
1764
1896
  let furthestTime = startTime;
1897
+ // this is a special-case for when a user wants to skip a sub
1898
+ // animation from being fired entirely.
1765
1899
  /** @type {?} */
1766
1900
  const duration = options.duration != null ? resolveTimingValue(options.duration) : null;
1767
1901
  /** @type {?} */
@@ -1859,9 +1993,9 @@ class AnimationTimelineBuilderVisitor {
1859
1993
  * @return {?}
1860
1994
  */
1861
1995
  _visitTiming(ast, context) {
1862
- if ((/** @type {?} */ (ast)).dynamic) {
1996
+ if (((/** @type {?} */ (ast))).dynamic) {
1863
1997
  /** @type {?} */
1864
- const strValue = (/** @type {?} */ (ast)).strValue;
1998
+ const strValue = ((/** @type {?} */ (ast))).strValue;
1865
1999
  /** @type {?} */
1866
2000
  const timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
1867
2001
  return resolveTiming(timingValue, context.errors);
@@ -1891,7 +2025,7 @@ class AnimationTimelineBuilderVisitor {
1891
2025
  }
1892
2026
  else {
1893
2027
  context.incrementTime(timings.duration);
1894
- this.visitStyle(/** @type {?} */ (style$$1), context);
2028
+ this.visitStyle((/** @type {?} */ (style$$1)), context);
1895
2029
  timeline.applyStylesToKeyframe();
1896
2030
  }
1897
2031
  context.currentAnimateTimings = null;
@@ -1906,7 +2040,7 @@ class AnimationTimelineBuilderVisitor {
1906
2040
  /** @type {?} */
1907
2041
  const timeline = context.currentTimeline;
1908
2042
  /** @type {?} */
1909
- const timings = /** @type {?} */ ((context.currentAnimateTimings));
2043
+ const timings = (/** @type {?} */ (context.currentAnimateTimings));
1910
2044
  // this is a special case for when a style() call
1911
2045
  // directly follows an animate() call (but not inside of an animate() call)
1912
2046
  if (!timings && timeline.getCurrentStyleProperties().length) {
@@ -1929,9 +2063,9 @@ class AnimationTimelineBuilderVisitor {
1929
2063
  */
1930
2064
  visitKeyframes(ast, context) {
1931
2065
  /** @type {?} */
1932
- const currentAnimateTimings = /** @type {?} */ ((context.currentAnimateTimings));
2066
+ const currentAnimateTimings = (/** @type {?} */ (context.currentAnimateTimings));
1933
2067
  /** @type {?} */
1934
- const startTime = (/** @type {?} */ ((context.currentTimeline))).duration;
2068
+ const startTime = ((/** @type {?} */ (context.currentTimeline))).duration;
1935
2069
  /** @type {?} */
1936
2070
  const duration = currentAnimateTimings.duration;
1937
2071
  /** @type {?} */
@@ -1960,10 +2094,12 @@ class AnimationTimelineBuilderVisitor {
1960
2094
  * @return {?}
1961
2095
  */
1962
2096
  visitQuery(ast, context) {
2097
+ // in the event that the first step before this is a style step we need
2098
+ // to ensure the styles are applied before the children are animated
1963
2099
  /** @type {?} */
1964
2100
  const startTime = context.currentTimeline.currentTime;
1965
2101
  /** @type {?} */
1966
- const options = /** @type {?} */ ((ast.options || {}));
2102
+ const options = (/** @type {?} */ ((ast.options || {})));
1967
2103
  /** @type {?} */
1968
2104
  const delay = options.delay ? resolveTimingValue(options.delay) : 0;
1969
2105
  if (delay && (context.previousNode.type === 6 /* Style */ ||
@@ -2013,7 +2149,7 @@ class AnimationTimelineBuilderVisitor {
2013
2149
  */
2014
2150
  visitStagger(ast, context) {
2015
2151
  /** @type {?} */
2016
- const parentContext = /** @type {?} */ ((context.parentContext));
2152
+ const parentContext = (/** @type {?} */ (context.parentContext));
2017
2153
  /** @type {?} */
2018
2154
  const tl = context.currentTimeline;
2019
2155
  /** @type {?} */
@@ -2052,7 +2188,7 @@ class AnimationTimelineBuilderVisitor {
2052
2188
  }
2053
2189
  }
2054
2190
  /** @type {?} */
2055
- const DEFAULT_NOOP_PREVIOUS_NODE = /** @type {?} */ ({});
2191
+ const DEFAULT_NOOP_PREVIOUS_NODE = (/** @type {?} */ ({}));
2056
2192
  class AnimationTimelineContext {
2057
2193
  /**
2058
2194
  * @param {?} _driver
@@ -2096,12 +2232,12 @@ class AnimationTimelineContext {
2096
2232
  if (!options)
2097
2233
  return;
2098
2234
  /** @type {?} */
2099
- const newOptions = /** @type {?} */ (options);
2235
+ const newOptions = (/** @type {?} */ (options));
2100
2236
  /** @type {?} */
2101
2237
  let optionsToUpdate = this.options;
2102
2238
  // NOTE: this will get patched up when other animation methods support duration overrides
2103
2239
  if (newOptions.duration != null) {
2104
- (/** @type {?} */ (optionsToUpdate)).duration = resolveTimingValue(newOptions.duration);
2240
+ ((/** @type {?} */ (optionsToUpdate))).duration = resolveTimingValue(newOptions.duration);
2105
2241
  }
2106
2242
  if (newOptions.delay != null) {
2107
2243
  optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
@@ -2110,7 +2246,7 @@ class AnimationTimelineContext {
2110
2246
  const newParams = newOptions.params;
2111
2247
  if (newParams) {
2112
2248
  /** @type {?} */
2113
- let paramsToUpdate = /** @type {?} */ ((optionsToUpdate.params));
2249
+ let paramsToUpdate = (/** @type {?} */ (optionsToUpdate.params));
2114
2250
  if (!paramsToUpdate) {
2115
2251
  paramsToUpdate = this.options.params = {};
2116
2252
  }
@@ -2220,7 +2356,6 @@ class AnimationTimelineContext {
2220
2356
  results.push(this.element);
2221
2357
  }
2222
2358
  if (selector.length > 0) { // if :self is only used then the selector is empty
2223
- // if :self is only used then the selector is empty
2224
2359
  selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
2225
2360
  selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
2226
2361
  /** @type {?} */
@@ -2263,7 +2398,7 @@ class TimelineBuilder {
2263
2398
  this._elementTimelineStylesLookup = new Map();
2264
2399
  }
2265
2400
  this._localTimelineStyles = Object.create(this._backFill, {});
2266
- this._globalTimelineStyles = /** @type {?} */ ((this._elementTimelineStylesLookup.get(element)));
2401
+ this._globalTimelineStyles = (/** @type {?} */ (this._elementTimelineStylesLookup.get(element)));
2267
2402
  if (!this._globalTimelineStyles) {
2268
2403
  this._globalTimelineStyles = this._localTimelineStyles;
2269
2404
  this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
@@ -2296,6 +2431,10 @@ class TimelineBuilder {
2296
2431
  * @return {?}
2297
2432
  */
2298
2433
  delayNextStep(delay) {
2434
+ // in the event that a style() step is placed right before a stagger()
2435
+ // and that style() step is the very first style() value in the animation
2436
+ // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
2437
+ // properly applies the style() values to work with the stagger...
2299
2438
  /** @type {?} */
2300
2439
  const hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length;
2301
2440
  if (this.duration || hasPreStyleStep) {
@@ -2324,7 +2463,7 @@ class TimelineBuilder {
2324
2463
  if (this._currentKeyframe) {
2325
2464
  this._previousKeyframe = this._currentKeyframe;
2326
2465
  }
2327
- this._currentKeyframe = /** @type {?} */ ((this._keyframes.get(this.duration)));
2466
+ this._currentKeyframe = (/** @type {?} */ (this._keyframes.get(this.duration)));
2328
2467
  if (!this._currentKeyframe) {
2329
2468
  this._currentKeyframe = Object.create(this._backFill, {});
2330
2469
  this._keyframes.set(this.duration, this._currentKeyframe);
@@ -2555,6 +2694,7 @@ class SubTimelineBuilder extends TimelineBuilder {
2555
2694
  const totalTime = duration + delay;
2556
2695
  /** @type {?} */
2557
2696
  const startingGap = delay / totalTime;
2697
+ // the original starting keyframe now starts once the delay is done
2558
2698
  /** @type {?} */
2559
2699
  const newFirstKeyframe = copyStyles(keyframes[0], false);
2560
2700
  newFirstKeyframe['offset'] = 0;
@@ -2563,13 +2703,28 @@ class SubTimelineBuilder extends TimelineBuilder {
2563
2703
  const oldFirstKeyframe = copyStyles(keyframes[0], false);
2564
2704
  oldFirstKeyframe['offset'] = roundOffset(startingGap);
2565
2705
  newKeyframes.push(oldFirstKeyframe);
2706
+ /*
2707
+ When the keyframe is stretched then it means that the delay before the animation
2708
+ starts is gone. Instead the first keyframe is placed at the start of the animation
2709
+ and it is then copied to where it starts when the original delay is over. This basically
2710
+ means nothing animates during that delay, but the styles are still renderered. For this
2711
+ to work the original offset values that exist in the original keyframes must be "warped"
2712
+ so that they can take the new keyframe + delay into account.
2713
+
2714
+ delay=1000, duration=1000, keyframes = 0 .5 1
2715
+
2716
+ turns into
2717
+
2718
+ delay=0, duration=2000, keyframes = 0 .33 .66 1
2719
+ */
2720
+ // offsets between 1 ... n -1 are all warped by the keyframe stretch
2566
2721
  /** @type {?} */
2567
2722
  const limit = keyframes.length - 1;
2568
2723
  for (let i = 1; i <= limit; i++) {
2569
2724
  /** @type {?} */
2570
2725
  let kf = copyStyles(keyframes[i], false);
2571
2726
  /** @type {?} */
2572
- const oldOffset = /** @type {?} */ (kf['offset']);
2727
+ const oldOffset = (/** @type {?} */ (kf['offset']));
2573
2728
  /** @type {?} */
2574
2729
  const timeAtKeyframe = delay + oldOffset * duration;
2575
2730
  kf['offset'] = roundOffset(timeAtKeyframe / totalTime);
@@ -2610,7 +2765,7 @@ function flattenStyles(input, allStyles) {
2610
2765
  allProperties.forEach(prop => { styles[prop] = AUTO_STYLE; });
2611
2766
  }
2612
2767
  else {
2613
- copyStyles(/** @type {?} */ (token), false, styles);
2768
+ copyStyles((/** @type {?} */ (token)), false, styles);
2614
2769
  }
2615
2770
  });
2616
2771
  return styles;
@@ -2618,7 +2773,7 @@ function flattenStyles(input, allStyles) {
2618
2773
 
2619
2774
  /**
2620
2775
  * @fileoverview added by tsickle
2621
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2776
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2622
2777
  */
2623
2778
  class Animation {
2624
2779
  /**
@@ -2648,9 +2803,11 @@ class Animation {
2648
2803
  */
2649
2804
  buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {
2650
2805
  /** @type {?} */
2651
- const start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : /** @type {?} */ (startingStyles);
2806
+ const start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) :
2807
+ (/** @type {?} */ (startingStyles));
2652
2808
  /** @type {?} */
2653
- const dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : /** @type {?} */ (destinationStyles);
2809
+ const dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) :
2810
+ (/** @type {?} */ (destinationStyles));
2654
2811
  /** @type {?} */
2655
2812
  const errors = [];
2656
2813
  subInstructions = subInstructions || new ElementInstructionMap();
@@ -2667,7 +2824,7 @@ class Animation {
2667
2824
 
2668
2825
  /**
2669
2826
  * @fileoverview added by tsickle
2670
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2827
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2671
2828
  */
2672
2829
  /**
2673
2830
  * @license
@@ -2700,13 +2857,13 @@ class NoopAnimationStyleNormalizer {
2700
2857
  * @return {?}
2701
2858
  */
2702
2859
  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
2703
- return /** @type {?} */ (value);
2860
+ return (/** @type {?} */ (value));
2704
2861
  }
2705
2862
  }
2706
2863
 
2707
2864
  /**
2708
2865
  * @fileoverview added by tsickle
2709
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2866
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2710
2867
  */
2711
2868
  class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
2712
2869
  /**
@@ -2760,7 +2917,7 @@ function makeBooleanMap(keys) {
2760
2917
 
2761
2918
  /**
2762
2919
  * @fileoverview added by tsickle
2763
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2920
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2764
2921
  */
2765
2922
  /**
2766
2923
  * @param {?} element
@@ -2799,7 +2956,7 @@ function createTransitionInstruction(element, triggerName, fromState, toState, i
2799
2956
 
2800
2957
  /**
2801
2958
  * @fileoverview added by tsickle
2802
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
2959
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2803
2960
  */
2804
2961
  /** @type {?} */
2805
2962
  const EMPTY_OBJECT = {};
@@ -2941,7 +3098,7 @@ class AnimationStateStyles {
2941
3098
  this.styles.styles.forEach(value => {
2942
3099
  if (typeof value !== 'string') {
2943
3100
  /** @type {?} */
2944
- const styleObj = /** @type {?} */ (value);
3101
+ const styleObj = (/** @type {?} */ (value));
2945
3102
  Object.keys(styleObj).forEach(prop => {
2946
3103
  /** @type {?} */
2947
3104
  let val = styleObj[prop];
@@ -2958,7 +3115,7 @@ class AnimationStateStyles {
2958
3115
 
2959
3116
  /**
2960
3117
  * @fileoverview added by tsickle
2961
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
3118
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
2962
3119
  */
2963
3120
  /**
2964
3121
  * \@publicApi
@@ -3060,7 +3217,7 @@ function balanceProperties(obj, key1, key2) {
3060
3217
 
3061
3218
  /**
3062
3219
  * @fileoverview added by tsickle
3063
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
3220
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
3064
3221
  */
3065
3222
  /** @type {?} */
3066
3223
  const EMPTY_INSTRUCTION_MAP = new ElementInstructionMap();
@@ -3189,6 +3346,7 @@ class TimelineAnimationEngine {
3189
3346
  * @return {?}
3190
3347
  */
3191
3348
  listen(id, element, eventName, callback) {
3349
+ // triggerName, fromState, toState are all ignored for timeline animations
3192
3350
  /** @type {?} */
3193
3351
  const baseEvent = makeAnimationEvent(element, '', '', '');
3194
3352
  listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
@@ -3203,12 +3361,12 @@ class TimelineAnimationEngine {
3203
3361
  */
3204
3362
  command(id, element, command, args) {
3205
3363
  if (command == 'register') {
3206
- this.register(id, /** @type {?} */ (args[0]));
3364
+ this.register(id, (/** @type {?} */ (args[0])));
3207
3365
  return;
3208
3366
  }
3209
3367
  if (command == 'create') {
3210
3368
  /** @type {?} */
3211
- const options = /** @type {?} */ ((args[0] || {}));
3369
+ const options = (/** @type {?} */ ((args[0] || {})));
3212
3370
  this.create(id, element, options);
3213
3371
  return;
3214
3372
  }
@@ -3234,7 +3392,7 @@ class TimelineAnimationEngine {
3234
3392
  player.init();
3235
3393
  break;
3236
3394
  case 'setPosition':
3237
- player.setPosition(parseFloat(/** @type {?} */ (args[0])));
3395
+ player.setPosition(parseFloat((/** @type {?} */ (args[0]))));
3238
3396
  break;
3239
3397
  case 'destroy':
3240
3398
  this.destroy(id);
@@ -3245,7 +3403,7 @@ class TimelineAnimationEngine {
3245
3403
 
3246
3404
  /**
3247
3405
  * @fileoverview added by tsickle
3248
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
3406
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
3249
3407
  */
3250
3408
  /** @type {?} */
3251
3409
  const QUEUED_CLASSNAME = 'ng-animate-queued';
@@ -3293,9 +3451,9 @@ class StateValue {
3293
3451
  this.value = normalizeTriggerValue(value);
3294
3452
  if (isObj) {
3295
3453
  /** @type {?} */
3296
- const options = copyObj(/** @type {?} */ (input));
3454
+ const options = copyObj((/** @type {?} */ (input)));
3297
3455
  delete options['value'];
3298
- this.options = /** @type {?} */ (options);
3456
+ this.options = (/** @type {?} */ (options));
3299
3457
  }
3300
3458
  else {
3301
3459
  this.options = {};
@@ -3307,7 +3465,7 @@ class StateValue {
3307
3465
  /**
3308
3466
  * @return {?}
3309
3467
  */
3310
- get params() { return /** @type {?} */ (this.options.params); }
3468
+ get params() { return (/** @type {?} */ (this.options.params)); }
3311
3469
  /**
3312
3470
  * @param {?} options
3313
3471
  * @return {?}
@@ -3317,7 +3475,7 @@ class StateValue {
3317
3475
  const newParams = options.params;
3318
3476
  if (newParams) {
3319
3477
  /** @type {?} */
3320
- const oldParams = /** @type {?} */ ((this.options.params));
3478
+ const oldParams = (/** @type {?} */ (this.options.params));
3321
3479
  Object.keys(newParams).forEach(prop => {
3322
3480
  if (oldParams[prop] == null) {
3323
3481
  oldParams[prop] = newParams[prop];
@@ -3633,7 +3791,7 @@ class AnimationTransitionNamespace {
3633
3791
  /** @type {?} */
3634
3792
  const transition = trigger.fallbackTransition;
3635
3793
  /** @type {?} */
3636
- const elementStates = /** @type {?} */ ((this._engine.statesByElement.get(element)));
3794
+ const elementStates = (/** @type {?} */ (this._engine.statesByElement.get(element)));
3637
3795
  /** @type {?} */
3638
3796
  const fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
3639
3797
  /** @type {?} */
@@ -3667,6 +3825,8 @@ class AnimationTransitionNamespace {
3667
3825
  // this means that a * => VOID animation was detected and kicked off
3668
3826
  if (this.triggerLeaveAnimation(element, context, true))
3669
3827
  return;
3828
+ // find the player that is animating and make sure that the
3829
+ // removal is delayed until that player has completed
3670
3830
  /** @type {?} */
3671
3831
  let containsPotentialParentTransition = false;
3672
3832
  if (engine.totalAnimations) {
@@ -3737,7 +3897,7 @@ class AnimationTransitionNamespace {
3737
3897
  if (listener.name == entry.triggerName) {
3738
3898
  /** @type {?} */
3739
3899
  const baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
3740
- (/** @type {?} */ (baseEvent))['_data'] = microtaskId;
3900
+ ((/** @type {?} */ (baseEvent)))['_data'] = microtaskId;
3741
3901
  listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
3742
3902
  }
3743
3903
  });
@@ -3755,6 +3915,8 @@ class AnimationTransitionNamespace {
3755
3915
  });
3756
3916
  this._queue = [];
3757
3917
  return instructions.sort((a, b) => {
3918
+ // if depCount == 0 them move to front
3919
+ // otherwise if a contains b then move back
3758
3920
  /** @type {?} */
3759
3921
  const d0 = a.transition.ast.depCount;
3760
3922
  /** @type {?} */
@@ -3812,6 +3974,7 @@ class TransitionAnimationEngine {
3812
3974
  this.namespacesByHostElement = new Map();
3813
3975
  this.collectedEnterElements = [];
3814
3976
  this.collectedLeaveElements = [];
3977
+ // this method is designed to be overridden by the code that uses this engine
3815
3978
  this.onRemovalComplete = (element, context) => { };
3816
3979
  }
3817
3980
  /**
@@ -3948,6 +4111,11 @@ class TransitionAnimationEngine {
3948
4111
  * @return {?}
3949
4112
  */
3950
4113
  fetchNamespacesByElement(element) {
4114
+ // normally there should only be one namespace per element, however
4115
+ // if @triggers are placed on both the component element and then
4116
+ // its host element (within the component code) then there will be
4117
+ // two namespaces returned. We use a set here to simply the dedupe
4118
+ // of namespaces incase there are multiple triggers both the elm and host
3951
4119
  /** @type {?} */
3952
4120
  const namespaces = new Set();
3953
4121
  /** @type {?} */
@@ -3997,8 +4165,10 @@ class TransitionAnimationEngine {
3997
4165
  insertNode(namespaceId, element, parent, insertBefore) {
3998
4166
  if (!isElementNode(element))
3999
4167
  return;
4168
+ // special case for when an element is removed and reinserted (move operation)
4169
+ // when this occurs we do not want to use the element for deletion later
4000
4170
  /** @type {?} */
4001
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4171
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4002
4172
  if (details && details.setForRemoval) {
4003
4173
  details.setForRemoval = false;
4004
4174
  details.setForMove = true;
@@ -4175,7 +4345,7 @@ class TransitionAnimationEngine {
4175
4345
  */
4176
4346
  processLeaveNode(element) {
4177
4347
  /** @type {?} */
4178
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4348
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4179
4349
  if (details && details.setForRemoval) {
4180
4350
  // this will prevent it from removing it twice
4181
4351
  element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
@@ -4193,7 +4363,7 @@ class TransitionAnimationEngine {
4193
4363
  this.markElementAsDisabled(element, false);
4194
4364
  }
4195
4365
  this.driver.query(element, DISABLED_SELECTOR, true).forEach(node => {
4196
- this.markElementAsDisabled(element, false);
4366
+ this.markElementAsDisabled(node, false);
4197
4367
  });
4198
4368
  }
4199
4369
  /**
@@ -4240,6 +4410,9 @@ class TransitionAnimationEngine {
4240
4410
  this._flushFns.forEach(fn => fn());
4241
4411
  this._flushFns = [];
4242
4412
  if (this._whenQuietFns.length) {
4413
+ // we move these over to a variable so that
4414
+ // if any new callbacks are registered in another
4415
+ // flush they do not populate the existing set
4243
4416
  /** @type {?} */
4244
4417
  const quietFns = this._whenQuietFns;
4245
4418
  this._whenQuietFns = [];
@@ -4294,6 +4467,9 @@ class TransitionAnimationEngine {
4294
4467
  const allTriggerElements = Array.from(this.statesByElement.keys());
4295
4468
  /** @type {?} */
4296
4469
  const enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements);
4470
+ // this must occur before the instructions are built below such that
4471
+ // the :enter queries match the elements (since the timeline queries
4472
+ // are fired during instruction building).
4297
4473
  /** @type {?} */
4298
4474
  const enterNodeMapIds = new Map();
4299
4475
  /** @type {?} */
@@ -4314,7 +4490,7 @@ class TransitionAnimationEngine {
4314
4490
  /** @type {?} */
4315
4491
  const element = this.collectedLeaveElements[i];
4316
4492
  /** @type {?} */
4317
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4493
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4318
4494
  if (details && details.setForRemoval) {
4319
4495
  allLeaveNodes.push(element);
4320
4496
  mergedLeaveNodes.add(element);
@@ -4339,12 +4515,12 @@ class TransitionAnimationEngine {
4339
4515
  cleanupFns.push(() => {
4340
4516
  enterNodeMap.forEach((nodes, root) => {
4341
4517
  /** @type {?} */
4342
- const className = /** @type {?} */ ((enterNodeMapIds.get(root)));
4518
+ const className = (/** @type {?} */ (enterNodeMapIds.get(root)));
4343
4519
  nodes.forEach(node => removeClass(node, className));
4344
4520
  });
4345
4521
  leaveNodeMap.forEach((nodes, root) => {
4346
4522
  /** @type {?} */
4347
- const className = /** @type {?} */ ((leaveNodeMapIds.get(root)));
4523
+ const className = (/** @type {?} */ (leaveNodeMapIds.get(root)));
4348
4524
  nodes.forEach(node => removeClass(node, className));
4349
4525
  });
4350
4526
  allLeaveNodes.forEach(element => { this.processLeaveNode(element); });
@@ -4364,7 +4540,7 @@ class TransitionAnimationEngine {
4364
4540
  allPlayers.push(player);
4365
4541
  if (this.collectedEnterElements.length) {
4366
4542
  /** @type {?} */
4367
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4543
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4368
4544
  // move animations are currently not supported...
4369
4545
  if (details && details.setForMove) {
4370
4546
  player.destroy();
@@ -4374,11 +4550,11 @@ class TransitionAnimationEngine {
4374
4550
  /** @type {?} */
4375
4551
  const nodeIsOrphaned = !bodyNode || !this.driver.containsElement(bodyNode, element);
4376
4552
  /** @type {?} */
4377
- const leaveClassName = /** @type {?} */ ((leaveNodeMapIds.get(element)));
4553
+ const leaveClassName = (/** @type {?} */ (leaveNodeMapIds.get(element)));
4378
4554
  /** @type {?} */
4379
- const enterClassName = /** @type {?} */ ((enterNodeMapIds.get(element)));
4555
+ const enterClassName = (/** @type {?} */ (enterNodeMapIds.get(element)));
4380
4556
  /** @type {?} */
4381
- const instruction = /** @type {?} */ ((this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned)));
4557
+ const instruction = (/** @type {?} */ (this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned)));
4382
4558
  if (instruction.errors && instruction.errors.length) {
4383
4559
  erroneousTransitions.push(instruction);
4384
4560
  return;
@@ -4417,7 +4593,7 @@ class TransitionAnimationEngine {
4417
4593
  const props = Object.keys(stringMap);
4418
4594
  if (props.length) {
4419
4595
  /** @type {?} */
4420
- let setVal = /** @type {?} */ ((allPreStyleElements.get(element)));
4596
+ let setVal = (/** @type {?} */ (allPreStyleElements.get(element)));
4421
4597
  if (!setVal) {
4422
4598
  allPreStyleElements.set(element, setVal = new Set());
4423
4599
  }
@@ -4428,7 +4604,7 @@ class TransitionAnimationEngine {
4428
4604
  /** @type {?} */
4429
4605
  const props = Object.keys(stringMap);
4430
4606
  /** @type {?} */
4431
- let setVal = /** @type {?} */ ((allPostStyleElements.get(element)));
4607
+ let setVal = (/** @type {?} */ (allPostStyleElements.get(element)));
4432
4608
  if (!setVal) {
4433
4609
  allPostStyleElements.set(element, setVal = new Set());
4434
4610
  }
@@ -4440,14 +4616,18 @@ class TransitionAnimationEngine {
4440
4616
  /** @type {?} */
4441
4617
  const errors = [];
4442
4618
  erroneousTransitions.forEach(instruction => {
4443
- errors.push(`@${instruction.triggerName} has failed due to:\n`); /** @type {?} */
4444
- ((instruction.errors)).forEach(error => errors.push(`- ${error}\n`));
4619
+ errors.push(`@${instruction.triggerName} has failed due to:\n`);
4620
+ (/** @type {?} */ (instruction.errors)).forEach(error => errors.push(`- ${error}\n`));
4445
4621
  });
4446
4622
  allPlayers.forEach(player => player.destroy());
4447
4623
  this.reportError(errors);
4448
4624
  }
4449
4625
  /** @type {?} */
4450
4626
  const allPreviousPlayersMap = new Map();
4627
+ // this map works to tell which element in the DOM tree is contained by
4628
+ // which animation. Further down below this map will get populated once
4629
+ // the players are built and in doing so it can efficiently figure out
4630
+ // if a sub player is skipped due to a parent player having priority.
4451
4631
  /** @type {?} */
4452
4632
  const animationElementMap = new Map();
4453
4633
  queuedInstructions.forEach(entry => {
@@ -4468,10 +4648,18 @@ class TransitionAnimationEngine {
4468
4648
  prevPlayer.destroy();
4469
4649
  });
4470
4650
  });
4651
+ // this is a special case for nodes that will be removed (either by)
4652
+ // having their own leave animations or by being queried in a container
4653
+ // that will be removed once a parent animation is complete. The idea
4654
+ // here is that * styles must be identical to ! styles because of
4655
+ // backwards compatibility (* is also filled in by default in many places).
4656
+ // Otherwise * styles will return an empty value or auto since the element
4657
+ // that is being getComputedStyle'd will not be visible (since * = destination)
4471
4658
  /** @type {?} */
4472
4659
  const replaceNodes = allLeaveNodes.filter(node => {
4473
4660
  return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
4474
4661
  });
4662
+ // POST STAGE: fill the * styles
4475
4663
  /** @type {?} */
4476
4664
  const postStylesMap = new Map();
4477
4665
  /** @type {?} */
@@ -4481,6 +4669,7 @@ class TransitionAnimationEngine {
4481
4669
  replaceNodes.push(node);
4482
4670
  }
4483
4671
  });
4672
+ // PRE STAGE: fill the ! styles
4484
4673
  /** @type {?} */
4485
4674
  const preStylesMap = new Map();
4486
4675
  enterNodeMap.forEach((nodes, root) => {
@@ -4491,7 +4680,7 @@ class TransitionAnimationEngine {
4491
4680
  const post = postStylesMap.get(node);
4492
4681
  /** @type {?} */
4493
4682
  const pre = preStylesMap.get(node);
4494
- postStylesMap.set(node, /** @type {?} */ (Object.assign({}, post, pre)));
4683
+ postStylesMap.set(node, (/** @type {?} */ (Object.assign({}, post, pre))));
4495
4684
  });
4496
4685
  /** @type {?} */
4497
4686
  const rootPlayers = [];
@@ -4511,6 +4700,12 @@ class TransitionAnimationEngine {
4511
4700
  skippedPlayers.push(player);
4512
4701
  return;
4513
4702
  }
4703
+ // this will flow up the DOM and query the map to figure out
4704
+ // if a parent animation has priority over it. In the situation
4705
+ // that a parent is detected then it will cancel the loop. If
4706
+ // nothing is detected, or it takes a few hops to find a parent,
4707
+ // then it will fill in the missing nodes and signal them as having
4708
+ // a detected parent (or a NO_PARENT value via a special constant).
4514
4709
  /** @type {?} */
4515
4710
  let parentWithAnimation = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
4516
4711
  if (animationElementMap.size > 1) {
@@ -4558,6 +4753,8 @@ class TransitionAnimationEngine {
4558
4753
  });
4559
4754
  // find all of the sub players' corresponding inner animation player
4560
4755
  subPlayers.forEach(player => {
4756
+ // even if any players are not found for a sub animation then it
4757
+ // will still complete itself after the next tick since it's Noop
4561
4758
  /** @type {?} */
4562
4759
  const playersForElement = skippedPlayersMap.get(player.element);
4563
4760
  if (playersForElement && playersForElement.length) {
@@ -4584,7 +4781,7 @@ class TransitionAnimationEngine {
4584
4781
  /** @type {?} */
4585
4782
  const element = allLeaveNodes[i];
4586
4783
  /** @type {?} */
4587
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4784
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4588
4785
  removeClass(element, LEAVE_CLASSNAME);
4589
4786
  // this means the element has a removal animation that is being
4590
4787
  // taken care of and therefore the inner elements will hang around
@@ -4644,7 +4841,7 @@ class TransitionAnimationEngine {
4644
4841
  /** @type {?} */
4645
4842
  let containsData = false;
4646
4843
  /** @type {?} */
4647
- const details = /** @type {?} */ (element[REMOVAL_FLAG]);
4844
+ const details = (/** @type {?} */ (element[REMOVAL_FLAG]));
4648
4845
  if (details && details.setForRemoval)
4649
4846
  containsData = true;
4650
4847
  if (this.playersByElement.has(element))
@@ -4720,6 +4917,8 @@ class TransitionAnimationEngine {
4720
4917
  const triggerName = instruction.triggerName;
4721
4918
  /** @type {?} */
4722
4919
  const rootElement = instruction.element;
4920
+ // when a removal animation occurs, ALL previous players are collected
4921
+ // and destroyed (even if they are outside of the current namespace)
4723
4922
  /** @type {?} */
4724
4923
  const targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
4725
4924
  /** @type {?} */
@@ -4735,7 +4934,7 @@ class TransitionAnimationEngine {
4735
4934
  const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
4736
4935
  previousPlayers.forEach(player => {
4737
4936
  /** @type {?} */
4738
- const realPlayer = /** @type {?} */ (player.getRealPlayer());
4937
+ const realPlayer = (/** @type {?} */ (player.getRealPlayer()));
4739
4938
  if (realPlayer.beforeDestroy) {
4740
4939
  realPlayer.beforeDestroy();
4741
4940
  }
@@ -4761,6 +4960,8 @@ class TransitionAnimationEngine {
4761
4960
  const triggerName = instruction.triggerName;
4762
4961
  /** @type {?} */
4763
4962
  const rootElement = instruction.element;
4963
+ // we first run this so that the previous animation player
4964
+ // data can be passed into the successive animation players
4764
4965
  /** @type {?} */
4765
4966
  const allQueriedPlayers = [];
4766
4967
  /** @type {?} */
@@ -4772,6 +4973,7 @@ class TransitionAnimationEngine {
4772
4973
  /** @type {?} */
4773
4974
  const element = timelineInstruction.element;
4774
4975
  allConsumedElements.add(element);
4976
+ // FIXME (matsko): make sure to-be-removed animations are removed properly
4775
4977
  /** @type {?} */
4776
4978
  const details = element[REMOVAL_FLAG];
4777
4979
  if (details && details.removedBeforeQueried)
@@ -4782,8 +4984,12 @@ class TransitionAnimationEngine {
4782
4984
  const previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY)
4783
4985
  .map(p => p.getRealPlayer()))
4784
4986
  .filter(p => {
4987
+ // the `element` is not apart of the AnimationPlayer definition, but
4988
+ // Mock/WebAnimations
4989
+ // use the element within their implementation. This will be added in Angular5 to
4990
+ // AnimationPlayer
4785
4991
  /** @type {?} */
4786
- const pp = /** @type {?} */ (p);
4992
+ const pp = (/** @type {?} */ (p));
4787
4993
  return pp.element ? pp.element === element : false;
4788
4994
  });
4789
4995
  /** @type {?} */
@@ -4871,7 +5077,7 @@ class TransitionAnimationPlayer {
4871
5077
  this._queuedCallbacks = {};
4872
5078
  this._containsRealPlayer = true;
4873
5079
  this.overrideTotalTime(player.totalTime);
4874
- (/** @type {?} */ (this)).queued = false;
5080
+ ((/** @type {?} */ (this))).queued = false;
4875
5081
  }
4876
5082
  /**
4877
5083
  * @return {?}
@@ -4881,16 +5087,16 @@ class TransitionAnimationPlayer {
4881
5087
  * @param {?} totalTime
4882
5088
  * @return {?}
4883
5089
  */
4884
- overrideTotalTime(totalTime) { (/** @type {?} */ (this)).totalTime = totalTime; }
5090
+ overrideTotalTime(totalTime) { ((/** @type {?} */ (this))).totalTime = totalTime; }
4885
5091
  /**
4886
5092
  * @param {?} player
4887
5093
  * @return {?}
4888
5094
  */
4889
5095
  syncPlayerEvents(player) {
4890
5096
  /** @type {?} */
4891
- const p = /** @type {?} */ (this._player);
5097
+ const p = (/** @type {?} */ (this._player));
4892
5098
  if (p.triggerCallback) {
4893
- player.onStart(() => /** @type {?} */ ((p.triggerCallback))('start'));
5099
+ player.onStart(() => (/** @type {?} */ (p.triggerCallback))('start'));
4894
5100
  }
4895
5101
  player.onDone(() => this.finish());
4896
5102
  player.onDestroy(() => this.destroy());
@@ -4961,7 +5167,7 @@ class TransitionAnimationPlayer {
4961
5167
  * @return {?}
4962
5168
  */
4963
5169
  destroy() {
4964
- (/** @type {?} */ (this)).destroyed = true;
5170
+ ((/** @type {?} */ (this))).destroyed = true;
4965
5171
  this._player.destroy();
4966
5172
  }
4967
5173
  /**
@@ -4988,7 +5194,7 @@ class TransitionAnimationPlayer {
4988
5194
  */
4989
5195
  triggerCallback(phaseName) {
4990
5196
  /** @type {?} */
4991
- const p = /** @type {?} */ (this._player);
5197
+ const p = (/** @type {?} */ (this._player));
4992
5198
  if (p.triggerCallback) {
4993
5199
  p.triggerCallback(phaseName);
4994
5200
  }
@@ -5095,11 +5301,23 @@ function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, def
5095
5301
  });
5096
5302
  valuesMap.set(element, styles);
5097
5303
  });
5304
+ // we use a index variable here since Set.forEach(a, i) does not return
5305
+ // an index value for the closure (but instead just the value)
5098
5306
  /** @type {?} */
5099
5307
  let i = 0;
5100
5308
  elements.forEach(element => cloakElement(element, cloakVals[i++]));
5101
5309
  return failedElements;
5102
5310
  }
5311
+ /*
5312
+ Since the Angular renderer code will return a collection of inserted
5313
+ nodes in all areas of a DOM tree, it's up to this algorithm to figure
5314
+ out which nodes are roots for each animation @trigger.
5315
+
5316
+ By placing each inserted node into a Set and traversing upwards, it
5317
+ is possible to find the @trigger elements and well any direct *star
5318
+ insertion nodes, if a @trigger root is found then the enter element
5319
+ is placed into the Map[@trigger] spot.
5320
+ */
5103
5321
  /**
5104
5322
  * @param {?} roots
5105
5323
  * @param {?} nodes
@@ -5131,15 +5349,12 @@ function buildRootMap(roots, nodes) {
5131
5349
  /** @type {?} */
5132
5350
  const parent = node.parentNode;
5133
5351
  if (rootMap.has(parent)) { // ngIf inside @trigger
5134
- // ngIf inside @trigger
5135
5352
  root = parent;
5136
5353
  }
5137
5354
  else if (nodeSet.has(parent)) { // ngIf inside ngIf
5138
- // ngIf inside ngIf
5139
5355
  root = NULL_NODE;
5140
5356
  }
5141
5357
  else { // recurse upwards
5142
- // recurse upwards
5143
5358
  root = getRoot(parent);
5144
5359
  }
5145
5360
  localRootMap.set(node, root);
@@ -5149,7 +5364,7 @@ function buildRootMap(roots, nodes) {
5149
5364
  /** @type {?} */
5150
5365
  const root = getRoot(node);
5151
5366
  if (root !== NULL_NODE) {
5152
- /** @type {?} */ ((rootMap.get(root))).push(node);
5367
+ (/** @type {?} */ (rootMap.get(root))).push(node);
5153
5368
  }
5154
5369
  });
5155
5370
  return rootMap;
@@ -5223,7 +5438,7 @@ function _flattenGroupPlayersRecur(players, finalPlayers) {
5223
5438
  _flattenGroupPlayersRecur(player.players, finalPlayers);
5224
5439
  }
5225
5440
  else {
5226
- finalPlayers.push(/** @type {?} */ (player));
5441
+ finalPlayers.push((/** @type {?} */ (player)));
5227
5442
  }
5228
5443
  }
5229
5444
  }
@@ -5261,7 +5476,7 @@ function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElemen
5261
5476
  /** @type {?} */
5262
5477
  let preEntry = allPreStyleElements.get(element);
5263
5478
  if (preEntry) {
5264
- postEntry.forEach(data => /** @type {?} */ ((preEntry)).add(data));
5479
+ postEntry.forEach(data => (/** @type {?} */ (preEntry)).add(data));
5265
5480
  }
5266
5481
  else {
5267
5482
  allPreStyleElements.set(element, postEntry);
@@ -5272,7 +5487,7 @@ function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElemen
5272
5487
 
5273
5488
  /**
5274
5489
  * @fileoverview added by tsickle
5275
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
5490
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
5276
5491
  */
5277
5492
  class AnimationEngine {
5278
5493
  /**
@@ -5284,6 +5499,7 @@ class AnimationEngine {
5284
5499
  this.bodyNode = bodyNode;
5285
5500
  this._driver = _driver;
5286
5501
  this._triggerCache = {};
5502
+ // this method is designed to be overridden by the code that uses this engine
5287
5503
  this.onRemovalComplete = (element, context) => { };
5288
5504
  this._transitionEngine = new TransitionAnimationEngine(bodyNode, _driver, normalizer);
5289
5505
  this._timelineEngine = new TimelineAnimationEngine(bodyNode, _driver, normalizer);
@@ -5306,7 +5522,7 @@ class AnimationEngine {
5306
5522
  /** @type {?} */
5307
5523
  const errors = [];
5308
5524
  /** @type {?} */
5309
- const ast = /** @type {?} */ (buildAnimationAst(this._driver, /** @type {?} */ (metadata), errors));
5525
+ const ast = (/** @type {?} */ (buildAnimationAst(this._driver, (/** @type {?} */ (metadata)), errors)));
5310
5526
  if (errors.length) {
5311
5527
  throw new Error(`The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.join("\n - ")}`);
5312
5528
  }
@@ -5369,7 +5585,7 @@ class AnimationEngine {
5369
5585
  if (property.charAt(0) == '@') {
5370
5586
  const [id, action] = parseTimelineCommand(property);
5371
5587
  /** @type {?} */
5372
- const args = /** @type {?} */ (value);
5588
+ const args = (/** @type {?} */ (value));
5373
5589
  this._timelineEngine.command(id, element, action, args);
5374
5590
  }
5375
5591
  else {
@@ -5401,8 +5617,8 @@ class AnimationEngine {
5401
5617
  * @return {?}
5402
5618
  */
5403
5619
  get players() {
5404
- return (/** @type {?} */ (this._transitionEngine.players))
5405
- .concat(/** @type {?} */ (this._timelineEngine.players));
5620
+ return ((/** @type {?} */ (this._transitionEngine.players)))
5621
+ .concat((/** @type {?} */ (this._timelineEngine.players)));
5406
5622
  }
5407
5623
  /**
5408
5624
  * @return {?}
@@ -5412,15 +5628,16 @@ class AnimationEngine {
5412
5628
 
5413
5629
  /**
5414
5630
  * @fileoverview added by tsickle
5415
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
5631
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
5416
5632
  */
5417
- /** *
5633
+ /**
5418
5634
  * @license
5419
5635
  * Copyright Google Inc. All Rights Reserved.
5420
5636
  *
5421
5637
  * Use of this source code is governed by an MIT-style license that can be
5422
5638
  * found in the LICENSE file at https://angular.io/license
5423
- @type {?} */
5639
+ * @type {?}
5640
+ */
5424
5641
  const ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
5425
5642
  /** @type {?} */
5426
5643
  const ANIMATION_PROP = 'animation';
@@ -5651,7 +5868,7 @@ function countChars(value, char) {
5651
5868
 
5652
5869
  /**
5653
5870
  * @fileoverview added by tsickle
5654
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
5871
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
5655
5872
  */
5656
5873
  /** @type {?} */
5657
5874
  const DEFAULT_FILL_MODE = 'forwards';
@@ -5838,7 +6055,7 @@ class CssKeyframesPlayer {
5838
6055
 
5839
6056
  /**
5840
6057
  * @fileoverview added by tsickle
5841
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6058
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
5842
6059
  */
5843
6060
  class DirectStylePlayer extends NoopAnimationPlayer {
5844
6061
  /**
@@ -5860,7 +6077,7 @@ class DirectStylePlayer extends NoopAnimationPlayer {
5860
6077
  return;
5861
6078
  this.__initialized = true;
5862
6079
  Object.keys(this._styles).forEach(prop => {
5863
- /** @type {?} */ ((this._startingStyles))[prop] = this.element.style[prop];
6080
+ (/** @type {?} */ (this._startingStyles))[prop] = this.element.style[prop];
5864
6081
  });
5865
6082
  super.init();
5866
6083
  }
@@ -5883,7 +6100,7 @@ class DirectStylePlayer extends NoopAnimationPlayer {
5883
6100
  return;
5884
6101
  Object.keys(this._startingStyles).forEach(prop => {
5885
6102
  /** @type {?} */
5886
- const value = /** @type {?} */ ((this._startingStyles))[prop];
6103
+ const value = (/** @type {?} */ (this._startingStyles))[prop];
5887
6104
  if (value) {
5888
6105
  this.element.style.setProperty(prop, value);
5889
6106
  }
@@ -5898,7 +6115,7 @@ class DirectStylePlayer extends NoopAnimationPlayer {
5898
6115
 
5899
6116
  /**
5900
6117
  * @fileoverview added by tsickle
5901
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6118
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
5902
6119
  */
5903
6120
  /** @type {?} */
5904
6121
  const KEYFRAMES_NAME_PREFIX = 'gen_css_kf_';
@@ -5945,7 +6162,7 @@ class CssKeyframesDriver {
5945
6162
  * @return {?}
5946
6163
  */
5947
6164
  computeStyle(element, prop, defaultValue) {
5948
- return /** @type {?} */ ((/** @type {?} */ (window.getComputedStyle(element)))[prop]);
6165
+ return (/** @type {?} */ (((/** @type {?} */ (window.getComputedStyle(element))))[prop]));
5949
6166
  }
5950
6167
  /**
5951
6168
  * @param {?} element
@@ -5962,7 +6179,7 @@ class CssKeyframesDriver {
5962
6179
  keyframes.forEach(kf => {
5963
6180
  tab = TAB_SPACE;
5964
6181
  /** @type {?} */
5965
- const offset = parseFloat(kf["offset"]);
6182
+ const offset = parseFloat(kf.offset);
5966
6183
  keyframeStr += `${tab}${offset * 100}% {\n`;
5967
6184
  tab += TAB_SPACE;
5968
6185
  Object.keys(kf).forEach(prop => {
@@ -6004,7 +6221,7 @@ class CssKeyframesDriver {
6004
6221
  this._notifyFaultyScrubber();
6005
6222
  }
6006
6223
  /** @type {?} */
6007
- const previousCssKeyframePlayers = /** @type {?} */ (previousPlayers.filter(player => player instanceof CssKeyframesPlayer));
6224
+ const previousCssKeyframePlayers = (/** @type {?} */ (previousPlayers.filter(player => player instanceof CssKeyframesPlayer)));
6008
6225
  /** @type {?} */
6009
6226
  const previousStyles = {};
6010
6227
  if (allowPreviousPlayerStylesMerge(duration, delay)) {
@@ -6027,8 +6244,8 @@ class CssKeyframesDriver {
6027
6244
  /** @type {?} */
6028
6245
  const animationName = `${KEYFRAMES_NAME_PREFIX}${this._count++}`;
6029
6246
  /** @type {?} */
6030
- const kfElm = this.buildKeyframeElement(element, animationName, keyframes); /** @type {?} */
6031
- ((document.querySelector('head'))).appendChild(kfElm);
6247
+ const kfElm = this.buildKeyframeElement(element, animationName, keyframes);
6248
+ (/** @type {?} */ (document.querySelector('head'))).appendChild(kfElm);
6032
6249
  /** @type {?} */
6033
6250
  const player = new CssKeyframesPlayer(element, keyframes, animationName, duration, delay, easing, finalStyles);
6034
6251
  player.onDestroy(() => removeElement(kfElm));
@@ -6074,7 +6291,7 @@ function removeElement(node) {
6074
6291
 
6075
6292
  /**
6076
6293
  * @fileoverview added by tsickle
6077
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6294
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6078
6295
  */
6079
6296
  class WebAnimationsPlayer {
6080
6297
  /**
@@ -6096,8 +6313,8 @@ class WebAnimationsPlayer {
6096
6313
  this.time = 0;
6097
6314
  this.parentPlayer = null;
6098
6315
  this.currentSnapshot = {};
6099
- this._duration = /** @type {?} */ (options['duration']);
6100
- this._delay = /** @type {?} */ (options['delay']) || 0;
6316
+ this._duration = (/** @type {?} */ (options['duration']));
6317
+ this._delay = (/** @type {?} */ (options['delay'])) || 0;
6101
6318
  this.time = this._duration + this._delay;
6102
6319
  }
6103
6320
  /**
@@ -6126,7 +6343,7 @@ class WebAnimationsPlayer {
6126
6343
  this._initialized = true;
6127
6344
  /** @type {?} */
6128
6345
  const keyframes = this.keyframes;
6129
- (/** @type {?} */ (this)).domPlayer =
6346
+ ((/** @type {?} */ (this))).domPlayer =
6130
6347
  this._triggerWebAnimation(this.element, keyframes, this.options);
6131
6348
  this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
6132
6349
  this.domPlayer.addEventListener('finish', () => this._onFinish());
@@ -6153,7 +6370,7 @@ class WebAnimationsPlayer {
6153
6370
  _triggerWebAnimation(element, keyframes, options) {
6154
6371
  // jscompiler doesn't seem to know animate is a native property because it's not fully
6155
6372
  // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
6156
- return /** @type {?} */ (element['animate'](keyframes, options));
6373
+ return (/** @type {?} */ (element['animate'](keyframes, options)));
6157
6374
  }
6158
6375
  /**
6159
6376
  * @param {?} fn
@@ -6281,7 +6498,7 @@ class WebAnimationsPlayer {
6281
6498
 
6282
6499
  /**
6283
6500
  * @fileoverview added by tsickle
6284
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6501
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6285
6502
  */
6286
6503
  class WebAnimationsDriver {
6287
6504
  constructor() {
@@ -6323,7 +6540,7 @@ class WebAnimationsDriver {
6323
6540
  * @return {?}
6324
6541
  */
6325
6542
  computeStyle(element, prop, defaultValue) {
6326
- return /** @type {?} */ ((/** @type {?} */ (window.getComputedStyle(element)))[prop]);
6543
+ return (/** @type {?} */ (((/** @type {?} */ (window.getComputedStyle(element))))[prop]));
6327
6544
  }
6328
6545
  /**
6329
6546
  * @param {?} supported
@@ -6358,7 +6575,7 @@ class WebAnimationsDriver {
6358
6575
  /** @type {?} */
6359
6576
  const previousStyles = {};
6360
6577
  /** @type {?} */
6361
- const previousWebAnimationPlayers = /** @type {?} */ (previousPlayers.filter(player => player instanceof WebAnimationsPlayer));
6578
+ const previousWebAnimationPlayers = (/** @type {?} */ (previousPlayers.filter(player => player instanceof WebAnimationsPlayer)));
6362
6579
  if (allowPreviousPlayerStylesMerge(duration, delay)) {
6363
6580
  previousWebAnimationPlayers.forEach(player => {
6364
6581
  /** @type {?} */
@@ -6381,27 +6598,27 @@ function supportsWebAnimations() {
6381
6598
  * @return {?}
6382
6599
  */
6383
6600
  function getElementAnimateFn() {
6384
- return (isBrowser() && (/** @type {?} */ (Element)).prototype['animate']) || {};
6601
+ return (isBrowser() && ((/** @type {?} */ (Element))).prototype['animate']) || {};
6385
6602
  }
6386
6603
 
6387
6604
  /**
6388
6605
  * @fileoverview added by tsickle
6389
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6606
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6390
6607
  */
6391
6608
 
6392
6609
  /**
6393
6610
  * @fileoverview added by tsickle
6394
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6611
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6395
6612
  */
6396
6613
 
6397
6614
  /**
6398
6615
  * @fileoverview added by tsickle
6399
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6616
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6400
6617
  */
6401
6618
 
6402
6619
  /**
6403
6620
  * @fileoverview added by tsickle
6404
- * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
6621
+ * @suppress {checkTypes,extraRequire,missingReturn,uselessCode} checked by tsc
6405
6622
  */
6406
6623
 
6407
6624
  /**