source: trip-planner-front/node_modules/@angular/animations/bundles/animations-browser.umd.js@ 84d0fbb

Last change on this file since 84d0fbb was e29cc2e, checked in by Ema <ema_spirova@…>, 3 years ago

primeNG components

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