@angular/animations 13.2.3 → 14.0.0-next.3

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 (39) hide show
  1. package/animations.d.ts +7 -2
  2. package/browser/browser.d.ts +27 -27
  3. package/browser/testing/testing.d.ts +9 -15
  4. package/esm2020/browser/src/dsl/animation.mjs +1 -1
  5. package/esm2020/browser/src/dsl/animation_ast.mjs +1 -1
  6. package/esm2020/browser/src/dsl/animation_ast_builder.mjs +40 -49
  7. package/esm2020/browser/src/dsl/animation_dsl_visitor.mjs +1 -1
  8. package/esm2020/browser/src/dsl/animation_timeline_builder.mjs +77 -87
  9. package/esm2020/browser/src/dsl/animation_timeline_instruction.mjs +1 -1
  10. package/esm2020/browser/src/dsl/animation_transition_factory.mjs +20 -18
  11. package/esm2020/browser/src/dsl/animation_transition_instruction.mjs +8 -1
  12. package/esm2020/browser/src/dsl/animation_trigger.mjs +9 -9
  13. package/esm2020/browser/src/dsl/style_normalization/web_animations_style_normalizer.mjs +33 -9
  14. package/esm2020/browser/src/private_export.mjs +3 -3
  15. package/esm2020/browser/src/render/animation_driver.mjs +8 -5
  16. package/esm2020/browser/src/render/shared.mjs +31 -29
  17. package/esm2020/browser/src/render/special_cased_styles.mjs +7 -16
  18. package/esm2020/browser/src/render/timeline_animation_engine.mjs +15 -15
  19. package/esm2020/browser/src/render/transition_animation_engine.mjs +92 -83
  20. package/esm2020/browser/src/render/web_animations/web_animations_driver.mjs +12 -10
  21. package/esm2020/browser/src/render/web_animations/web_animations_player.mjs +16 -9
  22. package/esm2020/browser/src/util.mjs +38 -28
  23. package/esm2020/browser/testing/src/mock_animation_driver.mjs +17 -14
  24. package/esm2020/src/animation_metadata.mjs +1 -1
  25. package/esm2020/src/animations.mjs +1 -1
  26. package/esm2020/src/version.mjs +1 -1
  27. package/fesm2015/animations.mjs +1 -1
  28. package/fesm2015/animations.mjs.map +1 -1
  29. package/fesm2015/browser/testing.mjs +17 -14
  30. package/fesm2015/browser/testing.mjs.map +1 -1
  31. package/fesm2015/browser.mjs +389 -349
  32. package/fesm2015/browser.mjs.map +1 -1
  33. package/fesm2020/animations.mjs +1 -1
  34. package/fesm2020/animations.mjs.map +1 -1
  35. package/fesm2020/browser/testing.mjs +17 -14
  36. package/fesm2020/browser/testing.mjs.map +1 -1
  37. package/fesm2020/browser.mjs +387 -349
  38. package/fesm2020/browser.mjs.map +1 -1
  39. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license Angular v13.2.3
2
+ * @license Angular v14.0.0-next.3
3
3
  * (c) 2010-2022 Google LLC. https://angular.io/
4
4
  * License: MIT
5
5
  */
@@ -170,26 +170,26 @@ function optimizeGroupPlayer(players) {
170
170
  return new ɵAnimationGroupPlayer(players);
171
171
  }
172
172
  }
