UNPKG

206 kBJavaScriptView Raw
1/**
2 * @license Angular v9.0.1
3 * (c) 2010-2020 Google LLC. https://angular.io/
4 * License: MIT
5 */
6
7import { __spread, __decorate, __read, __extends, __assign, __values } from 'tslib';
8import { ɵAnimationGroupPlayer, NoopAnimationPlayer, AUTO_STYLE, ɵPRE_STYLE, sequence, style } from '@angular/animations';
9import { Injectable } from '@angular/core';
10
11function isBrowser() {
12 return (typeof window !== 'undefined' && typeof window.document !== 'undefined');
13}
14function isNode() {
15 return (typeof process !== 'undefined');
16}
17function optimizeGroupPlayer(players) {
18 switch (players.length) {
19 case 0:
20 return new NoopAnimationPlayer();
21 case 1:
22 return players[0];
23 default:
24 return new ɵAnimationGroupPlayer(players);
25 }
26}
27function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles, postStyles) {
28 if (preStyles === void 0) { preStyles = {}; }
29 if (postStyles === void 0) { postStyles = {}; }
30 var errors = [];
31 var normalizedKeyframes = [];
32 var previousOffset = -1;
33 var previousKeyframe = null;
34 keyframes.forEach(function (kf) {
35 var offset = kf['offset'];
36 var isSameOffset = offset == previousOffset;
37 var normalizedKeyframe = (isSameOffset && previousKeyframe) || {};
38 Object.keys(kf).forEach(function (prop) {
39 var normalizedProp = prop;
40 var normalizedValue = kf[prop];
41 if (prop !== 'offset') {
42 normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
43 switch (normalizedValue) {
44 case ɵPRE_STYLE:
45 normalizedValue = preStyles[prop];
46 break;
47 case AUTO_STYLE:
48 normalizedValue = postStyles[prop];
49 break;
50 default:
51 normalizedValue =
52 normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);
53 break;
54 }
55 }
56 normalizedKeyframe[normalizedProp] = normalizedValue;
57 });
58 if (!isSameOffset) {
59 normalizedKeyframes.push(normalizedKeyframe);
60 }
61 previousKeyframe = normalizedKeyframe;
62 previousOffset = offset;
63 });
64 if (errors.length) {
65 var LINE_START = '\n - ';
66 throw new Error("Unable to animate due to the following errors:" + LINE_START + errors.join(LINE_START));
67 }
68 return normalizedKeyframes;
69}
70function listenOnPlayer(player, eventName, event, callback) {
71 switch (eventName) {
72 case 'start':
73 player.onStart(function () { return callback(event && copyAnimationEvent(event, 'start', player)); });
74 break;
75 case 'done':
76 player.onDone(function () { return callback(event && copyAnimationEvent(event, 'done', player)); });
77 break;
78 case 'destroy':
79 player.onDestroy(function () { return callback(event && copyAnimationEvent(event, 'destroy', player)); });
80 break;
81 }
82}
83function copyAnimationEvent(e, phaseName, player) {
84 var totalTime = player.totalTime;
85 var disabled = player.disabled ? true : false;
86 var event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);
87 var data = e['_data'];
88 if (data != null) {
89 event['_data'] = data;
90 }
91 return event;
92}
93function makeAnimationEvent(element, triggerName, fromState, toState, phaseName, totalTime, disabled) {
94 if (phaseName === void 0) { phaseName = ''; }
95 if (totalTime === void 0) { totalTime = 0; }
96 return { element: element, triggerName: triggerName, fromState: fromState, toState: toState, phaseName: phaseName, totalTime: totalTime, disabled: !!disabled };
97}
98function getOrSetAsInMap(map, key, defaultValue) {
99 var value;
100 if (map instanceof Map) {
101 value = map.get(key);
102 if (!value) {
103 map.set(key, value = defaultValue);
104 }
105 }
106 else {
107 value = map[key];
108 if (!value) {
109 value = map[key] = defaultValue;
110 }
111 }
112 return value;
113}
114function parseTimelineCommand(command) {
115 var separatorPos = command.indexOf(':');
116 var id = command.substring(1, separatorPos);
117 var action = command.substr(separatorPos + 1);
118 return [id, action];
119}
120var _contains = function (elm1, elm2) { return false; };
121var ɵ0 = _contains;
122var _matches = function (element, selector) {
123 return false;
124};
125var ɵ1 = _matches;
126var _query = function (element, selector, multi) {
127 return [];
128};
129var ɵ2 = _query;
130// Define utility methods for browsers and platform-server(domino) where Element
131// and utility methods exist.
132var _isNode = isNode();
133if (_isNode || typeof Element !== 'undefined') {
134 // this is well supported in all browsers
135 _contains = function (elm1, elm2) { return elm1.contains(elm2); };
136 _matches = (function () {
137 if (_isNode || Element.prototype.matches) {
138 return function (element, selector) { return element.matches(selector); };
139 }
140 else {
141 var proto = Element.prototype;
142 var fn_1 = proto.matchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector ||
143 proto.oMatchesSelector || proto.webkitMatchesSelector;
144 if (fn_1) {
145 return function (element, selector) { return fn_1.apply(element, [selector]); };
146 }
147 else {
148 return _matches;
149 }
150 }
151 })();
152 _query = function (element, selector, multi) {
153 var results = [];
154 if (multi) {
155 results.push.apply(results, __spread(element.querySelectorAll(selector)));
156 }
157 else {
158 var elm = element.querySelector(selector);
159 if (elm) {
160 results.push(elm);
161 }
162 }
163 return results;
164 };
165}
166function containsVendorPrefix(prop) {
167 // Webkit is the only real popular vendor prefix nowadays
168 // cc: http://shouldiprefix.com/
169 return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit
170}
171var _CACHED_BODY = null;
172var _IS_WEBKIT = false;
173function validateStyleProperty(prop) {
174 if (!_CACHED_BODY) {
175 _CACHED_BODY = getBodyNode() || {};
176 _IS_WEBKIT = _CACHED_BODY.style ? ('WebkitAppearance' in _CACHED_BODY.style) : false;
177 }
178 var result = true;
179 if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {
180 result = prop in _CACHED_BODY.style;
181 if (!result && _IS_WEBKIT) {
182 var camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.substr(1);
183 result = camelProp in _CACHED_BODY.style;
184 }
185 }
186 return result;
187}
188function getBodyNode() {
189 if (typeof document != 'undefined') {
190 return document.body;
191 }
192 return null;
193}
194var matchesElement = _matches;
195var containsElement = _contains;
196var invokeQuery = _query;
197function hypenatePropsObject(object) {
198 var newObj = {};
199 Object.keys(object).forEach(function (prop) {
200 var newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
201 newObj[newProp] = object[prop];
202 });
203 return newObj;
204}
205
206/**
207 * @publicApi
208 */
209var NoopAnimationDriver = /** @class */ (function () {
210 function NoopAnimationDriver() {
211 }
212 NoopAnimationDriver.prototype.validateStyleProperty = function (prop) { return validateStyleProperty(prop); };
213 NoopAnimationDriver.prototype.matchesElement = function (element, selector) {
214 return matchesElement(element, selector);
215 };
216 NoopAnimationDriver.prototype.containsElement = function (elm1, elm2) { return containsElement(elm1, elm2); };
217 NoopAnimationDriver.prototype.query = function (element, selector, multi) {
218 return invokeQuery(element, selector, multi);
219 };
220 NoopAnimationDriver.prototype.computeStyle = function (element, prop, defaultValue) {
221 return defaultValue || '';
222 };
223 NoopAnimationDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
224 if (previousPlayers === void 0) { previousPlayers = []; }
225 return new NoopAnimationPlayer(duration, delay);
226 };
227 NoopAnimationDriver = __decorate([
228 Injectable()
229 ], NoopAnimationDriver);
230 return NoopAnimationDriver;
231}());
232/**
233 * @publicApi
234 */
235var AnimationDriver = /** @class */ (function () {
236 function AnimationDriver() {
237 }
238 AnimationDriver.NOOP = new NoopAnimationDriver();
239 return AnimationDriver;
240}());
241
242/**
243 * @license
244 * Copyright Google Inc. All Rights Reserved.
245 *
246 * Use of this source code is governed by an MIT-style license that can be
247 * found in the LICENSE file at https://angular.io/license
248 */
249var ONE_SECOND = 1000;
250var SUBSTITUTION_EXPR_START = '{{';
251var SUBSTITUTION_EXPR_END = '}}';
252var ENTER_CLASSNAME = 'ng-enter';
253var LEAVE_CLASSNAME = 'ng-leave';
254var ENTER_SELECTOR = '.ng-enter';
255var LEAVE_SELECTOR = '.ng-leave';
256var NG_TRIGGER_CLASSNAME = 'ng-trigger';
257var NG_TRIGGER_SELECTOR = '.ng-trigger';
258var NG_ANIMATING_CLASSNAME = 'ng-animating';
259var NG_ANIMATING_SELECTOR = '.ng-animating';
260function resolveTimingValue(value) {
261 if (typeof value == 'number')
262 return value;
263 var matches = value.match(/^(-?[\.\d]+)(m?s)/);
264 if (!matches || matches.length < 2)
265 return 0;
266 return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
267}
268function _convertTimeValueToMS(value, unit) {
269 switch (unit) {
270 case 's':
271 return value * ONE_SECOND;
272 default: // ms or something else
273 return value;
274 }
275}
276function resolveTiming(timings, errors, allowNegativeValues) {
277 return timings.hasOwnProperty('duration') ?
278 timings :
279 parseTimeExpression(timings, errors, allowNegativeValues);
280}
281function parseTimeExpression(exp, errors, allowNegativeValues) {
282 var regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
283 var duration;
284 var delay = 0;
285 var easing = '';
286 if (typeof exp === 'string') {
287 var matches = exp.match(regex);
288 if (matches === null) {
289 errors.push("The provided timing value \"" + exp + "\" is invalid.");
290 return { duration: 0, delay: 0, easing: '' };
291 }
292 duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
293 var delayMatch = matches[3];
294 if (delayMatch != null) {
295 delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);
296 }
297 var easingVal = matches[5];
298 if (easingVal) {
299 easing = easingVal;
300 }
301 }
302 else {
303 duration = exp;
304 }
305 if (!allowNegativeValues) {
306 var containsErrors = false;
307 var startIndex = errors.length;
308 if (duration < 0) {
309 errors.push("Duration values below 0 are not allowed for this animation step.");
310 containsErrors = true;
311 }
312 if (delay < 0) {
313 errors.push("Delay values below 0 are not allowed for this animation step.");
314 containsErrors = true;
315 }
316 if (containsErrors) {
317 errors.splice(startIndex, 0, "The provided timing value \"" + exp + "\" is invalid.");
318 }
319 }
320 return { duration: duration, delay: delay, easing: easing };
321}
322function copyObj(obj, destination) {
323 if (destination === void 0) { destination = {}; }
324 Object.keys(obj).forEach(function (prop) { destination[prop] = obj[prop]; });
325 return destination;
326}
327function normalizeStyles(styles) {
328 var normalizedStyles = {};
329 if (Array.isArray(styles)) {
330 styles.forEach(function (data) { return copyStyles(data, false, normalizedStyles); });
331 }
332 else {
333 copyStyles(styles, false, normalizedStyles);
334 }
335 return normalizedStyles;
336}
337function copyStyles(styles, readPrototype, destination) {
338 if (destination === void 0) { destination = {}; }
339 if (readPrototype) {
340 // we make use of a for-in loop so that the
341 // prototypically inherited properties are
342 // revealed from the backFill map
343 for (var prop in styles) {
344 destination[prop] = styles[prop];
345 }
346 }
347 else {
348 copyObj(styles, destination);
349 }
350 return destination;
351}
352function getStyleAttributeString(element, key, value) {
353 // Return the key-value pair string to be added to the style attribute for the
354 // given CSS style key.
355 if (value) {
356 return key + ':' + value + ';';
357 }
358 else {
359 return '';
360 }
361}
362function writeStyleAttribute(element) {
363 // Read the style property of the element and manually reflect it to the
364 // style attribute. This is needed because Domino on platform-server doesn't
365 // understand the full set of allowed CSS properties and doesn't reflect some
366 // of them automatically.
367 var styleAttrValue = '';
368 for (var i = 0; i < element.style.length; i++) {
369 var key = element.style.item(i);
370 styleAttrValue += getStyleAttributeString(element, key, element.style.getPropertyValue(key));
371 }
372 for (var key in element.style) {
373 // Skip internal Domino properties that don't need to be reflected.
374 if (!element.style.hasOwnProperty(key) || key.startsWith('_')) {
375 continue;
376 }
377 var dashKey = camelCaseToDashCase(key);
378 styleAttrValue += getStyleAttributeString(element, dashKey, element.style[key]);
379 }
380 element.setAttribute('style', styleAttrValue);
381}
382function setStyles(element, styles, formerStyles) {
383 if (element['style']) {
384 Object.keys(styles).forEach(function (prop) {
385 var camelProp = dashCaseToCamelCase(prop);
386 if (formerStyles && !formerStyles.hasOwnProperty(prop)) {
387 formerStyles[prop] = element.style[camelProp];
388 }
389 element.style[camelProp] = styles[prop];
390 });
391 // On the server set the 'style' attribute since it's not automatically reflected.
392 if (isNode()) {
393 writeStyleAttribute(element);
394 }
395 }
396}
397function eraseStyles(element, styles) {
398 if (element['style']) {
399 Object.keys(styles).forEach(function (prop) {
400 var camelProp = dashCaseToCamelCase(prop);
401 element.style[camelProp] = '';
402 });
403 // On the server set the 'style' attribute since it's not automatically reflected.
404 if (isNode()) {
405 writeStyleAttribute(element);
406 }
407 }
408}
409function normalizeAnimationEntry(steps) {
410 if (Array.isArray(steps)) {
411 if (steps.length == 1)
412 return steps[0];
413 return sequence(steps);
414 }
415 return steps;
416}
417function validateStyleParams(value, options, errors) {
418 var params = options.params || {};
419 var matches = extractStyleParams(value);
420 if (matches.length) {
421 matches.forEach(function (varName) {
422 if (!params.hasOwnProperty(varName)) {
423 errors.push("Unable to resolve the local animation param " + varName + " in the given list of values");
424 }
425 });
426 }
427}
428var PARAM_REGEX = new RegExp(SUBSTITUTION_EXPR_START + "\\s*(.+?)\\s*" + SUBSTITUTION_EXPR_END, 'g');
429function extractStyleParams(value) {
430 var params = [];
431 if (typeof value === 'string') {
432 var match = void 0;
433 while (match = PARAM_REGEX.exec(value)) {
434 params.push(match[1]);
435 }
436 PARAM_REGEX.lastIndex = 0;
437 }
438 return params;
439}
440function interpolateParams(value, params, errors) {
441 var original = value.toString();
442 var str = original.replace(PARAM_REGEX, function (_, varName) {
443 var localVal = params[varName];
444 // this means that the value was never overridden by the data passed in by the user
445 if (!params.hasOwnProperty(varName)) {
446 errors.push("Please provide a value for the animation param " + varName);
447 localVal = '';
448 }
449 return localVal.toString();
450 });
451 // we do this to assert that numeric values stay as they are
452 return str == original ? value : str;
453}
454function iteratorToArray(iterator) {
455 var arr = [];
456 var item = iterator.next();
457 while (!item.done) {
458 arr.push(item.value);
459 item = iterator.next();
460 }
461 return arr;
462}
463function mergeAnimationOptions(source, destination) {
464 if (source.params) {
465 var p0_1 = source.params;
466 if (!destination.params) {
467 destination.params = {};
468 }
469 var p1_1 = destination.params;
470 Object.keys(p0_1).forEach(function (param) {
471 if (!p1_1.hasOwnProperty(param)) {
472 p1_1[param] = p0_1[param];
473 }
474 });
475 }
476 return destination;
477}
478var DASH_CASE_REGEXP = /-+([a-z0-9])/g;
479function dashCaseToCamelCase(input) {
480 return input.replace(DASH_CASE_REGEXP, function () {
481 var m = [];
482 for (var _i = 0; _i < arguments.length; _i++) {
483 m[_i] = arguments[_i];
484 }
485 return m[1].toUpperCase();
486 });
487}
488function camelCaseToDashCase(input) {
489 return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
490}
491function allowPreviousPlayerStylesMerge(duration, delay) {
492 return duration === 0 || delay === 0;
493}
494function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
495 var previousStyleProps = Object.keys(previousStyles);
496 if (previousStyleProps.length && keyframes.length) {
497 var startingKeyframe_1 = keyframes[0];
498 var missingStyleProps_1 = [];
499 previousStyleProps.forEach(function (prop) {
500 if (!startingKeyframe_1.hasOwnProperty(prop)) {
501 missingStyleProps_1.push(prop);
502 }
503 startingKeyframe_1[prop] = previousStyles[prop];
504 });
505 if (missingStyleProps_1.length) {
506 var _loop_1 = function () {
507 var kf = keyframes[i];
508 missingStyleProps_1.forEach(function (prop) { kf[prop] = computeStyle(element, prop); });
509 };
510 // tslint:disable-next-line
511 for (var i = 1; i < keyframes.length; i++) {
512 _loop_1();
513 }
514 }
515 }
516 return keyframes;
517}
518function visitDslNode(visitor, node, context) {
519 switch (node.type) {
520 case 7 /* Trigger */:
521 return visitor.visitTrigger(node, context);
522 case 0 /* State */:
523 return visitor.visitState(node, context);
524 case 1 /* Transition */:
525 return visitor.visitTransition(node, context);
526 case 2 /* Sequence */:
527 return visitor.visitSequence(node, context);
528 case 3 /* Group */:
529 return visitor.visitGroup(node, context);
530 case 4 /* Animate */:
531 return visitor.visitAnimate(node, context);
532 case 5 /* Keyframes */:
533 return visitor.visitKeyframes(node, context);
534 case 6 /* Style */:
535 return visitor.visitStyle(node, context);
536 case 8 /* Reference */:
537 return visitor.visitReference(node, context);
538 case 9 /* AnimateChild */:
539 return visitor.visitAnimateChild(node, context);
540 case 10 /* AnimateRef */:
541 return visitor.visitAnimateRef(node, context);
542 case 11 /* Query */:
543 return visitor.visitQuery(node, context);
544 case 12 /* Stagger */:
545 return visitor.visitStagger(node, context);
546 default:
547 throw new Error("Unable to resolve animation metadata node #" + node.type);
548 }
549}
550function computeStyle(element, prop) {
551 return window.getComputedStyle(element)[prop];
552}
553
554/**
555 * @license
556 * Copyright Google Inc. All Rights Reserved.
557 *
558 * Use of this source code is governed by an MIT-style license that can be
559 * found in the LICENSE file at https://angular.io/license
560 */
561var ANY_STATE = '*';
562function parseTransitionExpr(transitionValue, errors) {
563 var expressions = [];
564 if (typeof transitionValue == 'string') {
565 transitionValue.split(/\s*,\s*/).forEach(function (str) { return parseInnerTransitionStr(str, expressions, errors); });
566 }
567 else {
568 expressions.push(transitionValue);
569 }
570 return expressions;
571}
572function parseInnerTransitionStr(eventStr, expressions, errors) {
573 if (eventStr[0] == ':') {
574 var result = parseAnimationAlias(eventStr, errors);
575 if (typeof result == 'function') {
576 expressions.push(result);
577 return;
578 }
579 eventStr = result;
580 }
581 var match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
582 if (match == null || match.length < 4) {
583 errors.push("The provided transition expression \"" + eventStr + "\" is not supported");
584 return expressions;
585 }
586 var fromState = match[1];
587 var separator = match[2];
588 var toState = match[3];
589 expressions.push(makeLambdaFromStates(fromState, toState));
590 var isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
591 if (separator[0] == '<' && !isFullAnyStateExpr) {
592 expressions.push(makeLambdaFromStates(toState, fromState));
593 }
594}
595function parseAnimationAlias(alias, errors) {
596 switch (alias) {
597 case ':enter':
598 return 'void => *';
599 case ':leave':
600 return '* => void';
601 case ':increment':
602 return function (fromState, toState) { return parseFloat(toState) > parseFloat(fromState); };
603 case ':decrement':
604 return function (fromState, toState) { return parseFloat(toState) < parseFloat(fromState); };
605 default:
606 errors.push("The transition alias value \"" + alias + "\" is not supported");
607 return '* => *';
608 }
609}
610// DO NOT REFACTOR ... keep the follow set instantiations
611// with the values intact (closure compiler for some reason
612// removes follow-up lines that add the values outside of
613// the constructor...
614var TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
615var FALSE_BOOLEAN_VALUES = new Set(['false', '0']);
616function makeLambdaFromStates(lhs, rhs) {
617 var LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
618 var RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);
619 return function (fromState, toState) {
620 var lhsMatch = lhs == ANY_STATE || lhs == fromState;
621 var rhsMatch = rhs == ANY_STATE || rhs == toState;
622 if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
623 lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
624 }
625 if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
626 rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
627 }
628 return lhsMatch && rhsMatch;
629 };
630}
631
632var SELF_TOKEN = ':self';
633var SELF_TOKEN_REGEX = new RegExp("s*" + SELF_TOKEN + "s*,?", 'g');
634/*
635 * [Validation]
636 * The visitor code below will traverse the animation AST generated by the animation verb functions
637 * (the output is a tree of objects) and attempt to perform a series of validations on the data. The
638 * following corner-cases will be validated:
639 *
640 * 1. Overlap of animations
641 * Given that a CSS property cannot be animated in more than one place at the same time, it's
642 * important that this behavior is detected and validated. The way in which this occurs is that
643 * each time a style property is examined, a string-map containing the property will be updated with
644 * the start and end times for when the property is used within an animation step.
645 *
646 * If there are two or more parallel animations that are currently running (these are invoked by the
647 * group()) on the same element then the validator will throw an error. Since the start/end timing
648 * values are collected for each property then if the current animation step is animating the same
649 * property and its timing values fall anywhere into the window of time that the property is
650 * currently being animated within then this is what causes an error.
651 *
652 * 2. Timing values
653 * The validator will validate to see if a timing value of `duration delay easing` or
654 * `durationNumber` is valid or not.
655 *
656 * (note that upon validation the code below will replace the timing data with an object containing
657 * {duration,delay,easing}.
658 *
659 * 3. Offset Validation
660 * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
661 * Offsets within keyframes() are considered valid when:
662 *
663 * - No offsets are used at all
664 * - Each style() entry contains an offset value
665 * - Each offset is between 0 and 1
666 * - Each offset is greater to or equal than the previous one
667 *
668 * Otherwise an error will be thrown.
669 */
670function buildAnimationAst(driver, metadata, errors) {
671 return new AnimationAstBuilderVisitor(driver).build(metadata, errors);
672}
673var ROOT_SELECTOR = '';
674var AnimationAstBuilderVisitor = /** @class */ (function () {
675 function AnimationAstBuilderVisitor(_driver) {
676 this._driver = _driver;
677 }
678 AnimationAstBuilderVisitor.prototype.build = function (metadata, errors) {
679 var context = new AnimationAstBuilderContext(errors);
680 this._resetContextStyleTimingState(context);
681 return visitDslNode(this, normalizeAnimationEntry(metadata), context);
682 };
683 AnimationAstBuilderVisitor.prototype._resetContextStyleTimingState = function (context) {
684 context.currentQuerySelector = ROOT_SELECTOR;
685 context.collectedStyles = {};
686 context.collectedStyles[ROOT_SELECTOR] = {};
687 context.currentTime = 0;
688 };
689 AnimationAstBuilderVisitor.prototype.visitTrigger = function (metadata, context) {
690 var _this = this;
691 var queryCount = context.queryCount = 0;
692 var depCount = context.depCount = 0;
693 var states = [];
694 var transitions = [];
695 if (metadata.name.charAt(0) == '@') {
696 context.errors.push('animation triggers cannot be prefixed with an `@` sign (e.g. trigger(\'@foo\', [...]))');
697 }
698 metadata.definitions.forEach(function (def) {
699 _this._resetContextStyleTimingState(context);
700 if (def.type == 0 /* State */) {
701 var stateDef_1 = def;
702 var name_1 = stateDef_1.name;
703 name_1.toString().split(/\s*,\s*/).forEach(function (n) {
704 stateDef_1.name = n;
705 states.push(_this.visitState(stateDef_1, context));
706 });
707 stateDef_1.name = name_1;
708 }
709 else if (def.type == 1 /* Transition */) {
710 var transition = _this.visitTransition(def, context);
711 queryCount += transition.queryCount;
712 depCount += transition.depCount;
713 transitions.push(transition);
714 }
715 else {
716 context.errors.push('only state() and transition() definitions can sit inside of a trigger()');
717 }
718 });
719 return {
720 type: 7 /* Trigger */,
721 name: metadata.name, states: states, transitions: transitions, queryCount: queryCount, depCount: depCount,
722 options: null
723 };
724 };
725 AnimationAstBuilderVisitor.prototype.visitState = function (metadata, context) {
726 var styleAst = this.visitStyle(metadata.styles, context);
727 var astParams = (metadata.options && metadata.options.params) || null;
728 if (styleAst.containsDynamicStyles) {
729 var missingSubs_1 = new Set();
730 var params_1 = astParams || {};
731 styleAst.styles.forEach(function (value) {
732 if (isObject(value)) {
733 var stylesObj_1 = value;
734 Object.keys(stylesObj_1).forEach(function (prop) {
735 extractStyleParams(stylesObj_1[prop]).forEach(function (sub) {
736 if (!params_1.hasOwnProperty(sub)) {
737 missingSubs_1.add(sub);
738 }
739 });
740 });
741 }
742 });
743 if (missingSubs_1.size) {
744 var missingSubsArr = iteratorToArray(missingSubs_1.values());
745 context.errors.push("state(\"" + metadata.name + "\", ...) must define default values for all the following style substitutions: " + missingSubsArr.join(', '));
746 }
747 }
748 return {
749 type: 0 /* State */,
750 name: metadata.name,
751 style: styleAst,
752 options: astParams ? { params: astParams } : null
753 };
754 };
755 AnimationAstBuilderVisitor.prototype.visitTransition = function (metadata, context) {
756 context.queryCount = 0;
757 context.depCount = 0;
758 var animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
759 var matchers = parseTransitionExpr(metadata.expr, context.errors);
760 return {
761 type: 1 /* Transition */,
762 matchers: matchers,
763 animation: animation,
764 queryCount: context.queryCount,
765 depCount: context.depCount,
766 options: normalizeAnimationOptions(metadata.options)
767 };
768 };
769 AnimationAstBuilderVisitor.prototype.visitSequence = function (metadata, context) {
770 var _this = this;
771 return {
772 type: 2 /* Sequence */,
773 steps: metadata.steps.map(function (s) { return visitDslNode(_this, s, context); }),
774 options: normalizeAnimationOptions(metadata.options)
775 };
776 };
777 AnimationAstBuilderVisitor.prototype.visitGroup = function (metadata, context) {
778 var _this = this;
779 var currentTime = context.currentTime;
780 var furthestTime = 0;
781 var steps = metadata.steps.map(function (step) {
782 context.currentTime = currentTime;
783 var innerAst = visitDslNode(_this, step, context);
784 furthestTime = Math.max(furthestTime, context.currentTime);
785 return innerAst;
786 });
787 context.currentTime = furthestTime;
788 return {
789 type: 3 /* Group */,
790 steps: steps,
791 options: normalizeAnimationOptions(metadata.options)
792 };
793 };
794 AnimationAstBuilderVisitor.prototype.visitAnimate = function (metadata, context) {
795 var timingAst = constructTimingAst(metadata.timings, context.errors);
796 context.currentAnimateTimings = timingAst;
797 var styleAst;
798 var styleMetadata = metadata.styles ? metadata.styles : style({});
799 if (styleMetadata.type == 5 /* Keyframes */) {
800 styleAst = this.visitKeyframes(styleMetadata, context);
801 }
802 else {
803 var styleMetadata_1 = metadata.styles;
804 var isEmpty = false;
805 if (!styleMetadata_1) {
806 isEmpty = true;
807 var newStyleData = {};
808 if (timingAst.easing) {
809 newStyleData['easing'] = timingAst.easing;
810 }
811 styleMetadata_1 = style(newStyleData);
812 }
813 context.currentTime += timingAst.duration + timingAst.delay;
814 var _styleAst = this.visitStyle(styleMetadata_1, context);
815 _styleAst.isEmptyStep = isEmpty;
816 styleAst = _styleAst;
817 }
818 context.currentAnimateTimings = null;
819 return {
820 type: 4 /* Animate */,
821 timings: timingAst,
822 style: styleAst,
823 options: null
824 };
825 };
826 AnimationAstBuilderVisitor.prototype.visitStyle = function (metadata, context) {
827 var ast = this._makeStyleAst(metadata, context);
828 this._validateStyleAst(ast, context);
829 return ast;
830 };
831 AnimationAstBuilderVisitor.prototype._makeStyleAst = function (metadata, context) {
832 var styles = [];
833 if (Array.isArray(metadata.styles)) {
834 metadata.styles.forEach(function (styleTuple) {
835 if (typeof styleTuple == 'string') {
836 if (styleTuple == AUTO_STYLE) {
837 styles.push(styleTuple);
838 }
839 else {
840 context.errors.push("The provided style string value " + styleTuple + " is not allowed.");
841 }
842 }
843 else {
844 styles.push(styleTuple);
845 }
846 });
847 }
848 else {
849 styles.push(metadata.styles);
850 }
851 var containsDynamicStyles = false;
852 var collectedEasing = null;
853 styles.forEach(function (styleData) {
854 if (isObject(styleData)) {
855 var styleMap = styleData;
856 var easing = styleMap['easing'];
857 if (easing) {
858 collectedEasing = easing;
859 delete styleMap['easing'];
860 }
861 if (!containsDynamicStyles) {
862 for (var prop in styleMap) {
863 var value = styleMap[prop];
864 if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
865 containsDynamicStyles = true;
866 break;
867 }
868 }
869 }
870 }
871 });
872 return {
873 type: 6 /* Style */,
874 styles: styles,
875 easing: collectedEasing,
876 offset: metadata.offset, containsDynamicStyles: containsDynamicStyles,
877 options: null
878 };
879 };
880 AnimationAstBuilderVisitor.prototype._validateStyleAst = function (ast, context) {
881 var _this = this;
882 var timings = context.currentAnimateTimings;
883 var endTime = context.currentTime;
884 var startTime = context.currentTime;
885 if (timings && startTime > 0) {
886 startTime -= timings.duration + timings.delay;
887 }
888 ast.styles.forEach(function (tuple) {
889 if (typeof tuple == 'string')
890 return;
891 Object.keys(tuple).forEach(function (prop) {
892 if (!_this._driver.validateStyleProperty(prop)) {
893 context.errors.push("The provided animation property \"" + prop + "\" is not a supported CSS property for animations");
894 return;
895 }
896 var collectedStyles = context.collectedStyles[context.currentQuerySelector];
897 var collectedEntry = collectedStyles[prop];
898 var updateCollectedStyle = true;
899 if (collectedEntry) {
900 if (startTime != endTime && startTime >= collectedEntry.startTime &&
901 endTime <= collectedEntry.endTime) {
902 context.errors.push("The CSS property \"" + prop + "\" that exists between the times of \"" + collectedEntry.startTime + "ms\" and \"" + collectedEntry.endTime + "ms\" is also being animated in a parallel animation between the times of \"" + startTime + "ms\" and \"" + endTime + "ms\"");
903 updateCollectedStyle = false;
904 }
905 // we always choose the smaller start time value since we
906 // want to have a record of the entire animation window where
907 // the style property is being animated in between
908 startTime = collectedEntry.startTime;
909 }
910 if (updateCollectedStyle) {
911 collectedStyles[prop] = { startTime: startTime, endTime: endTime };
912 }
913 if (context.options) {
914 validateStyleParams(tuple[prop], context.options, context.errors);
915 }
916 });
917 });
918 };
919 AnimationAstBuilderVisitor.prototype.visitKeyframes = function (metadata, context) {
920 var _this = this;
921 var ast = { type: 5 /* Keyframes */, styles: [], options: null };
922 if (!context.currentAnimateTimings) {
923 context.errors.push("keyframes() must be placed inside of a call to animate()");
924 return ast;
925 }
926 var MAX_KEYFRAME_OFFSET = 1;
927 var totalKeyframesWithOffsets = 0;
928 var offsets = [];
929 var offsetsOutOfOrder = false;
930 var keyframesOutOfRange = false;
931 var previousOffset = 0;
932 var keyframes = metadata.steps.map(function (styles) {
933 var style = _this._makeStyleAst(styles, context);
934 var offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);
935 var offset = 0;
936 if (offsetVal != null) {
937 totalKeyframesWithOffsets++;
938 offset = style.offset = offsetVal;
939 }
940 keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
941 offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
942 previousOffset = offset;
943 offsets.push(offset);
944 return style;
945 });
946 if (keyframesOutOfRange) {
947 context.errors.push("Please ensure that all keyframe offsets are between 0 and 1");
948 }
949 if (offsetsOutOfOrder) {
950 context.errors.push("Please ensure that all keyframe offsets are in order");
951 }
952 var length = metadata.steps.length;
953 var generatedOffset = 0;
954 if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
955 context.errors.push("Not all style() steps within the declared keyframes() contain offsets");
956 }
957 else if (totalKeyframesWithOffsets == 0) {
958 generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
959 }
960 var limit = length - 1;
961 var currentTime = context.currentTime;
962 var currentAnimateTimings = context.currentAnimateTimings;
963 var animateDuration = currentAnimateTimings.duration;
964 keyframes.forEach(function (kf, i) {
965 var offset = generatedOffset > 0 ? (i == limit ? 1 : (generatedOffset * i)) : offsets[i];
966 var durationUpToThisFrame = offset * animateDuration;
967 context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
968 currentAnimateTimings.duration = durationUpToThisFrame;
969 _this._validateStyleAst(kf, context);
970 kf.offset = offset;
971 ast.styles.push(kf);
972 });
973 return ast;
974 };
975 AnimationAstBuilderVisitor.prototype.visitReference = function (metadata, context) {
976 return {
977 type: 8 /* Reference */,
978 animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
979 options: normalizeAnimationOptions(metadata.options)
980 };
981 };
982 AnimationAstBuilderVisitor.prototype.visitAnimateChild = function (metadata, context) {
983 context.depCount++;
984 return {
985 type: 9 /* AnimateChild */,
986 options: normalizeAnimationOptions(metadata.options)
987 };
988 };
989 AnimationAstBuilderVisitor.prototype.visitAnimateRef = function (metadata, context) {
990 return {
991 type: 10 /* AnimateRef */,
992 animation: this.visitReference(metadata.animation, context),
993 options: normalizeAnimationOptions(metadata.options)
994 };
995 };
996 AnimationAstBuilderVisitor.prototype.visitQuery = function (metadata, context) {
997 var parentSelector = context.currentQuerySelector;
998 var options = (metadata.options || {});
999 context.queryCount++;
1000 context.currentQuery = metadata;
1001 var _a = __read(normalizeSelector(metadata.selector), 2), selector = _a[0], includeSelf = _a[1];
1002 context.currentQuerySelector =
1003 parentSelector.length ? (parentSelector + ' ' + selector) : selector;
1004 getOrSetAsInMap(context.collectedStyles, context.currentQuerySelector, {});
1005 var animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
1006 context.currentQuery = null;
1007 context.currentQuerySelector = parentSelector;
1008 return {
1009 type: 11 /* Query */,
1010 selector: selector,
1011 limit: options.limit || 0,
1012 optional: !!options.optional, includeSelf: includeSelf, animation: animation,
1013 originalSelector: metadata.selector,
1014 options: normalizeAnimationOptions(metadata.options)
1015 };
1016 };
1017 AnimationAstBuilderVisitor.prototype.visitStagger = function (metadata, context) {
1018 if (!context.currentQuery) {
1019 context.errors.push("stagger() can only be used inside of query()");
1020 }
1021 var timings = metadata.timings === 'full' ?
1022 { duration: 0, delay: 0, easing: 'full' } :
1023 resolveTiming(metadata.timings, context.errors, true);
1024 return {
1025 type: 12 /* Stagger */,
1026 animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context), timings: timings,
1027 options: null
1028 };
1029 };
1030 return AnimationAstBuilderVisitor;
1031}());
1032function normalizeSelector(selector) {
1033 var hasAmpersand = selector.split(/\s*,\s*/).find(function (token) { return token == SELF_TOKEN; }) ? true : false;
1034 if (hasAmpersand) {
1035 selector = selector.replace(SELF_TOKEN_REGEX, '');
1036 }
1037 // the :enter and :leave selectors are filled in at runtime during timeline building
1038 selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR)
1039 .replace(/@\w+/g, function (match) { return NG_TRIGGER_SELECTOR + '-' + match.substr(1); })
1040 .replace(/:animating/g, NG_ANIMATING_SELECTOR);
1041 return [selector, hasAmpersand];
1042}
1043function normalizeParams(obj) {
1044 return obj ? copyObj(obj) : null;
1045}
1046var AnimationAstBuilderContext = /** @class */ (function () {
1047 function AnimationAstBuilderContext(errors) {
1048 this.errors = errors;
1049 this.queryCount = 0;
1050 this.depCount = 0;
1051 this.currentTransition = null;
1052 this.currentQuery = null;
1053 this.currentQuerySelector = null;
1054 this.currentAnimateTimings = null;
1055 this.currentTime = 0;
1056 this.collectedStyles = {};
1057 this.options = null;
1058 }
1059 return AnimationAstBuilderContext;
1060}());
1061function consumeOffset(styles) {
1062 if (typeof styles == 'string')
1063 return null;
1064 var offset = null;
1065 if (Array.isArray(styles)) {
1066 styles.forEach(function (styleTuple) {
1067 if (isObject(styleTuple) && styleTuple.hasOwnProperty('offset')) {
1068 var obj = styleTuple;
1069 offset = parseFloat(obj['offset']);
1070 delete obj['offset'];
1071 }
1072 });
1073 }
1074 else if (isObject(styles) && styles.hasOwnProperty('offset')) {
1075 var obj = styles;
1076 offset = parseFloat(obj['offset']);
1077 delete obj['offset'];
1078 }
1079 return offset;
1080}
1081function isObject(value) {
1082 return !Array.isArray(value) && typeof value == 'object';
1083}
1084function constructTimingAst(value, errors) {
1085 var timings = null;
1086 if (value.hasOwnProperty('duration')) {
1087 timings = value;
1088 }
1089 else if (typeof value == 'number') {
1090 var duration = resolveTiming(value, errors).duration;
1091 return makeTimingAst(duration, 0, '');
1092 }
1093 var strValue = value;
1094 var isDynamic = strValue.split(/\s+/).some(function (v) { return v.charAt(0) == '{' && v.charAt(1) == '{'; });
1095 if (isDynamic) {
1096 var ast = makeTimingAst(0, 0, '');
1097 ast.dynamic = true;
1098 ast.strValue = strValue;
1099 return ast;
1100 }
1101 timings = timings || resolveTiming(strValue, errors);
1102 return makeTimingAst(timings.duration, timings.delay, timings.easing);
1103}
1104function normalizeAnimationOptions(options) {
1105 if (options) {
1106 options = copyObj(options);
1107 if (options['params']) {
1108 options['params'] = normalizeParams(options['params']);
1109 }
1110 }
1111 else {
1112 options = {};
1113 }
1114 return options;
1115}
1116function makeTimingAst(duration, delay, easing) {
1117 return { duration: duration, delay: delay, easing: easing };
1118}
1119
1120function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing, subTimeline) {
1121 if (easing === void 0) { easing = null; }
1122 if (subTimeline === void 0) { subTimeline = false; }
1123 return {
1124 type: 1 /* TimelineAnimation */,
1125 element: element,
1126 keyframes: keyframes,
1127 preStyleProps: preStyleProps,
1128 postStyleProps: postStyleProps,
1129 duration: duration,
1130 delay: delay,
1131 totalTime: duration + delay, easing: easing, subTimeline: subTimeline
1132 };
1133}
1134
1135var ElementInstructionMap = /** @class */ (function () {
1136 function ElementInstructionMap() {
1137 this._map = new Map();
1138 }
1139 ElementInstructionMap.prototype.consume = function (element) {
1140 var instructions = this._map.get(element);
1141 if (instructions) {
1142 this._map.delete(element);
1143 }
1144 else {
1145 instructions = [];
1146 }
1147 return instructions;
1148 };
1149 ElementInstructionMap.prototype.append = function (element, instructions) {
1150 var existingInstructions = this._map.get(element);
1151 if (!existingInstructions) {
1152 this._map.set(element, existingInstructions = []);
1153 }
1154 existingInstructions.push.apply(existingInstructions, __spread(instructions));
1155 };
1156 ElementInstructionMap.prototype.has = function (element) { return this._map.has(element); };
1157 ElementInstructionMap.prototype.clear = function () { this._map.clear(); };
1158 return ElementInstructionMap;
1159}());
1160
1161var ONE_FRAME_IN_MILLISECONDS = 1;
1162var ENTER_TOKEN = ':enter';
1163var ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
1164var LEAVE_TOKEN = ':leave';
1165var LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
1166/*
1167 * The code within this file aims to generate web-animations-compatible keyframes from Angular's
1168 * animation DSL code.
1169 *
1170 * The code below will be converted from:
1171 *
1172 * ```
1173 * sequence([
1174 * style({ opacity: 0 }),
1175 * animate(1000, style({ opacity: 0 }))
1176 * ])
1177 * ```
1178 *
1179 * To:
1180 * ```
1181 * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]
1182 * duration = 1000
1183 * delay = 0
1184 * easing = ''
1185 * ```
1186 *
1187 * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
1188 * combination of prototypical inheritance, AST traversal and merge-sort-like algorithms are used.
1189 *
1190 * [AST Traversal]
1191 * Each of the animation verbs, when executed, will return an string-map object representing what
1192 * type of action it is (style, animate, group, etc...) and the data associated with it. This means
1193 * that when functional composition mix of these functions is evaluated (like in the example above)
1194 * then it will end up producing a tree of objects representing the animation itself.
1195 *
1196 * When this animation object tree is processed by the visitor code below it will visit each of the
1197 * verb statements within the visitor. And during each visit it will build the context of the
1198 * animation keyframes by interacting with the `TimelineBuilder`.
1199 *
1200 * [TimelineBuilder]
1201 * This class is responsible for tracking the styles and building a series of keyframe objects for a
1202 * timeline between a start and end time. The builder starts off with an initial timeline and each
1203 * time the AST comes across a `group()`, `keyframes()` or a combination of the two wihtin a
1204 * `sequence()` then it will generate a sub timeline for each step as well as a new one after
1205 * they are complete.
1206 *
1207 * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub
1208 * timeline was created (based on one of the cases above) then the parent timeline will attempt to
1209 * merge the styles used within the sub timelines into itself (only with group() this will happen).
1210 * This happens with a merge operation (much like how the merge works in mergesort) and it will only
1211 * copy the most recently used styles from the sub timelines into the parent timeline. This ensures
1212 * that if the styles are used later on in another phase of the animation then they will be the most
1213 * up-to-date values.
1214 *
1215 * [How Missing Styles Are Updated]
1216 * Each timeline has a `backFill` property which is responsible for filling in new styles into
1217 * already processed keyframes if a new style shows up later within the animation sequence.
1218 *
1219 * ```
1220 * sequence([
1221 * style({ width: 0 }),
1222 * animate(1000, style({ width: 100 })),
1223 * animate(1000, style({ width: 200 })),
1224 * animate(1000, style({ width: 300 }))
1225 * animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere
1226 * else
1227 * ])
1228 * ```
1229 *
1230 * What is happening here is that the `height` value is added later in the sequence, but is missing
1231 * from all previous animation steps. Therefore when a keyframe is created it would also be missing
1232 * from all previous keyframes up until where it is first used. For the timeline keyframe generation
1233 * to properly fill in the style it will place the previous value (the value from the parent
1234 * timeline) or a default value of `*` into the backFill object. Given that each of the keyframe
1235 * styles are objects that prototypically inhert from the backFill object, this means that if a
1236 * value is added into the backFill then it will automatically propagate any missing values to all
1237 * keyframes. Therefore the missing `height` value will be properly filled into the already
1238 * processed keyframes.
1239 *
1240 * When a sub-timeline is created it will have its own backFill property. This is done so that
1241 * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
1242 * keyframes
1243 *
1244 * (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
1245 *
1246 * [Validation]
1247 * The code in this file is not responsible for validation. That functionality happens with within
1248 * the `AnimationValidatorVisitor` code.
1249 */
1250function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors) {
1251 if (startingStyles === void 0) { startingStyles = {}; }
1252 if (finalStyles === void 0) { finalStyles = {}; }
1253 if (errors === void 0) { errors = []; }
1254 return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
1255}
1256var AnimationTimelineBuilderVisitor = /** @class */ (function () {
1257 function AnimationTimelineBuilderVisitor() {
1258 }
1259 AnimationTimelineBuilderVisitor.prototype.buildKeyframes = function (driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors) {
1260 if (errors === void 0) { errors = []; }
1261 subInstructions = subInstructions || new ElementInstructionMap();
1262 var context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
1263 context.options = options;
1264 context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
1265 visitDslNode(this, ast, context);
1266 // this checks to see if an actual animation happened
1267 var timelines = context.timelines.filter(function (timeline) { return timeline.containsAnimation(); });
1268 if (timelines.length && Object.keys(finalStyles).length) {
1269 var tl = timelines[timelines.length - 1];
1270 if (!tl.allowOnlyTimelineStyles()) {
1271 tl.setStyles([finalStyles], null, context.errors, options);
1272 }
1273 }
1274 return timelines.length ? timelines.map(function (timeline) { return timeline.buildKeyframes(); }) :
1275 [createTimelineInstruction(rootElement, [], [], [], 0, 0, '', false)];
1276 };
1277 AnimationTimelineBuilderVisitor.prototype.visitTrigger = function (ast, context) {
1278 // these values are not visited in this AST
1279 };
1280 AnimationTimelineBuilderVisitor.prototype.visitState = function (ast, context) {
1281 // these values are not visited in this AST
1282 };
1283 AnimationTimelineBuilderVisitor.prototype.visitTransition = function (ast, context) {
1284 // these values are not visited in this AST
1285 };
1286 AnimationTimelineBuilderVisitor.prototype.visitAnimateChild = function (ast, context) {
1287 var elementInstructions = context.subInstructions.consume(context.element);
1288 if (elementInstructions) {
1289 var innerContext = context.createSubContext(ast.options);
1290 var startTime = context.currentTimeline.currentTime;
1291 var endTime = this._visitSubInstructions(elementInstructions, innerContext, innerContext.options);
1292 if (startTime != endTime) {
1293 // we do this on the upper context because we created a sub context for
1294 // the sub child animations
1295 context.transformIntoNewTimeline(endTime);
1296 }
1297 }
1298 context.previousNode = ast;
1299 };
1300 AnimationTimelineBuilderVisitor.prototype.visitAnimateRef = function (ast, context) {
1301 var innerContext = context.createSubContext(ast.options);
1302 innerContext.transformIntoNewTimeline();
1303 this.visitReference(ast.animation, innerContext);
1304 context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
1305 context.previousNode = ast;
1306 };
1307 AnimationTimelineBuilderVisitor.prototype._visitSubInstructions = function (instructions, context, options) {
1308 var startTime = context.currentTimeline.currentTime;
1309 var furthestTime = startTime;
1310 // this is a special-case for when a user wants to skip a sub
1311 // animation from being fired entirely.
1312 var duration = options.duration != null ? resolveTimingValue(options.duration) : null;
1313 var delay = options.delay != null ? resolveTimingValue(options.delay) : null;
1314 if (duration !== 0) {
1315 instructions.forEach(function (instruction) {
1316 var instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);
1317 furthestTime =
1318 Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);
1319 });
1320 }
1321 return furthestTime;
1322 };
1323 AnimationTimelineBuilderVisitor.prototype.visitReference = function (ast, context) {
1324 context.updateOptions(ast.options, true);
1325 visitDslNode(this, ast.animation, context);
1326 context.previousNode = ast;
1327 };
1328 AnimationTimelineBuilderVisitor.prototype.visitSequence = function (ast, context) {
1329 var _this = this;
1330 var subContextCount = context.subContextCount;
1331 var ctx = context;
1332 var options = ast.options;
1333 if (options && (options.params || options.delay)) {
1334 ctx = context.createSubContext(options);
1335 ctx.transformIntoNewTimeline();
1336 if (options.delay != null) {
1337 if (ctx.previousNode.type == 6 /* Style */) {
1338 ctx.currentTimeline.snapshotCurrentStyles();
1339 ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
1340 }
1341 var delay = resolveTimingValue(options.delay);
1342 ctx.delayNextStep(delay);
1343 }
1344 }
1345 if (ast.steps.length) {
1346 ast.steps.forEach(function (s) { return visitDslNode(_this, s, ctx); });
1347 // this is here just incase the inner steps only contain or end with a style() call
1348 ctx.currentTimeline.applyStylesToKeyframe();
1349 // this means that some animation function within the sequence
1350 // ended up creating a sub timeline (which means the current
1351 // timeline cannot overlap with the contents of the sequence)
1352 if (ctx.subContextCount > subContextCount) {
1353 ctx.transformIntoNewTimeline();
1354 }
1355 }
1356 context.previousNode = ast;
1357 };
1358 AnimationTimelineBuilderVisitor.prototype.visitGroup = function (ast, context) {
1359 var _this = this;
1360 var innerTimelines = [];
1361 var furthestTime = context.currentTimeline.currentTime;
1362 var delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;
1363 ast.steps.forEach(function (s) {
1364 var innerContext = context.createSubContext(ast.options);
1365 if (delay) {
1366 innerContext.delayNextStep(delay);
1367 }
1368 visitDslNode(_this, s, innerContext);
1369 furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);
1370 innerTimelines.push(innerContext.currentTimeline);
1371 });
1372 // this operation is run after the AST loop because otherwise
1373 // if the parent timeline's collected styles were updated then
1374 // it would pass in invalid data into the new-to-be forked items
1375 innerTimelines.forEach(function (timeline) { return context.currentTimeline.mergeTimelineCollectedStyles(timeline); });
1376 context.transformIntoNewTimeline(furthestTime);
1377 context.previousNode = ast;
1378 };
1379 AnimationTimelineBuilderVisitor.prototype._visitTiming = function (ast, context) {
1380 if (ast.dynamic) {
1381 var strValue = ast.strValue;
1382 var timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
1383 return resolveTiming(timingValue, context.errors);
1384 }
1385 else {
1386 return { duration: ast.duration, delay: ast.delay, easing: ast.easing };
1387 }
1388 };
1389 AnimationTimelineBuilderVisitor.prototype.visitAnimate = function (ast, context) {
1390 var timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);
1391 var timeline = context.currentTimeline;
1392 if (timings.delay) {
1393 context.incrementTime(timings.delay);
1394 timeline.snapshotCurrentStyles();
1395 }
1396 var style = ast.style;
1397 if (style.type == 5 /* Keyframes */) {
1398 this.visitKeyframes(style, context);
1399 }
1400 else {
1401 context.incrementTime(timings.duration);
1402 this.visitStyle(style, context);
1403 timeline.applyStylesToKeyframe();
1404 }
1405 context.currentAnimateTimings = null;
1406 context.previousNode = ast;
1407 };
1408 AnimationTimelineBuilderVisitor.prototype.visitStyle = function (ast, context) {
1409 var timeline = context.currentTimeline;
1410 var timings = context.currentAnimateTimings;
1411 // this is a special case for when a style() call
1412 // directly follows an animate() call (but not inside of an animate() call)
1413 if (!timings && timeline.getCurrentStyleProperties().length) {
1414 timeline.forwardFrame();
1415 }
1416 var easing = (timings && timings.easing) || ast.easing;
1417 if (ast.isEmptyStep) {
1418 timeline.applyEmptyStep(easing);
1419 }
1420 else {
1421 timeline.setStyles(ast.styles, easing, context.errors, context.options);
1422 }
1423 context.previousNode = ast;
1424 };
1425 AnimationTimelineBuilderVisitor.prototype.visitKeyframes = function (ast, context) {
1426 var currentAnimateTimings = context.currentAnimateTimings;
1427 var startTime = (context.currentTimeline).duration;
1428 var duration = currentAnimateTimings.duration;
1429 var innerContext = context.createSubContext();
1430 var innerTimeline = innerContext.currentTimeline;
1431 innerTimeline.easing = currentAnimateTimings.easing;
1432 ast.styles.forEach(function (step) {
1433 var offset = step.offset || 0;
1434 innerTimeline.forwardTime(offset * duration);
1435 innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);
1436 innerTimeline.applyStylesToKeyframe();
1437 });
1438 // this will ensure that the parent timeline gets all the styles from
1439 // the child even if the new timeline below is not used
1440 context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline);
1441 // we do this because the window between this timeline and the sub timeline
1442 // should ensure that the styles within are exactly the same as they were before
1443 context.transformIntoNewTimeline(startTime + duration);
1444 context.previousNode = ast;
1445 };
1446 AnimationTimelineBuilderVisitor.prototype.visitQuery = function (ast, context) {
1447 var _this = this;
1448 // in the event that the first step before this is a style step we need
1449 // to ensure the styles are applied before the children are animated
1450 var startTime = context.currentTimeline.currentTime;
1451 var options = (ast.options || {});
1452 var delay = options.delay ? resolveTimingValue(options.delay) : 0;
1453 if (delay && (context.previousNode.type === 6 /* Style */ ||
1454 (startTime == 0 && context.currentTimeline.getCurrentStyleProperties().length))) {
1455 context.currentTimeline.snapshotCurrentStyles();
1456 context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
1457 }
1458 var furthestTime = startTime;
1459 var elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);
1460 context.currentQueryTotal = elms.length;
1461 var sameElementTimeline = null;
1462 elms.forEach(function (element, i) {
1463 context.currentQueryIndex = i;
1464 var innerContext = context.createSubContext(ast.options, element);
1465 if (delay) {
1466 innerContext.delayNextStep(delay);
1467 }
1468 if (element === context.element) {
1469 sameElementTimeline = innerContext.currentTimeline;
1470 }
1471 visitDslNode(_this, ast.animation, innerContext);
1472 // this is here just incase the inner steps only contain or end
1473 // with a style() call (which is here to signal that this is a preparatory
1474 // call to style an element before it is animated again)
1475 innerContext.currentTimeline.applyStylesToKeyframe();
1476 var endTime = innerContext.currentTimeline.currentTime;
1477 furthestTime = Math.max(furthestTime, endTime);
1478 });
1479 context.currentQueryIndex = 0;
1480 context.currentQueryTotal = 0;
1481 context.transformIntoNewTimeline(furthestTime);
1482 if (sameElementTimeline) {
1483 context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);
1484 context.currentTimeline.snapshotCurrentStyles();
1485 }
1486 context.previousNode = ast;
1487 };
1488 AnimationTimelineBuilderVisitor.prototype.visitStagger = function (ast, context) {
1489 var parentContext = context.parentContext;
1490 var tl = context.currentTimeline;
1491 var timings = ast.timings;
1492 var duration = Math.abs(timings.duration);
1493 var maxTime = duration * (context.currentQueryTotal - 1);
1494 var delay = duration * context.currentQueryIndex;
1495 var staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;
1496 switch (staggerTransformer) {
1497 case 'reverse':
1498 delay = maxTime - delay;
1499 break;
1500 case 'full':
1501 delay = parentContext.currentStaggerTime;
1502 break;
1503 }
1504 var timeline = context.currentTimeline;
1505 if (delay) {
1506 timeline.delayNextStep(delay);
1507 }
1508 var startingTime = timeline.currentTime;
1509 visitDslNode(this, ast.animation, context);
1510 context.previousNode = ast;
1511 // time = duration + delay
1512 // the reason why this computation is so complex is because
1513 // the inner timeline may either have a delay value or a stretched
1514 // keyframe depending on if a subtimeline is not used or is used.
1515 parentContext.currentStaggerTime =
1516 (tl.currentTime - startingTime) + (tl.startTime - parentContext.currentTimeline.startTime);
1517 };
1518 return AnimationTimelineBuilderVisitor;
1519}());
1520var DEFAULT_NOOP_PREVIOUS_NODE = {};
1521var AnimationTimelineContext = /** @class */ (function () {
1522 function AnimationTimelineContext(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {
1523 this._driver = _driver;
1524 this.element = element;
1525 this.subInstructions = subInstructions;
1526 this._enterClassName = _enterClassName;
1527 this._leaveClassName = _leaveClassName;
1528 this.errors = errors;
1529 this.timelines = timelines;
1530 this.parentContext = null;
1531 this.currentAnimateTimings = null;
1532 this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
1533 this.subContextCount = 0;
1534 this.options = {};
1535 this.currentQueryIndex = 0;
1536 this.currentQueryTotal = 0;
1537 this.currentStaggerTime = 0;
1538 this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
1539 timelines.push(this.currentTimeline);
1540 }
1541 Object.defineProperty(AnimationTimelineContext.prototype, "params", {
1542 get: function () { return this.options.params; },
1543 enumerable: true,
1544 configurable: true
1545 });
1546 AnimationTimelineContext.prototype.updateOptions = function (options, skipIfExists) {
1547 var _this = this;
1548 if (!options)
1549 return;
1550 var newOptions = options;
1551 var optionsToUpdate = this.options;
1552 // NOTE: this will get patched up when other animation methods support duration overrides
1553 if (newOptions.duration != null) {
1554 optionsToUpdate.duration = resolveTimingValue(newOptions.duration);
1555 }
1556 if (newOptions.delay != null) {
1557 optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
1558 }
1559 var newParams = newOptions.params;
1560 if (newParams) {
1561 var paramsToUpdate_1 = optionsToUpdate.params;
1562 if (!paramsToUpdate_1) {
1563 paramsToUpdate_1 = this.options.params = {};
1564 }
1565 Object.keys(newParams).forEach(function (name) {
1566 if (!skipIfExists || !paramsToUpdate_1.hasOwnProperty(name)) {
1567 paramsToUpdate_1[name] = interpolateParams(newParams[name], paramsToUpdate_1, _this.errors);
1568 }
1569 });
1570 }
1571 };
1572 AnimationTimelineContext.prototype._copyOptions = function () {
1573 var options = {};
1574 if (this.options) {
1575 var oldParams_1 = this.options.params;
1576 if (oldParams_1) {
1577 var params_1 = options['params'] = {};
1578 Object.keys(oldParams_1).forEach(function (name) { params_1[name] = oldParams_1[name]; });
1579 }
1580 }
1581 return options;
1582 };
1583 AnimationTimelineContext.prototype.createSubContext = function (options, element, newTime) {
1584 if (options === void 0) { options = null; }
1585 var target = element || this.element;
1586 var context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));
1587 context.previousNode = this.previousNode;
1588 context.currentAnimateTimings = this.currentAnimateTimings;
1589 context.options = this._copyOptions();
1590 context.updateOptions(options);
1591 context.currentQueryIndex = this.currentQueryIndex;
1592 context.currentQueryTotal = this.currentQueryTotal;
1593 context.parentContext = this;
1594 this.subContextCount++;
1595 return context;
1596 };
1597 AnimationTimelineContext.prototype.transformIntoNewTimeline = function (newTime) {
1598 this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
1599 this.currentTimeline = this.currentTimeline.fork(this.element, newTime);
1600 this.timelines.push(this.currentTimeline);
1601 return this.currentTimeline;
1602 };
1603 AnimationTimelineContext.prototype.appendInstructionToTimeline = function (instruction, duration, delay) {
1604 var updatedTimings = {
1605 duration: duration != null ? duration : instruction.duration,
1606 delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,
1607 easing: ''
1608 };
1609 var builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
1610 this.timelines.push(builder);
1611 return updatedTimings;
1612 };
1613 AnimationTimelineContext.prototype.incrementTime = function (time) {
1614 this.currentTimeline.forwardTime(this.currentTimeline.duration + time);
1615 };
1616 AnimationTimelineContext.prototype.delayNextStep = function (delay) {
1617 // negative delays are not yet supported
1618 if (delay > 0) {
1619 this.currentTimeline.delayNextStep(delay);
1620 }
1621 };
1622 AnimationTimelineContext.prototype.invokeQuery = function (selector, originalSelector, limit, includeSelf, optional, errors) {
1623 var results = [];
1624 if (includeSelf) {
1625 results.push(this.element);
1626 }
1627 if (selector.length > 0) { // if :self is only used then the selector is empty
1628 selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
1629 selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
1630 var multi = limit != 1;
1631 var elements = this._driver.query(this.element, selector, multi);
1632 if (limit !== 0) {
1633 elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) :
1634 elements.slice(0, limit);
1635 }
1636 results.push.apply(results, __spread(elements));
1637 }
1638 if (!optional && results.length == 0) {
1639 errors.push("`query(\"" + originalSelector + "\")` returned zero elements. (Use `query(\"" + originalSelector + "\", { optional: true })` if you wish to allow this.)");
1640 }
1641 return results;
1642 };
1643 return AnimationTimelineContext;
1644}());
1645var TimelineBuilder = /** @class */ (function () {
1646 function TimelineBuilder(_driver, element, startTime, _elementTimelineStylesLookup) {
1647 this._driver = _driver;
1648 this.element = element;
1649 this.startTime = startTime;
1650 this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
1651 this.duration = 0;
1652 this._previousKeyframe = {};
1653 this._currentKeyframe = {};
1654 this._keyframes = new Map();
1655 this._styleSummary = {};
1656 this._pendingStyles = {};
1657 this._backFill = {};
1658 this._currentEmptyStepKeyframe = null;
1659 if (!this._elementTimelineStylesLookup) {
1660 this._elementTimelineStylesLookup = new Map();
1661 }
1662 this._localTimelineStyles = Object.create(this._backFill, {});
1663 this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
1664 if (!this._globalTimelineStyles) {
1665 this._globalTimelineStyles = this._localTimelineStyles;
1666 this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
1667 }
1668 this._loadKeyframe();
1669 }
1670 TimelineBuilder.prototype.containsAnimation = function () {
1671 switch (this._keyframes.size) {
1672 case 0:
1673 return false;
1674 case 1:
1675 return this.getCurrentStyleProperties().length > 0;
1676 default:
1677 return true;
1678 }
1679 };
1680 TimelineBuilder.prototype.getCurrentStyleProperties = function () { return Object.keys(this._currentKeyframe); };
1681 Object.defineProperty(TimelineBuilder.prototype, "currentTime", {
1682 get: function () { return this.startTime + this.duration; },
1683 enumerable: true,
1684 configurable: true
1685 });
1686 TimelineBuilder.prototype.delayNextStep = function (delay) {
1687 // in the event that a style() step is placed right before a stagger()
1688 // and that style() step is the very first style() value in the animation
1689 // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
1690 // properly applies the style() values to work with the stagger...
1691 var hasPreStyleStep = this._keyframes.size == 1 && Object.keys(this._pendingStyles).length;
1692 if (this.duration || hasPreStyleStep) {
1693 this.forwardTime(this.currentTime + delay);
1694 if (hasPreStyleStep) {
1695 this.snapshotCurrentStyles();
1696 }
1697 }
1698 else {
1699 this.startTime += delay;
1700 }
1701 };
1702 TimelineBuilder.prototype.fork = function (element, currentTime) {
1703 this.applyStylesToKeyframe();
1704 return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
1705 };
1706 TimelineBuilder.prototype._loadKeyframe = function () {
1707 if (this._currentKeyframe) {
1708 this._previousKeyframe = this._currentKeyframe;
1709 }
1710 this._currentKeyframe = this._keyframes.get(this.duration);
1711 if (!this._currentKeyframe) {
1712 this._currentKeyframe = Object.create(this._backFill, {});
1713 this._keyframes.set(this.duration, this._currentKeyframe);
1714 }
1715 };
1716 TimelineBuilder.prototype.forwardFrame = function () {
1717 this.duration += ONE_FRAME_IN_MILLISECONDS;
1718 this._loadKeyframe();
1719 };
1720 TimelineBuilder.prototype.forwardTime = function (time) {
1721 this.applyStylesToKeyframe();
1722 this.duration = time;
1723 this._loadKeyframe();
1724 };
1725 TimelineBuilder.prototype._updateStyle = function (prop, value) {
1726 this._localTimelineStyles[prop] = value;
1727 this._globalTimelineStyles[prop] = value;
1728 this._styleSummary[prop] = { time: this.currentTime, value: value };
1729 };
1730 TimelineBuilder.prototype.allowOnlyTimelineStyles = function () { return this._currentEmptyStepKeyframe !== this._currentKeyframe; };
1731 TimelineBuilder.prototype.applyEmptyStep = function (easing) {
1732 var _this = this;
1733 if (easing) {
1734 this._previousKeyframe['easing'] = easing;
1735 }
1736 // special case for animate(duration):
1737 // all missing styles are filled with a `*` value then
1738 // if any destination styles are filled in later on the same
1739 // keyframe then they will override the overridden styles
1740 // We use `_globalTimelineStyles` here because there may be
1741 // styles in previous keyframes that are not present in this timeline
1742 Object.keys(this._globalTimelineStyles).forEach(function (prop) {
1743 _this._backFill[prop] = _this._globalTimelineStyles[prop] || AUTO_STYLE;
1744 _this._currentKeyframe[prop] = AUTO_STYLE;
1745 });
1746 this._currentEmptyStepKeyframe = this._currentKeyframe;
1747 };
1748 TimelineBuilder.prototype.setStyles = function (input, easing, errors, options) {
1749 var _this = this;
1750 if (easing) {
1751 this._previousKeyframe['easing'] = easing;
1752 }
1753 var params = (options && options.params) || {};
1754 var styles = flattenStyles(input, this._globalTimelineStyles);
1755 Object.keys(styles).forEach(function (prop) {
1756 var val = interpolateParams(styles[prop], params, errors);
1757 _this._pendingStyles[prop] = val;
1758 if (!_this._localTimelineStyles.hasOwnProperty(prop)) {
1759 _this._backFill[prop] = _this._globalTimelineStyles.hasOwnProperty(prop) ?
1760 _this._globalTimelineStyles[prop] :
1761 AUTO_STYLE;
1762 }
1763 _this._updateStyle(prop, val);
1764 });
1765 };
1766 TimelineBuilder.prototype.applyStylesToKeyframe = function () {
1767 var _this = this;
1768 var styles = this._pendingStyles;
1769 var props = Object.keys(styles);
1770 if (props.length == 0)
1771 return;
1772 this._pendingStyles = {};
1773 props.forEach(function (prop) {
1774 var val = styles[prop];
1775 _this._currentKeyframe[prop] = val;
1776 });
1777 Object.keys(this._localTimelineStyles).forEach(function (prop) {
1778 if (!_this._currentKeyframe.hasOwnProperty(prop)) {
1779 _this._currentKeyframe[prop] = _this._localTimelineStyles[prop];
1780 }
1781 });
1782 };
1783 TimelineBuilder.prototype.snapshotCurrentStyles = function () {
1784 var _this = this;
1785 Object.keys(this._localTimelineStyles).forEach(function (prop) {
1786 var val = _this._localTimelineStyles[prop];
1787 _this._pendingStyles[prop] = val;
1788 _this._updateStyle(prop, val);
1789 });
1790 };
1791 TimelineBuilder.prototype.getFinalKeyframe = function () { return this._keyframes.get(this.duration); };
1792 Object.defineProperty(TimelineBuilder.prototype, "properties", {
1793 get: function () {
1794 var properties = [];
1795 for (var prop in this._currentKeyframe) {
1796 properties.push(prop);
1797 }
1798 return properties;
1799 },
1800 enumerable: true,
1801 configurable: true
1802 });
1803 TimelineBuilder.prototype.mergeTimelineCollectedStyles = function (timeline) {
1804 var _this = this;
1805 Object.keys(timeline._styleSummary).forEach(function (prop) {
1806 var details0 = _this._styleSummary[prop];
1807 var details1 = timeline._styleSummary[prop];
1808 if (!details0 || details1.time > details0.time) {
1809 _this._updateStyle(prop, details1.value);
1810 }
1811 });
1812 };
1813 TimelineBuilder.prototype.buildKeyframes = function () {
1814 var _this = this;
1815 this.applyStylesToKeyframe();
1816 var preStyleProps = new Set();
1817 var postStyleProps = new Set();
1818 var isEmpty = this._keyframes.size === 1 && this.duration === 0;
1819 var finalKeyframes = [];
1820 this._keyframes.forEach(function (keyframe, time) {
1821 var finalKeyframe = copyStyles(keyframe, true);
1822 Object.keys(finalKeyframe).forEach(function (prop) {
1823 var value = finalKeyframe[prop];
1824 if (value == ɵPRE_STYLE) {
1825 preStyleProps.add(prop);
1826 }
1827 else if (value == AUTO_STYLE) {
1828 postStyleProps.add(prop);
1829 }
1830 });
1831 if (!isEmpty) {
1832 finalKeyframe['offset'] = time / _this.duration;
1833 }
1834 finalKeyframes.push(finalKeyframe);
1835 });
1836 var preProps = preStyleProps.size ? iteratorToArray(preStyleProps.values()) : [];
1837 var postProps = postStyleProps.size ? iteratorToArray(postStyleProps.values()) : [];
1838 // special case for a 0-second animation (which is designed just to place styles onscreen)
1839 if (isEmpty) {
1840 var kf0 = finalKeyframes[0];
1841 var kf1 = copyObj(kf0);
1842 kf0['offset'] = 0;
1843 kf1['offset'] = 1;
1844 finalKeyframes = [kf0, kf1];
1845 }
1846 return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
1847 };
1848 return TimelineBuilder;
1849}());
1850var SubTimelineBuilder = /** @class */ (function (_super) {
1851 __extends(SubTimelineBuilder, _super);
1852 function SubTimelineBuilder(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe) {
1853 if (_stretchStartingKeyframe === void 0) { _stretchStartingKeyframe = false; }
1854 var _this = _super.call(this, driver, element, timings.delay) || this;
1855 _this.element = element;
1856 _this.keyframes = keyframes;
1857 _this.preStyleProps = preStyleProps;
1858 _this.postStyleProps = postStyleProps;
1859 _this._stretchStartingKeyframe = _stretchStartingKeyframe;
1860 _this.timings = { duration: timings.duration, delay: timings.delay, easing: timings.easing };
1861 return _this;
1862 }
1863 SubTimelineBuilder.prototype.containsAnimation = function () { return this.keyframes.length > 1; };
1864 SubTimelineBuilder.prototype.buildKeyframes = function () {
1865 var keyframes = this.keyframes;
1866 var _a = this.timings, delay = _a.delay, duration = _a.duration, easing = _a.easing;
1867 if (this._stretchStartingKeyframe && delay) {
1868 var newKeyframes = [];
1869 var totalTime = duration + delay;
1870 var startingGap = delay / totalTime;
1871 // the original starting keyframe now starts once the delay is done
1872 var newFirstKeyframe = copyStyles(keyframes[0], false);
1873 newFirstKeyframe['offset'] = 0;
1874 newKeyframes.push(newFirstKeyframe);
1875 var oldFirstKeyframe = copyStyles(keyframes[0], false);
1876 oldFirstKeyframe['offset'] = roundOffset(startingGap);
1877 newKeyframes.push(oldFirstKeyframe);
1878 /*
1879 When the keyframe is stretched then it means that the delay before the animation
1880 starts is gone. Instead the first keyframe is placed at the start of the animation
1881 and it is then copied to where it starts when the original delay is over. This basically
1882 means nothing animates during that delay, but the styles are still renderered. For this
1883 to work the original offset values that exist in the original keyframes must be "warped"
1884 so that they can take the new keyframe + delay into account.
1885
1886 delay=1000, duration=1000, keyframes = 0 .5 1
1887
1888 turns into
1889
1890 delay=0, duration=2000, keyframes = 0 .33 .66 1
1891 */
1892 // offsets between 1 ... n -1 are all warped by the keyframe stretch
1893 var limit = keyframes.length - 1;
1894 for (var i = 1; i <= limit; i++) {
1895 var kf = copyStyles(keyframes[i], false);
1896 var oldOffset = kf['offset'];
1897 var timeAtKeyframe = delay + oldOffset * duration;
1898 kf['offset'] = roundOffset(timeAtKeyframe / totalTime);
1899 newKeyframes.push(kf);
1900 }
1901 // the new starting keyframe should be added at the start
1902 duration = totalTime;
1903 delay = 0;
1904 easing = '';
1905 keyframes = newKeyframes;
1906 }
1907 return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);
1908 };
1909 return SubTimelineBuilder;
1910}(TimelineBuilder));
1911function roundOffset(offset, decimalPoints) {
1912 if (decimalPoints === void 0) { decimalPoints = 3; }
1913 var mult = Math.pow(10, decimalPoints - 1);
1914 return Math.round(offset * mult) / mult;
1915}
1916function flattenStyles(input, allStyles) {
1917 var styles = {};
1918 var allProperties;
1919 input.forEach(function (token) {
1920 if (token === '*') {
1921 allProperties = allProperties || Object.keys(allStyles);
1922 allProperties.forEach(function (prop) { styles[prop] = AUTO_STYLE; });
1923 }
1924 else {
1925 copyStyles(token, false, styles);
1926 }
1927 });
1928 return styles;
1929}
1930
1931var Animation = /** @class */ (function () {
1932 function Animation(_driver, input) {
1933 this._driver = _driver;
1934 var errors = [];
1935 var ast = buildAnimationAst(_driver, input, errors);
1936 if (errors.length) {
1937 var errorMessage = "animation validation failed:\n" + errors.join("\n");
1938 throw new Error(errorMessage);
1939 }
1940 this._animationAst = ast;
1941 }
1942 Animation.prototype.buildTimelines = function (element, startingStyles, destinationStyles, options, subInstructions) {
1943 var start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) :
1944 startingStyles;
1945 var dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) :
1946 destinationStyles;
1947 var errors = [];
1948 subInstructions = subInstructions || new ElementInstructionMap();
1949 var result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);
1950 if (errors.length) {
1951 var errorMessage = "animation building failed:\n" + errors.join("\n");
1952 throw new Error(errorMessage);
1953 }
1954 return result;
1955 };
1956 return Animation;
1957}());
1958
1959/**
1960 * @license
1961 * Copyright Google Inc. All Rights Reserved.
1962 *
1963 * Use of this source code is governed by an MIT-style license that can be
1964 * found in the LICENSE file at https://angular.io/license
1965 */
1966/**
1967 * @publicApi
1968 */
1969var AnimationStyleNormalizer = /** @class */ (function () {
1970 function AnimationStyleNormalizer() {
1971 }
1972 return AnimationStyleNormalizer;
1973}());
1974/**
1975 * @publicApi
1976 */
1977var NoopAnimationStyleNormalizer = /** @class */ (function () {
1978 function NoopAnimationStyleNormalizer() {
1979 }
1980 NoopAnimationStyleNormalizer.prototype.normalizePropertyName = function (propertyName, errors) { return propertyName; };
1981 NoopAnimationStyleNormalizer.prototype.normalizeStyleValue = function (userProvidedProperty, normalizedProperty, value, errors) {
1982 return value;
1983 };
1984 return NoopAnimationStyleNormalizer;
1985}());
1986
1987var WebAnimationsStyleNormalizer = /** @class */ (function (_super) {
1988 __extends(WebAnimationsStyleNormalizer, _super);
1989 function WebAnimationsStyleNormalizer() {
1990 return _super !== null && _super.apply(this, arguments) || this;
1991 }
1992 WebAnimationsStyleNormalizer.prototype.normalizePropertyName = function (propertyName, errors) {
1993 return dashCaseToCamelCase(propertyName);
1994 };
1995 WebAnimationsStyleNormalizer.prototype.normalizeStyleValue = function (userProvidedProperty, normalizedProperty, value, errors) {
1996 var unit = '';
1997 var strVal = value.toString().trim();
1998 if (DIMENSIONAL_PROP_MAP[normalizedProperty] && value !== 0 && value !== '0') {
1999 if (typeof value === 'number') {
2000 unit = 'px';
2001 }
2002 else {
2003 var valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/);
2004 if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
2005 errors.push("Please provide a CSS unit value for " + userProvidedProperty + ":" + value);
2006 }
2007 }
2008 }
2009 return strVal + unit;
2010 };
2011 return WebAnimationsStyleNormalizer;
2012}(AnimationStyleNormalizer));
2013var ɵ0$1 = function () { return 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'
2014 .split(',')); };
2015var DIMENSIONAL_PROP_MAP = (ɵ0$1)();
2016function makeBooleanMap(keys) {
2017 var map = {};
2018 keys.forEach(function (key) { return map[key] = true; });
2019 return map;
2020}
2021
2022function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
2023 return {
2024 type: 0 /* TransitionAnimation */,
2025 element: element,
2026 triggerName: triggerName,
2027 isRemovalTransition: isRemovalTransition,
2028 fromState: fromState,
2029 fromStyles: fromStyles,
2030 toState: toState,
2031 toStyles: toStyles,
2032 timelines: timelines,
2033 queriedElements: queriedElements,
2034 preStyleProps: preStyleProps,
2035 postStyleProps: postStyleProps,
2036 totalTime: totalTime,
2037 errors: errors
2038 };
2039}
2040
2041var EMPTY_OBJECT = {};
2042var AnimationTransitionFactory = /** @class */ (function () {
2043 function AnimationTransitionFactory(_triggerName, ast, _stateStyles) {
2044 this._triggerName = _triggerName;
2045 this.ast = ast;
2046 this._stateStyles = _stateStyles;
2047 }
2048 AnimationTransitionFactory.prototype.match = function (currentState, nextState, element, params) {
2049 return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
2050 };
2051 AnimationTransitionFactory.prototype.buildStyles = function (stateName, params, errors) {
2052 var backupStateStyler = this._stateStyles['*'];
2053 var stateStyler = this._stateStyles[stateName];
2054 var backupStyles = backupStateStyler ? backupStateStyler.buildStyles(params, errors) : {};
2055 return stateStyler ? stateStyler.buildStyles(params, errors) : backupStyles;
2056 };
2057 AnimationTransitionFactory.prototype.build = function (driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
2058 var errors = [];
2059 var transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;
2060 var currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;
2061 var currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);
2062 var nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;
2063 var nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);
2064 var queriedElements = new Set();
2065 var preStyleMap = new Map();
2066 var postStyleMap = new Map();
2067 var isRemoval = nextState === 'void';
2068 var animationOptions = { params: __assign(__assign({}, transitionAnimationParams), nextAnimationParams) };
2069 var timelines = skipAstBuild ? [] : buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
2070 var totalTime = 0;
2071 timelines.forEach(function (tl) { totalTime = Math.max(tl.duration + tl.delay, totalTime); });
2072 if (errors.length) {
2073 return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, totalTime, errors);
2074 }
2075 timelines.forEach(function (tl) {
2076 var elm = tl.element;
2077 var preProps = getOrSetAsInMap(preStyleMap, elm, {});
2078 tl.preStyleProps.forEach(function (prop) { return preProps[prop] = true; });
2079 var postProps = getOrSetAsInMap(postStyleMap, elm, {});
2080 tl.postStyleProps.forEach(function (prop) { return postProps[prop] = true; });
2081 if (elm !== element) {
2082 queriedElements.add(elm);
2083 }
2084 });
2085 var queriedElementsList = iteratorToArray(queriedElements.values());
2086 return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, queriedElementsList, preStyleMap, postStyleMap, totalTime);
2087 };
2088 return AnimationTransitionFactory;
2089}());
2090function oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {
2091 return matchFns.some(function (fn) { return fn(currentState, nextState, element, params); });
2092}
2093var AnimationStateStyles = /** @class */ (function () {
2094 function AnimationStateStyles(styles, defaultParams) {
2095 this.styles = styles;
2096 this.defaultParams = defaultParams;
2097 }
2098 AnimationStateStyles.prototype.buildStyles = function (params, errors) {
2099 var finalStyles = {};
2100 var combinedParams = copyObj(this.defaultParams);
2101 Object.keys(params).forEach(function (key) {
2102 var value = params[key];
2103 if (value != null) {
2104 combinedParams[key] = value;
2105 }
2106 });
2107 this.styles.styles.forEach(function (value) {
2108 if (typeof value !== 'string') {
2109 var styleObj_1 = value;
2110 Object.keys(styleObj_1).forEach(function (prop) {
2111 var val = styleObj_1[prop];
2112 if (val.length > 1) {
2113 val = interpolateParams(val, combinedParams, errors);
2114 }
2115 finalStyles[prop] = val;
2116 });
2117 }
2118 });
2119 return finalStyles;
2120 };
2121 return AnimationStateStyles;
2122}());
2123
2124/**
2125 * @publicApi
2126 */
2127function buildTrigger(name, ast) {
2128 return new AnimationTrigger(name, ast);
2129}
2130/**
2131* @publicApi
2132*/
2133var AnimationTrigger = /** @class */ (function () {
2134 function AnimationTrigger(name, ast) {
2135 var _this = this;
2136 this.name = name;
2137 this.ast = ast;
2138 this.transitionFactories = [];
2139 this.states = {};
2140 ast.states.forEach(function (ast) {
2141 var defaultParams = (ast.options && ast.options.params) || {};
2142 _this.states[ast.name] = new AnimationStateStyles(ast.style, defaultParams);
2143 });
2144 balanceProperties(this.states, 'true', '1');
2145 balanceProperties(this.states, 'false', '0');
2146 ast.transitions.forEach(function (ast) {
2147 _this.transitionFactories.push(new AnimationTransitionFactory(name, ast, _this.states));
2148 });
2149 this.fallbackTransition = createFallbackTransition(name, this.states);
2150 }
2151 Object.defineProperty(AnimationTrigger.prototype, "containsQueries", {
2152 get: function () { return this.ast.queryCount > 0; },
2153 enumerable: true,
2154 configurable: true
2155 });
2156 AnimationTrigger.prototype.matchTransition = function (currentState, nextState, element, params) {
2157 var entry = this.transitionFactories.find(function (f) { return f.match(currentState, nextState, element, params); });
2158 return entry || null;
2159 };
2160 AnimationTrigger.prototype.matchStyles = function (currentState, params, errors) {
2161 return this.fallbackTransition.buildStyles(currentState, params, errors);
2162 };
2163 return AnimationTrigger;
2164}());
2165function createFallbackTransition(triggerName, states) {
2166 var matchers = [function (fromState, toState) { return true; }];
2167 var animation = { type: 2 /* Sequence */, steps: [], options: null };
2168 var transition = {
2169 type: 1 /* Transition */,
2170 animation: animation,
2171 matchers: matchers,
2172 options: null,
2173 queryCount: 0,
2174 depCount: 0
2175 };
2176 return new AnimationTransitionFactory(triggerName, transition, states);
2177}
2178function balanceProperties(obj, key1, key2) {
2179 if (obj.hasOwnProperty(key1)) {
2180 if (!obj.hasOwnProperty(key2)) {
2181 obj[key2] = obj[key1];
2182 }
2183 }
2184 else if (obj.hasOwnProperty(key2)) {
2185 obj[key1] = obj[key2];
2186 }
2187}
2188
2189/**
2190 * @license
2191 * Copyright Google Inc. All Rights Reserved.
2192 *
2193 * Use of this source code is governed by an MIT-style license that can be
2194 * found in the LICENSE file at https://angular.io/license
2195 */
2196var EMPTY_INSTRUCTION_MAP = new ElementInstructionMap();
2197var TimelineAnimationEngine = /** @class */ (function () {
2198 function TimelineAnimationEngine(bodyNode, _driver, _normalizer) {
2199 this.bodyNode = bodyNode;
2200 this._driver = _driver;
2201 this._normalizer = _normalizer;
2202 this._animations = {};
2203 this._playersById = {};
2204 this.players = [];
2205 }
2206 TimelineAnimationEngine.prototype.register = function (id, metadata) {
2207 var errors = [];
2208 var ast = buildAnimationAst(this._driver, metadata, errors);
2209 if (errors.length) {
2210 throw new Error("Unable to build the animation due to the following errors: " + errors.join("\n"));
2211 }
2212 else {
2213 this._animations[id] = ast;
2214 }
2215 };
2216 TimelineAnimationEngine.prototype._buildPlayer = function (i, preStyles, postStyles) {
2217 var element = i.element;
2218 var keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
2219 return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
2220 };
2221 TimelineAnimationEngine.prototype.create = function (id, element, options) {
2222 var _this = this;
2223 if (options === void 0) { options = {}; }
2224 var errors = [];
2225 var ast = this._animations[id];
2226 var instructions;
2227 var autoStylesMap = new Map();
2228 if (ast) {
2229 instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, {}, {}, options, EMPTY_INSTRUCTION_MAP, errors);
2230 instructions.forEach(function (inst) {
2231 var styles = getOrSetAsInMap(autoStylesMap, inst.element, {});
2232 inst.postStyleProps.forEach(function (prop) { return styles[prop] = null; });
2233 });
2234 }
2235 else {
2236 errors.push('The requested animation doesn\'t exist or has already been destroyed');
2237 instructions = [];
2238 }
2239 if (errors.length) {
2240 throw new Error("Unable to create the animation due to the following errors: " + errors.join("\n"));
2241 }
2242 autoStylesMap.forEach(function (styles, element) {
2243 Object.keys(styles).forEach(function (prop) { styles[prop] = _this._driver.computeStyle(element, prop, AUTO_STYLE); });
2244 });
2245 var players = instructions.map(function (i) {
2246 var styles = autoStylesMap.get(i.element);
2247 return _this._buildPlayer(i, {}, styles);
2248 });
2249 var player = optimizeGroupPlayer(players);
2250 this._playersById[id] = player;
2251 player.onDestroy(function () { return _this.destroy(id); });
2252 this.players.push(player);
2253 return player;
2254 };
2255 TimelineAnimationEngine.prototype.destroy = function (id) {
2256 var player = this._getPlayer(id);
2257 player.destroy();
2258 delete this._playersById[id];
2259 var index = this.players.indexOf(player);
2260 if (index >= 0) {
2261 this.players.splice(index, 1);
2262 }
2263 };
2264 TimelineAnimationEngine.prototype._getPlayer = function (id) {
2265 var player = this._playersById[id];
2266 if (!player) {
2267 throw new Error("Unable to find the timeline player referenced by " + id);
2268 }
2269 return player;
2270 };
2271 TimelineAnimationEngine.prototype.listen = function (id, element, eventName, callback) {
2272 // triggerName, fromState, toState are all ignored for timeline animations
2273 var baseEvent = makeAnimationEvent(element, '', '', '');
2274 listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
2275 return function () { };
2276 };
2277 TimelineAnimationEngine.prototype.command = function (id, element, command, args) {
2278 if (command == 'register') {
2279 this.register(id, args[0]);
2280 return;
2281 }
2282 if (command == 'create') {
2283 var options = (args[0] || {});
2284 this.create(id, element, options);
2285 return;
2286 }
2287 var player = this._getPlayer(id);
2288 switch (command) {
2289 case 'play':
2290 player.play();
2291 break;
2292 case 'pause':
2293 player.pause();
2294 break;
2295 case 'reset':
2296 player.reset();
2297 break;
2298 case 'restart':
2299 player.restart();
2300 break;
2301 case 'finish':
2302 player.finish();
2303 break;
2304 case 'init':
2305 player.init();
2306 break;
2307 case 'setPosition':
2308 player.setPosition(parseFloat(args[0]));
2309 break;
2310 case 'destroy':
2311 this.destroy(id);
2312 break;
2313 }
2314 };
2315 return TimelineAnimationEngine;
2316}());
2317
2318var QUEUED_CLASSNAME = 'ng-animate-queued';
2319var QUEUED_SELECTOR = '.ng-animate-queued';
2320var DISABLED_CLASSNAME = 'ng-animate-disabled';
2321var DISABLED_SELECTOR = '.ng-animate-disabled';
2322var STAR_CLASSNAME = 'ng-star-inserted';
2323var STAR_SELECTOR = '.ng-star-inserted';
2324var EMPTY_PLAYER_ARRAY = [];
2325var NULL_REMOVAL_STATE = {
2326 namespaceId: '',
2327 setForRemoval: false,
2328 setForMove: false,
2329 hasAnimation: false,
2330 removedBeforeQueried: false
2331};
2332var NULL_REMOVED_QUERIED_STATE = {
2333 namespaceId: '',
2334 setForMove: false,
2335 setForRemoval: false,
2336 hasAnimation: false,
2337 removedBeforeQueried: true
2338};
2339var REMOVAL_FLAG = '__ng_removed';
2340var StateValue = /** @class */ (function () {
2341 function StateValue(input, namespaceId) {
2342 if (namespaceId === void 0) { namespaceId = ''; }
2343 this.namespaceId = namespaceId;
2344 var isObj = input && input.hasOwnProperty('value');
2345 var value = isObj ? input['value'] : input;
2346 this.value = normalizeTriggerValue(value);
2347 if (isObj) {
2348 var options = copyObj(input);
2349 delete options['value'];
2350 this.options = options;
2351 }
2352 else {
2353 this.options = {};
2354 }
2355 if (!this.options.params) {
2356 this.options.params = {};
2357 }
2358 }
2359 Object.defineProperty(StateValue.prototype, "params", {
2360 get: function () { return this.options.params; },
2361 enumerable: true,
2362 configurable: true
2363 });
2364 StateValue.prototype.absorbOptions = function (options) {
2365 var newParams = options.params;
2366 if (newParams) {
2367 var oldParams_1 = this.options.params;
2368 Object.keys(newParams).forEach(function (prop) {
2369 if (oldParams_1[prop] == null) {
2370 oldParams_1[prop] = newParams[prop];
2371 }
2372 });
2373 }
2374 };
2375 return StateValue;
2376}());
2377var VOID_VALUE = 'void';
2378var DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE);
2379var AnimationTransitionNamespace = /** @class */ (function () {
2380 function AnimationTransitionNamespace(id, hostElement, _engine) {
2381 this.id = id;
2382 this.hostElement = hostElement;
2383 this._engine = _engine;
2384 this.players = [];
2385 this._triggers = {};
2386 this._queue = [];
2387 this._elementListeners = new Map();
2388 this._hostClassName = 'ng-tns-' + id;
2389 addClass(hostElement, this._hostClassName);
2390 }
2391 AnimationTransitionNamespace.prototype.listen = function (element, name, phase, callback) {
2392 var _this = this;
2393 if (!this._triggers.hasOwnProperty(name)) {
2394 throw new Error("Unable to listen on the animation trigger event \"" + phase + "\" because the animation trigger \"" + name + "\" doesn't exist!");
2395 }
2396 if (phase == null || phase.length == 0) {
2397 throw new Error("Unable to listen on the animation trigger \"" + name + "\" because the provided event is undefined!");
2398 }
2399 if (!isTriggerEventValid(phase)) {
2400 throw new Error("The provided animation trigger event \"" + phase + "\" for the animation trigger \"" + name + "\" is not supported!");
2401 }
2402 var listeners = getOrSetAsInMap(this._elementListeners, element, []);
2403 var data = { name: name, phase: phase, callback: callback };
2404 listeners.push(data);
2405 var triggersWithStates = getOrSetAsInMap(this._engine.statesByElement, element, {});
2406 if (!triggersWithStates.hasOwnProperty(name)) {
2407 addClass(element, NG_TRIGGER_CLASSNAME);
2408 addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
2409 triggersWithStates[name] = DEFAULT_STATE_VALUE;
2410 }
2411 return function () {
2412 // the event listener is removed AFTER the flush has occurred such
2413 // that leave animations callbacks can fire (otherwise if the node
2414 // is removed in between then the listeners would be deregistered)
2415 _this._engine.afterFlush(function () {
2416 var index = listeners.indexOf(data);
2417 if (index >= 0) {
2418 listeners.splice(index, 1);
2419 }
2420 if (!_this._triggers[name]) {
2421 delete triggersWithStates[name];
2422 }
2423 });
2424 };
2425 };
2426 AnimationTransitionNamespace.prototype.register = function (name, ast) {
2427 if (this._triggers[name]) {
2428 // throw
2429 return false;
2430 }
2431 else {
2432 this._triggers[name] = ast;
2433 return true;
2434 }
2435 };
2436 AnimationTransitionNamespace.prototype._getTrigger = function (name) {
2437 var trigger = this._triggers[name];
2438 if (!trigger) {
2439 throw new Error("The provided animation trigger \"" + name + "\" has not been registered!");
2440 }
2441 return trigger;
2442 };
2443 AnimationTransitionNamespace.prototype.trigger = function (element, triggerName, value, defaultToFallback) {
2444 var _this = this;
2445 if (defaultToFallback === void 0) { defaultToFallback = true; }
2446 var trigger = this._getTrigger(triggerName);
2447 var player = new TransitionAnimationPlayer(this.id, triggerName, element);
2448 var triggersWithStates = this._engine.statesByElement.get(element);
2449 if (!triggersWithStates) {
2450 addClass(element, NG_TRIGGER_CLASSNAME);
2451 addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
2452 this._engine.statesByElement.set(element, triggersWithStates = {});
2453 }
2454 var fromState = triggersWithStates[triggerName];
2455 var toState = new StateValue(value, this.id);
2456 var isObj = value && value.hasOwnProperty('value');
2457 if (!isObj && fromState) {
2458 toState.absorbOptions(fromState.options);
2459 }
2460 triggersWithStates[triggerName] = toState;
2461 if (!fromState) {
2462 fromState = DEFAULT_STATE_VALUE;
2463 }
2464 var isRemoval = toState.value === VOID_VALUE;
2465 // normally this isn't reached by here, however, if an object expression
2466 // is passed in then it may be a new object each time. Comparing the value
2467 // is important since that will stay the same despite there being a new object.
2468 // The removal arc here is special cased because the same element is triggered
2469 // twice in the event that it contains animations on the outer/inner portions
2470 // of the host container
2471 if (!isRemoval && fromState.value === toState.value) {
2472 // this means that despite the value not changing, some inner params
2473 // have changed which means that the animation final styles need to be applied
2474 if (!objEquals(fromState.params, toState.params)) {
2475 var errors = [];
2476 var fromStyles_1 = trigger.matchStyles(fromState.value, fromState.params, errors);
2477 var toStyles_1 = trigger.matchStyles(toState.value, toState.params, errors);
2478 if (errors.length) {
2479 this._engine.reportError(errors);
2480 }
2481 else {
2482 this._engine.afterFlush(function () {
2483 eraseStyles(element, fromStyles_1);
2484 setStyles(element, toStyles_1);
2485 });
2486 }
2487 }
2488 return;
2489 }
2490 var playersOnElement = getOrSetAsInMap(this._engine.playersByElement, element, []);
2491 playersOnElement.forEach(function (player) {
2492 // only remove the player if it is queued on the EXACT same trigger/namespace
2493 // we only also deal with queued players here because if the animation has
2494 // started then we want to keep the player alive until the flush happens
2495 // (which is where the previousPlayers are passed into the new palyer)
2496 if (player.namespaceId == _this.id && player.triggerName == triggerName && player.queued) {
2497 player.destroy();
2498 }
2499 });
2500 var transition = trigger.matchTransition(fromState.value, toState.value, element, toState.params);
2501 var isFallbackTransition = false;
2502 if (!transition) {
2503 if (!defaultToFallback)
2504 return;
2505 transition = trigger.fallbackTransition;
2506 isFallbackTransition = true;
2507 }
2508 this._engine.totalQueuedPlayers++;
2509 this._queue.push({ element: element, triggerName: triggerName, transition: transition, fromState: fromState, toState: toState, player: player, isFallbackTransition: isFallbackTransition });
2510 if (!isFallbackTransition) {
2511 addClass(element, QUEUED_CLASSNAME);
2512 player.onStart(function () { removeClass(element, QUEUED_CLASSNAME); });
2513 }
2514 player.onDone(function () {
2515 var index = _this.players.indexOf(player);
2516 if (index >= 0) {
2517 _this.players.splice(index, 1);
2518 }
2519 var players = _this._engine.playersByElement.get(element);
2520 if (players) {
2521 var index_1 = players.indexOf(player);
2522 if (index_1 >= 0) {
2523 players.splice(index_1, 1);
2524 }
2525 }
2526 });
2527 this.players.push(player);
2528 playersOnElement.push(player);
2529 return player;
2530 };
2531 AnimationTransitionNamespace.prototype.deregister = function (name) {
2532 var _this = this;
2533 delete this._triggers[name];
2534 this._engine.statesByElement.forEach(function (stateMap, element) { delete stateMap[name]; });
2535 this._elementListeners.forEach(function (listeners, element) {
2536 _this._elementListeners.set(element, listeners.filter(function (entry) { return entry.name != name; }));
2537 });
2538 };
2539 AnimationTransitionNamespace.prototype.clearElementCache = function (element) {
2540 this._engine.statesByElement.delete(element);
2541 this._elementListeners.delete(element);
2542 var elementPlayers = this._engine.playersByElement.get(element);
2543 if (elementPlayers) {
2544 elementPlayers.forEach(function (player) { return player.destroy(); });
2545 this._engine.playersByElement.delete(element);
2546 }
2547 };
2548 AnimationTransitionNamespace.prototype._signalRemovalForInnerTriggers = function (rootElement, context) {
2549 var _this = this;
2550 var elements = this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true);
2551 // emulate a leave animation for all inner nodes within this node.
2552 // If there are no animations found for any of the nodes then clear the cache
2553 // for the element.
2554 elements.forEach(function (elm) {
2555 // this means that an inner remove() operation has already kicked off
2556 // the animation on this element...
2557 if (elm[REMOVAL_FLAG])
2558 return;
2559 var namespaces = _this._engine.fetchNamespacesByElement(elm);
2560 if (namespaces.size) {
2561 namespaces.forEach(function (ns) { return ns.triggerLeaveAnimation(elm, context, false, true); });
2562 }
2563 else {
2564 _this.clearElementCache(elm);
2565 }
2566 });
2567 // If the child elements were removed along with the parent, their animations might not
2568 // have completed. Clear all the elements from the cache so we don't end up with a memory leak.
2569 this._engine.afterFlushAnimationsDone(function () { return elements.forEach(function (elm) { return _this.clearElementCache(elm); }); });
2570 };
2571 AnimationTransitionNamespace.prototype.triggerLeaveAnimation = function (element, context, destroyAfterComplete, defaultToFallback) {
2572 var _this = this;
2573 var triggerStates = this._engine.statesByElement.get(element);
2574 if (triggerStates) {
2575 var players_1 = [];
2576 Object.keys(triggerStates).forEach(function (triggerName) {
2577 // this check is here in the event that an element is removed
2578 // twice (both on the host level and the component level)
2579 if (_this._triggers[triggerName]) {
2580 var player = _this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
2581 if (player) {
2582 players_1.push(player);
2583 }
2584 }
2585 });
2586 if (players_1.length) {
2587 this._engine.markElementAsRemoved(this.id, element, true, context);
2588 if (destroyAfterComplete) {
2589 optimizeGroupPlayer(players_1).onDone(function () { return _this._engine.processLeaveNode(element); });
2590 }
2591 return true;
2592 }
2593 }
2594 return false;
2595 };
2596 AnimationTransitionNamespace.prototype.prepareLeaveAnimationListeners = function (element) {
2597 var _this = this;
2598 var listeners = this._elementListeners.get(element);
2599 if (listeners) {
2600 var visitedTriggers_1 = new Set();
2601 listeners.forEach(function (listener) {
2602 var triggerName = listener.name;
2603 if (visitedTriggers_1.has(triggerName))
2604 return;
2605 visitedTriggers_1.add(triggerName);
2606 var trigger = _this._triggers[triggerName];
2607 var transition = trigger.fallbackTransition;
2608 var elementStates = _this._engine.statesByElement.get(element);
2609 var fromState = elementStates[triggerName] || DEFAULT_STATE_VALUE;
2610 var toState = new StateValue(VOID_VALUE);
2611 var player = new TransitionAnimationPlayer(_this.id, triggerName, element);
2612 _this._engine.totalQueuedPlayers++;
2613 _this._queue.push({
2614 element: element,
2615 triggerName: triggerName,
2616 transition: transition,
2617 fromState: fromState,
2618 toState: toState,
2619 player: player,
2620 isFallbackTransition: true
2621 });
2622 });
2623 }
2624 };
2625 AnimationTransitionNamespace.prototype.removeNode = function (element, context) {
2626 var _this = this;
2627 var engine = this._engine;
2628 if (element.childElementCount) {
2629 this._signalRemovalForInnerTriggers(element, context);
2630 }
2631 // this means that a * => VOID animation was detected and kicked off
2632 if (this.triggerLeaveAnimation(element, context, true))
2633 return;
2634 // find the player that is animating and make sure that the
2635 // removal is delayed until that player has completed
2636 var containsPotentialParentTransition = false;
2637 if (engine.totalAnimations) {
2638 var currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : [];
2639 // when this `if statement` does not continue forward it means that
2640 // a previous animation query has selected the current element and
2641 // is animating it. In this situation want to continue forwards and
2642 // allow the element to be queued up for animation later.
2643 if (currentPlayers && currentPlayers.length) {
2644 containsPotentialParentTransition = true;
2645 }
2646 else {
2647 var parent_1 = element;
2648 while (parent_1 = parent_1.parentNode) {
2649 var triggers = engine.statesByElement.get(parent_1);
2650 if (triggers) {
2651 containsPotentialParentTransition = true;
2652 break;
2653 }
2654 }
2655 }
2656 }
2657 // at this stage we know that the element will either get removed
2658 // during flush or will be picked up by a parent query. Either way
2659 // we need to fire the listeners for this element when it DOES get
2660 // removed (once the query parent animation is done or after flush)
2661 this.prepareLeaveAnimationListeners(element);
2662 // whether or not a parent has an animation we need to delay the deferral of the leave
2663 // operation until we have more information (which we do after flush() has been called)
2664 if (containsPotentialParentTransition) {
2665 engine.markElementAsRemoved(this.id, element, false, context);
2666 }
2667 else {
2668 var removalFlag = element[REMOVAL_FLAG];
2669 if (!removalFlag || removalFlag === NULL_REMOVAL_STATE) {
2670 // we do this after the flush has occurred such
2671 // that the callbacks can be fired
2672 engine.afterFlush(function () { return _this.clearElementCache(element); });
2673 engine.destroyInnerAnimations(element);
2674 engine._onRemovalComplete(element, context);
2675 }
2676 }
2677 };
2678 AnimationTransitionNamespace.prototype.insertNode = function (element, parent) { addClass(element, this._hostClassName); };
2679 AnimationTransitionNamespace.prototype.drainQueuedTransitions = function (microtaskId) {
2680 var _this = this;
2681 var instructions = [];
2682 this._queue.forEach(function (entry) {
2683 var player = entry.player;
2684 if (player.destroyed)
2685 return;
2686 var element = entry.element;
2687 var listeners = _this._elementListeners.get(element);
2688 if (listeners) {
2689 listeners.forEach(function (listener) {
2690 if (listener.name == entry.triggerName) {
2691 var baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
2692 baseEvent['_data'] = microtaskId;
2693 listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
2694 }
2695 });
2696 }
2697 if (player.markedForDestroy) {
2698 _this._engine.afterFlush(function () {
2699 // now we can destroy the element properly since the event listeners have
2700 // been bound to the player
2701 player.destroy();
2702 });
2703 }
2704 else {
2705 instructions.push(entry);
2706 }
2707 });
2708 this._queue = [];
2709 return instructions.sort(function (a, b) {
2710 // if depCount == 0 them move to front
2711 // otherwise if a contains b then move back
2712 var d0 = a.transition.ast.depCount;
2713 var d1 = b.transition.ast.depCount;
2714 if (d0 == 0 || d1 == 0) {
2715 return d0 - d1;
2716 }
2717 return _this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;
2718 });
2719 };
2720 AnimationTransitionNamespace.prototype.destroy = function (context) {
2721 this.players.forEach(function (p) { return p.destroy(); });
2722 this._signalRemovalForInnerTriggers(this.hostElement, context);
2723 };
2724 AnimationTransitionNamespace.prototype.elementContainsData = function (element) {
2725 var containsData = false;
2726 if (this._elementListeners.has(element))
2727 containsData = true;
2728 containsData =
2729 (this._queue.find(function (entry) { return entry.element === element; }) ? true : false) || containsData;
2730 return containsData;
2731 };
2732 return AnimationTransitionNamespace;
2733}());
2734var TransitionAnimationEngine = /** @class */ (function () {
2735 function TransitionAnimationEngine(bodyNode, driver, _normalizer) {
2736 this.bodyNode = bodyNode;
2737 this.driver = driver;
2738 this._normalizer = _normalizer;
2739 this.players = [];
2740 this.newHostElements = new Map();
2741 this.playersByElement = new Map();
2742 this.playersByQueriedElement = new Map();
2743 this.statesByElement = new Map();
2744 this.disabledNodes = new Set();
2745 this.totalAnimations = 0;
2746 this.totalQueuedPlayers = 0;
2747 this._namespaceLookup = {};
2748 this._namespaceList = [];
2749 this._flushFns = [];
2750 this._whenQuietFns = [];
2751 this.namespacesByHostElement = new Map();
2752 this.collectedEnterElements = [];
2753 this.collectedLeaveElements = [];
2754 // this method is designed to be overridden by the code that uses this engine
2755 this.onRemovalComplete = function (element, context) { };
2756 }
2757 /** @internal */
2758 TransitionAnimationEngine.prototype._onRemovalComplete = function (element, context) { this.onRemovalComplete(element, context); };
2759 Object.defineProperty(TransitionAnimationEngine.prototype, "queuedPlayers", {
2760 get: function () {
2761 var players = [];
2762 this._namespaceList.forEach(function (ns) {
2763 ns.players.forEach(function (player) {
2764 if (player.queued) {
2765 players.push(player);
2766 }
2767 });
2768 });
2769 return players;
2770 },
2771 enumerable: true,
2772 configurable: true
2773 });
2774 TransitionAnimationEngine.prototype.createNamespace = function (namespaceId, hostElement) {
2775 var ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);
2776 if (hostElement.parentNode) {
2777 this._balanceNamespaceList(ns, hostElement);
2778 }
2779 else {
2780 // defer this later until flush during when the host element has
2781 // been inserted so that we know exactly where to place it in
2782 // the namespace list
2783 this.newHostElements.set(hostElement, ns);
2784 // given that this host element is apart of the animation code, it
2785 // may or may not be inserted by a parent node that is an of an
2786 // animation renderer type. If this happens then we can still have
2787 // access to this item when we query for :enter nodes. If the parent
2788 // is a renderer then the set data-structure will normalize the entry
2789 this.collectEnterElement(hostElement);
2790 }
2791 return this._namespaceLookup[namespaceId] = ns;
2792 };
2793 TransitionAnimationEngine.prototype._balanceNamespaceList = function (ns, hostElement) {
2794 var limit = this._namespaceList.length - 1;
2795 if (limit >= 0) {
2796 var found = false;
2797 for (var i = limit; i >= 0; i--) {
2798 var nextNamespace = this._namespaceList[i];
2799 if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
2800 this._namespaceList.splice(i + 1, 0, ns);
2801 found = true;
2802 break;
2803 }
2804 }
2805 if (!found) {
2806 this._namespaceList.splice(0, 0, ns);
2807 }
2808 }
2809 else {
2810 this._namespaceList.push(ns);
2811 }
2812 this.namespacesByHostElement.set(hostElement, ns);
2813 return ns;
2814 };
2815 TransitionAnimationEngine.prototype.register = function (namespaceId, hostElement) {
2816 var ns = this._namespaceLookup[namespaceId];
2817 if (!ns) {
2818 ns = this.createNamespace(namespaceId, hostElement);
2819 }
2820 return ns;
2821 };
2822 TransitionAnimationEngine.prototype.registerTrigger = function (namespaceId, name, trigger) {
2823 var ns = this._namespaceLookup[namespaceId];
2824 if (ns && ns.register(name, trigger)) {
2825 this.totalAnimations++;
2826 }
2827 };
2828 TransitionAnimationEngine.prototype.destroy = function (namespaceId, context) {
2829 var _this = this;
2830 if (!namespaceId)
2831 return;
2832 var ns = this._fetchNamespace(namespaceId);
2833 this.afterFlush(function () {
2834 _this.namespacesByHostElement.delete(ns.hostElement);
2835 delete _this._namespaceLookup[namespaceId];
2836 var index = _this._namespaceList.indexOf(ns);
2837 if (index >= 0) {
2838 _this._namespaceList.splice(index, 1);
2839 }
2840 });
2841 this.afterFlushAnimationsDone(function () { return ns.destroy(context); });
2842 };
2843 TransitionAnimationEngine.prototype._fetchNamespace = function (id) { return this._namespaceLookup[id]; };
2844 TransitionAnimationEngine.prototype.fetchNamespacesByElement = function (element) {
2845 // normally there should only be one namespace per element, however
2846 // if @triggers are placed on both the component element and then
2847 // its host element (within the component code) then there will be
2848 // two namespaces returned. We use a set here to simply the dedupe
2849 // of namespaces incase there are multiple triggers both the elm and host
2850 var namespaces = new Set();
2851 var elementStates = this.statesByElement.get(element);
2852 if (elementStates) {
2853 var keys = Object.keys(elementStates);
2854 for (var i = 0; i < keys.length; i++) {
2855 var nsId = elementStates[keys[i]].namespaceId;
2856 if (nsId) {
2857 var ns = this._fetchNamespace(nsId);
2858 if (ns) {
2859 namespaces.add(ns);
2860 }
2861 }
2862 }
2863 }
2864 return namespaces;
2865 };
2866 TransitionAnimationEngine.prototype.trigger = function (namespaceId, element, name, value) {
2867 if (isElementNode(element)) {
2868 var ns = this._fetchNamespace(namespaceId);
2869 if (ns) {
2870 ns.trigger(element, name, value);
2871 return true;
2872 }
2873 }
2874 return false;
2875 };
2876 TransitionAnimationEngine.prototype.insertNode = function (namespaceId, element, parent, insertBefore) {
2877 if (!isElementNode(element))
2878 return;
2879 // special case for when an element is removed and reinserted (move operation)
2880 // when this occurs we do not want to use the element for deletion later
2881 var details = element[REMOVAL_FLAG];
2882 if (details && details.setForRemoval) {
2883 details.setForRemoval = false;
2884 details.setForMove = true;
2885 var index = this.collectedLeaveElements.indexOf(element);
2886 if (index >= 0) {
2887 this.collectedLeaveElements.splice(index, 1);
2888 }
2889 }
2890 // in the event that the namespaceId is blank then the caller
2891 // code does not contain any animation code in it, but it is
2892 // just being called so that the node is marked as being inserted
2893 if (namespaceId) {
2894 var ns = this._fetchNamespace(namespaceId);
2895 // This if-statement is a workaround for router issue #21947.
2896 // The router sometimes hits a race condition where while a route
2897 // is being instantiated a new navigation arrives, triggering leave
2898 // animation of DOM that has not been fully initialized, until this
2899 // is resolved, we need to handle the scenario when DOM is not in a
2900 // consistent state during the animation.
2901 if (ns) {
2902 ns.insertNode(element, parent);
2903 }
2904 }
2905 // only *directives and host elements are inserted before
2906 if (insertBefore) {
2907 this.collectEnterElement(element);
2908 }
2909 };
2910 TransitionAnimationEngine.prototype.collectEnterElement = function (element) { this.collectedEnterElements.push(element); };
2911 TransitionAnimationEngine.prototype.markElementAsDisabled = function (element, value) {
2912 if (value) {
2913 if (!this.disabledNodes.has(element)) {
2914 this.disabledNodes.add(element);
2915 addClass(element, DISABLED_CLASSNAME);
2916 }
2917 }
2918 else if (this.disabledNodes.has(element)) {
2919 this.disabledNodes.delete(element);
2920 removeClass(element, DISABLED_CLASSNAME);
2921 }
2922 };
2923 TransitionAnimationEngine.prototype.removeNode = function (namespaceId, element, isHostElement, context) {
2924 if (isElementNode(element)) {
2925 var ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
2926 if (ns) {
2927 ns.removeNode(element, context);
2928 }
2929 else {
2930 this.markElementAsRemoved(namespaceId, element, false, context);
2931 }
2932 if (isHostElement) {
2933 var hostNS = this.namespacesByHostElement.get(element);
2934 if (hostNS && hostNS.id !== namespaceId) {
2935 hostNS.removeNode(element, context);
2936 }
2937 }
2938 }
2939 else {
2940 this._onRemovalComplete(element, context);
2941 }
2942 };
2943 TransitionAnimationEngine.prototype.markElementAsRemoved = function (namespaceId, element, hasAnimation, context) {
2944 this.collectedLeaveElements.push(element);
2945 element[REMOVAL_FLAG] = {
2946 namespaceId: namespaceId,
2947 setForRemoval: context, hasAnimation: hasAnimation,
2948 removedBeforeQueried: false
2949 };
2950 };
2951 TransitionAnimationEngine.prototype.listen = function (namespaceId, element, name, phase, callback) {
2952 if (isElementNode(element)) {
2953 return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);
2954 }
2955 return function () { };
2956 };
2957 TransitionAnimationEngine.prototype._buildInstruction = function (entry, subTimelines, enterClassName, leaveClassName, skipBuildAst) {
2958 return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines, skipBuildAst);
2959 };
2960 TransitionAnimationEngine.prototype.destroyInnerAnimations = function (containerElement) {
2961 var _this = this;
2962 var elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);
2963 elements.forEach(function (element) { return _this.destroyActiveAnimationsForElement(element); });
2964 if (this.playersByQueriedElement.size == 0)
2965 return;
2966 elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);
2967 elements.forEach(function (element) { return _this.finishActiveQueriedAnimationOnElement(element); });
2968 };
2969 TransitionAnimationEngine.prototype.destroyActiveAnimationsForElement = function (element) {
2970 var players = this.playersByElement.get(element);
2971 if (players) {
2972 players.forEach(function (player) {
2973 // special case for when an element is set for destruction, but hasn't started.
2974 // in this situation we want to delay the destruction until the flush occurs
2975 // so that any event listeners attached to the player are triggered.
2976 if (player.queued) {
2977 player.markedForDestroy = true;
2978 }
2979 else {
2980 player.destroy();
2981 }
2982 });
2983 }
2984 };
2985 TransitionAnimationEngine.prototype.finishActiveQueriedAnimationOnElement = function (element) {
2986 var players = this.playersByQueriedElement.get(element);
2987 if (players) {
2988 players.forEach(function (player) { return player.finish(); });
2989 }
2990 };
2991 TransitionAnimationEngine.prototype.whenRenderingDone = function () {
2992 var _this = this;
2993 return new Promise(function (resolve) {
2994 if (_this.players.length) {
2995 return optimizeGroupPlayer(_this.players).onDone(function () { return resolve(); });
2996 }
2997 else {
2998 resolve();
2999 }
3000 });
3001 };
3002 TransitionAnimationEngine.prototype.processLeaveNode = function (element) {
3003 var _this = this;
3004 var details = element[REMOVAL_FLAG];
3005 if (details && details.setForRemoval) {
3006 // this will prevent it from removing it twice
3007 element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
3008 if (details.namespaceId) {
3009 this.destroyInnerAnimations(element);
3010 var ns = this._fetchNamespace(details.namespaceId);
3011 if (ns) {
3012 ns.clearElementCache(element);
3013 }
3014 }
3015 this._onRemovalComplete(element, details.setForRemoval);
3016 }
3017 if (this.driver.matchesElement(element, DISABLED_SELECTOR)) {
3018 this.markElementAsDisabled(element, false);
3019 }
3020 this.driver.query(element, DISABLED_SELECTOR, true).forEach(function (node) {
3021 _this.markElementAsDisabled(node, false);
3022 });
3023 };
3024 TransitionAnimationEngine.prototype.flush = function (microtaskId) {
3025 var _this = this;
3026 if (microtaskId === void 0) { microtaskId = -1; }
3027 var players = [];
3028 if (this.newHostElements.size) {
3029 this.newHostElements.forEach(function (ns, element) { return _this._balanceNamespaceList(ns, element); });
3030 this.newHostElements.clear();
3031 }
3032 if (this.totalAnimations && this.collectedEnterElements.length) {
3033 for (var i = 0; i < this.collectedEnterElements.length; i++) {
3034 var elm = this.collectedEnterElements[i];
3035 addClass(elm, STAR_CLASSNAME);
3036 }
3037 }
3038 if (this._namespaceList.length &&
3039 (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {
3040 var cleanupFns = [];
3041 try {
3042 players = this._flushAnimations(cleanupFns, microtaskId);
3043 }
3044 finally {
3045 for (var i = 0; i < cleanupFns.length; i++) {
3046 cleanupFns[i]();
3047 }
3048 }
3049 }
3050 else {
3051 for (var i = 0; i < this.collectedLeaveElements.length; i++) {
3052 var element = this.collectedLeaveElements[i];
3053 this.processLeaveNode(element);
3054 }
3055 }
3056 this.totalQueuedPlayers = 0;
3057 this.collectedEnterElements.length = 0;
3058 this.collectedLeaveElements.length = 0;
3059 this._flushFns.forEach(function (fn) { return fn(); });
3060 this._flushFns = [];
3061 if (this._whenQuietFns.length) {
3062 // we move these over to a variable so that
3063 // if any new callbacks are registered in another
3064 // flush they do not populate the existing set
3065 var quietFns_1 = this._whenQuietFns;
3066 this._whenQuietFns = [];
3067 if (players.length) {
3068 optimizeGroupPlayer(players).onDone(function () { quietFns_1.forEach(function (fn) { return fn(); }); });
3069 }
3070 else {
3071 quietFns_1.forEach(function (fn) { return fn(); });
3072 }
3073 }
3074 };
3075 TransitionAnimationEngine.prototype.reportError = function (errors) {
3076 throw new Error("Unable to process animations due to the following failed trigger transitions\n " + errors.join('\n'));
3077 };
3078 TransitionAnimationEngine.prototype._flushAnimations = function (cleanupFns, microtaskId) {
3079 var _this = this;
3080 var subTimelines = new ElementInstructionMap();
3081 var skippedPlayers = [];
3082 var skippedPlayersMap = new Map();
3083 var queuedInstructions = [];
3084 var queriedElements = new Map();
3085 var allPreStyleElements = new Map();
3086 var allPostStyleElements = new Map();
3087 var disabledElementsSet = new Set();
3088 this.disabledNodes.forEach(function (node) {
3089 disabledElementsSet.add(node);
3090 var nodesThatAreDisabled = _this.driver.query(node, QUEUED_SELECTOR, true);
3091 for (var i_1 = 0; i_1 < nodesThatAreDisabled.length; i_1++) {
3092 disabledElementsSet.add(nodesThatAreDisabled[i_1]);
3093 }
3094 });
3095 var bodyNode = this.bodyNode;
3096 var allTriggerElements = Array.from(this.statesByElement.keys());
3097 var enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements);
3098 // this must occur before the instructions are built below such that
3099 // the :enter queries match the elements (since the timeline queries
3100 // are fired during instruction building).
3101 var enterNodeMapIds = new Map();
3102 var i = 0;
3103 enterNodeMap.forEach(function (nodes, root) {
3104 var className = ENTER_CLASSNAME + i++;
3105 enterNodeMapIds.set(root, className);
3106 nodes.forEach(function (node) { return addClass(node, className); });
3107 });
3108 var allLeaveNodes = [];
3109 var mergedLeaveNodes = new Set();
3110 var leaveNodesWithoutAnimations = new Set();
3111 for (var i_2 = 0; i_2 < this.collectedLeaveElements.length; i_2++) {
3112 var element = this.collectedLeaveElements[i_2];
3113 var details = element[REMOVAL_FLAG];
3114 if (details && details.setForRemoval) {
3115 allLeaveNodes.push(element);
3116 mergedLeaveNodes.add(element);
3117 if (details.hasAnimation) {
3118 this.driver.query(element, STAR_SELECTOR, true).forEach(function (elm) { return mergedLeaveNodes.add(elm); });
3119 }
3120 else {
3121 leaveNodesWithoutAnimations.add(element);
3122 }
3123 }
3124 }
3125 var leaveNodeMapIds = new Map();
3126 var leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));
3127 leaveNodeMap.forEach(function (nodes, root) {
3128 var className = LEAVE_CLASSNAME + i++;
3129 leaveNodeMapIds.set(root, className);
3130 nodes.forEach(function (node) { return addClass(node, className); });
3131 });
3132 cleanupFns.push(function () {
3133 enterNodeMap.forEach(function (nodes, root) {
3134 var className = enterNodeMapIds.get(root);
3135 nodes.forEach(function (node) { return removeClass(node, className); });
3136 });
3137 leaveNodeMap.forEach(function (nodes, root) {
3138 var className = leaveNodeMapIds.get(root);
3139 nodes.forEach(function (node) { return removeClass(node, className); });
3140 });
3141 allLeaveNodes.forEach(function (element) { _this.processLeaveNode(element); });
3142 });
3143 var allPlayers = [];
3144 var erroneousTransitions = [];
3145 for (var i_3 = this._namespaceList.length - 1; i_3 >= 0; i_3--) {
3146 var ns = this._namespaceList[i_3];
3147 ns.drainQueuedTransitions(microtaskId).forEach(function (entry) {
3148 var player = entry.player;
3149 var element = entry.element;
3150 allPlayers.push(player);
3151 if (_this.collectedEnterElements.length) {
3152 var details = element[REMOVAL_FLAG];
3153 // move animations are currently not supported...
3154 if (details && details.setForMove) {
3155 player.destroy();
3156 return;
3157 }
3158 }
3159 var nodeIsOrphaned = !bodyNode || !_this.driver.containsElement(bodyNode, element);
3160 var leaveClassName = leaveNodeMapIds.get(element);
3161 var enterClassName = enterNodeMapIds.get(element);
3162 var instruction = _this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned);
3163 if (instruction.errors && instruction.errors.length) {
3164 erroneousTransitions.push(instruction);
3165 return;
3166 }
3167 // even though the element may not be apart of the DOM, it may
3168 // still be added at a later point (due to the mechanics of content
3169 // projection and/or dynamic component insertion) therefore it's
3170 // important we still style the element.
3171 if (nodeIsOrphaned) {
3172 player.onStart(function () { return eraseStyles(element, instruction.fromStyles); });
3173 player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
3174 skippedPlayers.push(player);
3175 return;
3176 }
3177 // if a unmatched transition is queued to go then it SHOULD NOT render
3178 // an animation and cancel the previously running animations.
3179 if (entry.isFallbackTransition) {
3180 player.onStart(function () { return eraseStyles(element, instruction.fromStyles); });
3181 player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
3182 skippedPlayers.push(player);
3183 return;
3184 }
3185 // this means that if a parent animation uses this animation as a sub trigger
3186 // then it will instruct the timeline builder to not add a player delay, but
3187 // instead stretch the first keyframe gap up until the animation starts. The
3188 // reason this is important is to prevent extra initialization styles from being
3189 // required by the user in the animation.
3190 instruction.timelines.forEach(function (tl) { return tl.stretchStartingKeyframe = true; });
3191 subTimelines.append(element, instruction.timelines);
3192 var tuple = { instruction: instruction, player: player, element: element };
3193 queuedInstructions.push(tuple);
3194 instruction.queriedElements.forEach(function (element) { return getOrSetAsInMap(queriedElements, element, []).push(player); });
3195 instruction.preStyleProps.forEach(function (stringMap, element) {
3196 var props = Object.keys(stringMap);
3197 if (props.length) {
3198 var setVal_1 = allPreStyleElements.get(element);
3199 if (!setVal_1) {
3200 allPreStyleElements.set(element, setVal_1 = new Set());
3201 }
3202 props.forEach(function (prop) { return setVal_1.add(prop); });
3203 }
3204 });
3205 instruction.postStyleProps.forEach(function (stringMap, element) {
3206 var props = Object.keys(stringMap);
3207 var setVal = allPostStyleElements.get(element);
3208 if (!setVal) {
3209 allPostStyleElements.set(element, setVal = new Set());
3210 }
3211 props.forEach(function (prop) { return setVal.add(prop); });
3212 });
3213 });
3214 }
3215 if (erroneousTransitions.length) {
3216 var errors_1 = [];
3217 erroneousTransitions.forEach(function (instruction) {
3218 errors_1.push("@" + instruction.triggerName + " has failed due to:\n");
3219 instruction.errors.forEach(function (error) { return errors_1.push("- " + error + "\n"); });
3220 });
3221 allPlayers.forEach(function (player) { return player.destroy(); });
3222 this.reportError(errors_1);
3223 }
3224 var allPreviousPlayersMap = new Map();
3225 // this map works to tell which element in the DOM tree is contained by
3226 // which animation. Further down below this map will get populated once
3227 // the players are built and in doing so it can efficiently figure out
3228 // if a sub player is skipped due to a parent player having priority.
3229 var animationElementMap = new Map();
3230 queuedInstructions.forEach(function (entry) {
3231 var element = entry.element;
3232 if (subTimelines.has(element)) {
3233 animationElementMap.set(element, element);
3234 _this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);
3235 }
3236 });
3237 skippedPlayers.forEach(function (player) {
3238 var element = player.element;
3239 var previousPlayers = _this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
3240 previousPlayers.forEach(function (prevPlayer) {
3241 getOrSetAsInMap(allPreviousPlayersMap, element, []).push(prevPlayer);
3242 prevPlayer.destroy();
3243 });
3244 });
3245 // this is a special case for nodes that will be removed (either by)
3246 // having their own leave animations or by being queried in a container
3247 // that will be removed once a parent animation is complete. The idea
3248 // here is that * styles must be identical to ! styles because of
3249 // backwards compatibility (* is also filled in by default in many places).
3250 // Otherwise * styles will return an empty value or auto since the element
3251 // that is being getComputedStyle'd will not be visible (since * = destination)
3252 var replaceNodes = allLeaveNodes.filter(function (node) {
3253 return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
3254 });
3255 // POST STAGE: fill the * styles
3256 var postStylesMap = new Map();
3257 var allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, AUTO_STYLE);
3258 allLeaveQueriedNodes.forEach(function (node) {
3259 if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
3260 replaceNodes.push(node);
3261 }
3262 });
3263 // PRE STAGE: fill the ! styles
3264 var preStylesMap = new Map();
3265 enterNodeMap.forEach(function (nodes, root) {
3266 cloakAndComputeStyles(preStylesMap, _this.driver, new Set(nodes), allPreStyleElements, ɵPRE_STYLE);
3267 });
3268 replaceNodes.forEach(function (node) {
3269 var post = postStylesMap.get(node);
3270 var pre = preStylesMap.get(node);
3271 postStylesMap.set(node, __assign(__assign({}, post), pre));
3272 });
3273 var rootPlayers = [];
3274 var subPlayers = [];
3275 var NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};
3276 queuedInstructions.forEach(function (entry) {
3277 var element = entry.element, player = entry.player, instruction = entry.instruction;
3278 // this means that it was never consumed by a parent animation which
3279 // means that it is independent and therefore should be set for animation
3280 if (subTimelines.has(element)) {
3281 if (disabledElementsSet.has(element)) {
3282 player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
3283 player.disabled = true;
3284 player.overrideTotalTime(instruction.totalTime);
3285 skippedPlayers.push(player);
3286 return;
3287 }
3288 // this will flow up the DOM and query the map to figure out
3289 // if a parent animation has priority over it. In the situation
3290 // that a parent is detected then it will cancel the loop. If
3291 // nothing is detected, or it takes a few hops to find a parent,
3292 // then it will fill in the missing nodes and signal them as having
3293 // a detected parent (or a NO_PARENT value via a special constant).
3294 var parentWithAnimation_1 = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
3295 if (animationElementMap.size > 1) {
3296 var elm = element;
3297 var parentsToAdd = [];
3298 while (elm = elm.parentNode) {
3299 var detectedParent = animationElementMap.get(elm);
3300 if (detectedParent) {
3301 parentWithAnimation_1 = detectedParent;
3302 break;
3303 }
3304 parentsToAdd.push(elm);
3305 }
3306 parentsToAdd.forEach(function (parent) { return animationElementMap.set(parent, parentWithAnimation_1); });
3307 }
3308 var innerPlayer = _this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);
3309 player.setRealPlayer(innerPlayer);
3310 if (parentWithAnimation_1 === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {
3311 rootPlayers.push(player);
3312 }
3313 else {
3314 var parentPlayers = _this.playersByElement.get(parentWithAnimation_1);
3315 if (parentPlayers && parentPlayers.length) {
3316 player.parentPlayer = optimizeGroupPlayer(parentPlayers);
3317 }
3318 skippedPlayers.push(player);
3319 }
3320 }
3321 else {
3322 eraseStyles(element, instruction.fromStyles);
3323 player.onDestroy(function () { return setStyles(element, instruction.toStyles); });
3324 // there still might be a ancestor player animating this
3325 // element therefore we will still add it as a sub player
3326 // even if its animation may be disabled
3327 subPlayers.push(player);
3328 if (disabledElementsSet.has(element)) {
3329 skippedPlayers.push(player);
3330 }
3331 }
3332 });
3333 // find all of the sub players' corresponding inner animation player
3334 subPlayers.forEach(function (player) {
3335 // even if any players are not found for a sub animation then it
3336 // will still complete itself after the next tick since it's Noop
3337 var playersForElement = skippedPlayersMap.get(player.element);
3338 if (playersForElement && playersForElement.length) {
3339 var innerPlayer = optimizeGroupPlayer(playersForElement);
3340 player.setRealPlayer(innerPlayer);
3341 }
3342 });
3343 // the reason why we don't actually play the animation is
3344 // because all that a skipped player is designed to do is to
3345 // fire the start/done transition callback events
3346 skippedPlayers.forEach(function (player) {
3347 if (player.parentPlayer) {
3348 player.syncPlayerEvents(player.parentPlayer);
3349 }
3350 else {
3351 player.destroy();
3352 }
3353 });
3354 // run through all of the queued removals and see if they
3355 // were picked up by a query. If not then perform the removal
3356 // operation right away unless a parent animation is ongoing.
3357 for (var i_4 = 0; i_4 < allLeaveNodes.length; i_4++) {
3358 var element = allLeaveNodes[i_4];
3359 var details = element[REMOVAL_FLAG];
3360 removeClass(element, LEAVE_CLASSNAME);
3361 // this means the element has a removal animation that is being
3362 // taken care of and therefore the inner elements will hang around
3363 // until that animation is over (or the parent queried animation)
3364 if (details && details.hasAnimation)
3365 continue;
3366 var players = [];
3367 // if this element is queried or if it contains queried children
3368 // then we want for the element not to be removed from the page
3369 // until the queried animations have finished
3370 if (queriedElements.size) {
3371 var queriedPlayerResults = queriedElements.get(element);
3372 if (queriedPlayerResults && queriedPlayerResults.length) {
3373 players.push.apply(players, __spread(queriedPlayerResults));
3374 }
3375 var queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);
3376 for (var j = 0; j < queriedInnerElements.length; j++) {
3377 var queriedPlayers = queriedElements.get(queriedInnerElements[j]);
3378 if (queriedPlayers && queriedPlayers.length) {
3379 players.push.apply(players, __spread(queriedPlayers));
3380 }
3381 }
3382 }
3383 var activePlayers = players.filter(function (p) { return !p.destroyed; });
3384 if (activePlayers.length) {
3385 removeNodesAfterAnimationDone(this, element, activePlayers);
3386 }
3387 else {
3388 this.processLeaveNode(element);
3389 }
3390 }
3391 // this is required so the cleanup method doesn't remove them
3392 allLeaveNodes.length = 0;
3393 rootPlayers.forEach(function (player) {
3394 _this.players.push(player);
3395 player.onDone(function () {
3396 player.destroy();
3397 var index = _this.players.indexOf(player);
3398 _this.players.splice(index, 1);
3399 });
3400 player.play();
3401 });
3402 return rootPlayers;
3403 };
3404 TransitionAnimationEngine.prototype.elementContainsData = function (namespaceId, element) {
3405 var containsData = false;
3406 var details = element[REMOVAL_FLAG];
3407 if (details && details.setForRemoval)
3408 containsData = true;
3409 if (this.playersByElement.has(element))
3410 containsData = true;
3411 if (this.playersByQueriedElement.has(element))
3412 containsData = true;
3413 if (this.statesByElement.has(element))
3414 containsData = true;
3415 return this._fetchNamespace(namespaceId).elementContainsData(element) || containsData;
3416 };
3417 TransitionAnimationEngine.prototype.afterFlush = function (callback) { this._flushFns.push(callback); };
3418 TransitionAnimationEngine.prototype.afterFlushAnimationsDone = function (callback) { this._whenQuietFns.push(callback); };
3419 TransitionAnimationEngine.prototype._getPreviousPlayers = function (element, isQueriedElement, namespaceId, triggerName, toStateValue) {
3420 var players = [];
3421 if (isQueriedElement) {
3422 var queriedElementPlayers = this.playersByQueriedElement.get(element);
3423 if (queriedElementPlayers) {
3424 players = queriedElementPlayers;
3425 }
3426 }
3427 else {
3428 var elementPlayers = this.playersByElement.get(element);
3429 if (elementPlayers) {
3430 var isRemovalAnimation_1 = !toStateValue || toStateValue == VOID_VALUE;
3431 elementPlayers.forEach(function (player) {
3432 if (player.queued)
3433 return;
3434 if (!isRemovalAnimation_1 && player.triggerName != triggerName)
3435 return;
3436 players.push(player);
3437 });
3438 }
3439 }
3440 if (namespaceId || triggerName) {
3441 players = players.filter(function (player) {
3442 if (namespaceId && namespaceId != player.namespaceId)
3443 return false;
3444 if (triggerName && triggerName != player.triggerName)
3445 return false;
3446 return true;
3447 });
3448 }
3449 return players;
3450 };
3451 TransitionAnimationEngine.prototype._beforeAnimationBuild = function (namespaceId, instruction, allPreviousPlayersMap) {
3452 var e_1, _a;
3453 var triggerName = instruction.triggerName;
3454 var rootElement = instruction.element;
3455 // when a removal animation occurs, ALL previous players are collected
3456 // and destroyed (even if they are outside of the current namespace)
3457 var targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
3458 var targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;
3459 var _loop_1 = function (timelineInstruction) {
3460 var element = timelineInstruction.element;
3461 var isQueriedElement = element !== rootElement;
3462 var players = getOrSetAsInMap(allPreviousPlayersMap, element, []);
3463 var previousPlayers = this_1._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
3464 previousPlayers.forEach(function (player) {
3465 var realPlayer = player.getRealPlayer();
3466 if (realPlayer.beforeDestroy) {
3467 realPlayer.beforeDestroy();
3468 }
3469 player.destroy();
3470 players.push(player);
3471 });
3472 };
3473 var this_1 = this;
3474 try {
3475 for (var _b = __values(instruction.timelines), _c = _b.next(); !_c.done; _c = _b.next()) {
3476 var timelineInstruction = _c.value;
3477 _loop_1(timelineInstruction);
3478 }
3479 }
3480 catch (e_1_1) { e_1 = { error: e_1_1 }; }
3481 finally {
3482 try {
3483 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3484 }
3485 finally { if (e_1) throw e_1.error; }
3486 }
3487 // this needs to be done so that the PRE/POST styles can be
3488 // computed properly without interfering with the previous animation
3489 eraseStyles(rootElement, instruction.fromStyles);
3490 };
3491 TransitionAnimationEngine.prototype._buildAnimation = function (namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {
3492 var _this = this;
3493 var triggerName = instruction.triggerName;
3494 var rootElement = instruction.element;
3495 // we first run this so that the previous animation player
3496 // data can be passed into the successive animation players
3497 var allQueriedPlayers = [];
3498 var allConsumedElements = new Set();
3499 var allSubElements = new Set();
3500 var allNewPlayers = instruction.timelines.map(function (timelineInstruction) {
3501 var element = timelineInstruction.element;
3502 allConsumedElements.add(element);
3503 // FIXME (matsko): make sure to-be-removed animations are removed properly
3504 var details = element[REMOVAL_FLAG];
3505 if (details && details.removedBeforeQueried)
3506 return new NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);
3507 var isQueriedElement = element !== rootElement;
3508 var previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY)
3509 .map(function (p) { return p.getRealPlayer(); }))
3510 .filter(function (p) {
3511 // the `element` is not apart of the AnimationPlayer definition, but
3512 // Mock/WebAnimations
3513 // use the element within their implementation. This will be added in Angular5 to
3514 // AnimationPlayer
3515 var pp = p;
3516 return pp.element ? pp.element === element : false;
3517 });
3518 var preStyles = preStylesMap.get(element);
3519 var postStyles = postStylesMap.get(element);
3520 var keyframes = normalizeKeyframes(_this.driver, _this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
3521 var player = _this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
3522 // this means that this particular player belongs to a sub trigger. It is
3523 // important that we match this player up with the corresponding (@trigger.listener)
3524 if (timelineInstruction.subTimeline && skippedPlayersMap) {
3525 allSubElements.add(element);
3526 }
3527 if (isQueriedElement) {
3528 var wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);
3529 wrappedPlayer.setRealPlayer(player);
3530 allQueriedPlayers.push(wrappedPlayer);
3531 }
3532 return player;
3533 });
3534 allQueriedPlayers.forEach(function (player) {
3535 getOrSetAsInMap(_this.playersByQueriedElement, player.element, []).push(player);
3536 player.onDone(function () { return deleteOrUnsetInMap(_this.playersByQueriedElement, player.element, player); });
3537 });
3538 allConsumedElements.forEach(function (element) { return addClass(element, NG_ANIMATING_CLASSNAME); });
3539 var player = optimizeGroupPlayer(allNewPlayers);
3540 player.onDestroy(function () {
3541 allConsumedElements.forEach(function (element) { return removeClass(element, NG_ANIMATING_CLASSNAME); });
3542 setStyles(rootElement, instruction.toStyles);
3543 });
3544 // this basically makes all of the callbacks for sub element animations
3545 // be dependent on the upper players for when they finish
3546 allSubElements.forEach(function (element) { getOrSetAsInMap(skippedPlayersMap, element, []).push(player); });
3547 return player;
3548 };
3549 TransitionAnimationEngine.prototype._buildPlayer = function (instruction, keyframes, previousPlayers) {
3550 if (keyframes.length > 0) {
3551 return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);
3552 }
3553 // special case for when an empty transition|definition is provided
3554 // ... there is no point in rendering an empty animation
3555 return new NoopAnimationPlayer(instruction.duration, instruction.delay);
3556 };
3557 return TransitionAnimationEngine;
3558}());
3559var TransitionAnimationPlayer = /** @class */ (function () {
3560 function TransitionAnimationPlayer(namespaceId, triggerName, element) {
3561 this.namespaceId = namespaceId;
3562 this.triggerName = triggerName;
3563 this.element = element;
3564 this._player = new NoopAnimationPlayer();
3565 this._containsRealPlayer = false;
3566 this._queuedCallbacks = {};
3567 this.destroyed = false;
3568 this.markedForDestroy = false;
3569 this.disabled = false;
3570 this.queued = true;
3571 this.totalTime = 0;
3572 }
3573 TransitionAnimationPlayer.prototype.setRealPlayer = function (player) {
3574 var _this = this;
3575 if (this._containsRealPlayer)
3576 return;
3577 this._player = player;
3578 Object.keys(this._queuedCallbacks).forEach(function (phase) {
3579 _this._queuedCallbacks[phase].forEach(function (callback) { return listenOnPlayer(player, phase, undefined, callback); });
3580 });
3581 this._queuedCallbacks = {};
3582 this._containsRealPlayer = true;
3583 this.overrideTotalTime(player.totalTime);
3584 this.queued = false;
3585 };
3586 TransitionAnimationPlayer.prototype.getRealPlayer = function () { return this._player; };
3587 TransitionAnimationPlayer.prototype.overrideTotalTime = function (totalTime) { this.totalTime = totalTime; };
3588 TransitionAnimationPlayer.prototype.syncPlayerEvents = function (player) {
3589 var _this = this;
3590 var p = this._player;
3591 if (p.triggerCallback) {
3592 player.onStart(function () { return p.triggerCallback('start'); });
3593 }
3594 player.onDone(function () { return _this.finish(); });
3595 player.onDestroy(function () { return _this.destroy(); });
3596 };
3597 TransitionAnimationPlayer.prototype._queueEvent = function (name, callback) {
3598 getOrSetAsInMap(this._queuedCallbacks, name, []).push(callback);
3599 };
3600 TransitionAnimationPlayer.prototype.onDone = function (fn) {
3601 if (this.queued) {
3602 this._queueEvent('done', fn);
3603 }
3604 this._player.onDone(fn);
3605 };
3606 TransitionAnimationPlayer.prototype.onStart = function (fn) {
3607 if (this.queued) {
3608 this._queueEvent('start', fn);
3609 }
3610 this._player.onStart(fn);
3611 };
3612 TransitionAnimationPlayer.prototype.onDestroy = function (fn) {
3613 if (this.queued) {
3614 this._queueEvent('destroy', fn);
3615 }
3616 this._player.onDestroy(fn);
3617 };
3618 TransitionAnimationPlayer.prototype.init = function () { this._player.init(); };
3619 TransitionAnimationPlayer.prototype.hasStarted = function () { return this.queued ? false : this._player.hasStarted(); };
3620 TransitionAnimationPlayer.prototype.play = function () { !this.queued && this._player.play(); };
3621 TransitionAnimationPlayer.prototype.pause = function () { !this.queued && this._player.pause(); };
3622 TransitionAnimationPlayer.prototype.restart = function () { !this.queued && this._player.restart(); };
3623 TransitionAnimationPlayer.prototype.finish = function () { this._player.finish(); };
3624 TransitionAnimationPlayer.prototype.destroy = function () {
3625 this.destroyed = true;
3626 this._player.destroy();
3627 };
3628 TransitionAnimationPlayer.prototype.reset = function () { !this.queued && this._player.reset(); };
3629 TransitionAnimationPlayer.prototype.setPosition = function (p) {
3630 if (!this.queued) {
3631 this._player.setPosition(p);
3632 }
3633 };
3634 TransitionAnimationPlayer.prototype.getPosition = function () { return this.queued ? 0 : this._player.getPosition(); };
3635 /** @internal */
3636 TransitionAnimationPlayer.prototype.triggerCallback = function (phaseName) {
3637 var p = this._player;
3638 if (p.triggerCallback) {
3639 p.triggerCallback(phaseName);
3640 }
3641 };
3642 return TransitionAnimationPlayer;
3643}());
3644function deleteOrUnsetInMap(map, key, value) {
3645 var currentValues;
3646 if (map instanceof Map) {
3647 currentValues = map.get(key);
3648 if (currentValues) {
3649 if (currentValues.length) {
3650 var index = currentValues.indexOf(value);
3651 currentValues.splice(index, 1);
3652 }
3653 if (currentValues.length == 0) {
3654 map.delete(key);
3655 }
3656 }
3657 }
3658 else {
3659 currentValues = map[key];
3660 if (currentValues) {
3661 if (currentValues.length) {
3662 var index = currentValues.indexOf(value);
3663 currentValues.splice(index, 1);
3664 }
3665 if (currentValues.length == 0) {
3666 delete map[key];
3667 }
3668 }
3669 }
3670 return currentValues;
3671}
3672function normalizeTriggerValue(value) {
3673 // we use `!= null` here because it's the most simple
3674 // way to test against a "falsy" value without mixing
3675 // in empty strings or a zero value. DO NOT OPTIMIZE.
3676 return value != null ? value : null;
3677}
3678function isElementNode(node) {
3679 return node && node['nodeType'] === 1;
3680}
3681function isTriggerEventValid(eventName) {
3682 return eventName == 'start' || eventName == 'done';
3683}
3684function cloakElement(element, value) {
3685 var oldValue = element.style.display;
3686 element.style.display = value != null ? value : 'none';
3687 return oldValue;
3688}
3689function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {
3690 var cloakVals = [];
3691 elements.forEach(function (element) { return cloakVals.push(cloakElement(element)); });
3692 var failedElements = [];
3693 elementPropsMap.forEach(function (props, element) {
3694 var styles = {};
3695 props.forEach(function (prop) {
3696 var value = styles[prop] = driver.computeStyle(element, prop, defaultStyle);
3697 // there is no easy way to detect this because a sub element could be removed
3698 // by a parent animation element being detached.
3699 if (!value || value.length == 0) {
3700 element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
3701 failedElements.push(element);
3702 }
3703 });
3704 valuesMap.set(element, styles);
3705 });
3706 // we use a index variable here since Set.forEach(a, i) does not return
3707 // an index value for the closure (but instead just the value)
3708 var i = 0;
3709 elements.forEach(function (element) { return cloakElement(element, cloakVals[i++]); });
3710 return failedElements;
3711}
3712/*
3713Since the Angular renderer code will return a collection of inserted
3714nodes in all areas of a DOM tree, it's up to this algorithm to figure
3715out which nodes are roots for each animation @trigger.
3716
3717By placing each inserted node into a Set and traversing upwards, it
3718is possible to find the @trigger elements and well any direct *star
3719insertion nodes, if a @trigger root is found then the enter element
3720is placed into the Map[@trigger] spot.
3721 */
3722function buildRootMap(roots, nodes) {
3723 var rootMap = new Map();
3724 roots.forEach(function (root) { return rootMap.set(root, []); });
3725 if (nodes.length == 0)
3726 return rootMap;
3727 var NULL_NODE = 1;
3728 var nodeSet = new Set(nodes);
3729 var localRootMap = new Map();
3730 function getRoot(node) {
3731 if (!node)
3732 return NULL_NODE;
3733 var root = localRootMap.get(node);
3734 if (root)
3735 return root;
3736 var parent = node.parentNode;
3737 if (rootMap.has(parent)) { // ngIf inside @trigger
3738 root = parent;
3739 }
3740 else if (nodeSet.has(parent)) { // ngIf inside ngIf
3741 root = NULL_NODE;
3742 }
3743 else { // recurse upwards
3744 root = getRoot(parent);
3745 }
3746 localRootMap.set(node, root);
3747 return root;
3748 }
3749 nodes.forEach(function (node) {
3750 var root = getRoot(node);
3751 if (root !== NULL_NODE) {
3752 rootMap.get(root).push(node);
3753 }
3754 });
3755 return rootMap;
3756}
3757var CLASSES_CACHE_KEY = '$$classes';
3758function containsClass(element, className) {
3759 if (element.classList) {
3760 return element.classList.contains(className);
3761 }
3762 else {
3763 var classes = element[CLASSES_CACHE_KEY];
3764 return classes && classes[className];
3765 }
3766}
3767function addClass(element, className) {
3768 if (element.classList) {
3769 element.classList.add(className);
3770 }
3771 else {
3772 var classes = element[CLASSES_CACHE_KEY];
3773 if (!classes) {
3774 classes = element[CLASSES_CACHE_KEY] = {};
3775 }
3776 classes[className] = true;
3777 }
3778}
3779function removeClass(element, className) {
3780 if (element.classList) {
3781 element.classList.remove(className);
3782 }
3783 else {
3784 var classes = element[CLASSES_CACHE_KEY];
3785 if (classes) {
3786 delete classes[className];
3787 }
3788 }
3789}
3790function removeNodesAfterAnimationDone(engine, element, players) {
3791 optimizeGroupPlayer(players).onDone(function () { return engine.processLeaveNode(element); });
3792}
3793function flattenGroupPlayers(players) {
3794 var finalPlayers = [];
3795 _flattenGroupPlayersRecur(players, finalPlayers);
3796 return finalPlayers;
3797}
3798function _flattenGroupPlayersRecur(players, finalPlayers) {
3799 for (var i = 0; i < players.length; i++) {
3800 var player = players[i];
3801 if (player instanceof ɵAnimationGroupPlayer) {
3802 _flattenGroupPlayersRecur(player.players, finalPlayers);
3803 }
3804 else {
3805 finalPlayers.push(player);
3806 }
3807 }
3808}
3809function objEquals(a, b) {
3810 var k1 = Object.keys(a);
3811 var k2 = Object.keys(b);
3812 if (k1.length != k2.length)
3813 return false;
3814 for (var i = 0; i < k1.length; i++) {
3815 var prop = k1[i];
3816 if (!b.hasOwnProperty(prop) || a[prop] !== b[prop])
3817 return false;
3818 }
3819 return true;
3820}
3821function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {
3822 var postEntry = allPostStyleElements.get(element);
3823 if (!postEntry)
3824 return false;
3825 var preEntry = allPreStyleElements.get(element);
3826 if (preEntry) {
3827 postEntry.forEach(function (data) { return preEntry.add(data); });
3828 }
3829 else {
3830 allPreStyleElements.set(element, postEntry);
3831 }
3832 allPostStyleElements.delete(element);
3833 return true;
3834}
3835
3836var AnimationEngine = /** @class */ (function () {
3837 function AnimationEngine(bodyNode, _driver, normalizer) {
3838 var _this = this;
3839 this.bodyNode = bodyNode;
3840 this._driver = _driver;
3841 this._triggerCache = {};
3842 // this method is designed to be overridden by the code that uses this engine
3843 this.onRemovalComplete = function (element, context) { };
3844 this._transitionEngine = new TransitionAnimationEngine(bodyNode, _driver, normalizer);
3845 this._timelineEngine = new TimelineAnimationEngine(bodyNode, _driver, normalizer);
3846 this._transitionEngine.onRemovalComplete = function (element, context) {
3847 return _this.onRemovalComplete(element, context);
3848 };
3849 }
3850 AnimationEngine.prototype.registerTrigger = function (componentId, namespaceId, hostElement, name, metadata) {
3851 var cacheKey = componentId + '-' + name;
3852 var trigger = this._triggerCache[cacheKey];
3853 if (!trigger) {
3854 var errors = [];
3855 var ast = buildAnimationAst(this._driver, metadata, errors);
3856 if (errors.length) {
3857 throw new Error("The animation trigger \"" + name + "\" has failed to build due to the following errors:\n - " + errors.join("\n - "));
3858 }
3859 trigger = buildTrigger(name, ast);
3860 this._triggerCache[cacheKey] = trigger;
3861 }
3862 this._transitionEngine.registerTrigger(namespaceId, name, trigger);
3863 };
3864 AnimationEngine.prototype.register = function (namespaceId, hostElement) {
3865 this._transitionEngine.register(namespaceId, hostElement);
3866 };
3867 AnimationEngine.prototype.destroy = function (namespaceId, context) {
3868 this._transitionEngine.destroy(namespaceId, context);
3869 };
3870 AnimationEngine.prototype.onInsert = function (namespaceId, element, parent, insertBefore) {
3871 this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
3872 };
3873 AnimationEngine.prototype.onRemove = function (namespaceId, element, context, isHostElement) {
3874 this._transitionEngine.removeNode(namespaceId, element, isHostElement || false, context);
3875 };
3876 AnimationEngine.prototype.disableAnimations = function (element, disable) {
3877 this._transitionEngine.markElementAsDisabled(element, disable);
3878 };
3879 AnimationEngine.prototype.process = function (namespaceId, element, property, value) {
3880 if (property.charAt(0) == '@') {
3881 var _a = __read(parseTimelineCommand(property), 2), id = _a[0], action = _a[1];
3882 var args = value;
3883 this._timelineEngine.command(id, element, action, args);
3884 }
3885 else {
3886 this._transitionEngine.trigger(namespaceId, element, property, value);
3887 }
3888 };
3889 AnimationEngine.prototype.listen = function (namespaceId, element, eventName, eventPhase, callback) {
3890 // @@listen
3891 if (eventName.charAt(0) == '@') {
3892 var _a = __read(parseTimelineCommand(eventName), 2), id = _a[0], action = _a[1];
3893 return this._timelineEngine.listen(id, element, action, callback);
3894 }
3895 return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
3896 };
3897 AnimationEngine.prototype.flush = function (microtaskId) {
3898 if (microtaskId === void 0) { microtaskId = -1; }
3899 this._transitionEngine.flush(microtaskId);
3900 };
3901 Object.defineProperty(AnimationEngine.prototype, "players", {
3902 get: function () {
3903 return this._transitionEngine.players
3904 .concat(this._timelineEngine.players);
3905 },
3906 enumerable: true,
3907 configurable: true
3908 });
3909 AnimationEngine.prototype.whenRenderingDone = function () { return this._transitionEngine.whenRenderingDone(); };
3910 return AnimationEngine;
3911}());
3912
3913/**
3914 * @license
3915 * Copyright Google Inc. All Rights Reserved.
3916 *
3917 * Use of this source code is governed by an MIT-style license that can be
3918 * found in the LICENSE file at https://angular.io/license
3919 */
3920/**
3921 * Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
3922 * detected.
3923 *
3924 * In CSS there exist properties that cannot be animated within a keyframe animation
3925 * (whether it be via CSS keyframes or web-animations) and the animation implementation
3926 * will ignore them. This function is designed to detect those special cased styles and
3927 * return a container that will be executed at the start and end of the animation.
3928 *
3929 * @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`
3930 */
3931function packageNonAnimatableStyles(element, styles) {
3932 var startStyles = null;
3933 var endStyles = null;
3934 if (Array.isArray(styles) && styles.length) {
3935 startStyles = filterNonAnimatableStyles(styles[0]);
3936 if (styles.length > 1) {
3937 endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
3938 }
3939 }
3940 else if (styles) {
3941 startStyles = filterNonAnimatableStyles(styles);
3942 }
3943 return (startStyles || endStyles) ? new SpecialCasedStyles(element, startStyles, endStyles) :
3944 null;
3945}
3946/**
3947 * Designed to be executed during a keyframe-based animation to apply any special-cased styles.
3948 *
3949 * When started (when the `start()` method is run) then the provided `startStyles`
3950 * will be applied. When finished (when the `finish()` method is called) the
3951 * `endStyles` will be applied as well any any starting styles. Finally when
3952 * `destroy()` is called then all styles will be removed.
3953 */
3954var SpecialCasedStyles = /** @class */ (function () {
3955 function SpecialCasedStyles(_element, _startStyles, _endStyles) {
3956 this._element = _element;
3957 this._startStyles = _startStyles;
3958 this._endStyles = _endStyles;
3959 this._state = 0 /* Pending */;
3960 var initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
3961 if (!initialStyles) {
3962 SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = {});
3963 }
3964 this._initialStyles = initialStyles;
3965 }
3966 SpecialCasedStyles.prototype.start = function () {
3967 if (this._state < 1 /* Started */) {
3968 if (this._startStyles) {
3969 setStyles(this._element, this._startStyles, this._initialStyles);
3970 }
3971 this._state = 1 /* Started */;
3972 }
3973 };
3974 SpecialCasedStyles.prototype.finish = function () {
3975 this.start();
3976 if (this._state < 2 /* Finished */) {
3977 setStyles(this._element, this._initialStyles);
3978 if (this._endStyles) {
3979 setStyles(this._element, this._endStyles);
3980 this._endStyles = null;
3981 }
3982 this._state = 1 /* Started */;
3983 }
3984 };
3985 SpecialCasedStyles.prototype.destroy = function () {
3986 this.finish();
3987 if (this._state < 3 /* Destroyed */) {
3988 SpecialCasedStyles.initialStylesByElement.delete(this._element);
3989 if (this._startStyles) {
3990 eraseStyles(this._element, this._startStyles);
3991 this._endStyles = null;
3992 }
3993 if (this._endStyles) {
3994 eraseStyles(this._element, this._endStyles);
3995 this._endStyles = null;
3996 }
3997 setStyles(this._element, this._initialStyles);
3998 this._state = 3 /* Destroyed */;
3999 }
4000 };
4001 SpecialCasedStyles.initialStylesByElement = new WeakMap();
4002 return SpecialCasedStyles;
4003}());
4004function filterNonAnimatableStyles(styles) {
4005 var result = null;
4006 var props = Object.keys(styles);
4007 for (var i = 0; i < props.length; i++) {
4008 var prop = props[i];
4009 if (isNonAnimatableStyle(prop)) {
4010 result = result || {};
4011 result[prop] = styles[prop];
4012 }
4013 }
4014 return result;
4015}
4016function isNonAnimatableStyle(prop) {
4017 return prop === 'display' || prop === 'position';
4018}
4019
4020/**
4021 * @license
4022 * Copyright Google Inc. All Rights Reserved.
4023 *
4024 * Use of this source code is governed by an MIT-style license that can be
4025 * found in the LICENSE file at https://angular.io/license
4026 */
4027var ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
4028var ANIMATION_PROP = 'animation';
4029var ANIMATIONEND_EVENT = 'animationend';
4030var ONE_SECOND$1 = 1000;
4031var ElementAnimationStyleHandler = /** @class */ (function () {
4032 function ElementAnimationStyleHandler(_element, _name, _duration, _delay, _easing, _fillMode, _onDoneFn) {
4033 var _this = this;
4034 this._element = _element;
4035 this._name = _name;
4036 this._duration = _duration;
4037 this._delay = _delay;
4038 this._easing = _easing;
4039 this._fillMode = _fillMode;
4040 this._onDoneFn = _onDoneFn;
4041 this._finished = false;
4042 this._destroyed = false;
4043 this._startTime = 0;
4044 this._position = 0;
4045 this._eventFn = function (e) { return _this._handleCallback(e); };
4046 }
4047 ElementAnimationStyleHandler.prototype.apply = function () {
4048 applyKeyframeAnimation(this._element, this._duration + "ms " + this._easing + " " + this._delay + "ms 1 normal " + this._fillMode + " " + this._name);
4049 addRemoveAnimationEvent(this._element, this._eventFn, false);
4050 this._startTime = Date.now();
4051 };
4052 ElementAnimationStyleHandler.prototype.pause = function () { playPauseAnimation(this._element, this._name, 'paused'); };
4053 ElementAnimationStyleHandler.prototype.resume = function () { playPauseAnimation(this._element, this._name, 'running'); };
4054 ElementAnimationStyleHandler.prototype.setPosition = function (position) {
4055 var index = findIndexForAnimation(this._element, this._name);
4056 this._position = position * this._duration;
4057 setAnimationStyle(this._element, 'Delay', "-" + this._position + "ms", index);
4058 };
4059 ElementAnimationStyleHandler.prototype.getPosition = function () { return this._position; };
4060 ElementAnimationStyleHandler.prototype._handleCallback = function (event) {
4061 var timestamp = event._ngTestManualTimestamp || Date.now();
4062 var elapsedTime = parseFloat(event.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)) * ONE_SECOND$1;
4063 if (event.animationName == this._name &&
4064 Math.max(timestamp - this._startTime, 0) >= this._delay && elapsedTime >= this._duration) {
4065 this.finish();
4066 }
4067 };
4068 ElementAnimationStyleHandler.prototype.finish = function () {
4069 if (this._finished)
4070 return;
4071 this._finished = true;
4072 this._onDoneFn();
4073 addRemoveAnimationEvent(this._element, this._eventFn, true);
4074 };
4075 ElementAnimationStyleHandler.prototype.destroy = function () {
4076 if (this._destroyed)
4077 return;
4078 this._destroyed = true;
4079 this.finish();
4080 removeKeyframeAnimation(this._element, this._name);
4081 };
4082 return ElementAnimationStyleHandler;
4083}());
4084function playPauseAnimation(element, name, status) {
4085 var index = findIndexForAnimation(element, name);
4086 setAnimationStyle(element, 'PlayState', status, index);
4087}
4088function applyKeyframeAnimation(element, value) {
4089 var anim = getAnimationStyle(element, '').trim();
4090 var index = 0;
4091 if (anim.length) {
4092 index = countChars(anim, ',') + 1;
4093 value = anim + ", " + value;
4094 }
4095 setAnimationStyle(element, '', value);
4096 return index;
4097}
4098function removeKeyframeAnimation(element, name) {
4099 var anim = getAnimationStyle(element, '');
4100 var tokens = anim.split(',');
4101 var index = findMatchingTokenIndex(tokens, name);
4102 if (index >= 0) {
4103 tokens.splice(index, 1);
4104 var newValue = tokens.join(',');
4105 setAnimationStyle(element, '', newValue);
4106 }
4107}
4108function findIndexForAnimation(element, value) {
4109 var anim = getAnimationStyle(element, '');
4110 if (anim.indexOf(',') > 0) {
4111 var tokens = anim.split(',');
4112 return findMatchingTokenIndex(tokens, value);
4113 }
4114 return findMatchingTokenIndex([anim], value);
4115}
4116function findMatchingTokenIndex(tokens, searchToken) {
4117 for (var i = 0; i < tokens.length; i++) {
4118 if (tokens[i].indexOf(searchToken) >= 0) {
4119 return i;
4120 }
4121 }
4122 return -1;
4123}
4124function addRemoveAnimationEvent(element, fn, doRemove) {
4125 doRemove ? element.removeEventListener(ANIMATIONEND_EVENT, fn) :
4126 element.addEventListener(ANIMATIONEND_EVENT, fn);
4127}
4128function setAnimationStyle(element, name, value, index) {
4129 var prop = ANIMATION_PROP + name;
4130 if (index != null) {
4131 var oldValue = element.style[prop];
4132 if (oldValue.length) {
4133 var tokens = oldValue.split(',');
4134 tokens[index] = value;
4135 value = tokens.join(',');
4136 }
4137 }
4138 element.style[prop] = value;
4139}
4140function getAnimationStyle(element, name) {
4141 return element.style[ANIMATION_PROP + name];
4142}
4143function countChars(value, char) {
4144 var count = 0;
4145 for (var i = 0; i < value.length; i++) {
4146 var c = value.charAt(i);
4147 if (c === char)
4148 count++;
4149 }
4150 return count;
4151}
4152
4153var DEFAULT_FILL_MODE = 'forwards';
4154var DEFAULT_EASING = 'linear';
4155var CssKeyframesPlayer = /** @class */ (function () {
4156 function CssKeyframesPlayer(element, keyframes, animationName, _duration, _delay, easing, _finalStyles, _specialStyles) {
4157 this.element = element;
4158 this.keyframes = keyframes;
4159 this.animationName = animationName;
4160 this._duration = _duration;
4161 this._delay = _delay;
4162 this._finalStyles = _finalStyles;
4163 this._specialStyles = _specialStyles;
4164 this._onDoneFns = [];
4165 this._onStartFns = [];
4166 this._onDestroyFns = [];
4167 this._started = false;
4168 this.currentSnapshot = {};
4169 this._state = 0;
4170 this.easing = easing || DEFAULT_EASING;
4171 this.totalTime = _duration + _delay;
4172 this._buildStyler();
4173 }
4174 CssKeyframesPlayer.prototype.onStart = function (fn) { this._onStartFns.push(fn); };
4175 CssKeyframesPlayer.prototype.onDone = function (fn) { this._onDoneFns.push(fn); };
4176 CssKeyframesPlayer.prototype.onDestroy = function (fn) { this._onDestroyFns.push(fn); };
4177 CssKeyframesPlayer.prototype.destroy = function () {
4178 this.init();
4179 if (this._state >= 4 /* DESTROYED */)
4180 return;
4181 this._state = 4 /* DESTROYED */;
4182 this._styler.destroy();
4183 this._flushStartFns();
4184 this._flushDoneFns();
4185 if (this._specialStyles) {
4186 this._specialStyles.destroy();
4187 }
4188 this._onDestroyFns.forEach(function (fn) { return fn(); });
4189 this._onDestroyFns = [];
4190 };
4191 CssKeyframesPlayer.prototype._flushDoneFns = function () {
4192 this._onDoneFns.forEach(function (fn) { return fn(); });
4193 this._onDoneFns = [];
4194 };
4195 CssKeyframesPlayer.prototype._flushStartFns = function () {
4196 this._onStartFns.forEach(function (fn) { return fn(); });
4197 this._onStartFns = [];
4198 };
4199 CssKeyframesPlayer.prototype.finish = function () {
4200 this.init();
4201 if (this._state >= 3 /* FINISHED */)
4202 return;
4203 this._state = 3 /* FINISHED */;
4204 this._styler.finish();
4205 this._flushStartFns();
4206 if (this._specialStyles) {
4207 this._specialStyles.finish();
4208 }
4209 this._flushDoneFns();
4210 };
4211 CssKeyframesPlayer.prototype.setPosition = function (value) { this._styler.setPosition(value); };
4212 CssKeyframesPlayer.prototype.getPosition = function () { return this._styler.getPosition(); };
4213 CssKeyframesPlayer.prototype.hasStarted = function () { return this._state >= 2 /* STARTED */; };
4214 CssKeyframesPlayer.prototype.init = function () {
4215 if (this._state >= 1 /* INITIALIZED */)
4216 return;
4217 this._state = 1 /* INITIALIZED */;
4218 var elm = this.element;
4219 this._styler.apply();
4220 if (this._delay) {
4221 this._styler.pause();
4222 }
4223 };
4224 CssKeyframesPlayer.prototype.play = function () {
4225 this.init();
4226 if (!this.hasStarted()) {
4227 this._flushStartFns();
4228 this._state = 2 /* STARTED */;
4229 if (this._specialStyles) {
4230 this._specialStyles.start();
4231 }
4232 }
4233 this._styler.resume();
4234 };
4235 CssKeyframesPlayer.prototype.pause = function () {
4236 this.init();
4237 this._styler.pause();
4238 };
4239 CssKeyframesPlayer.prototype.restart = function () {
4240 this.reset();
4241 this.play();
4242 };
4243 CssKeyframesPlayer.prototype.reset = function () {
4244 this._styler.destroy();
4245 this._buildStyler();
4246 this._styler.apply();
4247 };
4248 CssKeyframesPlayer.prototype._buildStyler = function () {
4249 var _this = this;
4250 this._styler = new ElementAnimationStyleHandler(this.element, this.animationName, this._duration, this._delay, this.easing, DEFAULT_FILL_MODE, function () { return _this.finish(); });
4251 };
4252 /** @internal */
4253 CssKeyframesPlayer.prototype.triggerCallback = function (phaseName) {
4254 var methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
4255 methods.forEach(function (fn) { return fn(); });
4256 methods.length = 0;
4257 };
4258 CssKeyframesPlayer.prototype.beforeDestroy = function () {
4259 var _this = this;
4260 this.init();
4261 var styles = {};
4262 if (this.hasStarted()) {
4263 var finished_1 = this._state >= 3 /* FINISHED */;
4264 Object.keys(this._finalStyles).forEach(function (prop) {
4265 if (prop != 'offset') {
4266 styles[prop] = finished_1 ? _this._finalStyles[prop] : computeStyle(_this.element, prop);
4267 }
4268 });
4269 }
4270 this.currentSnapshot = styles;
4271 };
4272 return CssKeyframesPlayer;
4273}());
4274
4275var DirectStylePlayer = /** @class */ (function (_super) {
4276 __extends(DirectStylePlayer, _super);
4277 function DirectStylePlayer(element, styles) {
4278 var _this = _super.call(this) || this;
4279 _this.element = element;
4280 _this._startingStyles = {};
4281 _this.__initialized = false;
4282 _this._styles = hypenatePropsObject(styles);
4283 return _this;
4284 }
4285 DirectStylePlayer.prototype.init = function () {
4286 var _this = this;
4287 if (this.__initialized || !this._startingStyles)
4288 return;
4289 this.__initialized = true;
4290 Object.keys(this._styles).forEach(function (prop) {
4291 _this._startingStyles[prop] = _this.element.style[prop];
4292 });
4293 _super.prototype.init.call(this);
4294 };
4295 DirectStylePlayer.prototype.play = function () {
4296 var _this = this;
4297 if (!this._startingStyles)
4298 return;
4299 this.init();
4300 Object.keys(this._styles)
4301 .forEach(function (prop) { return _this.element.style.setProperty(prop, _this._styles[prop]); });
4302 _super.prototype.play.call(this);
4303 };
4304 DirectStylePlayer.prototype.destroy = function () {
4305 var _this = this;
4306 if (!this._startingStyles)
4307 return;
4308 Object.keys(this._startingStyles).forEach(function (prop) {
4309 var value = _this._startingStyles[prop];
4310 if (value) {
4311 _this.element.style.setProperty(prop, value);
4312 }
4313 else {
4314 _this.element.style.removeProperty(prop);
4315 }
4316 });
4317 this._startingStyles = null;
4318 _super.prototype.destroy.call(this);
4319 };
4320 return DirectStylePlayer;
4321}(NoopAnimationPlayer));
4322
4323var KEYFRAMES_NAME_PREFIX = 'gen_css_kf_';
4324var TAB_SPACE = ' ';
4325var CssKeyframesDriver = /** @class */ (function () {
4326 function CssKeyframesDriver() {
4327 this._count = 0;
4328 this._head = document.querySelector('head');
4329 this._warningIssued = false;
4330 }
4331 CssKeyframesDriver.prototype.validateStyleProperty = function (prop) { return validateStyleProperty(prop); };
4332 CssKeyframesDriver.prototype.matchesElement = function (element, selector) {
4333 return matchesElement(element, selector);
4334 };
4335 CssKeyframesDriver.prototype.containsElement = function (elm1, elm2) { return containsElement(elm1, elm2); };
4336 CssKeyframesDriver.prototype.query = function (element, selector, multi) {
4337 return invokeQuery(element, selector, multi);
4338 };
4339 CssKeyframesDriver.prototype.computeStyle = function (element, prop, defaultValue) {
4340 return window.getComputedStyle(element)[prop];
4341 };
4342 CssKeyframesDriver.prototype.buildKeyframeElement = function (element, name, keyframes) {
4343 keyframes = keyframes.map(function (kf) { return hypenatePropsObject(kf); });
4344 var keyframeStr = "@keyframes " + name + " {\n";
4345 var tab = '';
4346 keyframes.forEach(function (kf) {
4347 tab = TAB_SPACE;
4348 var offset = parseFloat(kf['offset']);
4349 keyframeStr += "" + tab + offset * 100 + "% {\n";
4350 tab += TAB_SPACE;
4351 Object.keys(kf).forEach(function (prop) {
4352 var value = kf[prop];
4353 switch (prop) {
4354 case 'offset':
4355 return;
4356 case 'easing':
4357 if (value) {
4358 keyframeStr += tab + "animation-timing-function: " + value + ";\n";
4359 }
4360 return;
4361 default:
4362 keyframeStr += "" + tab + prop + ": " + value + ";\n";
4363 return;
4364 }
4365 });
4366 keyframeStr += tab + "}\n";
4367 });
4368 keyframeStr += "}\n";
4369 var kfElm = document.createElement('style');
4370 kfElm.innerHTML = keyframeStr;
4371 return kfElm;
4372 };
4373 CssKeyframesDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
4374 if (previousPlayers === void 0) { previousPlayers = []; }
4375 if (scrubberAccessRequested) {
4376 this._notifyFaultyScrubber();
4377 }
4378 var previousCssKeyframePlayers = previousPlayers.filter(function (player) { return player instanceof CssKeyframesPlayer; });
4379 var previousStyles = {};
4380 if (allowPreviousPlayerStylesMerge(duration, delay)) {
4381 previousCssKeyframePlayers.forEach(function (player) {
4382 var styles = player.currentSnapshot;
4383 Object.keys(styles).forEach(function (prop) { return previousStyles[prop] = styles[prop]; });
4384 });
4385 }
4386 keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
4387 var finalStyles = flattenKeyframesIntoStyles(keyframes);
4388 // if there is no animation then there is no point in applying
4389 // styles and waiting for an event to get fired. This causes lag.
4390 // It's better to just directly apply the styles to the element
4391 // via the direct styling animation player.
4392 if (duration == 0) {
4393 return new DirectStylePlayer(element, finalStyles);
4394 }
4395 var animationName = "" + KEYFRAMES_NAME_PREFIX + this._count++;
4396 var kfElm = this.buildKeyframeElement(element, animationName, keyframes);
4397 document.querySelector('head').appendChild(kfElm);
4398 var specialStyles = packageNonAnimatableStyles(element, keyframes);
4399 var player = new CssKeyframesPlayer(element, keyframes, animationName, duration, delay, easing, finalStyles, specialStyles);
4400 player.onDestroy(function () { return removeElement(kfElm); });
4401 return player;
4402 };
4403 CssKeyframesDriver.prototype._notifyFaultyScrubber = function () {
4404 if (!this._warningIssued) {
4405 console.warn('@angular/animations: please load the web-animations.js polyfill to allow programmatic access...\n', ' visit http://bit.ly/IWukam to learn more about using the web-animation-js polyfill.');
4406 this._warningIssued = true;
4407 }
4408 };
4409 return CssKeyframesDriver;
4410}());
4411function flattenKeyframesIntoStyles(keyframes) {
4412 var flatKeyframes = {};
4413 if (keyframes) {
4414 var kfs = Array.isArray(keyframes) ? keyframes : [keyframes];
4415 kfs.forEach(function (kf) {
4416 Object.keys(kf).forEach(function (prop) {
4417 if (prop == 'offset' || prop == 'easing')
4418 return;
4419 flatKeyframes[prop] = kf[prop];
4420 });
4421 });
4422 }
4423 return flatKeyframes;
4424}
4425function removeElement(node) {
4426 node.parentNode.removeChild(node);
4427}
4428
4429var WebAnimationsPlayer = /** @class */ (function () {
4430 function WebAnimationsPlayer(element, keyframes, options, _specialStyles) {
4431 this.element = element;
4432 this.keyframes = keyframes;
4433 this.options = options;
4434 this._specialStyles = _specialStyles;
4435 this._onDoneFns = [];
4436 this._onStartFns = [];
4437 this._onDestroyFns = [];
4438 this._initialized = false;
4439 this._finished = false;
4440 this._started = false;
4441 this._destroyed = false;
4442 this.time = 0;
4443 this.parentPlayer = null;
4444 this.currentSnapshot = {};
4445 this._duration = options['duration'];
4446 this._delay = options['delay'] || 0;
4447 this.time = this._duration + this._delay;
4448 }
4449 WebAnimationsPlayer.prototype._onFinish = function () {
4450 if (!this._finished) {
4451 this._finished = true;
4452 this._onDoneFns.forEach(function (fn) { return fn(); });
4453 this._onDoneFns = [];
4454 }
4455 };
4456 WebAnimationsPlayer.prototype.init = function () {
4457 this._buildPlayer();
4458 this._preparePlayerBeforeStart();
4459 };
4460 WebAnimationsPlayer.prototype._buildPlayer = function () {
4461 var _this = this;
4462 if (this._initialized)
4463 return;
4464 this._initialized = true;
4465 var keyframes = this.keyframes;
4466 this.domPlayer =
4467 this._triggerWebAnimation(this.element, keyframes, this.options);
4468 this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : {};
4469 this.domPlayer.addEventListener('finish', function () { return _this._onFinish(); });
4470 };
4471 WebAnimationsPlayer.prototype._preparePlayerBeforeStart = function () {
4472 // this is required so that the player doesn't start to animate right away
4473 if (this._delay) {
4474 this._resetDomPlayerState();
4475 }
4476 else {
4477 this.domPlayer.pause();
4478 }
4479 };
4480 /** @internal */
4481 WebAnimationsPlayer.prototype._triggerWebAnimation = function (element, keyframes, options) {
4482 // jscompiler doesn't seem to know animate is a native property because it's not fully
4483 // supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
4484 return element['animate'](keyframes, options);
4485 };
4486 WebAnimationsPlayer.prototype.onStart = function (fn) { this._onStartFns.push(fn); };
4487 WebAnimationsPlayer.prototype.onDone = function (fn) { this._onDoneFns.push(fn); };
4488 WebAnimationsPlayer.prototype.onDestroy = function (fn) { this._onDestroyFns.push(fn); };
4489 WebAnimationsPlayer.prototype.play = function () {
4490 this._buildPlayer();
4491 if (!this.hasStarted()) {
4492 this._onStartFns.forEach(function (fn) { return fn(); });
4493 this._onStartFns = [];
4494 this._started = true;
4495 if (this._specialStyles) {
4496 this._specialStyles.start();
4497 }
4498 }
4499 this.domPlayer.play();
4500 };
4501 WebAnimationsPlayer.prototype.pause = function () {
4502 this.init();
4503 this.domPlayer.pause();
4504 };
4505 WebAnimationsPlayer.prototype.finish = function () {
4506 this.init();
4507 if (this._specialStyles) {
4508 this._specialStyles.finish();
4509 }
4510 this._onFinish();
4511 this.domPlayer.finish();
4512 };
4513 WebAnimationsPlayer.prototype.reset = function () {
4514 this._resetDomPlayerState();
4515 this._destroyed = false;
4516 this._finished = false;
4517 this._started = false;
4518 };
4519 WebAnimationsPlayer.prototype._resetDomPlayerState = function () {
4520 if (this.domPlayer) {
4521 this.domPlayer.cancel();
4522 }
4523 };
4524 WebAnimationsPlayer.prototype.restart = function () {
4525 this.reset();
4526 this.play();
4527 };
4528 WebAnimationsPlayer.prototype.hasStarted = function () { return this._started; };
4529 WebAnimationsPlayer.prototype.destroy = function () {
4530 if (!this._destroyed) {
4531 this._destroyed = true;
4532 this._resetDomPlayerState();
4533 this._onFinish();
4534 if (this._specialStyles) {
4535 this._specialStyles.destroy();
4536 }
4537 this._onDestroyFns.forEach(function (fn) { return fn(); });
4538 this._onDestroyFns = [];
4539 }
4540 };
4541 WebAnimationsPlayer.prototype.setPosition = function (p) { this.domPlayer.currentTime = p * this.time; };
4542 WebAnimationsPlayer.prototype.getPosition = function () { return this.domPlayer.currentTime / this.time; };
4543 Object.defineProperty(WebAnimationsPlayer.prototype, "totalTime", {
4544 get: function () { return this._delay + this._duration; },
4545 enumerable: true,
4546 configurable: true
4547 });
4548 WebAnimationsPlayer.prototype.beforeDestroy = function () {
4549 var _this = this;
4550 var styles = {};
4551 if (this.hasStarted()) {
4552 Object.keys(this._finalKeyframe).forEach(function (prop) {
4553 if (prop != 'offset') {
4554 styles[prop] =
4555 _this._finished ? _this._finalKeyframe[prop] : computeStyle(_this.element, prop);
4556 }
4557 });
4558 }
4559 this.currentSnapshot = styles;
4560 };
4561 /** @internal */
4562 WebAnimationsPlayer.prototype.triggerCallback = function (phaseName) {
4563 var methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
4564 methods.forEach(function (fn) { return fn(); });
4565 methods.length = 0;
4566 };
4567 return WebAnimationsPlayer;
4568}());
4569
4570var WebAnimationsDriver = /** @class */ (function () {
4571 function WebAnimationsDriver() {
4572 this._isNativeImpl = /\{\s*\[native\s+code\]\s*\}/.test(getElementAnimateFn().toString());
4573 this._cssKeyframesDriver = new CssKeyframesDriver();
4574 }
4575 WebAnimationsDriver.prototype.validateStyleProperty = function (prop) { return validateStyleProperty(prop); };
4576 WebAnimationsDriver.prototype.matchesElement = function (element, selector) {
4577 return matchesElement(element, selector);
4578 };
4579 WebAnimationsDriver.prototype.containsElement = function (elm1, elm2) { return containsElement(elm1, elm2); };
4580 WebAnimationsDriver.prototype.query = function (element, selector, multi) {
4581 return invokeQuery(element, selector, multi);
4582 };
4583 WebAnimationsDriver.prototype.computeStyle = function (element, prop, defaultValue) {
4584 return window.getComputedStyle(element)[prop];
4585 };
4586 WebAnimationsDriver.prototype.overrideWebAnimationsSupport = function (supported) { this._isNativeImpl = supported; };
4587 WebAnimationsDriver.prototype.animate = function (element, keyframes, duration, delay, easing, previousPlayers, scrubberAccessRequested) {
4588 if (previousPlayers === void 0) { previousPlayers = []; }
4589 var useKeyframes = !scrubberAccessRequested && !this._isNativeImpl;
4590 if (useKeyframes) {
4591 return this._cssKeyframesDriver.animate(element, keyframes, duration, delay, easing, previousPlayers);
4592 }
4593 var fill = delay == 0 ? 'both' : 'forwards';
4594 var playerOptions = { duration: duration, delay: delay, fill: fill };
4595 // we check for this to avoid having a null|undefined value be present
4596 // for the easing (which results in an error for certain browsers #9752)
4597 if (easing) {
4598 playerOptions['easing'] = easing;
4599 }
4600 var previousStyles = {};
4601 var previousWebAnimationPlayers = previousPlayers.filter(function (player) { return player instanceof WebAnimationsPlayer; });
4602 if (allowPreviousPlayerStylesMerge(duration, delay)) {
4603 previousWebAnimationPlayers.forEach(function (player) {
4604 var styles = player.currentSnapshot;
4605 Object.keys(styles).forEach(function (prop) { return previousStyles[prop] = styles[prop]; });
4606 });
4607 }
4608 keyframes = keyframes.map(function (styles) { return copyStyles(styles, false); });
4609 keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
4610 var specialStyles = packageNonAnimatableStyles(element, keyframes);
4611 return new WebAnimationsPlayer(element, keyframes, playerOptions, specialStyles);
4612 };
4613 return WebAnimationsDriver;
4614}());
4615function supportsWebAnimations() {
4616 return typeof getElementAnimateFn() === 'function';
4617}
4618function getElementAnimateFn() {
4619 return (isBrowser() && Element.prototype['animate']) || {};
4620}
4621
4622/**
4623 * @license
4624 * Copyright Google Inc. All Rights Reserved.
4625 *
4626 * Use of this source code is governed by an MIT-style license that can be
4627 * found in the LICENSE file at https://angular.io/license
4628 */
4629
4630/**
4631 * @license
4632 * Copyright Google Inc. All Rights Reserved.
4633 *
4634 * Use of this source code is governed by an MIT-style license that can be
4635 * found in the LICENSE file at https://angular.io/license
4636 */
4637
4638/**
4639 * @license
4640 * Copyright Google Inc. All Rights Reserved.
4641 *
4642 * Use of this source code is governed by an MIT-style license that can be
4643 * found in the LICENSE file at https://angular.io/license
4644 */
4645
4646/**
4647 * @license
4648 * Copyright Google Inc. All Rights Reserved.
4649 *
4650 * Use of this source code is governed by an MIT-style license that can be
4651 * found in the LICENSE file at https://angular.io/license
4652 */
4653
4654/**
4655 * Generated bundle index. Do not edit.
4656 */
4657
4658export { AnimationDriver, Animation as ɵAnimation, AnimationDriver as ɵAnimationDriver, AnimationEngine as ɵAnimationEngine, AnimationStyleNormalizer as ɵAnimationStyleNormalizer, CssKeyframesDriver as ɵCssKeyframesDriver, CssKeyframesPlayer as ɵCssKeyframesPlayer, NoopAnimationDriver as ɵNoopAnimationDriver, NoopAnimationStyleNormalizer as ɵNoopAnimationStyleNormalizer, WebAnimationsDriver as ɵWebAnimationsDriver, WebAnimationsPlayer as ɵWebAnimationsPlayer, WebAnimationsStyleNormalizer as ɵWebAnimationsStyleNormalizer, allowPreviousPlayerStylesMerge as ɵallowPreviousPlayerStylesMerge, SpecialCasedStyles as ɵangular_packages_animations_browser_browser_a, containsElement as ɵcontainsElement, invokeQuery as ɵinvokeQuery, matchesElement as ɵmatchesElement, supportsWebAnimations as ɵsupportsWebAnimations, validateStyleProperty as ɵvalidateStyleProperty };
4659//# sourceMappingURL=browser.js.map