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