173
- function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles = {}, postStyles = {}) {
173
+ function normalizeKeyframes$1(driver, normalizer, element, keyframes, preStyles = new Map(), postStyles = new Map()) {
174
174
  const errors = [];
175
175
  const normalizedKeyframes = [];
176
176
  let previousOffset = -1;
177
177
  let previousKeyframe = null;
178
178
  keyframes.forEach(kf => {
179
- const offset = kf['offset'];
179
+ const offset = kf.get('offset');
180
180
  const isSameOffset = offset == previousOffset;
181
- const normalizedKeyframe = (isSameOffset && previousKeyframe) || {};
182
- Object.keys(kf).forEach(prop => {
181
+ const normalizedKeyframe = (isSameOffset && previousKeyframe) || new Map();
182
+ kf.forEach((val, prop) => {
183
183
  let normalizedProp = prop;
184
- let normalizedValue = kf[prop];
184
+ let normalizedValue = val;
185
185
  if (prop !== 'offset') {
186
186
  normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
187
187
  switch (normalizedValue) {
188
188
  case ɵPRE_STYLE:
189
- normalizedValue = preStyles[prop];
189
+ normalizedValue = preStyles.get(prop);
190
190
  break;
191
191
  case AUTO_STYLE:
192
- normalizedValue = postStyles[prop];
192
+ normalizedValue = postStyles.get(prop);
193
193
  break;
194
194
  default:
195
195
  normalizedValue =
@@ -197,7 +197,7 @@ function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
197
197
  break;
198
198
  }
199
199
  }
200
- normalizedKeyframe[normalizedProp] = normalizedValue;
200
+ normalizedKeyframe.set(normalizedProp, normalizedValue);
201
201
  });
202
202
  if (!isSameOffset) {
203
203
  normalizedKeyframes.push(normalizedKeyframe);
@@ -236,19 +236,10 @@ function copyAnimationEvent(e, phaseName, player) {
236
236
  function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {
237
237
  return { element, triggerName, fromState, toState, phaseName, totalTime, disabled: !!disabled };
238
238
  }
239
- function getOrSetAsInMap(map, key, defaultValue) {
240
- let value;
241
- if (map instanceof Map) {
242
- value = map.get(key);
243
- if (!value) {
244
- map.set(key, value = defaultValue);
245
- }
246
- }
247
- else {
248
- value = map[key];
249
- if (!value) {
250
- value = map[key] = defaultValue;
251
- }
239
+ function getOrSetDefaultValue(map, key, defaultValue) {
240
+ let value = map.get(key);
241
+ if (!value) {
242
+ map.set(key, value = defaultValue);
252
243
  }
253
244
  return value;
254
245
  }
@@ -262,6 +253,14 @@ let _contains = (elm1, elm2) => false;
262
253
  let _query = (element, selector, multi) => {
263
254
  return [];
264
255
  };
256
+ let _documentElement = null;
257
+ function getParentElement(element) {
258
+ const parent = element.parentNode || element.host; // consider host to support shadow DOM
259
+ if (parent === _documentElement) {
260
+ return null;
261
+ }
262
+ return parent;
263
+ }
265
264
  // Define utility methods for browsers and platform-server(domino) where Element
266
265
  // and utility methods exist.
267
266
  const _isNode = isNode();
@@ -270,12 +269,15 @@ if (_isNode || typeof Element !== 'undefined') {
270
269
  _contains = (elm1, elm2) => elm1.contains(elm2);
271
270
  }
272
271
  else {
272
+ // Read the document element in an IIFE that's been marked pure to avoid a top-level property
273
+ // read that may prevent tree-shaking.
274
+ _documentElement = /* @__PURE__ */ (() => document.documentElement)();
273
275
  _contains = (elm1, elm2) => {
274
- while (elm2 && elm2 !== document.documentElement) {
276
+ while (elm2) {
275
277
  if (elm2 === elm1) {
276
278
  return true;
277
279
  }
278
- elm2 = elm2.parentNode || elm2.host; // consider host to support shadow DOM
280
+ elm2 = getParentElement(elm2);
279
281
  }
280
282
  return false;
281
283
  };
@@ -318,13 +320,13 @@ function getBodyNode() {
318
320
  }
319
321
  const containsElement = _contains;
320
322
  const invokeQuery = _query;
321
- function hypenatePropsObject(object) {
322
- const newObj = {};
323
- Object.keys(object).forEach(prop => {
323
+ function hypenatePropsKeys(original) {
324
+ const newMap = new Map();
325
+ original.forEach((val, prop) => {
324
326
  const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
325
- newObj[newProp] = object[prop];
327
+ newMap.set(newProp, val);
326
328
  });
327
- return newObj;
329
+ return newMap;
328
330
  }
329
331
 
330
332
  /**
@@ -348,6 +350,9 @@ class NoopAnimationDriver {
348
350
  containsElement(elm1, elm2) {
349
351
  return containsElement(elm1, elm2);
350
352
  }
353
+ getParentElement(element) {
354
+ return getParentElement(element);
355
+ }
351
356
  query(element, selector, multi) {
352
357
  return invokeQuery(element, selector, multi);
353
358
  }
@@ -358,9 +363,9 @@ class NoopAnimationDriver {
358
363
  return new NoopAnimationPlayer(duration, delay);
359
364
  }
360
365
  }
361
- NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
362
- NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: NoopAnimationDriver });
363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.3", ngImport: i0, type: NoopAnimationDriver, decorators: [{
366
+ NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.3", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
367
+ NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.3", ngImport: i0, type: NoopAnimationDriver });
368
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.3", ngImport: i0, type: NoopAnimationDriver, decorators: [{
364
369
  type: Injectable
365
370
  }] });
366
371
  /**
@@ -454,27 +459,41 @@ function copyObj(obj, destination = {}) {
454
459
  });
455
460
  return destination;
456
461
  }
462
+ function convertToMap(obj) {
463
+ const styleMap = new Map();
464
+ Object.keys(obj).forEach(prop => {
465
+ const val = obj[prop];
466
+ styleMap.set(prop, val);
467
+ });
468
+ return styleMap;
469
+ }
470
+ function normalizeKeyframes(keyframes) {
471
+ if (!keyframes.length) {
472
+ return [];
473
+ }
474
+ if (keyframes[0] instanceof Map) {
475
+ return keyframes;
476
+ }
477
+ return keyframes.map(kf => convertToMap(kf));
478
+ }
457
479
  function normalizeStyles(styles) {
458
- const normalizedStyles = {};
480
+ const normalizedStyles = new Map();
459
481
  if (Array.isArray(styles)) {
460
- styles.forEach(data => copyStyles(data, false, normalizedStyles));
482
+ styles.forEach(data => copyStyles(data, normalizedStyles));
461
483
  }
462
484
  else {
463
- copyStyles(styles, false, normalizedStyles);
485
+ copyStyles(styles, normalizedStyles);
464
486
  }
465
487
  return normalizedStyles;
466
488
  }
467
- function copyStyles(styles, readPrototype, destination = {}) {
468
- if (readPrototype) {
469
- // we make use of a for-in loop so that the
470
- // prototypically inherited properties are
471
- // revealed from the backFill map
472
- for (let prop in styles) {
473
- destination[prop] = styles[prop];
489
+ function copyStyles(styles, destination = new Map(), backfill) {
490
+ if (backfill) {
491
+ for (let [prop, val] of backfill) {
492
+ destination.set(prop, val);
474
493
  }
475
494
  }
476
- else {
477
- copyObj(styles, destination);
495
+ for (let [prop, val] of styles) {
496
+ destination.set(prop, val);
478
497
  }
479
498
  return destination;
480
499
  }
@@ -510,12 +529,12 @@ function writeStyleAttribute(element) {
510
529
  }
511
530
  function setStyles(element, styles, formerStyles) {
512
531
  if (element['style']) {
513
- Object.keys(styles).forEach(prop => {
532
+ styles.forEach((val, prop) => {
514
533
  const camelProp = dashCaseToCamelCase(prop);
515
- if (formerStyles && !formerStyles.hasOwnProperty(prop)) {
516
- formerStyles[prop] = element.style[camelProp];
534
+ if (formerStyles && !formerStyles.has(prop)) {
535
+ formerStyles.set(prop, element.style[camelProp]);
517
536
  }
518
- element.style[camelProp] = styles[prop];
537
+ element.style[camelProp] = val;
519
538
  });
520
539
  // On the server set the 'style' attribute since it's not automatically reflected.
521
540
  if (isNode()) {
@@ -525,7 +544,7 @@ function setStyles(element, styles, formerStyles) {
525
544
  }
526
545
  function eraseStyles(element, styles) {
527
546
  if (element['style']) {
528
- Object.keys(styles).forEach(prop => {
547
+ styles.forEach((_, prop) => {
529
548
  const camelProp = dashCaseToCamelCase(prop);
530
549
  element.style[camelProp] = '';
531
550
  });
@@ -600,23 +619,19 @@ function allowPreviousPlayerStylesMerge(duration, delay) {
600
619
  return duration === 0 || delay === 0;
601
620
  }
602
621
  function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
603
- const previousStyleProps = Object.keys(previousStyles);
604
- if (previousStyleProps.length && keyframes.length) {
622
+ if (previousStyles.size && keyframes.length) {
605
623
  let startingKeyframe = keyframes[0];
606
624
  let missingStyleProps = [];
607
- previousStyleProps.forEach(prop => {
608
- if (!startingKeyframe.hasOwnProperty(prop)) {
625
+ previousStyles.forEach((val, prop) => {
626
+ if (!startingKeyframe.has(prop)) {
609
627
  missingStyleProps.push(prop);
610
628
  }
611
- startingKeyframe[prop] = previousStyles[prop];
629
+ startingKeyframe.set(prop, val);
612
630
  });
613
631
  if (missingStyleProps.length) {
614
- // tslint:disable-next-line
615
- for (var i = 1; i < keyframes.length; i++) {
632
+ for (let i = 1; i < keyframes.length; i++) {
616
633
  let kf = keyframes[i];
617
- missingStyleProps.forEach(function (prop) {
618
- kf[prop] = computeStyle(element, prop);
619
- });
634
+ missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));
620
635
  }
621
636
  }
622
637
  }
@@ -796,8 +811,8 @@ class AnimationAstBuilderVisitor {
796
811
  }
797
812
  _resetContextStyleTimingState(context) {
798
813
  context.currentQuerySelector = ROOT_SELECTOR;
799
- context.collectedStyles = {};
800
- context.collectedStyles[ROOT_SELECTOR] = {};
814
+ context.collectedStyles = new Map();
815
+ context.collectedStyles.set(ROOT_SELECTOR, new Map());
801
816
  context.currentTime = 0;
802
817
  }
803
818
  visitTrigger(metadata, context) {
@@ -845,11 +860,10 @@ class AnimationAstBuilderVisitor {
845
860
  if (styleAst.containsDynamicStyles) {
846
861
  const missingSubs = new Set();
847
862
  const params = astParams || {};
848
- styleAst.styles.forEach(value => {
849
- if (isObject(value)) {
850
- const stylesObj = value;
851
- Object.keys(stylesObj).forEach(prop => {
852
- extractStyleParams(stylesObj[prop]).forEach(sub => {
863
+ styleAst.styles.forEach(style => {
864
+ if (style instanceof Map) {
865
+ style.forEach(value => {
866
+ extractStyleParams(value).forEach(sub => {
853
867
  if (!params.hasOwnProperty(sub)) {
854
868
  missingSubs.add(sub);
855
869
  }
@@ -945,37 +959,30 @@ class AnimationAstBuilderVisitor {
945
959
  }
946
960
  _makeStyleAst(metadata, context) {
947
961
  const styles = [];
948
- if (Array.isArray(metadata.styles)) {
949
- metadata.styles.forEach(styleTuple => {
950
- if (typeof styleTuple == 'string') {
951
- if (styleTuple == AUTO_STYLE) {
952
- styles.push(styleTuple);
953
- }
954
- else {
955
- context.errors.push(invalidStyleValue(styleTuple));
956
- }
962
+ const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
963
+ for (let styleTuple of metadataStyles) {
964
+ if (typeof styleTuple === 'string') {
965
+ if (styleTuple === AUTO_STYLE) {
966
+ styles.push(styleTuple);
957
967
  }
958
968
  else {
959
- styles.push(styleTuple);
969
+ context.errors.push(invalidStyleValue(styleTuple));
960
970
  }
961
- });
962
- }
963
- else {
964
- styles.push(metadata.styles);
971
+ }
972
+ else {
973
+ styles.push(convertToMap(styleTuple));
974
+ }
965
975
  }
966
976
  let containsDynamicStyles = false;
967
977
  let collectedEasing = null;
968
978
  styles.forEach(styleData => {
969
- if (isObject(styleData)) {
970
- const styleMap = styleData;
971
- const easing = styleMap['easing'];
972
- if (easing) {
973
- collectedEasing = easing;
974
- delete styleMap['easing'];
979
+ if (styleData instanceof Map) {
980
+ if (styleData.has('easing')) {
981
+ collectedEasing = styleData.get('easing');
982
+ styleData.delete('easing');
975
983
  }
976
984
  if (!containsDynamicStyles) {
977
- for (let prop in styleMap) {
978
- const value = styleMap[prop];
985
+ for (let value of styleData.values()) {
979
986
  if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
980
987
  containsDynamicStyles = true;
981
988
  break;
@@ -1001,15 +1008,17 @@ class AnimationAstBuilderVisitor {
1001
1008
  startTime -= timings.duration + timings.delay;
1002
1009
  }
1003
1010
  ast.styles.forEach(tuple => {
1004
- if (typeof tuple == 'string')
1011
+ if (typeof tuple === 'string')
1005
1012
  return;
1006
- Object.keys(tuple).forEach(prop => {
1013
+ tuple.forEach((value, prop) => {
1007
1014
  if (!this._driver.validateStyleProperty(prop)) {
1008
1015
  context.errors.push(invalidProperty(prop));
1009
1016
  return;
1010
1017
  }
1011
- const collectedStyles = context.collectedStyles[context.currentQuerySelector];
1012
- const collectedEntry = collectedStyles[prop];
1018
+ // This is guaranteed to have a defined Map at this querySelector location making it
1019
+ // safe to add the assertion here. It is set as a default empty map in prior methods.
1020
+ const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
1021
+ const collectedEntry = collectedStyles.get(prop);
1013
1022
  let updateCollectedStyle = true;
1014
1023
  if (collectedEntry) {
1015
1024
  if (startTime != endTime && startTime >= collectedEntry.startTime &&
@@ -1023,10 +1032,10 @@ class AnimationAstBuilderVisitor {
1023
1032
  startTime = collectedEntry.startTime;
1024
1033
  }
1025
1034
  if (updateCollectedStyle) {
1026
- collectedStyles[prop] = { startTime, endTime };
1035
+ collectedStyles.set(prop, { startTime, endTime });
1027
1036
  }
1028
1037
  if (context.options) {
1029
- validateStyleParams(tuple[prop], context.options, context.errors);
1038
+ validateStyleParams(value, context.options, context.errors);
1030
1039
  }
1031
1040
  });
1032
1041
  });
@@ -1115,7 +1124,7 @@ class AnimationAstBuilderVisitor {
1115
1124
  const [selector, includeSelf] = normalizeSelector(metadata.selector);
1116
1125
  context.currentQuerySelector =
1117
1126
  parentSelector.length ? (parentSelector + ' ' + selector) : selector;
1118
- getOrSetAsInMap(context.collectedStyles, context.currentQuerySelector, {});
1127
+ getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
1119
1128
  const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
1120
1129
  context.currentQuery = null;
1121
1130
  context.currentQuerySelector = parentSelector;
@@ -1170,7 +1179,7 @@ class AnimationAstBuilderContext {
1170
1179
  this.currentQuerySelector = null;
1171
1180
  this.currentAnimateTimings = null;
1172
1181
  this.currentTime = 0;
1173
- this.collectedStyles = {};
1182
+ this.collectedStyles = new Map();
1174
1183
  this.options = null;
1175
1184
  }
1176
1185
  }
@@ -1180,23 +1189,20 @@ function consumeOffset(styles) {
1180
1189
  let offset = null;
1181
1190
  if (Array.isArray(styles)) {
1182
1191
  styles.forEach(styleTuple => {
1183
- if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) {
1192
+ if (styleTuple instanceof Map && styleTuple.has('offset')) {
1184
1193
  const obj = styleTuple;
1185
- offset = parseFloat(obj['offset']);
1186
- delete obj['offset'];
1194
+ offset = parseFloat(obj.get('offset'));
1195
+ obj.delete('offset');
1187
1196
  }
1188
1197
  });
1189
1198
  }
1190
- else if (isObject(styles) && styles.hasOwnProperty('offset')) {
1199
+ else if (styles instanceof Map && styles.has('offset')) {
1191
1200
  const obj = styles;
1192
- offset = parseFloat(obj['offset']);
1193
- delete obj['offset'];
1201
+ offset = parseFloat(obj.get('offset'));
1202
+ obj.delete('offset');
1194
1203
  }
1195
1204
  return offset;
1196
1205
  }
1197
- function isObject(value) {
1198
- return !Array.isArray(value) && typeof value == 'object';
1199
- }
1200
1206
  function constructTimingAst(value, errors) {
1201
1207
  let timings = null;
1202
1208
  if (value.hasOwnProperty('duration')) {
@@ -1304,7 +1310,7 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
1304
1310
  * ```
1305
1311
  *
1306
1312
  * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
1307
- * combination of prototypical inheritance, AST traversal and merge-sort-like algorithms are used.
1313
+ * combination of AST traversal and merge-sort-like algorithms are used.
1308
1314
  *
1309
1315
  * [AST Traversal]
1310
1316
  * Each of the animation verbs, when executed, will return an string-map object representing what
@@ -1350,23 +1356,18 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
1350
1356
  * from all previous animation steps. Therefore when a keyframe is created it would also be missing
1351
1357
  * from all previous keyframes up until where it is first used. For the timeline keyframe generation
1352
1358
  * to properly fill in the style it will place the previous value (the value from the parent
1353
- * timeline) or a default value of `*` into the backFill object. Given that each of the keyframe
1354
- * styles is an object that prototypically inherits from the backFill object, this means that if a
1355
- * value is added into the backFill then it will automatically propagate any missing values to all
1356
- * keyframes. Therefore the missing `height` value will be properly filled into the already
1357
- * processed keyframes.
1359
+ * timeline) or a default value of `*` into the backFill map. The `copyStyles` method in util.ts
1360
+ * handles propagating that backfill map to the styles object.
1358
1361
  *
1359
1362
  * When a sub-timeline is created it will have its own backFill property. This is done so that
1360
1363
  * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
1361
1364
  * keyframes
1362
1365
  *
1363
- * (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
1364
- *
1365
1366
  * [Validation]
1366
1367
  * The code in this file is not responsible for validation. That functionality happens with within
1367
1368
  * the `AnimationValidatorVisitor` code.
1368
1369
  */
1369
- function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = {}, finalStyles = {}, options, subInstructions, errors = []) {
1370
+ function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstructions, errors = []) {
1370
1371
  return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
1371
1372
  }
1372
1373
  class AnimationTimelineBuilderVisitor {
@@ -1374,15 +1375,17 @@ class AnimationTimelineBuilderVisitor {
1374
1375
  subInstructions = subInstructions || new ElementInstructionMap();
1375
1376
  const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
1376
1377
  context.options = options;
1378
+ const delay = options.delay ? resolveTimingValue(options.delay) : 0;
1379
+ context.currentTimeline.delayNextStep(delay);
1377
1380
  context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
1378
1381
  visitDslNode(this, ast, context);
1379
1382
  // this checks to see if an actual animation happened
1380
1383
  const timelines = context.timelines.filter(timeline => timeline.containsAnimation());
1381
- if (Object.keys(finalStyles).length) {
1382
- // note: we just want to apply the final styles for the rootElement, so we do not
1383
- // just apply the styles to the last timeline but the last timeline which
1384
- // element is the root one (basically `*`-styles are replaced with the actual
1385
- // state style values only for the root element)
1384
+ // note: we just want to apply the final styles for the rootElement, so we do not
1385
+ // just apply the styles to the last timeline but the last timeline which
1386
+ // element is the root one (basically `*`-styles are replaced with the actual
1387
+ // state style values only for the root element)
1388
+ if (timelines.length && finalStyles.size) {
1386
1389
  let lastRootTimeline;
1387
1390
  for (let i = timelines.length - 1; i >= 0; i--) {
1388
1391
  const timeline = timelines[i];
@@ -1395,8 +1398,9 @@ class AnimationTimelineBuilderVisitor {
1395
1398
  lastRootTimeline.setStyles([finalStyles], null, context.errors, options);
1396
1399
  }
1397
1400
  }
1398
- return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) :
1399
- [createTimelineInstruction(rootElement, [], [], [], 0, 0, '', false)];
1401
+ return timelines.length ?
1402
+ timelines.map(timeline => timeline.buildKeyframes()) :
1403
+ [createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];
1400
1404
  }
1401
1405
  visitTrigger(ast, context) {
1402
1406
  // these values are not visited in this AST
@@ -1532,7 +1536,7 @@ class AnimationTimelineBuilderVisitor {
1532
1536
  const timings = context.currentAnimateTimings;
1533
1537
  // this is a special case for when a style() call
1534
1538
  // directly follows an animate() call (but not inside of an animate() call)
1535
- if (!timings && timeline.getCurrentStyleProperties().length) {
1539
+ if (!timings && timeline.hasCurrentStyleProperties()) {
1536
1540
  timeline.forwardFrame();
1537
1541
  }
1538
1542
  const easing = (timings && timings.easing) || ast.easing;
@@ -1573,7 +1577,7 @@ class AnimationTimelineBuilderVisitor {
1573
1577
  const delay = options.delay ? resolveTimingValue(options.delay) : 0;
1574
1578
  if (delay &&
1575
1579
  (context.previousNode.type === 6 /* Style */ ||
1576
- (startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
1580
+ (startTime == 0 && context.currentTimeline.hasCurrentStyleProperties()))) {
1577
1581
  context.currentTimeline.snapshotCurrentStyles();
1578
1582
  context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
1579
1583
  }
@@ -1767,17 +1771,17 @@ class TimelineBuilder {
1767
1771
  this.startTime = startTime;
1768
1772
  this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
1769
1773
  this.duration = 0;
1770
- this._previousKeyframe = {};
1771
- this._currentKeyframe = {};
1774
+ this._previousKeyframe = new Map();
1775
+ this._currentKeyframe = new Map();
1772
1776
  this._keyframes = new Map();
1773
- this._styleSummary = {};
1774
- this._pendingStyles = {};
1775
- this._backFill = {};
1777
+ this._styleSummary = new Map();
1778
+ this._localTimelineStyles = new Map();
1779
+ this._pendingStyles = new Map();
1780
+ this._backFill = new Map();
1776
1781
  this._currentEmptyStepKeyframe = null;
1777
1782
  if (!this._elementTimelineStylesLookup) {
1778
1783
  this._elementTimelineStylesLookup = new Map();
1779
1784
  }
1780
- this._localTimelineStyles = Object.create(this._backFill, {});
1781
1785
  this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
1782
1786
  if (!this._globalTimelineStyles) {
1783
1787
  this._globalTimelineStyles = this._localTimelineStyles;
@@ -1790,13 +1794,13 @@ class TimelineBuilder {
1790
1794
  case 0:
1791
1795
  return false;
1792
1796
  case 1:
1793
- return this.getCurrentStyleProperties().length > 0;
1797
+ return this.hasCurrentStyleProperties();
1794
1798
  default:
1795
1799
  return true;
1796
1800
  }
1797
1801
  }
1798
- getCurrentStyleProperties() {
1799
- return Object.keys(this._currentKeyframe);
1802
+ hasCurrentStyleProperties() {
1803
+ return this._currentKeyframe.size > 0;
1800
1804
  }
1801
1805
  get currentTime() {
1802
1806
  return this.startTime + this.duration;
@@ -1806,7 +1810,7 @@ class TimelineBuilder {
1806
1810
  // and that style() step is the very first style() value in the animation
1807
1811
  // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
1808
1812
  // properly applies the style() values to work with the stagger...
1809
- const hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length;
1813
+ const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;
1810
1814
  if (this.duration || hasPreStyleStep) {
1811
1815
  this.forwardTime(this.currentTime + delay);
1812
1816
  if (hasPreStyleStep) {
@@ -1827,7 +1831,7 @@ class TimelineBuilder {
1827
1831
  }
1828
1832
  this._currentKeyframe = this._keyframes.get(this.duration);
1829
1833
  if (!this._currentKeyframe) {
1830
- this._currentKeyframe = Object.create(this._backFill, {});
1834
+ this._currentKeyframe = new Map();
1831
1835
  this._keyframes.set(this.duration, this._currentKeyframe);
1832
1836
  }
1833
1837
  }
@@ -1841,16 +1845,16 @@ class TimelineBuilder {
1841
1845
  this._loadKeyframe();
1842
1846
  }
1843
1847
  _updateStyle(prop, value) {
1844
- this._localTimelineStyles[prop] = value;
1845
- this._globalTimelineStyles[prop] = value;
1846
- this._styleSummary[prop] = { time: this.currentTime, value };
1848
+ this._localTimelineStyles.set(prop, value);
1849
+ this._globalTimelineStyles.set(prop, value);
1850
+ this._styleSummary.set(prop, { time: this.currentTime, value });
1847
1851
  }
1848
1852
  allowOnlyTimelineStyles() {
1849
1853
  return this._currentEmptyStepKeyframe !== this._currentKeyframe;
1850
1854
  }
1851
1855
  applyEmptyStep(easing) {
1852
1856
  if (easing) {
1853
- this._previousKeyframe['easing'] = easing;
1857
+ this._previousKeyframe.set('easing', easing);
1854
1858
  }
1855
1859
  // special case for animate(duration):
1856
1860
  // all missing styles are filled with a `*` value then
@@ -1858,51 +1862,45 @@ class TimelineBuilder {
1858
1862
  // keyframe then they will override the overridden styles
1859
1863
  // We use `_globalTimelineStyles` here because there may be
1860
1864
  // styles in previous keyframes that are not present in this timeline
1861
- Object.keys(this._globalTimelineStyles).forEach(prop => {
1862
- this._backFill[prop] = this._globalTimelineStyles[prop] || AUTO_STYLE;
1863
- this._currentKeyframe[prop] = AUTO_STYLE;
1864
- });
1865
+ for (let [prop, value] of this._globalTimelineStyles) {
1866
+ this._backFill.set(prop, value || AUTO_STYLE);
1867
+ this._currentKeyframe.set(prop, AUTO_STYLE);
1868
+ }
1865
1869
  this._currentEmptyStepKeyframe = this._currentKeyframe;
1866
1870
  }
1867
1871
  setStyles(input, easing, errors, options) {
1868
1872
  if (easing) {
1869
- this._previousKeyframe['easing'] = easing;
1873
+ this._previousKeyframe.set('easing', easing);
1870
1874
  }
1871
1875
  const params = (options && options.params) || {};
1872
1876
  const styles = flattenStyles(input, this._globalTimelineStyles);
1873
- Object.keys(styles).forEach(prop => {
1874
- const val = interpolateParams(styles[prop], params, errors);
1875
- this._pendingStyles[prop] = val;
1876
- if (!this._localTimelineStyles.hasOwnProperty(prop)) {
1877
- this._backFill[prop] = this._globalTimelineStyles.hasOwnProperty(prop) ?
1878
- this._globalTimelineStyles[prop] :
1879
- AUTO_STYLE;
1877
+ for (let [prop, value] of styles) {
1878
+ const val = interpolateParams(value, params, errors);
1879
+ this._pendingStyles.set(prop, val);
1880
+ if (!this._localTimelineStyles.has(prop)) {
1881
+ this._backFill.set(prop, this._globalTimelineStyles.get(prop) || AUTO_STYLE);
1880
1882
  }
1881
1883
  this._updateStyle(prop, val);
1882
- });
1884
+ }
1883
1885
  }
1884
1886
  applyStylesToKeyframe() {
1885
- const styles = this._pendingStyles;
1886
- const props = Object.keys(styles);
1887
- if (props.length == 0)
1887
+ if (this._pendingStyles.size == 0)
1888
1888
  return;
1889
- this._pendingStyles = {};
1890
- props.forEach(prop => {
1891
- const val = styles[prop];
1892
- this._currentKeyframe[prop] = val;
1889
+ this._pendingStyles.forEach((val, prop) => {
1890
+ this._currentKeyframe.set(prop, val);
1893
1891
  });
1894
- Object.keys(this._localTimelineStyles).forEach(prop => {
1895
- if (!this._currentKeyframe.hasOwnProperty(prop)) {
1896
- this._currentKeyframe[prop] = this._localTimelineStyles[prop];
1892
+ this._pendingStyles.clear();
1893
+ this._localTimelineStyles.forEach((val, prop) => {
1894
+ if (!this._currentKeyframe.has(prop)) {
1895
+ this._currentKeyframe.set(prop, val);
1897
1896
  }
1898
1897
  });
1899
1898
  }
1900
1899
  snapshotCurrentStyles() {
1901
- Object.keys(this._localTimelineStyles).forEach(prop => {
1902
- const val = this._localTimelineStyles[prop];
1903
- this._pendingStyles[prop] = val;
1900
+ for (let [prop, val] of this._localTimelineStyles) {
1901
+ this._pendingStyles.set(prop, val);
1904
1902
  this._updateStyle(prop, val);
1905
- });
1903
+ }
1906
1904
  }
1907
1905
  getFinalKeyframe() {
1908
1906
  return this._keyframes.get(this.duration);
@@ -1915,9 +1913,8 @@ class TimelineBuilder {
1915
1913
  return properties;
1916
1914
  }
1917
1915
  mergeTimelineCollectedStyles(timeline) {
1918
- Object.keys(timeline._styleSummary).forEach(prop => {
1919
- const details0 = this._styleSummary[prop];
1920
- const details1 = timeline._styleSummary[prop];
1916
+ timeline._styleSummary.forEach((details1, prop) => {
1917
+ const details0 = this._styleSummary.get(prop);
1921
1918
  if (!details0 || details1.time > details0.time) {
1922
1919
  this._updateStyle(prop, details1.value);
1923
1920
  }
@@ -1930,18 +1927,17 @@ class TimelineBuilder {
1930
1927
  const isEmpty = this._keyframes.size === 1 && this.duration === 0;
1931
1928
  let finalKeyframes = [];
1932
1929
  this._keyframes.forEach((keyframe, time) => {
1933
- const finalKeyframe = copyStyles(keyframe, true);
1934
- Object.keys(finalKeyframe).forEach(prop => {
1935
- const value = finalKeyframe[prop];
1936
- if (value == ɵPRE_STYLE) {
1930
+ const finalKeyframe = copyStyles(keyframe, new Map(), this._backFill);
1931
+ finalKeyframe.forEach((value, prop) => {
1932
+ if (value === ɵPRE_STYLE) {
1937
1933
  preStyleProps.add(prop);
1938
1934
  }
1939
- else if (value == AUTO_STYLE) {
1935
+ else if (value === AUTO_STYLE) {
1940
1936
  postStyleProps.add(prop);
1941
1937
  }
1942
1938
  });
1943
1939
  if (!isEmpty) {
1944
- finalKeyframe['offset'] = time / this.duration;
1940
+ finalKeyframe.set('offset', time / this.duration);
1945
1941
  }
1946
1942
  finalKeyframes.push(finalKeyframe);
1947
1943
  });
@@ -1950,9 +1946,9 @@ class TimelineBuilder {
1950
1946
  // special case for a 0-second animation (which is designed just to place styles onscreen)
1951
1947
  if (isEmpty) {
1952
1948
  const kf0 = finalKeyframes[0];
1953
- const kf1 = copyObj(kf0);
1954
- kf0['offset'] = 0;
1955
- kf1['offset'] = 1;
1949
+ const kf1 = new Map(kf0);
1950
+ kf0.set('offset', 0);
1951
+ kf1.set('offset', 1);
1956
1952
  finalKeyframes = [kf0, kf1];
1957
1953
  }
1958
1954
  return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
@@ -1978,11 +1974,11 @@ class SubTimelineBuilder extends TimelineBuilder {
1978
1974
  const totalTime = duration + delay;
1979
1975
  const startingGap = delay / totalTime;
1980
1976
  // the original starting keyframe now starts once the delay is done
1981
- const newFirstKeyframe = copyStyles(keyframes[0], false);
1982
- newFirstKeyframe['offset'] = 0;
1977
+ const newFirstKeyframe = copyStyles(keyframes[0]);
1978
+ newFirstKeyframe.set('offset', 0);
1983
1979
  newKeyframes.push(newFirstKeyframe);
1984
- const oldFirstKeyframe = copyStyles(keyframes[0], false);
1985
- oldFirstKeyframe['offset'] = roundOffset(startingGap);
1980
+ const oldFirstKeyframe = copyStyles(keyframes[0]);
1981
+ oldFirstKeyframe.set('offset', roundOffset(startingGap));
1986
1982
  newKeyframes.push(oldFirstKeyframe);
1987
1983
  /*
1988
1984
  When the keyframe is stretched then it means that the delay before the animation
@@ -2001,10 +1997,10 @@ class SubTimelineBuilder extends TimelineBuilder {
2001
1997
  // offsets between 1 ... n -1 are all warped by the keyframe stretch
2002
1998
  const limit = keyframes.length - 1;
2003
1999
  for (let i = 1; i <= limit; i++) {
2004
- let kf = copyStyles(keyframes[i], false);
2005
- const oldOffset = kf['offset'];
2000
+ let kf = copyStyles(keyframes[i]);
2001
+ const oldOffset = kf.get('offset');
2006
2002
  const timeAtKeyframe = delay + oldOffset * duration;
2007
- kf['offset'] = roundOffset(timeAtKeyframe / totalTime);
2003
+ kf.set('offset', roundOffset(timeAtKeyframe / totalTime));
2008
2004
  newKeyframes.push(kf);
2009
2005
  }
2010
2006
  // the new starting keyframe should be added at the start
@@ -2021,17 +2017,17 @@ function roundOffset(offset, decimalPoints = 3) {
2021
2017
  return Math.round(offset * mult) / mult;
2022
2018
  }
2023
2019
  function flattenStyles(input, allStyles) {
2024
- const styles = {};
2020
+ const styles = new Map();
2025
2021
  let allProperties;
2026
2022
  input.forEach(token => {
2027
2023
  if (token === '*') {
2028
- allProperties = allProperties || Object.keys(allStyles);
2029
- allProperties.forEach(prop => {
2030
- styles[prop] = AUTO_STYLE;
2031
- });
2024
+ allProperties = allProperties || allStyles.keys();
2025
+ for (let prop of allProperties) {
2026
+ styles.set(prop, AUTO_STYLE);
2027
+ }
2032
2028
  }
2033
2029
  else {
2034
- copyStyles(token, false, styles);
2030
+ copyStyles(token, styles);
2035
2031
  }
2036
2032
  });
2037
2033
  return styles;
@@ -2093,6 +2089,37 @@ class NoopAnimationStyleNormalizer {
2093
2089
  * Use of this source code is governed by an MIT-style license that can be
2094
2090
  * found in the LICENSE file at https://angular.io/license
2095
2091
  */
2092
+ const DIMENSIONAL_PROP_SET = new Set([
2093
+ 'width',
2094
+ 'height',
2095
+ 'minWidth',
2096
+ 'minHeight',
2097
+ 'maxWidth',
2098
+ 'maxHeight',
2099
+ 'left',
2100
+ 'top',
2101
+ 'bottom',
2102
+ 'right',
2103
+ 'fontSize',
2104
+ 'outlineWidth',
2105
+ 'outlineOffset',
2106
+ 'paddingTop',
2107
+ 'paddingLeft',
2108
+ 'paddingBottom',
2109
+ 'paddingRight',
2110
+ 'marginTop',
2111
+ 'marginLeft',
2112
+ 'marginBottom',
2113
+ 'marginRight',
2114
+ 'borderRadius',
2115
+ 'borderWidth',
2116
+ 'borderTopWidth',
2117
+ 'borderLeftWidth',
2118
+ 'borderRightWidth',
2119
+ 'borderBottomWidth',
2120
+ 'textIndent',
2121
+ 'perspective'
2122
+ ]);
2096
2123
  class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
2097
2124
  normalizePropertyName(propertyName, errors) {
2098
2125
  return dashCaseToCamelCase(propertyName);
@@ -2100,7 +2127,7 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
2100
2127
  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
2101
2128
  let unit = '';
2102
2129
  const strVal = value.toString().trim();
2103
- if (DIMENSIONAL_PROP_MAP[normalizedProperty] && value !== 0 && value !== '0') {
2130
+ if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {
2104
2131
  if (typeof value === 'number') {
2105
2132
  unit = 'px';
2106
2133
  }
@@ -2114,14 +2141,14 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
2114
2141
  return strVal + unit;
2115
2142
  }
2116
2143
  }
2117
- const DIMENSIONAL_PROP_MAP = (() => makeBooleanMap('width,height,minWidth,minHeight,maxWidth,maxHeight,left,top,bottom,right,fontSize,outlineWidth,outlineOffset,paddingTop,paddingLeft,paddingBottom,paddingRight,marginTop,marginLeft,marginBottom,marginRight,borderRadius,borderWidth,borderTopWidth,borderLeftWidth,borderRightWidth,borderBottomWidth,textIndent,perspective'
2118
- .split(',')))();
2119
- function makeBooleanMap(keys) {
2120
- const map = {};
2121
- keys.forEach(key => map[key] = true);
2122
- return map;
2123
- }
2124
2144
 
2145
+ /**
2146
+ * @license
2147
+ * Copyright Google LLC All Rights Reserved.
2148
+ *
2149
+ * Use of this source code is governed by an MIT-style license that can be
2150
+ * found in the LICENSE file at https://angular.io/license
2151
+ */
2125
2152
  function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
2126
2153
  return {
2127
2154
  type: 0 /* TransitionAnimation */,
@@ -2152,10 +2179,11 @@ class AnimationTransitionFactory {
2152
2179
  return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
2153
2180
  }
2154
2181
  buildStyles(stateName, params, errors) {
2155
- const backupStateStyler = this._stateStyles['*'];
2156
- const stateStyler = this._stateStyles[stateName];
2157
- const backupStyles = backupStateStyler ? backupStateStyler.buildStyles(params, errors) : {};
2158
- return stateStyler ? stateStyler.buildStyles(params, errors) : backupStyles;
2182
+ let styler = this._stateStyles.get('*');
2183
+ if (stateName !== undefined) {
2184
+ styler = this._stateStyles.get(stateName?.toString()) || styler;
2185
+ }
2186
+ return styler ? styler.buildStyles(params, errors) : new Map();
2159
2187
  }
2160
2188
  build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
2161
2189
  const errors = [];
@@ -2168,7 +2196,10 @@ class AnimationTransitionFactory {
2168
2196
  const preStyleMap = new Map();
2169
2197
  const postStyleMap = new Map();
2170
2198
  const isRemoval = nextState === 'void';
2171
- const animationOptions = { params: { ...transitionAnimationParams, ...nextAnimationParams } };
2199
+ const animationOptions = {
2200
+ params: { ...transitionAnimationParams, ...nextAnimationParams },
2201
+ delay: this.ast.options?.delay,
2202
+ };
2172
2203
  const timelines = skipAstBuild ?
2173
2204
  [] :
2174
2205
  buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
@@ -2181,10 +2212,10 @@ class AnimationTransitionFactory {
2181
2212
  }
2182
2213
  timelines.forEach(tl => {
2183
2214
  const elm = tl.element;
2184
- const preProps = getOrSetAsInMap(preStyleMap, elm, {});
2185
- tl.preStyleProps.forEach(prop => preProps[prop] = true);
2186
- const postProps = getOrSetAsInMap(postStyleMap, elm, {});
2187
- tl.postStyleProps.forEach(prop => postProps[prop] = true);
2215
+ const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());
2216
+ tl.preStyleProps.forEach(prop => preProps.add(prop));
2217
+ const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());
2218
+ tl.postStyleProps.forEach(prop => postProps.add(prop));
2188
2219
  if (elm !== element) {
2189
2220
  queriedElements.add(elm);
2190
2221
  }
@@ -2203,25 +2234,23 @@ class AnimationStateStyles {
2203
2234
  this.normalizer = normalizer;
2204
2235
  }
2205
2236
  buildStyles(params, errors) {
2206
- const finalStyles = {};
2237
+ const finalStyles = new Map();
2207
2238
  const combinedParams = copyObj(this.defaultParams);
2208
2239
  Object.keys(params).forEach(key => {
2209
2240
  const value = params[key];
2210
- if (value != null) {
2241
+ if (value !== null) {
2211
2242
  combinedParams[key] = value;
2212
2243
  }
2213
2244
  });
2214
2245
  this.styles.styles.forEach(value => {
2215
2246
  if (typeof value !== 'string') {
2216
- const styleObj = value;
2217
- Object.keys(styleObj).forEach(prop => {
2218
- let val = styleObj[prop];
2219
- if (val.length > 1) {
2247
+ value.forEach((val, prop) => {
2248
+ if (val) {
2220
2249
  val = interpolateParams(val, combinedParams, errors);
2221
2250
  }
2222
2251
  const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);
2223
2252
  val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);
2224
- finalStyles[normalizedProp] = val;
2253
+ finalStyles.set(normalizedProp, val);
2225
2254
  });
2226
2255
  }
2227
2256
  });
@@ -2238,10 +2267,10 @@ class AnimationTrigger {
2238
2267
  this.ast = ast;
2239
2268
  this._normalizer = _normalizer;
2240
2269
  this.transitionFactories = [];
2241
- this.states = {};
2270
+ this.states = new Map();
2242
2271
  ast.states.forEach(ast => {
2243
2272
  const defaultParams = (ast.options && ast.options.params) || {};
2244
- this.states[ast.name] = new AnimationStateStyles(ast.style, defaultParams, _normalizer);
2273
+ this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));
2245
2274
  });
2246
2275
  balanceProperties(this.states, 'true', '1');
2247
2276
  balanceProperties(this.states, 'false', '0');
@@ -2274,14 +2303,14 @@ function createFallbackTransition(triggerName, states, normalizer) {
2274
2303
  };
2275
2304
  return new AnimationTransitionFactory(triggerName, transition, states);
2276
2305
  }
2277
- function balanceProperties(obj, key1, key2) {
2278
- if (obj.hasOwnProperty(key1)) {
2279
- if (!obj.hasOwnProperty(key2)) {
2280
- obj[key2] = obj[key1];
2306
+ function balanceProperties(stateMap, key1, key2) {
2307
+ if (stateMap.has(key1)) {
2308
+ if (!stateMap.has(key2)) {
2309
+ stateMap.set(key2, stateMap.get(key1));
2281
2310
  }
2282
2311
  }
2283
- else if (obj.hasOwnProperty(key2)) {
2284
- obj[key1] = obj[key2];
2312
+ else if (stateMap.has(key2)) {
2313
+ stateMap.set(key1, stateMap.get(key2));
2285
2314
  }
2286
2315
  }
2287
2316
 
@@ -2298,8 +2327,8 @@ class TimelineAnimationEngine {
2298
2327
  this.bodyNode = bodyNode;
2299
2328
  this._driver = _driver;
2300
2329
  this._normalizer = _normalizer;
2301
- this._animations = {};
2302
- this._playersById = {};
2330
+ this._animations = new Map();
2331
+ this._playersById = new Map();
2303
2332
  this.players = [];
2304
2333
  }
2305
2334
  register(id, metadata) {
@@ -2309,24 +2338,24 @@ class TimelineAnimationEngine {
2309
2338
  throw registerFailed(errors);
2310
2339
  }
2311
2340
  else {
2312
- this._animations[id] = ast;
2341
+ this._animations.set(id, ast);
2313
2342
  }
2314
2343
  }
2315
2344
  _buildPlayer(i, preStyles, postStyles) {
2316
2345
  const element = i.element;
2317
- const keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
2346
+ const keyframes = normalizeKeyframes$1(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
2318
2347
  return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
2319
2348
  }
2320
2349
  create(id, element, options = {}) {
2321
2350
  const errors = [];
2322
- const ast = this._animations[id];
2351
+ const ast = this._animations.get(id);
2323
2352
  let instructions;
2324
2353
  const autoStylesMap = new Map();
2325
2354
  if (ast) {
2326
- instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, {}, {}, options, EMPTY_INSTRUCTION_MAP, errors);
2355
+ instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);
2327
2356
  instructions.forEach(inst => {
2328
- const styles = getOrSetAsInMap(autoStylesMap, inst.element, {});
2329
- inst.postStyleProps.forEach(prop => styles[prop] = null);
2357
+ const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());
2358
+ inst.postStyleProps.forEach(prop => styles.set(prop, null));
2330
2359
  });
2331
2360
  }
2332
2361
  else {
@@ -2337,16 +2366,16 @@ class TimelineAnimationEngine {
2337
2366
  throw createAnimationFailed(errors);
2338
2367
  }
2339
2368
  autoStylesMap.forEach((styles, element) => {
2340
- Object.keys(styles).forEach(prop => {
2341
- styles[prop] = this._driver.computeStyle(element, prop, AUTO_STYLE);
2369
+ styles.forEach((_, prop) => {
2370
+ styles.set(prop, this._driver.computeStyle(element, prop, AUTO_STYLE));
2342
2371
  });
2343
2372
  });
2344
2373
  const players = instructions.map(i => {
2345
2374
  const styles = autoStylesMap.get(i.element);
2346
- return this._buildPlayer(i, {}, styles);
2375
+ return this._buildPlayer(i, new Map(), styles);
2347
2376
  });
2348
2377
  const player = optimizeGroupPlayer(players);
2349
- this._playersById[id] = player;
2378
+ this._playersById.set(id, player);
2350
2379
  player.onDestroy(() => this.destroy(id));
2351
2380
  this.players.push(player);
2352
2381
  return player;
@@ -2354,14 +2383,14 @@ class TimelineAnimationEngine {
2354
2383
  destroy(id) {
2355
2384
  const player = this._getPlayer(id);
2356
2385
  player.destroy();
2357
- delete this._playersById[id];
2386
+ this._playersById.delete(id);
2358
2387
  const index = this.players.indexOf(player);
2359
2388
  if (index >= 0) {
2360
2389
  this.players.splice(index, 1);
2361
2390
  }
2362
2391
  }
2363
2392
  _getPlayer(id) {
2364
- const player = this._playersById[id];
2393
+ const player = this._playersById.get(id);
2365
2394
  if (!player) {
2366
2395
  throw missingPlayer(id);
2367
2396
  }
@@ -2483,14 +2512,14 @@ class AnimationTransitionNamespace {
2483
2512
  this.hostElement = hostElement;
2484
2513
  this._engine = _engine;
2485
2514
  this.players = [];
2486
- this._triggers = {};
2515
+ this._triggers = new Map();
2487
2516
  this._queue = [];
2488
2517
  this._elementListeners = new Map();
2489
2518
  this._hostClassName = 'ng-tns-' + id;
2490
2519
  addClass(hostElement, this._hostClassName);
2491
2520
  }
2492
2521
  listen(element, name, phase, callback) {
2493
- if (!this._triggers.hasOwnProperty(name)) {
2522
+ if (!this._triggers.has(name)) {
2494
2523
  throw missingTrigger(phase, name);
2495
2524
  }
2496
2525
  if (phase == null || phase.length == 0) {
@@ -2499,14 +2528,14 @@ class AnimationTransitionNamespace {
2499
2528
  if (!isTriggerEventValid(phase)) {
2500
2529
  throw unsupportedTriggerEvent(phase, name);
2501
2530
  }
2502
- const listeners = getOrSetAsInMap(this._elementListeners, element, []);
2531
+ const listeners = getOrSetDefaultValue(this._elementListeners, element, []);
2503
2532
  const data = { name, phase, callback };
2504
2533
  listeners.push(data);
2505
- const triggersWithStates = getOrSetAsInMap(this._engine.statesByElement, element, {});
2506
- if (!triggersWithStates.hasOwnProperty(name)) {
2534
+ const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());
2535
+ if (!triggersWithStates.has(name)) {
2507
2536
  addClass(element, NG_TRIGGER_CLASSNAME);
2508
2537
  addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
2509
- triggersWithStates[name] = DEFAULT_STATE_VALUE;
2538
+ triggersWithStates.set(name, DEFAULT_STATE_VALUE);
2510
2539
  }
2511
2540
  return () => {
2512
2541
  // the event listener is removed AFTER the flush has occurred such
@@ -2517,24 +2546,24 @@ class AnimationTransitionNamespace {
2517
2546
  if (index >= 0) {
2518
2547
  listeners.splice(index, 1);
2519
2548
  }
2520
- if (!this._triggers[name]) {
2521
- delete triggersWithStates[name];
2549
+ if (!this._triggers.has(name)) {
2550
+ triggersWithStates.delete(name);
2522
2551
  }
2523
2552
  });
2524
2553
  };
2525
2554
  }
2526
2555
  register(name, ast) {
2527
- if (this._triggers[name]) {
2556
+ if (this._triggers.has(name)) {
2528
2557
  // throw
2529
2558
  return false;
2530
2559
  }
2531
2560
  else {
2532
- this._triggers[name] = ast;
2561
+ this._triggers.set(name, ast);
2533
2562
  return true;
2534
2563
  }
2535
2564
  }
2536
2565
  _getTrigger(name) {
2537
- const trigger = this._triggers[name];
2566
+ const trigger = this._triggers.get(name);
2538
2567
  if (!trigger) {
2539
2568
  throw unregisteredTrigger(name);
2540
2569
  }
@@ -2547,15 +2576,15 @@ class AnimationTransitionNamespace {
2547
2576
  if (!triggersWithStates) {
2548
2577
  addClass(element, NG_TRIGGER_CLASSNAME);
2549
2578
  addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
2550
- this._engine.statesByElement.set(element, triggersWithStates = {});
2579
+ this._engine.statesByElement.set(element, triggersWithStates = new Map());
2551
2580
  }
2552
- let fromState = triggersWithStates[triggerName];
2581
+ let fromState = triggersWithStates.get(triggerName);
2553
2582
  const toState = new StateValue(value, this.id);
2554
2583
  const isObj = value && value.hasOwnProperty('value');
2555
2584
  if (!isObj && fromState) {
2556
2585
  toState.absorbOptions(fromState.options);
2557
2586
  }
2558
- triggersWithStates[triggerName] = toState;
2587
+ triggersWithStates.set(triggerName, toState);
2559
2588
  if (!fromState) {
2560
2589
  fromState = DEFAULT_STATE_VALUE;
2561
2590
  }
@@ -2585,7 +2614,7 @@ class AnimationTransitionNamespace {
2585
2614
  }
2586
2615
  return;
2587
2616
  }
2588
- const playersOnElement = getOrSetAsInMap(this._engine.playersByElement, element, []);
2617
+ const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);
2589
2618
  playersOnElement.forEach(player => {
2590
2619
  // only remove the player if it is queued on the EXACT same trigger/namespace
2591
2620
  // we only also deal with queued players here because if the animation has
@@ -2629,10 +2658,8 @@ class AnimationTransitionNamespace {
2629
2658
  return player;
2630
2659
  }
2631
2660
  deregister(name) {
2632
- delete this._triggers[name];
2633
- this._engine.statesByElement.forEach((stateMap, element) => {
2634
- delete stateMap[name];
2635
- });
2661
+ this._triggers.delete(name);
2662
+ this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));
2636
2663
  this._elementListeners.forEach((listeners, element) => {
2637
2664
  this._elementListeners.set(element, listeners.filter(entry => {
2638
2665
  return entry.name != name;
@@ -2675,11 +2702,11 @@ class AnimationTransitionNamespace {
2675
2702
  const previousTriggersValues = new Map();
2676
2703
  if (triggerStates) {
2677
2704
  const players = [];
2678
- Object.keys(triggerStates).forEach(triggerName => {
2679
- previousTriggersValues.set(triggerName, triggerStates[triggerName].value);
2705
+ triggerStates.forEach((state, triggerName) => {
2706
+ previousTriggersValues.set(triggerName, state.value);
2680
2707
  // this check is here in the event that an element is removed
2681
2708
  // twice (both on the host level and the component level)
2682
- if (this._triggers[triggerName]) {
2709
+ if (this._triggers.has(triggerName)) {
2683
2710
  const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
2684
2711
  if (player) {
2685
2712
  players.push(player);
@@ -2708,9 +2735,9 @@ class AnimationTransitionNamespace {
2708
2735
  if (visitedTriggers.has(triggerName))
2709
2736
  return;
2710
2737
  visitedTriggers.add(triggerName);
2711
- const trigger = this._triggers[triggerName];
2738
+ const trigger = this._triggers.get(triggerName);
2712
2739
  const transition = trigger.fallbackTransition;
2713
- const fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
2740
+ const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;
2714
2741
  const toState = new StateValue(VOID_VALUE);
2715
2742
  const player = new TransitionAnimationPlayer(this.id, triggerName, element);
2716
2743
  this._engine.totalQueuedPlayers++;
@@ -2892,25 +2919,52 @@ class TransitionAnimationEngine {
2892
2919
  return this._namespaceLookup[namespaceId] = ns;
2893
2920
  }
2894
2921
  _balanceNamespaceList(ns, hostElement) {
2895
- const limit = this._namespaceList.length - 1;
2922
+ const namespaceList = this._namespaceList;
2923
+ const namespacesByHostElement = this.namespacesByHostElement;
2924
+ const limit = namespaceList.length - 1;
2896
2925
  if (limit >= 0) {
2897
2926
  let found = false;
2898
- for (let i = limit; i >= 0; i--) {
2899
- const nextNamespace = this._namespaceList[i];
2900
- if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
2901
- this._namespaceList.splice(i + 1, 0, ns);
2902
- found = true;
2903
- break;
2927
+ if (this.driver.getParentElement !== undefined) {
2928
+ // Fast path for when the driver implements `getParentElement`, which allows us to find the
2929
+ // closest ancestor with an existing namespace that we can then insert `ns` after, without
2930
+ // having to inspect all existing namespaces.
2931
+ let ancestor = this.driver.getParentElement(hostElement);
2932
+ while (ancestor) {
2933
+ const ancestorNs = namespacesByHostElement.get(ancestor);
2934
+ if (ancestorNs) {
2935
+ // An animation namespace has been registered for this ancestor, so we insert `ns`
2936
+ // right after it to establish top-down ordering of animation namespaces.
2937
+ const index = namespaceList.indexOf(ancestorNs);
2938
+ namespaceList.splice(index + 1, 0, ns);
2939
+ found = true;
2940
+ break;
2941
+ }
2942
+ ancestor = this.driver.getParentElement(ancestor);
2943
+ }
2944
+ }
2945
+ else {
2946
+ // Slow path for backwards compatibility if the driver does not implement
2947
+ // `getParentElement`, to be removed once `getParentElement` is a required method.
2948
+ for (let i = limit; i >= 0; i--) {
2949
+ const nextNamespace = namespaceList[i];
2950
+ if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
2951
+ namespaceList.splice(i + 1, 0, ns);
2952
+ found = true;
2953
+ break;
2954
+ }
2904
2955
  }
2905
2956
  }
2906
2957
  if (!found) {
2907
- this._namespaceList.splice(0, 0, ns);
2958
+ // No namespace exists that is an ancestor of `ns`, so `ns` is inserted at the front to
2959
+ // ensure that any existing descendants are ordered after `ns`, retaining the desired
2960
+ // top-down ordering.
2961
+ namespaceList.unshift(ns);
2908
2962
  }
2909
2963
  }
2910
2964
  else {
2911
- this._namespaceList.push(ns);
2965
+ namespaceList.push(ns);
2912
2966
  }
2913
- this.namespacesByHostElement.set(hostElement, ns);
2967
+ namespacesByHostElement.set(hostElement, ns);
2914
2968
  return ns;
2915
2969
  }
2916
2970
  register(namespaceId, hostElement) {
@@ -2952,11 +3006,9 @@ class TransitionAnimationEngine {
2952
3006
  const namespaces = new Set();
2953
3007
  const elementStates = this.statesByElement.get(element);
2954
3008
  if (elementStates) {
2955
- const keys = Object.keys(elementStates);
2956
- for (let i = 0; i < keys.length; i++) {
2957
- const nsId = elementStates[keys[i]].namespaceId;
2958
- if (nsId) {
2959
- const ns = this._fetchNamespace(nsId);
3009
+ for (let stateValue of elementStates.values()) {
3010
+ if (stateValue.namespaceId) {
3011
+ const ns = this._fetchNamespace(stateValue.namespaceId);
2960
3012
  if (ns) {
2961
3013
  namespaces.add(ns);
2962
3014
  }
@@ -3263,8 +3315,10 @@ class TransitionAnimationEngine {
3263
3315
  // we need to restore the previous trigger value since the element has
3264
3316
  // only been moved and hasn't actually left the DOM
3265
3317
  const triggersWithStates = this.statesByElement.get(entry.element);
3266
- if (triggersWithStates && triggersWithStates[entry.triggerName]) {
3267
- triggersWithStates[entry.triggerName].value = previousValue;
3318
+ if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {
3319
+ const state = triggersWithStates.get(entry.triggerName);
3320
+ state.value = previousValue;
3321
+ triggersWithStates.set(entry.triggerName, state);
3268
3322
  }
3269
3323
  }
3270
3324
  player.destroy();
@@ -3314,24 +3368,22 @@ class TransitionAnimationEngine {
3314
3368
  subTimelines.append(element, instruction.timelines);
3315
3369
  const tuple = { instruction, player, element };
3316
3370
  queuedInstructions.push(tuple);
3317
- instruction.queriedElements.forEach(element => getOrSetAsInMap(queriedElements, element, []).push(player));
3371
+ instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));
3318
3372
  instruction.preStyleProps.forEach((stringMap, element) => {
3319
- const props = Object.keys(stringMap);
3320
- if (props.length) {
3373
+ if (stringMap.size) {
3321
3374
  let setVal = allPreStyleElements.get(element);
3322
3375
  if (!setVal) {
3323
3376
  allPreStyleElements.set(element, setVal = new Set());
3324
3377
  }
3325
- props.forEach(prop => setVal.add(prop));
3378
+ stringMap.forEach((_, prop) => setVal.add(prop));
3326
3379
  }
3327
3380
  });
3328
3381
  instruction.postStyleProps.forEach((stringMap, element) => {
3329
- const props = Object.keys(stringMap);
3330
3382
  let setVal = allPostStyleElements.get(element);
3331
3383
  if (!setVal) {
3332
3384
  allPostStyleElements.set(element, setVal = new Set());
3333
3385
  }
3334
- props.forEach(prop => setVal.add(prop));
3386
+ stringMap.forEach((_, prop) => setVal.add(prop));
3335
3387
  });
3336
3388
  });
3337
3389
  }
@@ -3360,7 +3412,7 @@ class TransitionAnimationEngine {
3360
3412
  const element = player.element;
3361
3413
  const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
3362
3414
  previousPlayers.forEach(prevPlayer => {
3363
- getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer);
3415
+ getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);
3364
3416
  prevPlayer.destroy();
3365
3417
  });
3366
3418
  });
@@ -3390,7 +3442,7 @@ class TransitionAnimationEngine {
3390
3442
  replaceNodes.forEach(node => {
3391
3443
  const post = postStylesMap.get(node);
3392
3444
  const pre = preStylesMap.get(node);
3393
- postStylesMap.set(node, { ...post, ...pre });
3445
+ postStylesMap.set(node, new Map([...Array.from(post?.entries() ?? []), ...Array.from(pre?.entries() ?? [])]));
3394
3446
  });
3395
3447
  const rootPlayers = [];
3396
3448
  const subPlayers = [];
@@ -3584,7 +3636,7 @@ class TransitionAnimationEngine {
3584
3636
  for (const timelineInstruction of instruction.timelines) {
3585
3637
  const element = timelineInstruction.element;
3586
3638
  const isQueriedElement = element !== rootElement;
3587
- const players = getOrSetAsInMap(allPreviousPlayersMap, element, []);
3639
+ const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);
3588
3640
  const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
3589
3641
  previousPlayers.forEach(player => {
3590
3642
  const realPlayer = player.getRealPlayer();
@@ -3627,7 +3679,7 @@ class TransitionAnimationEngine {
3627
3679
  });
3628
3680
  const preStyles = preStylesMap.get(element);
3629
3681
  const postStyles = postStylesMap.get(element);
3630
- const keyframes = normalizeKeyframes(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
3682
+ const keyframes = normalizeKeyframes$1(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
3631
3683
  const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
3632
3684
  // this means that this particular player belongs to a sub trigger. It is
3633
3685
  // important that we match this player up with the corresponding (@trigger.listener)
@@ -3642,7 +3694,7 @@ class TransitionAnimationEngine {
3642
3694
  return player;
3643
3695
  });
3644
3696
  allQueriedPlayers.forEach(player => {
3645
- getOrSetAsInMap(this.playersByQueriedElement, player.element, []).push(player);
3697
+ getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);
3646
3698
  player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
3647
3699
  });
3648
3700
  allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
@@ -3654,7 +3706,7 @@ class TransitionAnimationEngine {
3654
3706
  // this basically makes all of the callbacks for sub element animations
3655
3707
  // be dependent on the upper players for when they finish
3656
3708
  allSubElements.forEach(element => {
3657
- getOrSetAsInMap(skippedPlayersMap, element, []).push(player);
3709
+ getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);
3658
3710
  });
3659
3711
  return player;
3660
3712
  }
@@ -3674,7 +3726,7 @@ class TransitionAnimationPlayer {
3674
3726
  this.element = element;
3675
3727
  this._player = new NoopAnimationPlayer();
3676
3728
  this._containsRealPlayer = false;
3677
- this._queuedCallbacks = {};
3729
+ this._queuedCallbacks = new Map();
3678
3730
  this.destroyed = false;
3679
3731
  this.markedForDestroy = false;
3680
3732
  this.disabled = false;
@@ -3685,10 +3737,10 @@ class TransitionAnimationPlayer {
3685
3737
  if (this._containsRealPlayer)
3686
3738
  return;
3687
3739
  this._player = player;
3688
- Object.keys(this._queuedCallbacks).forEach(phase => {
3689
- this._queuedCallbacks[phase].forEach(callback => listenOnPlayer(player, phase, undefined, callback));
3740
+ this._queuedCallbacks.forEach((callbacks, phase) => {
3741
+ callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));
3690
3742
  });
3691
- this._queuedCallbacks = {};
3743
+ this._queuedCallbacks.clear();
3692
3744
  this._containsRealPlayer = true;
3693
3745
  this.overrideTotalTime(player.totalTime);
3694
3746
  this.queued = false;
@@ -3708,7 +3760,7 @@ class TransitionAnimationPlayer {
3708
3760
  player.onDestroy(() => this.destroy());
3709
3761
  }
3710
3762
  _queueEvent(name, callback) {
3711
- getOrSetAsInMap(this._queuedCallbacks, name, []).push(callback);
3763
+ getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);
3712
3764
  }
3713
3765
  onDone(fn) {
3714
3766
  if (this.queued) {
@@ -3770,29 +3822,14 @@ class TransitionAnimationPlayer {
3770
3822
  }
3771
3823
  }
3772
3824
  function deleteOrUnsetInMap(map, key, value) {
3773
- let currentValues;
3774
- if (map instanceof Map) {
3775
- currentValues = map.get(key);
3776
- if (currentValues) {
3777
- if (currentValues.length) {
3778
- const index = currentValues.indexOf(value);
3779
- currentValues.splice(index, 1);
3780
- }
3781
- if (currentValues.length == 0) {
3782
- map.delete(key);
3783
- }
3825
+ let currentValues = map.get(key);
3826
+ if (currentValues) {
3827
+ if (currentValues.length) {
3828
+ const index = currentValues.indexOf(value);
3829
+ currentValues.splice(index, 1);
3784
3830
  }
3785
- }
3786
- else {
3787
- currentValues = map[key];
3788
- if (currentValues) {
3789
- if (currentValues.length) {
3790
- const index = currentValues.indexOf(value);
3791
- currentValues.splice(index, 1);
3792
- }
3793
- if (currentValues.length == 0) {
3794
- delete map[key];
3795
- }
3831
+ if (currentValues.length == 0) {
3832
+ map.delete(key);
3796
3833
  }
3797
3834
  }
3798
3835
  return currentValues;
@@ -3819,9 +3856,10 @@ function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, def
3819
3856
  elements.forEach(element => cloakVals.push(cloakElement(element)));
3820
3857
  const failedElements = [];
3821
3858
  elementPropsMap.forEach((props, element) => {
3822
- const styles = {};
3859
+ const styles = new Map();
3823
3860
  props.forEach(prop => {
3824
- const value = styles[prop] = driver.computeStyle(element, prop, defaultStyle);
3861
+ const value = driver.computeStyle(element, prop, defaultStyle);
3862
+ styles.set(prop, value);
3825
3863
  // there is no easy way to detect this because a sub element could be removed
3826
3864
  // by a parent animation element being detached.
3827
3865
  if (!value || value.length == 0) {
@@ -4005,13 +4043,6 @@ class AnimationEngine {
4005
4043
  }
4006
4044
  }
4007
4045
 
4008
- /**
4009
- * @license
4010
- * Copyright Google LLC All Rights Reserved.
4011
- *
4012
- * Use of this source code is governed by an MIT-style license that can be
4013
- * found in the LICENSE file at https://angular.io/license
4014
- */
4015
4046
  /**
4016
4047
  * Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
4017
4048
  * detected.
@@ -4032,7 +4063,7 @@ function packageNonAnimatableStyles(element, styles) {
4032
4063
  endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
4033
4064
  }
4034
4065
  }
4035
- else if (styles) {
4066
+ else if (styles instanceof Map) {
4036
4067
  startStyles = filterNonAnimatableStyles(styles);
4037
4068
  }
4038
4069
  return (startStyles || endStyles) ? new SpecialCasedStyles(element, startStyles, endStyles) :
@@ -4054,7 +4085,7 @@ class SpecialCasedStyles {
4054
4085
  this._state = 0 /* Pending */;
4055
4086
  let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
4056
4087
  if (!initialStyles) {
4057
- SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = {});
4088
+ SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());
4058
4089
  }
4059
4090
  this._initialStyles = initialStyles;
4060
4091
  }
@@ -4097,14 +4128,12 @@ class SpecialCasedStyles {
4097
4128
  SpecialCasedStyles.initialStylesByElement = ( /* @__PURE__ */new WeakMap());
4098
4129
  function filterNonAnimatableStyles(styles) {
4099
4130
  let result = null;
4100
- const props = Object.keys(styles);
4101
- for (let i = 0; i < props.length; i++) {
4102
- const prop = props[i];
4131
+ styles.forEach((val, prop) => {
4103
4132
  if (isNonAnimatableStyle(prop)) {
4104
- result = result || {};
4105
- result[prop] = styles[prop];
4133
+ result = result || new Map();
4134
+ result.set(prop, val);
4106
4135
  }
4107
- }
4136
+ });
4108
4137
  return result;
4109
4138
  }
4110
4139
  function isNonAnimatableStyle(prop) {
@@ -4126,7 +4155,7 @@ class WebAnimationsPlayer {
4126
4155
  this._destroyed = false;
4127
4156
  this.time = 0;
4128
4157
  this.parentPlayer = null;
4129
- this.currentSnapshot = {};
4158
+ this.currentSnapshot = new Map();
4130
4159
  this._duration = options['duration'];
4131
4160
  this._delay = options['delay'] || 0;
4132
4161
  this.time = this._duration + this._delay;
@@ -4149,7 +4178,7 @@ class WebAnimationsPlayer {
4149
4178
  const keyframes = this.keyframes;
4150
4179
  this.domPlayer =
4151
4180
  this._triggerWebAnimation(this.element, keyframes, this.options);
4152
- this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
4181
+ this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();
4153
4182
  this.domPlayer.addEventListener('finish', () => this._onFinish());
4154
4183
  }
4155
4184
  _preparePlayerBeforeStart() {
@@ -4161,11 +4190,18 @@ class WebAnimationsPlayer {
4161
4190
  this.domPlayer.pause();
4162
4191
  }
4163
4192
  }
4193
+ _convertKeyframesToObject(keyframes) {
4194
+ const kfs = [];
4195
+ keyframes.forEach(frame => {
4196
+ kfs.push(Object.fromEntries(frame));
4197
+ });
4198
+ return kfs;
4199
+ }
4164
4200
  /** @internal */
4165
4201
  _triggerWebAnimation(element, keyframes, options) {
4166
4202
  // jscompiler doesn't seem to know animate is a native property because it's not fully
4167
4203
  // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
4168
- return element['animate'](keyframes, options);
4204
+ return element['animate'](this._convertKeyframesToObject(keyframes), options);
4169
4205
  }
4170
4206
  onStart(fn) {
4171
4207
  this._onStartFns.push(fn);
@@ -4243,15 +4279,15 @@ class WebAnimationsPlayer {
4243
4279
  return this._delay + this._duration;
4244
4280
  }
4245
4281
  beforeDestroy() {
4246
- const styles = {};
4282
+ const styles = new Map();
4247
4283
  if (this.hasStarted()) {
4248
4284
  // note: this code is invoked only when the `play` function was called prior to this
4249
4285
  // (thus `hasStarted` returns true), this implies that the code that initializes
4250
4286
  // `_finalKeyframe` has also been executed and the non-null assertion can be safely used here
4251
4287
  const finalKeyframe = this._finalKeyframe;
4252
- Object.keys(finalKeyframe).forEach(prop => {
4253
- if (prop != 'offset') {
4254
- styles[prop] = this._finished ? finalKeyframe[prop] : computeStyle(this.element, prop);
4288
+ finalKeyframe.forEach((val, prop) => {
4289
+ if (prop !== 'offset') {
4290
+ styles.set(prop, this._finished ? val : computeStyle(this.element, prop));
4255
4291
  }
4256
4292
  });
4257
4293
  }
@@ -4259,7 +4295,7 @@ class WebAnimationsPlayer {
4259
4295
  }
4260
4296
  /** @internal */
4261
4297
  triggerCallback(phaseName) {
4262
- const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
4298
+ const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;
4263
4299
  methods.forEach(fn => fn());
4264
4300
  methods.length = 0;
4265
4301
  }
@@ -4276,6 +4312,9 @@ class WebAnimationsDriver {
4276
4312
  containsElement(elm1, elm2) {
4277
4313
  return containsElement(elm1, elm2);
4278
4314
  }
4315
+ getParentElement(element) {
4316
+ return getParentElement(element);
4317
+ }
4279
4318
  query(element, selector, multi) {
4280
4319
  return invokeQuery(element, selector, multi);
4281
4320
  }
@@ -4290,18 +4329,17 @@ class WebAnimationsDriver {
4290
4329
  if (easing) {
4291
4330
  playerOptions['easing'] = easing;
4292
4331
  }
4293
- const previousStyles = {};
4332
+ const previousStyles = new Map();
4294
4333
  const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);
4295
4334
  if (allowPreviousPlayerStylesMerge(duration, delay)) {
4296
4335
  previousWebAnimationPlayers.forEach(player => {
4297
- let styles = player.currentSnapshot;
4298
- Object.keys(styles).forEach(prop => previousStyles[prop] = styles[prop]);
4336
+ player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));
4299
4337
  });
4300
4338
  }
4301
- keyframes = keyframes.map(styles => copyStyles(styles, false));
4302
- keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
4303
- const specialStyles = packageNonAnimatableStyles(element, keyframes);
4304
- return new WebAnimationsPlayer(element, keyframes, playerOptions, specialStyles);
4339
+ let _keyframes = normalizeKeyframes(keyframes).map(styles => copyStyles(styles));
4340
+ _keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);
4341
+ const specialStyles = packageNonAnimatableStyles(element, _keyframes);
4342
+ return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);
4305
4343
  }
4306
4344
  }
4307
4345
 
@@ -4341,5 +4379,5 @@ class WebAnimationsDriver {
4341
4379
  * Generated bundle index. Do not edit.
4342
4380
  */
4343
4381
 
4344
- export { AnimationDriver, Animation as ɵAnimation, AnimationEngine as ɵAnimationEngine, AnimationStyleNormalizer as ɵAnimationStyleNormalizer, NoopAnimationDriver as ɵNoopAnimationDriver, NoopAnimationStyleNormalizer as ɵNoopAnimationStyleNormalizer, WebAnimationsDriver as ɵWebAnimationsDriver, WebAnimationsPlayer as ɵWebAnimationsPlayer, WebAnimationsStyleNormalizer as ɵWebAnimationsStyleNormalizer, allowPreviousPlayerStylesMerge as ɵallowPreviousPlayerStylesMerge, containsElement as ɵcontainsElement, invokeQuery as ɵinvokeQuery, validateStyleProperty as ɵvalidateStyleProperty };
4382
+ export { AnimationDriver, Animation as ɵAnimation, AnimationEngine as ɵAnimationEngine, AnimationStyleNormalizer as ɵAnimationStyleNormalizer, NoopAnimationDriver as ɵNoopAnimationDriver, NoopAnimationStyleNormalizer as ɵNoopAnimationStyleNormalizer, WebAnimationsDriver as ɵWebAnimationsDriver, WebAnimationsPlayer as ɵWebAnimationsPlayer, WebAnimationsStyleNormalizer as ɵWebAnimationsStyleNormalizer, allowPreviousPlayerStylesMerge as ɵallowPreviousPlayerStylesMerge, containsElement as ɵcontainsElement, getParentElement as ɵgetParentElement, invokeQuery as ɵinvokeQuery, normalizeKeyframes as ɵnormalizeKeyframes, validateStyleProperty as ɵvalidateStyleProperty };
4345
4383
  //# sourceMappingURL=browser.mjs.map