@angular/animations 13.2.0 → 14.0.0-next.2
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 +14 -89
- package/browser/testing/testing.d.ts +8 -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 -5
- package/esm2020/browser/src/render/animation_driver.mjs +4 -4
- package/esm2020/browser/src/render/shared.mjs +18 -27
- 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 +55 -73
- package/esm2020/browser/src/render/web_animations/web_animations_driver.mjs +10 -29
- 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 +14 -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 +14 -14
- package/fesm2015/browser/testing.mjs.map +1 -1
- package/fesm2015/browser.mjs +336 -791
- 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 +14 -14
- package/fesm2020/browser/testing.mjs.map +1 -1
- package/fesm2020/browser.mjs +334 -790
- package/fesm2020/browser.mjs.map +1 -1
- package/package.json +2 -2
- package/esm2020/browser/src/render/css_keyframes/css_keyframes_driver.mjs +0 -121
- package/esm2020/browser/src/render/css_keyframes/css_keyframes_player.mjs +0 -133
- package/esm2020/browser/src/render/css_keyframes/direct_style_player.mjs +0 -51
- package/esm2020/browser/src/render/css_keyframes/element_animation_style_handler.mjs +0 -137
package/fesm2020/browser.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular
|
|
2
|
+
* @license Angular v14.0.0-next.2
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -36,26 +36,26 @@ function optimizeGroupPlayer(players) {
|
|
|
36
36
|
return new ɵAnimationGroupPlayer(players);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
|
|
39
|
+
function normalizeKeyframes$1(driver, normalizer, element, keyframes, preStyles = new Map(), postStyles = new Map()) {
|
|
40
40
|
const errors = [];
|
|
41
41
|
const normalizedKeyframes = [];
|
|
42
42
|
let previousOffset = -1;
|
|
43
43
|
let previousKeyframe = null;
|
|
44
44
|
keyframes.forEach(kf => {
|
|
45
|
-
const offset = kf
|
|
45
|
+
const offset = kf.get('offset');
|
|
46
46
|
const isSameOffset = offset == previousOffset;
|
|
47
|
-
const normalizedKeyframe = (isSameOffset && previousKeyframe) ||
|
|
48
|
-
|
|
47
|
+
const normalizedKeyframe = (isSameOffset && previousKeyframe) || new Map();
|
|
48
|
+
kf.forEach((val, prop) => {
|
|
49
49
|
let normalizedProp = prop;
|
|
50
|
-
let normalizedValue =
|
|
50
|
+
let normalizedValue = val;
|
|
51
51
|
if (prop !== 'offset') {
|
|
52
52
|
normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
|
|
53
53
|
switch (normalizedValue) {
|
|
54
54
|
case ɵPRE_STYLE:
|
|
55
|
-
normalizedValue = preStyles
|
|
55
|
+
normalizedValue = preStyles.get(prop);
|
|
56
56
|
break;
|
|
57
57
|
case AUTO_STYLE:
|
|
58
|
-
normalizedValue = postStyles
|
|
58
|
+
normalizedValue = postStyles.get(prop);
|
|
59
59
|
break;
|
|
60
60
|
default:
|
|
61
61
|
normalizedValue =
|
|
@@ -63,7 +63,7 @@ function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
|
|
|
63
63
|
break;
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
normalizedKeyframe
|
|
66
|
+
normalizedKeyframe.set(normalizedProp, normalizedValue);
|
|
67
67
|
});
|
|
68
68
|
if (!isSameOffset) {
|
|
69
69
|
normalizedKeyframes.push(normalizedKeyframe);
|
|
@@ -103,19 +103,10 @@ function copyAnimationEvent(e, phaseName, player) {
|
|
|
103
103
|
function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {
|
|
104
104
|
return { element, triggerName, fromState, toState, phaseName, totalTime, disabled: !!disabled };
|
|
105
105
|
}
|
|
106
|
-
function
|
|
107
|
-
let value;
|
|
108
|
-
if (
|
|
109
|
-
value =
|
|
110
|
-
if (!value) {
|
|
111
|
-
map.set(key, value = defaultValue);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
value = map[key];
|
|
116
|
-
if (!value) {
|
|
117
|
-
value = map[key] = defaultValue;
|
|
118
|
-
}
|
|
106
|
+
function getOrSetDefaultValue(map, key, defaultValue) {
|
|
107
|
+
let value = map.get(key);
|
|
108
|
+
if (!value) {
|
|
109
|
+
map.set(key, value = defaultValue);
|
|
119
110
|
}
|
|
120
111
|
return value;
|
|
121
112
|
}
|
|
@@ -185,13 +176,13 @@ function getBodyNode() {
|
|
|
185
176
|
}
|
|
186
177
|
const containsElement = _contains;
|
|
187
178
|
const invokeQuery = _query;
|
|
188
|
-
function
|
|
189
|
-
const
|
|
190
|
-
|
|
179
|
+
function hypenatePropsKeys(original) {
|
|
180
|
+
const newMap = new Map();
|
|
181
|
+
original.forEach((val, prop) => {
|
|
191
182
|
const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
|
|
192
|
-
|
|
183
|
+
newMap.set(newProp, val);
|
|
193
184
|
});
|
|
194
|
-
return
|
|
185
|
+
return newMap;
|
|
195
186
|
}
|
|
196
187
|
|
|
197
188
|
/**
|
|
@@ -225,9 +216,9 @@ class NoopAnimationDriver {
|
|
|
225
216
|
return new NoopAnimationPlayer(duration, delay);
|
|
226
217
|
}
|
|
227
218
|
}
|
|
228
|
-
NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
229
|
-
NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
230
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
219
|
+
NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.2", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
220
|
+
NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.2", ngImport: i0, type: NoopAnimationDriver });
|
|
221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.2", ngImport: i0, type: NoopAnimationDriver, decorators: [{
|
|
231
222
|
type: Injectable
|
|
232
223
|
}] });
|
|
233
224
|
/**
|
|
@@ -244,7 +235,7 @@ AnimationDriver.NOOP = ( /* @__PURE__ */new NoopAnimationDriver());
|
|
|
244
235
|
* Use of this source code is governed by an MIT-style license that can be
|
|
245
236
|
* found in the LICENSE file at https://angular.io/license
|
|
246
237
|
*/
|
|
247
|
-
const ONE_SECOND
|
|
238
|
+
const ONE_SECOND = 1000;
|
|
248
239
|
const SUBSTITUTION_EXPR_START = '{{';
|
|
249
240
|
const SUBSTITUTION_EXPR_END = '}}';
|
|
250
241
|
const ENTER_CLASSNAME = 'ng-enter';
|
|
@@ -264,7 +255,7 @@ function resolveTimingValue(value) {
|
|
|
264
255
|
function _convertTimeValueToMS(value, unit) {
|
|
265
256
|
switch (unit) {
|
|
266
257
|
case 's':
|
|
267
|
-
return value * ONE_SECOND
|
|
258
|
+
return value * ONE_SECOND;
|
|
268
259
|
default: // ms or something else
|
|
269
260
|
return value;
|
|
270
261
|
}
|
|
@@ -321,27 +312,41 @@ function copyObj(obj, destination = {}) {
|
|
|
321
312
|
});
|
|
322
313
|
return destination;
|
|
323
314
|
}
|
|
315
|
+
function convertToMap(obj) {
|
|
316
|
+
const styleMap = new Map();
|
|
317
|
+
Object.keys(obj).forEach(prop => {
|
|
318
|
+
const val = obj[prop];
|
|
319
|
+
styleMap.set(prop, val);
|
|
320
|
+
});
|
|
321
|
+
return styleMap;
|
|
322
|
+
}
|
|
323
|
+
function normalizeKeyframes(keyframes) {
|
|
324
|
+
if (!keyframes.length) {
|
|
325
|
+
return [];
|
|
326
|
+
}
|
|
327
|
+
if (keyframes[0] instanceof Map) {
|
|
328
|
+
return keyframes;
|
|
329
|
+
}
|
|
330
|
+
return keyframes.map(kf => convertToMap(kf));
|
|
331
|
+
}
|
|
324
332
|
function normalizeStyles(styles) {
|
|
325
|
-
const normalizedStyles =
|
|
333
|
+
const normalizedStyles = new Map();
|
|
326
334
|
if (Array.isArray(styles)) {
|
|
327
|
-
styles.forEach(data => copyStyles(data,
|
|
335
|
+
styles.forEach(data => copyStyles(data, normalizedStyles));
|
|
328
336
|
}
|
|
329
337
|
else {
|
|
330
|
-
copyStyles(styles,
|
|
338
|
+
copyStyles(styles, normalizedStyles);
|
|
331
339
|
}
|
|
332
340
|
return normalizedStyles;
|
|
333
341
|
}
|
|
334
|
-
function copyStyles(styles,
|
|
335
|
-
if (
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
// revealed from the backFill map
|
|
339
|
-
for (let prop in styles) {
|
|
340
|
-
destination[prop] = styles[prop];
|
|
342
|
+
function copyStyles(styles, destination = new Map(), backfill) {
|
|
343
|
+
if (backfill) {
|
|
344
|
+
for (let [prop, val] of backfill) {
|
|
345
|
+
destination.set(prop, val);
|
|
341
346
|
}
|
|
342
347
|
}
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
for (let [prop, val] of styles) {
|
|
349
|
+
destination.set(prop, val);
|
|
345
350
|
}
|
|
346
351
|
return destination;
|
|
347
352
|
}
|
|
@@ -377,12 +382,12 @@ function writeStyleAttribute(element) {
|
|
|
377
382
|
}
|
|
378
383
|
function setStyles(element, styles, formerStyles) {
|
|
379
384
|
if (element['style']) {
|
|
380
|
-
|
|
385
|
+
styles.forEach((val, prop) => {
|
|
381
386
|
const camelProp = dashCaseToCamelCase(prop);
|
|
382
|
-
if (formerStyles && !formerStyles.
|
|
383
|
-
formerStyles
|
|
387
|
+
if (formerStyles && !formerStyles.has(prop)) {
|
|
388
|
+
formerStyles.set(prop, element.style[camelProp]);
|
|
384
389
|
}
|
|
385
|
-
element.style[camelProp] =
|
|
390
|
+
element.style[camelProp] = val;
|
|
386
391
|
});
|
|
387
392
|
// On the server set the 'style' attribute since it's not automatically reflected.
|
|
388
393
|
if (isNode()) {
|
|
@@ -392,7 +397,7 @@ function setStyles(element, styles, formerStyles) {
|
|
|
392
397
|
}
|
|
393
398
|
function eraseStyles(element, styles) {
|
|
394
399
|
if (element['style']) {
|
|
395
|
-
|
|
400
|
+
styles.forEach((_, prop) => {
|
|
396
401
|
const camelProp = dashCaseToCamelCase(prop);
|
|
397
402
|
element.style[camelProp] = '';
|
|
398
403
|
});
|
|
@@ -467,23 +472,19 @@ function allowPreviousPlayerStylesMerge(duration, delay) {
|
|
|
467
472
|
return duration === 0 || delay === 0;
|
|
468
473
|
}
|
|
469
474
|
function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
|
|
470
|
-
|
|
471
|
-
if (previousStyleProps.length && keyframes.length) {
|
|
475
|
+
if (previousStyles.size && keyframes.length) {
|
|
472
476
|
let startingKeyframe = keyframes[0];
|
|
473
477
|
let missingStyleProps = [];
|
|
474
|
-
|
|
475
|
-
if (!startingKeyframe.
|
|
478
|
+
previousStyles.forEach((val, prop) => {
|
|
479
|
+
if (!startingKeyframe.has(prop)) {
|
|
476
480
|
missingStyleProps.push(prop);
|
|
477
481
|
}
|
|
478
|
-
startingKeyframe
|
|
482
|
+
startingKeyframe.set(prop, val);
|
|
479
483
|
});
|
|
480
484
|
if (missingStyleProps.length) {
|
|
481
|
-
|
|
482
|
-
for (var i = 1; i < keyframes.length; i++) {
|
|
485
|
+
for (let i = 1; i < keyframes.length; i++) {
|
|
483
486
|
let kf = keyframes[i];
|
|
484
|
-
missingStyleProps.forEach(
|
|
485
|
-
kf[prop] = computeStyle(element, prop);
|
|
486
|
-
});
|
|
487
|
+
missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));
|
|
487
488
|
}
|
|
488
489
|
}
|
|
489
490
|
}
|
|
@@ -663,8 +664,8 @@ class AnimationAstBuilderVisitor {
|
|
|
663
664
|
}
|
|
664
665
|
_resetContextStyleTimingState(context) {
|
|
665
666
|
context.currentQuerySelector = ROOT_SELECTOR;
|
|
666
|
-
context.collectedStyles =
|
|
667
|
-
context.collectedStyles
|
|
667
|
+
context.collectedStyles = new Map();
|
|
668
|
+
context.collectedStyles.set(ROOT_SELECTOR, new Map());
|
|
668
669
|
context.currentTime = 0;
|
|
669
670
|
}
|
|
670
671
|
visitTrigger(metadata, context) {
|
|
@@ -712,11 +713,10 @@ class AnimationAstBuilderVisitor {
|
|
|
712
713
|
if (styleAst.containsDynamicStyles) {
|
|
713
714
|
const missingSubs = new Set();
|
|
714
715
|
const params = astParams || {};
|
|
715
|
-
styleAst.styles.forEach(
|
|
716
|
-
if (
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
extractStyleParams(stylesObj[prop]).forEach(sub => {
|
|
716
|
+
styleAst.styles.forEach(style => {
|
|
717
|
+
if (style instanceof Map) {
|
|
718
|
+
style.forEach(value => {
|
|
719
|
+
extractStyleParams(value).forEach(sub => {
|
|
720
720
|
if (!params.hasOwnProperty(sub)) {
|
|
721
721
|
missingSubs.add(sub);
|
|
722
722
|
}
|
|
@@ -813,37 +813,30 @@ class AnimationAstBuilderVisitor {
|
|
|
813
813
|
}
|
|
814
814
|
_makeStyleAst(metadata, context) {
|
|
815
815
|
const styles = [];
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
}
|
|
822
|
-
else {
|
|
823
|
-
context.errors.push(`The provided style string value ${styleTuple} is not allowed.`);
|
|
824
|
-
}
|
|
816
|
+
const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
|
|
817
|
+
for (let styleTuple of metadataStyles) {
|
|
818
|
+
if (typeof styleTuple === 'string') {
|
|
819
|
+
if (styleTuple === AUTO_STYLE) {
|
|
820
|
+
styles.push(styleTuple);
|
|
825
821
|
}
|
|
826
822
|
else {
|
|
827
|
-
|
|
823
|
+
context.errors.push(`The provided style string value ${styleTuple} is not allowed.`);
|
|
828
824
|
}
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
styles.push(convertToMap(styleTuple));
|
|
828
|
+
}
|
|
833
829
|
}
|
|
834
830
|
let containsDynamicStyles = false;
|
|
835
831
|
let collectedEasing = null;
|
|
836
832
|
styles.forEach(styleData => {
|
|
837
|
-
if (
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
collectedEasing = easing;
|
|
842
|
-
delete styleMap['easing'];
|
|
833
|
+
if (styleData instanceof Map) {
|
|
834
|
+
if (styleData.has('easing')) {
|
|
835
|
+
collectedEasing = styleData.get('easing');
|
|
836
|
+
styleData.delete('easing');
|
|
843
837
|
}
|
|
844
838
|
if (!containsDynamicStyles) {
|
|
845
|
-
for (let
|
|
846
|
-
const value = styleMap[prop];
|
|
839
|
+
for (let value of styleData.values()) {
|
|
847
840
|
if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
|
|
848
841
|
containsDynamicStyles = true;
|
|
849
842
|
break;
|
|
@@ -869,15 +862,17 @@ class AnimationAstBuilderVisitor {
|
|
|
869
862
|
startTime -= timings.duration + timings.delay;
|
|
870
863
|
}
|
|
871
864
|
ast.styles.forEach(tuple => {
|
|
872
|
-
if (typeof tuple
|
|
865
|
+
if (typeof tuple === 'string')
|
|
873
866
|
return;
|
|
874
|
-
|
|
867
|
+
tuple.forEach((value, prop) => {
|
|
875
868
|
if (!this._driver.validateStyleProperty(prop)) {
|
|
876
869
|
context.errors.push(`The provided animation property "${prop}" is not a supported CSS property for animations`);
|
|
877
870
|
return;
|
|
878
871
|
}
|
|
879
|
-
|
|
880
|
-
|
|
872
|
+
// This is guaranteed to have a defined Map at this querySelector location making it
|
|
873
|
+
// safe to add the assertion here. It is set as a default empty map in prior methods.
|
|
874
|
+
const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
|
|
875
|
+
const collectedEntry = collectedStyles.get(prop);
|
|
881
876
|
let updateCollectedStyle = true;
|
|
882
877
|
if (collectedEntry) {
|
|
883
878
|
if (startTime != endTime && startTime >= collectedEntry.startTime &&
|
|
@@ -892,10 +887,10 @@ class AnimationAstBuilderVisitor {
|
|
|
892
887
|
startTime = collectedEntry.startTime;
|
|
893
888
|
}
|
|
894
889
|
if (updateCollectedStyle) {
|
|
895
|
-
collectedStyles
|
|
890
|
+
collectedStyles.set(prop, { startTime, endTime });
|
|
896
891
|
}
|
|
897
892
|
if (context.options) {
|
|
898
|
-
validateStyleParams(
|
|
893
|
+
validateStyleParams(value, context.options, context.errors);
|
|
899
894
|
}
|
|
900
895
|
});
|
|
901
896
|
});
|
|
@@ -984,7 +979,7 @@ class AnimationAstBuilderVisitor {
|
|
|
984
979
|
const [selector, includeSelf] = normalizeSelector(metadata.selector);
|
|
985
980
|
context.currentQuerySelector =
|
|
986
981
|
parentSelector.length ? (parentSelector + ' ' + selector) : selector;
|
|
987
|
-
|
|
982
|
+
getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
|
|
988
983
|
const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
|
|
989
984
|
context.currentQuery = null;
|
|
990
985
|
context.currentQuerySelector = parentSelector;
|
|
@@ -1039,7 +1034,7 @@ class AnimationAstBuilderContext {
|
|
|
1039
1034
|
this.currentQuerySelector = null;
|
|
1040
1035
|
this.currentAnimateTimings = null;
|
|
1041
1036
|
this.currentTime = 0;
|
|
1042
|
-
this.collectedStyles =
|
|
1037
|
+
this.collectedStyles = new Map();
|
|
1043
1038
|
this.options = null;
|
|
1044
1039
|
}
|
|
1045
1040
|
}
|
|
@@ -1049,23 +1044,20 @@ function consumeOffset(styles) {
|
|
|
1049
1044
|
let offset = null;
|
|
1050
1045
|
if (Array.isArray(styles)) {
|
|
1051
1046
|
styles.forEach(styleTuple => {
|
|
1052
|
-
if (
|
|
1047
|
+
if (styleTuple instanceof Map && styleTuple.has('offset')) {
|
|
1053
1048
|
const obj = styleTuple;
|
|
1054
|
-
offset = parseFloat(obj
|
|
1055
|
-
delete
|
|
1049
|
+
offset = parseFloat(obj.get('offset'));
|
|
1050
|
+
obj.delete('offset');
|
|
1056
1051
|
}
|
|
1057
1052
|
});
|
|
1058
1053
|
}
|
|
1059
|
-
else if (
|
|
1054
|
+
else if (styles instanceof Map && styles.has('offset')) {
|
|
1060
1055
|
const obj = styles;
|
|
1061
|
-
offset = parseFloat(obj
|
|
1062
|
-
delete
|
|
1056
|
+
offset = parseFloat(obj.get('offset'));
|
|
1057
|
+
obj.delete('offset');
|
|
1063
1058
|
}
|
|
1064
1059
|
return offset;
|
|
1065
1060
|
}
|
|
1066
|
-
function isObject(value) {
|
|
1067
|
-
return !Array.isArray(value) && typeof value == 'object';
|
|
1068
|
-
}
|
|
1069
1061
|
function constructTimingAst(value, errors) {
|
|
1070
1062
|
let timings = null;
|
|
1071
1063
|
if (value.hasOwnProperty('duration')) {
|
|
@@ -1173,7 +1165,7 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
|
|
|
1173
1165
|
* ```
|
|
1174
1166
|
*
|
|
1175
1167
|
* For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
|
|
1176
|
-
* combination of
|
|
1168
|
+
* combination of AST traversal and merge-sort-like algorithms are used.
|
|
1177
1169
|
*
|
|
1178
1170
|
* [AST Traversal]
|
|
1179
1171
|
* Each of the animation verbs, when executed, will return an string-map object representing what
|
|
@@ -1219,23 +1211,18 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
|
|
|
1219
1211
|
* from all previous animation steps. Therefore when a keyframe is created it would also be missing
|
|
1220
1212
|
* from all previous keyframes up until where it is first used. For the timeline keyframe generation
|
|
1221
1213
|
* to properly fill in the style it will place the previous value (the value from the parent
|
|
1222
|
-
* timeline) or a default value of `*` into the backFill
|
|
1223
|
-
*
|
|
1224
|
-
* value is added into the backFill then it will automatically propagate any missing values to all
|
|
1225
|
-
* keyframes. Therefore the missing `height` value will be properly filled into the already
|
|
1226
|
-
* processed keyframes.
|
|
1214
|
+
* timeline) or a default value of `*` into the backFill map. The `copyStyles` method in util.ts
|
|
1215
|
+
* handles propagating that backfill map to the styles object.
|
|
1227
1216
|
*
|
|
1228
1217
|
* When a sub-timeline is created it will have its own backFill property. This is done so that
|
|
1229
1218
|
* styles present within the sub-timeline do not accidentally seep into the previous/future timeline
|
|
1230
1219
|
* keyframes
|
|
1231
1220
|
*
|
|
1232
|
-
* (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
|
|
1233
|
-
*
|
|
1234
1221
|
* [Validation]
|
|
1235
1222
|
* The code in this file is not responsible for validation. That functionality happens with within
|
|
1236
1223
|
* the `AnimationValidatorVisitor` code.
|
|
1237
1224
|
*/
|
|
1238
|
-
function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles =
|
|
1225
|
+
function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstructions, errors = []) {
|
|
1239
1226
|
return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
|
|
1240
1227
|
}
|
|
1241
1228
|
class AnimationTimelineBuilderVisitor {
|
|
@@ -1243,15 +1230,17 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1243
1230
|
subInstructions = subInstructions || new ElementInstructionMap();
|
|
1244
1231
|
const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
|
|
1245
1232
|
context.options = options;
|
|
1233
|
+
const delay = options.delay ? resolveTimingValue(options.delay) : 0;
|
|
1234
|
+
context.currentTimeline.delayNextStep(delay);
|
|
1246
1235
|
context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
|
|
1247
1236
|
visitDslNode(this, ast, context);
|
|
1248
1237
|
// this checks to see if an actual animation happened
|
|
1249
1238
|
const timelines = context.timelines.filter(timeline => timeline.containsAnimation());
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1239
|
+
// note: we just want to apply the final styles for the rootElement, so we do not
|
|
1240
|
+
// just apply the styles to the last timeline but the last timeline which
|
|
1241
|
+
// element is the root one (basically `*`-styles are replaced with the actual
|
|
1242
|
+
// state style values only for the root element)
|
|
1243
|
+
if (timelines.length && finalStyles.size) {
|
|
1255
1244
|
let lastRootTimeline;
|
|
1256
1245
|
for (let i = timelines.length - 1; i >= 0; i--) {
|
|
1257
1246
|
const timeline = timelines[i];
|
|
@@ -1264,8 +1253,9 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1264
1253
|
lastRootTimeline.setStyles([finalStyles], null, context.errors, options);
|
|
1265
1254
|
}
|
|
1266
1255
|
}
|
|
1267
|
-
return timelines.length ?
|
|
1268
|
-
|
|
1256
|
+
return timelines.length ?
|
|
1257
|
+
timelines.map(timeline => timeline.buildKeyframes()) :
|
|
1258
|
+
[createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];
|
|
1269
1259
|
}
|
|
1270
1260
|
visitTrigger(ast, context) {
|
|
1271
1261
|
// these values are not visited in this AST
|
|
@@ -1401,7 +1391,7 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1401
1391
|
const timings = context.currentAnimateTimings;
|
|
1402
1392
|
// this is a special case for when a style() call
|
|
1403
1393
|
// directly follows an animate() call (but not inside of an animate() call)
|
|
1404
|
-
if (!timings && timeline.
|
|
1394
|
+
if (!timings && timeline.hasCurrentStyleProperties()) {
|
|
1405
1395
|
timeline.forwardFrame();
|
|
1406
1396
|
}
|
|
1407
1397
|
const easing = (timings && timings.easing) || ast.easing;
|
|
@@ -1442,7 +1432,7 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1442
1432
|
const delay = options.delay ? resolveTimingValue(options.delay) : 0;
|
|
1443
1433
|
if (delay &&
|
|
1444
1434
|
(context.previousNode.type === 6 /* Style */ ||
|
|
1445
|
-
(startTime == 0 && context.currentTimeline.
|
|
1435
|
+
(startTime == 0 && context.currentTimeline.hasCurrentStyleProperties()))) {
|
|
1446
1436
|
context.currentTimeline.snapshotCurrentStyles();
|
|
1447
1437
|
context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
|
|
1448
1438
|
}
|
|
@@ -1636,17 +1626,17 @@ class TimelineBuilder {
|
|
|
1636
1626
|
this.startTime = startTime;
|
|
1637
1627
|
this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
|
|
1638
1628
|
this.duration = 0;
|
|
1639
|
-
this._previousKeyframe =
|
|
1640
|
-
this._currentKeyframe =
|
|
1629
|
+
this._previousKeyframe = new Map();
|
|
1630
|
+
this._currentKeyframe = new Map();
|
|
1641
1631
|
this._keyframes = new Map();
|
|
1642
|
-
this._styleSummary =
|
|
1643
|
-
this.
|
|
1644
|
-
this.
|
|
1632
|
+
this._styleSummary = new Map();
|
|
1633
|
+
this._localTimelineStyles = new Map();
|
|
1634
|
+
this._pendingStyles = new Map();
|
|
1635
|
+
this._backFill = new Map();
|
|
1645
1636
|
this._currentEmptyStepKeyframe = null;
|
|
1646
1637
|
if (!this._elementTimelineStylesLookup) {
|
|
1647
1638
|
this._elementTimelineStylesLookup = new Map();
|
|
1648
1639
|
}
|
|
1649
|
-
this._localTimelineStyles = Object.create(this._backFill, {});
|
|
1650
1640
|
this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
|
|
1651
1641
|
if (!this._globalTimelineStyles) {
|
|
1652
1642
|
this._globalTimelineStyles = this._localTimelineStyles;
|
|
@@ -1659,13 +1649,13 @@ class TimelineBuilder {
|
|
|
1659
1649
|
case 0:
|
|
1660
1650
|
return false;
|
|
1661
1651
|
case 1:
|
|
1662
|
-
return this.
|
|
1652
|
+
return this.hasCurrentStyleProperties();
|
|
1663
1653
|
default:
|
|
1664
1654
|
return true;
|
|
1665
1655
|
}
|
|
1666
1656
|
}
|
|
1667
|
-
|
|
1668
|
-
return
|
|
1657
|
+
hasCurrentStyleProperties() {
|
|
1658
|
+
return this._currentKeyframe.size > 0;
|
|
1669
1659
|
}
|
|
1670
1660
|
get currentTime() {
|
|
1671
1661
|
return this.startTime + this.duration;
|
|
@@ -1675,7 +1665,7 @@ class TimelineBuilder {
|
|
|
1675
1665
|
// and that style() step is the very first style() value in the animation
|
|
1676
1666
|
// then we need to make a copy of the keyframe [0, copy, 1] so that the delay
|
|
1677
1667
|
// properly applies the style() values to work with the stagger...
|
|
1678
|
-
const hasPreStyleStep = this._keyframes.size
|
|
1668
|
+
const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;
|
|
1679
1669
|
if (this.duration || hasPreStyleStep) {
|
|
1680
1670
|
this.forwardTime(this.currentTime + delay);
|
|
1681
1671
|
if (hasPreStyleStep) {
|
|
@@ -1696,7 +1686,7 @@ class TimelineBuilder {
|
|
|
1696
1686
|
}
|
|
1697
1687
|
this._currentKeyframe = this._keyframes.get(this.duration);
|
|
1698
1688
|
if (!this._currentKeyframe) {
|
|
1699
|
-
this._currentKeyframe =
|
|
1689
|
+
this._currentKeyframe = new Map();
|
|
1700
1690
|
this._keyframes.set(this.duration, this._currentKeyframe);
|
|
1701
1691
|
}
|
|
1702
1692
|
}
|
|
@@ -1710,16 +1700,16 @@ class TimelineBuilder {
|
|
|
1710
1700
|
this._loadKeyframe();
|
|
1711
1701
|
}
|
|
1712
1702
|
_updateStyle(prop, value) {
|
|
1713
|
-
this._localTimelineStyles
|
|
1714
|
-
this._globalTimelineStyles
|
|
1715
|
-
this._styleSummary
|
|
1703
|
+
this._localTimelineStyles.set(prop, value);
|
|
1704
|
+
this._globalTimelineStyles.set(prop, value);
|
|
1705
|
+
this._styleSummary.set(prop, { time: this.currentTime, value });
|
|
1716
1706
|
}
|
|
1717
1707
|
allowOnlyTimelineStyles() {
|
|
1718
1708
|
return this._currentEmptyStepKeyframe !== this._currentKeyframe;
|
|
1719
1709
|
}
|
|
1720
1710
|
applyEmptyStep(easing) {
|
|
1721
1711
|
if (easing) {
|
|
1722
|
-
this._previousKeyframe
|
|
1712
|
+
this._previousKeyframe.set('easing', easing);
|
|
1723
1713
|
}
|
|
1724
1714
|
// special case for animate(duration):
|
|
1725
1715
|
// all missing styles are filled with a `*` value then
|
|
@@ -1727,51 +1717,45 @@ class TimelineBuilder {
|
|
|
1727
1717
|
// keyframe then they will override the overridden styles
|
|
1728
1718
|
// We use `_globalTimelineStyles` here because there may be
|
|
1729
1719
|
// styles in previous keyframes that are not present in this timeline
|
|
1730
|
-
|
|
1731
|
-
this._backFill
|
|
1732
|
-
this._currentKeyframe
|
|
1733
|
-
}
|
|
1720
|
+
for (let [prop, value] of this._globalTimelineStyles) {
|
|
1721
|
+
this._backFill.set(prop, value || AUTO_STYLE);
|
|
1722
|
+
this._currentKeyframe.set(prop, AUTO_STYLE);
|
|
1723
|
+
}
|
|
1734
1724
|
this._currentEmptyStepKeyframe = this._currentKeyframe;
|
|
1735
1725
|
}
|
|
1736
1726
|
setStyles(input, easing, errors, options) {
|
|
1737
1727
|
if (easing) {
|
|
1738
|
-
this._previousKeyframe
|
|
1728
|
+
this._previousKeyframe.set('easing', easing);
|
|
1739
1729
|
}
|
|
1740
1730
|
const params = (options && options.params) || {};
|
|
1741
1731
|
const styles = flattenStyles(input, this._globalTimelineStyles);
|
|
1742
|
-
|
|
1743
|
-
const val = interpolateParams(
|
|
1744
|
-
this._pendingStyles
|
|
1745
|
-
if (!this._localTimelineStyles.
|
|
1746
|
-
this._backFill
|
|
1747
|
-
this._globalTimelineStyles[prop] :
|
|
1748
|
-
AUTO_STYLE;
|
|
1732
|
+
for (let [prop, value] of styles) {
|
|
1733
|
+
const val = interpolateParams(value, params, errors);
|
|
1734
|
+
this._pendingStyles.set(prop, val);
|
|
1735
|
+
if (!this._localTimelineStyles.has(prop)) {
|
|
1736
|
+
this._backFill.set(prop, this._globalTimelineStyles.get(prop) || AUTO_STYLE);
|
|
1749
1737
|
}
|
|
1750
1738
|
this._updateStyle(prop, val);
|
|
1751
|
-
}
|
|
1739
|
+
}
|
|
1752
1740
|
}
|
|
1753
1741
|
applyStylesToKeyframe() {
|
|
1754
|
-
|
|
1755
|
-
const props = Object.keys(styles);
|
|
1756
|
-
if (props.length == 0)
|
|
1742
|
+
if (this._pendingStyles.size == 0)
|
|
1757
1743
|
return;
|
|
1758
|
-
this._pendingStyles
|
|
1759
|
-
|
|
1760
|
-
const val = styles[prop];
|
|
1761
|
-
this._currentKeyframe[prop] = val;
|
|
1744
|
+
this._pendingStyles.forEach((val, prop) => {
|
|
1745
|
+
this._currentKeyframe.set(prop, val);
|
|
1762
1746
|
});
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1747
|
+
this._pendingStyles.clear();
|
|
1748
|
+
this._localTimelineStyles.forEach((val, prop) => {
|
|
1749
|
+
if (!this._currentKeyframe.has(prop)) {
|
|
1750
|
+
this._currentKeyframe.set(prop, val);
|
|
1766
1751
|
}
|
|
1767
1752
|
});
|
|
1768
1753
|
}
|
|
1769
1754
|
snapshotCurrentStyles() {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
this._pendingStyles[prop] = val;
|
|
1755
|
+
for (let [prop, val] of this._localTimelineStyles) {
|
|
1756
|
+
this._pendingStyles.set(prop, val);
|
|
1773
1757
|
this._updateStyle(prop, val);
|
|
1774
|
-
}
|
|
1758
|
+
}
|
|
1775
1759
|
}
|
|
1776
1760
|
getFinalKeyframe() {
|
|
1777
1761
|
return this._keyframes.get(this.duration);
|
|
@@ -1784,9 +1768,8 @@ class TimelineBuilder {
|
|
|
1784
1768
|
return properties;
|
|
1785
1769
|
}
|
|
1786
1770
|
mergeTimelineCollectedStyles(timeline) {
|
|
1787
|
-
|
|
1788
|
-
const details0 = this._styleSummary
|
|
1789
|
-
const details1 = timeline._styleSummary[prop];
|
|
1771
|
+
timeline._styleSummary.forEach((details1, prop) => {
|
|
1772
|
+
const details0 = this._styleSummary.get(prop);
|
|
1790
1773
|
if (!details0 || details1.time > details0.time) {
|
|
1791
1774
|
this._updateStyle(prop, details1.value);
|
|
1792
1775
|
}
|
|
@@ -1799,18 +1782,17 @@ class TimelineBuilder {
|
|
|
1799
1782
|
const isEmpty = this._keyframes.size === 1 && this.duration === 0;
|
|
1800
1783
|
let finalKeyframes = [];
|
|
1801
1784
|
this._keyframes.forEach((keyframe, time) => {
|
|
1802
|
-
const finalKeyframe = copyStyles(keyframe,
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
if (value == ɵPRE_STYLE) {
|
|
1785
|
+
const finalKeyframe = copyStyles(keyframe, new Map(), this._backFill);
|
|
1786
|
+
finalKeyframe.forEach((value, prop) => {
|
|
1787
|
+
if (value === ɵPRE_STYLE) {
|
|
1806
1788
|
preStyleProps.add(prop);
|
|
1807
1789
|
}
|
|
1808
|
-
else if (value
|
|
1790
|
+
else if (value === AUTO_STYLE) {
|
|
1809
1791
|
postStyleProps.add(prop);
|
|
1810
1792
|
}
|
|
1811
1793
|
});
|
|
1812
1794
|
if (!isEmpty) {
|
|
1813
|
-
finalKeyframe
|
|
1795
|
+
finalKeyframe.set('offset', time / this.duration);
|
|
1814
1796
|
}
|
|
1815
1797
|
finalKeyframes.push(finalKeyframe);
|
|
1816
1798
|
});
|
|
@@ -1819,9 +1801,9 @@ class TimelineBuilder {
|
|
|
1819
1801
|
// special case for a 0-second animation (which is designed just to place styles onscreen)
|
|
1820
1802
|
if (isEmpty) {
|
|
1821
1803
|
const kf0 = finalKeyframes[0];
|
|
1822
|
-
const kf1 =
|
|
1823
|
-
kf0
|
|
1824
|
-
kf1
|
|
1804
|
+
const kf1 = new Map(kf0);
|
|
1805
|
+
kf0.set('offset', 0);
|
|
1806
|
+
kf1.set('offset', 1);
|
|
1825
1807
|
finalKeyframes = [kf0, kf1];
|
|
1826
1808
|
}
|
|
1827
1809
|
return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
|
|
@@ -1847,11 +1829,11 @@ class SubTimelineBuilder extends TimelineBuilder {
|
|
|
1847
1829
|
const totalTime = duration + delay;
|
|
1848
1830
|
const startingGap = delay / totalTime;
|
|
1849
1831
|
// the original starting keyframe now starts once the delay is done
|
|
1850
|
-
const newFirstKeyframe = copyStyles(keyframes[0]
|
|
1851
|
-
newFirstKeyframe
|
|
1832
|
+
const newFirstKeyframe = copyStyles(keyframes[0]);
|
|
1833
|
+
newFirstKeyframe.set('offset', 0);
|
|
1852
1834
|
newKeyframes.push(newFirstKeyframe);
|
|
1853
|
-
const oldFirstKeyframe = copyStyles(keyframes[0]
|
|
1854
|
-
oldFirstKeyframe
|
|
1835
|
+
const oldFirstKeyframe = copyStyles(keyframes[0]);
|
|
1836
|
+
oldFirstKeyframe.set('offset', roundOffset(startingGap));
|
|
1855
1837
|
newKeyframes.push(oldFirstKeyframe);
|
|
1856
1838
|
/*
|
|
1857
1839
|
When the keyframe is stretched then it means that the delay before the animation
|
|
@@ -1870,10 +1852,10 @@ class SubTimelineBuilder extends TimelineBuilder {
|
|
|
1870
1852
|
// offsets between 1 ... n -1 are all warped by the keyframe stretch
|
|
1871
1853
|
const limit = keyframes.length - 1;
|
|
1872
1854
|
for (let i = 1; i <= limit; i++) {
|
|
1873
|
-
let kf = copyStyles(keyframes[i]
|
|
1874
|
-
const oldOffset = kf
|
|
1855
|
+
let kf = copyStyles(keyframes[i]);
|
|
1856
|
+
const oldOffset = kf.get('offset');
|
|
1875
1857
|
const timeAtKeyframe = delay + oldOffset * duration;
|
|
1876
|
-
kf
|
|
1858
|
+
kf.set('offset', roundOffset(timeAtKeyframe / totalTime));
|
|
1877
1859
|
newKeyframes.push(kf);
|
|
1878
1860
|
}
|
|
1879
1861
|
// the new starting keyframe should be added at the start
|
|
@@ -1890,17 +1872,17 @@ function roundOffset(offset, decimalPoints = 3) {
|
|
|
1890
1872
|
return Math.round(offset * mult) / mult;
|
|
1891
1873
|
}
|
|
1892
1874
|
function flattenStyles(input, allStyles) {
|
|
1893
|
-
const styles =
|
|
1875
|
+
const styles = new Map();
|
|
1894
1876
|
let allProperties;
|
|
1895
1877
|
input.forEach(token => {
|
|
1896
1878
|
if (token === '*') {
|
|
1897
|
-
allProperties = allProperties ||
|
|
1898
|
-
|
|
1899
|
-
styles
|
|
1900
|
-
}
|
|
1879
|
+
allProperties = allProperties || allStyles.keys();
|
|
1880
|
+
for (let prop of allProperties) {
|
|
1881
|
+
styles.set(prop, AUTO_STYLE);
|
|
1882
|
+
}
|
|
1901
1883
|
}
|
|
1902
1884
|
else {
|
|
1903
|
-
copyStyles(token,
|
|
1885
|
+
copyStyles(token, styles);
|
|
1904
1886
|
}
|
|
1905
1887
|
});
|
|
1906
1888
|
return styles;
|
|
@@ -1964,6 +1946,37 @@ class NoopAnimationStyleNormalizer {
|
|
|
1964
1946
|
* Use of this source code is governed by an MIT-style license that can be
|
|
1965
1947
|
* found in the LICENSE file at https://angular.io/license
|
|
1966
1948
|
*/
|
|
1949
|
+
const DIMENSIONAL_PROP_SET = new Set([
|
|
1950
|
+
'width',
|
|
1951
|
+
'height',
|
|
1952
|
+
'minWidth',
|
|
1953
|
+
'minHeight',
|
|
1954
|
+
'maxWidth',
|
|
1955
|
+
'maxHeight',
|
|
1956
|
+
'left',
|
|
1957
|
+
'top',
|
|
1958
|
+
'bottom',
|
|
1959
|
+
'right',
|
|
1960
|
+
'fontSize',
|
|
1961
|
+
'outlineWidth',
|
|
1962
|
+
'outlineOffset',
|
|
1963
|
+
'paddingTop',
|
|
1964
|
+
'paddingLeft',
|
|
1965
|
+
'paddingBottom',
|
|
1966
|
+
'paddingRight',
|
|
1967
|
+
'marginTop',
|
|
1968
|
+
'marginLeft',
|
|
1969
|
+
'marginBottom',
|
|
1970
|
+
'marginRight',
|
|
1971
|
+
'borderRadius',
|
|
1972
|
+
'borderWidth',
|
|
1973
|
+
'borderTopWidth',
|
|
1974
|
+
'borderLeftWidth',
|
|
1975
|
+
'borderRightWidth',
|
|
1976
|
+
'borderBottomWidth',
|
|
1977
|
+
'textIndent',
|
|
1978
|
+
'perspective'
|
|
1979
|
+
]);
|
|
1967
1980
|
class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
1968
1981
|
normalizePropertyName(propertyName, errors) {
|
|
1969
1982
|
return dashCaseToCamelCase(propertyName);
|
|
@@ -1971,7 +1984,7 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
|
1971
1984
|
normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
|
|
1972
1985
|
let unit = '';
|
|
1973
1986
|
const strVal = value.toString().trim();
|
|
1974
|
-
if (
|
|
1987
|
+
if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {
|
|
1975
1988
|
if (typeof value === 'number') {
|
|
1976
1989
|
unit = 'px';
|
|
1977
1990
|
}
|
|
@@ -1985,14 +1998,14 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
|
1985
1998
|
return strVal + unit;
|
|
1986
1999
|
}
|
|
1987
2000
|
}
|
|
1988
|
-
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'
|
|
1989
|
-
.split(',')))();
|
|
1990
|
-
function makeBooleanMap(keys) {
|
|
1991
|
-
const map = {};
|
|
1992
|
-
keys.forEach(key => map[key] = true);
|
|
1993
|
-
return map;
|
|
1994
|
-
}
|
|
1995
2001
|
|
|
2002
|
+
/**
|
|
2003
|
+
* @license
|
|
2004
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2005
|
+
*
|
|
2006
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2007
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2008
|
+
*/
|
|
1996
2009
|
function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
|
|
1997
2010
|
return {
|
|
1998
2011
|
type: 0 /* TransitionAnimation */,
|
|
@@ -2023,10 +2036,11 @@ class AnimationTransitionFactory {
|
|
|
2023
2036
|
return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
|
|
2024
2037
|
}
|
|
2025
2038
|
buildStyles(stateName, params, errors) {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2039
|
+
let styler = this._stateStyles.get('*');
|
|
2040
|
+
if (stateName !== undefined) {
|
|
2041
|
+
styler = this._stateStyles.get(stateName?.toString()) || styler;
|
|
2042
|
+
}
|
|
2043
|
+
return styler ? styler.buildStyles(params, errors) : new Map();
|
|
2030
2044
|
}
|
|
2031
2045
|
build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
|
|
2032
2046
|
const errors = [];
|
|
@@ -2039,7 +2053,10 @@ class AnimationTransitionFactory {
|
|
|
2039
2053
|
const preStyleMap = new Map();
|
|
2040
2054
|
const postStyleMap = new Map();
|
|
2041
2055
|
const isRemoval = nextState === 'void';
|
|
2042
|
-
const animationOptions = {
|
|
2056
|
+
const animationOptions = {
|
|
2057
|
+
params: { ...transitionAnimationParams, ...nextAnimationParams },
|
|
2058
|
+
delay: this.ast.options?.delay,
|
|
2059
|
+
};
|
|
2043
2060
|
const timelines = skipAstBuild ?
|
|
2044
2061
|
[] :
|
|
2045
2062
|
buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
|
|
@@ -2052,10 +2069,10 @@ class AnimationTransitionFactory {
|
|
|
2052
2069
|
}
|
|
2053
2070
|
timelines.forEach(tl => {
|
|
2054
2071
|
const elm = tl.element;
|
|
2055
|
-
const preProps =
|
|
2056
|
-
tl.preStyleProps.forEach(prop => preProps
|
|
2057
|
-
const postProps =
|
|
2058
|
-
tl.postStyleProps.forEach(prop => postProps
|
|
2072
|
+
const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());
|
|
2073
|
+
tl.preStyleProps.forEach(prop => preProps.add(prop));
|
|
2074
|
+
const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());
|
|
2075
|
+
tl.postStyleProps.forEach(prop => postProps.add(prop));
|
|
2059
2076
|
if (elm !== element) {
|
|
2060
2077
|
queriedElements.add(elm);
|
|
2061
2078
|
}
|
|
@@ -2074,25 +2091,23 @@ class AnimationStateStyles {
|
|
|
2074
2091
|
this.normalizer = normalizer;
|
|
2075
2092
|
}
|
|
2076
2093
|
buildStyles(params, errors) {
|
|
2077
|
-
const finalStyles =
|
|
2094
|
+
const finalStyles = new Map();
|
|
2078
2095
|
const combinedParams = copyObj(this.defaultParams);
|
|
2079
2096
|
Object.keys(params).forEach(key => {
|
|
2080
2097
|
const value = params[key];
|
|
2081
|
-
if (value
|
|
2098
|
+
if (value !== null) {
|
|
2082
2099
|
combinedParams[key] = value;
|
|
2083
2100
|
}
|
|
2084
2101
|
});
|
|
2085
2102
|
this.styles.styles.forEach(value => {
|
|
2086
2103
|
if (typeof value !== 'string') {
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
let val = styleObj[prop];
|
|
2090
|
-
if (val.length > 1) {
|
|
2104
|
+
value.forEach((val, prop) => {
|
|
2105
|
+
if (val) {
|
|
2091
2106
|
val = interpolateParams(val, combinedParams, errors);
|
|
2092
2107
|
}
|
|
2093
2108
|
const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);
|
|
2094
2109
|
val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);
|
|
2095
|
-
finalStyles
|
|
2110
|
+
finalStyles.set(normalizedProp, val);
|
|
2096
2111
|
});
|
|
2097
2112
|
}
|
|
2098
2113
|
});
|
|
@@ -2109,10 +2124,10 @@ class AnimationTrigger {
|
|
|
2109
2124
|
this.ast = ast;
|
|
2110
2125
|
this._normalizer = _normalizer;
|
|
2111
2126
|
this.transitionFactories = [];
|
|
2112
|
-
this.states =
|
|
2127
|
+
this.states = new Map();
|
|
2113
2128
|
ast.states.forEach(ast => {
|
|
2114
2129
|
const defaultParams = (ast.options && ast.options.params) || {};
|
|
2115
|
-
this.states
|
|
2130
|
+
this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));
|
|
2116
2131
|
});
|
|
2117
2132
|
balanceProperties(this.states, 'true', '1');
|
|
2118
2133
|
balanceProperties(this.states, 'false', '0');
|
|
@@ -2145,14 +2160,14 @@ function createFallbackTransition(triggerName, states, normalizer) {
|
|
|
2145
2160
|
};
|
|
2146
2161
|
return new AnimationTransitionFactory(triggerName, transition, states);
|
|
2147
2162
|
}
|
|
2148
|
-
function balanceProperties(
|
|
2149
|
-
if (
|
|
2150
|
-
if (!
|
|
2151
|
-
|
|
2163
|
+
function balanceProperties(stateMap, key1, key2) {
|
|
2164
|
+
if (stateMap.has(key1)) {
|
|
2165
|
+
if (!stateMap.has(key2)) {
|
|
2166
|
+
stateMap.set(key2, stateMap.get(key1));
|
|
2152
2167
|
}
|
|
2153
2168
|
}
|
|
2154
|
-
else if (
|
|
2155
|
-
|
|
2169
|
+
else if (stateMap.has(key2)) {
|
|
2170
|
+
stateMap.set(key1, stateMap.get(key2));
|
|
2156
2171
|
}
|
|
2157
2172
|
}
|
|
2158
2173
|
|
|
@@ -2169,8 +2184,8 @@ class TimelineAnimationEngine {
|
|
|
2169
2184
|
this.bodyNode = bodyNode;
|
|
2170
2185
|
this._driver = _driver;
|
|
2171
2186
|
this._normalizer = _normalizer;
|
|
2172
|
-
this._animations =
|
|
2173
|
-
this._playersById =
|
|
2187
|
+
this._animations = new Map();
|
|
2188
|
+
this._playersById = new Map();
|
|
2174
2189
|
this.players = [];
|
|
2175
2190
|
}
|
|
2176
2191
|
register(id, metadata) {
|
|
@@ -2180,24 +2195,24 @@ class TimelineAnimationEngine {
|
|
|
2180
2195
|
throw new Error(`Unable to build the animation due to the following errors: ${errors.join('\n')}`);
|
|
2181
2196
|
}
|
|
2182
2197
|
else {
|
|
2183
|
-
this._animations
|
|
2198
|
+
this._animations.set(id, ast);
|
|
2184
2199
|
}
|
|
2185
2200
|
}
|
|
2186
2201
|
_buildPlayer(i, preStyles, postStyles) {
|
|
2187
2202
|
const element = i.element;
|
|
2188
|
-
const keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
|
|
2203
|
+
const keyframes = normalizeKeyframes$1(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
|
|
2189
2204
|
return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
|
|
2190
2205
|
}
|
|
2191
2206
|
create(id, element, options = {}) {
|
|
2192
2207
|
const errors = [];
|
|
2193
|
-
const ast = this._animations
|
|
2208
|
+
const ast = this._animations.get(id);
|
|
2194
2209
|
let instructions;
|
|
2195
2210
|
const autoStylesMap = new Map();
|
|
2196
2211
|
if (ast) {
|
|
2197
|
-
instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME,
|
|
2212
|
+
instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);
|
|
2198
2213
|
instructions.forEach(inst => {
|
|
2199
|
-
const styles =
|
|
2200
|
-
inst.postStyleProps.forEach(prop => styles
|
|
2214
|
+
const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());
|
|
2215
|
+
inst.postStyleProps.forEach(prop => styles.set(prop, null));
|
|
2201
2216
|
});
|
|
2202
2217
|
}
|
|
2203
2218
|
else {
|
|
@@ -2208,16 +2223,16 @@ class TimelineAnimationEngine {
|
|
|
2208
2223
|
throw new Error(`Unable to create the animation due to the following errors: ${errors.join('\n')}`);
|
|
2209
2224
|
}
|
|
2210
2225
|
autoStylesMap.forEach((styles, element) => {
|
|
2211
|
-
|
|
2212
|
-
styles
|
|
2226
|
+
styles.forEach((_, prop) => {
|
|
2227
|
+
styles.set(prop, this._driver.computeStyle(element, prop, AUTO_STYLE));
|
|
2213
2228
|
});
|
|
2214
2229
|
});
|
|
2215
2230
|
const players = instructions.map(i => {
|
|
2216
2231
|
const styles = autoStylesMap.get(i.element);
|
|
2217
|
-
return this._buildPlayer(i,
|
|
2232
|
+
return this._buildPlayer(i, new Map(), styles);
|
|
2218
2233
|
});
|
|
2219
2234
|
const player = optimizeGroupPlayer(players);
|
|
2220
|
-
this._playersById
|
|
2235
|
+
this._playersById.set(id, player);
|
|
2221
2236
|
player.onDestroy(() => this.destroy(id));
|
|
2222
2237
|
this.players.push(player);
|
|
2223
2238
|
return player;
|
|
@@ -2225,14 +2240,14 @@ class TimelineAnimationEngine {
|
|
|
2225
2240
|
destroy(id) {
|
|
2226
2241
|
const player = this._getPlayer(id);
|
|
2227
2242
|
player.destroy();
|
|
2228
|
-
|
|
2243
|
+
this._playersById.delete(id);
|
|
2229
2244
|
const index = this.players.indexOf(player);
|
|
2230
2245
|
if (index >= 0) {
|
|
2231
2246
|
this.players.splice(index, 1);
|
|
2232
2247
|
}
|
|
2233
2248
|
}
|
|
2234
2249
|
_getPlayer(id) {
|
|
2235
|
-
const player = this._playersById
|
|
2250
|
+
const player = this._playersById.get(id);
|
|
2236
2251
|
if (!player) {
|
|
2237
2252
|
throw new Error(`Unable to find the timeline player referenced by ${id}`);
|
|
2238
2253
|
}
|
|
@@ -2354,14 +2369,14 @@ class AnimationTransitionNamespace {
|
|
|
2354
2369
|
this.hostElement = hostElement;
|
|
2355
2370
|
this._engine = _engine;
|
|
2356
2371
|
this.players = [];
|
|
2357
|
-
this._triggers =
|
|
2372
|
+
this._triggers = new Map();
|
|
2358
2373
|
this._queue = [];
|
|
2359
2374
|
this._elementListeners = new Map();
|
|
2360
2375
|
this._hostClassName = 'ng-tns-' + id;
|
|
2361
2376
|
addClass(hostElement, this._hostClassName);
|
|
2362
2377
|
}
|
|
2363
2378
|
listen(element, name, phase, callback) {
|
|
2364
|
-
if (!this._triggers.
|
|
2379
|
+
if (!this._triggers.has(name)) {
|
|
2365
2380
|
throw new Error(`Unable to listen on the animation trigger event "${phase}" because the animation trigger "${name}" doesn\'t exist!`);
|
|
2366
2381
|
}
|
|
2367
2382
|
if (phase == null || phase.length == 0) {
|
|
@@ -2370,14 +2385,14 @@ class AnimationTransitionNamespace {
|
|
|
2370
2385
|
if (!isTriggerEventValid(phase)) {
|
|
2371
2386
|
throw new Error(`The provided animation trigger event "${phase}" for the animation trigger "${name}" is not supported!`);
|
|
2372
2387
|
}
|
|
2373
|
-
const listeners =
|
|
2388
|
+
const listeners = getOrSetDefaultValue(this._elementListeners, element, []);
|
|
2374
2389
|
const data = { name, phase, callback };
|
|
2375
2390
|
listeners.push(data);
|
|
2376
|
-
const triggersWithStates =
|
|
2377
|
-
if (!triggersWithStates.
|
|
2391
|
+
const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());
|
|
2392
|
+
if (!triggersWithStates.has(name)) {
|
|
2378
2393
|
addClass(element, NG_TRIGGER_CLASSNAME);
|
|
2379
2394
|
addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
|
|
2380
|
-
triggersWithStates
|
|
2395
|
+
triggersWithStates.set(name, DEFAULT_STATE_VALUE);
|
|
2381
2396
|
}
|
|
2382
2397
|
return () => {
|
|
2383
2398
|
// the event listener is removed AFTER the flush has occurred such
|
|
@@ -2388,24 +2403,24 @@ class AnimationTransitionNamespace {
|
|
|
2388
2403
|
if (index >= 0) {
|
|
2389
2404
|
listeners.splice(index, 1);
|
|
2390
2405
|
}
|
|
2391
|
-
if (!this._triggers
|
|
2392
|
-
delete
|
|
2406
|
+
if (!this._triggers.has(name)) {
|
|
2407
|
+
triggersWithStates.delete(name);
|
|
2393
2408
|
}
|
|
2394
2409
|
});
|
|
2395
2410
|
};
|
|
2396
2411
|
}
|
|
2397
2412
|
register(name, ast) {
|
|
2398
|
-
if (this._triggers
|
|
2413
|
+
if (this._triggers.has(name)) {
|
|
2399
2414
|
// throw
|
|
2400
2415
|
return false;
|
|
2401
2416
|
}
|
|
2402
2417
|
else {
|
|
2403
|
-
this._triggers
|
|
2418
|
+
this._triggers.set(name, ast);
|
|
2404
2419
|
return true;
|
|
2405
2420
|
}
|
|
2406
2421
|
}
|
|
2407
2422
|
_getTrigger(name) {
|
|
2408
|
-
const trigger = this._triggers
|
|
2423
|
+
const trigger = this._triggers.get(name);
|
|
2409
2424
|
if (!trigger) {
|
|
2410
2425
|
throw new Error(`The provided animation trigger "${name}" has not been registered!`);
|
|
2411
2426
|
}
|
|
@@ -2418,15 +2433,15 @@ class AnimationTransitionNamespace {
|
|
|
2418
2433
|
if (!triggersWithStates) {
|
|
2419
2434
|
addClass(element, NG_TRIGGER_CLASSNAME);
|
|
2420
2435
|
addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
|
|
2421
|
-
this._engine.statesByElement.set(element, triggersWithStates =
|
|
2436
|
+
this._engine.statesByElement.set(element, triggersWithStates = new Map());
|
|
2422
2437
|
}
|
|
2423
|
-
let fromState = triggersWithStates
|
|
2438
|
+
let fromState = triggersWithStates.get(triggerName);
|
|
2424
2439
|
const toState = new StateValue(value, this.id);
|
|
2425
2440
|
const isObj = value && value.hasOwnProperty('value');
|
|
2426
2441
|
if (!isObj && fromState) {
|
|
2427
2442
|
toState.absorbOptions(fromState.options);
|
|
2428
2443
|
}
|
|
2429
|
-
triggersWithStates
|
|
2444
|
+
triggersWithStates.set(triggerName, toState);
|
|
2430
2445
|
if (!fromState) {
|
|
2431
2446
|
fromState = DEFAULT_STATE_VALUE;
|
|
2432
2447
|
}
|
|
@@ -2456,7 +2471,7 @@ class AnimationTransitionNamespace {
|
|
|
2456
2471
|
}
|
|
2457
2472
|
return;
|
|
2458
2473
|
}
|
|
2459
|
-
const playersOnElement =
|
|
2474
|
+
const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);
|
|
2460
2475
|
playersOnElement.forEach(player => {
|
|
2461
2476
|
// only remove the player if it is queued on the EXACT same trigger/namespace
|
|
2462
2477
|
// we only also deal with queued players here because if the animation has
|
|
@@ -2500,10 +2515,8 @@ class AnimationTransitionNamespace {
|
|
|
2500
2515
|
return player;
|
|
2501
2516
|
}
|
|
2502
2517
|
deregister(name) {
|
|
2503
|
-
|
|
2504
|
-
this._engine.statesByElement.forEach(
|
|
2505
|
-
delete stateMap[name];
|
|
2506
|
-
});
|
|
2518
|
+
this._triggers.delete(name);
|
|
2519
|
+
this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));
|
|
2507
2520
|
this._elementListeners.forEach((listeners, element) => {
|
|
2508
2521
|
this._elementListeners.set(element, listeners.filter(entry => {
|
|
2509
2522
|
return entry.name != name;
|
|
@@ -2546,11 +2559,11 @@ class AnimationTransitionNamespace {
|
|
|
2546
2559
|
const previousTriggersValues = new Map();
|
|
2547
2560
|
if (triggerStates) {
|
|
2548
2561
|
const players = [];
|
|
2549
|
-
|
|
2550
|
-
previousTriggersValues.set(triggerName,
|
|
2562
|
+
triggerStates.forEach((state, triggerName) => {
|
|
2563
|
+
previousTriggersValues.set(triggerName, state.value);
|
|
2551
2564
|
// this check is here in the event that an element is removed
|
|
2552
2565
|
// twice (both on the host level and the component level)
|
|
2553
|
-
if (this._triggers
|
|
2566
|
+
if (this._triggers.has(triggerName)) {
|
|
2554
2567
|
const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
|
|
2555
2568
|
if (player) {
|
|
2556
2569
|
players.push(player);
|
|
@@ -2579,9 +2592,9 @@ class AnimationTransitionNamespace {
|
|
|
2579
2592
|
if (visitedTriggers.has(triggerName))
|
|
2580
2593
|
return;
|
|
2581
2594
|
visitedTriggers.add(triggerName);
|
|
2582
|
-
const trigger = this._triggers
|
|
2595
|
+
const trigger = this._triggers.get(triggerName);
|
|
2583
2596
|
const transition = trigger.fallbackTransition;
|
|
2584
|
-
const fromState = elementStates
|
|
2597
|
+
const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;
|
|
2585
2598
|
const toState = new StateValue(VOID_VALUE);
|
|
2586
2599
|
const player = new TransitionAnimationPlayer(this.id, triggerName, element);
|
|
2587
2600
|
this._engine.totalQueuedPlayers++;
|
|
@@ -2823,11 +2836,9 @@ class TransitionAnimationEngine {
|
|
|
2823
2836
|
const namespaces = new Set();
|
|
2824
2837
|
const elementStates = this.statesByElement.get(element);
|
|
2825
2838
|
if (elementStates) {
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
if (nsId) {
|
|
2830
|
-
const ns = this._fetchNamespace(nsId);
|
|
2839
|
+
for (let stateValue of elementStates.values()) {
|
|
2840
|
+
if (stateValue.namespaceId) {
|
|
2841
|
+
const ns = this._fetchNamespace(stateValue.namespaceId);
|
|
2831
2842
|
if (ns) {
|
|
2832
2843
|
namespaces.add(ns);
|
|
2833
2844
|
}
|
|
@@ -3134,8 +3145,10 @@ class TransitionAnimationEngine {
|
|
|
3134
3145
|
// we need to restore the previous trigger value since the element has
|
|
3135
3146
|
// only been moved and hasn't actually left the DOM
|
|
3136
3147
|
const triggersWithStates = this.statesByElement.get(entry.element);
|
|
3137
|
-
if (triggersWithStates && triggersWithStates
|
|
3138
|
-
triggersWithStates
|
|
3148
|
+
if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {
|
|
3149
|
+
const state = triggersWithStates.get(entry.triggerName);
|
|
3150
|
+
state.value = previousValue;
|
|
3151
|
+
triggersWithStates.set(entry.triggerName, state);
|
|
3139
3152
|
}
|
|
3140
3153
|
}
|
|
3141
3154
|
player.destroy();
|
|
@@ -3185,24 +3198,22 @@ class TransitionAnimationEngine {
|
|
|
3185
3198
|
subTimelines.append(element, instruction.timelines);
|
|
3186
3199
|
const tuple = { instruction, player, element };
|
|
3187
3200
|
queuedInstructions.push(tuple);
|
|
3188
|
-
instruction.queriedElements.forEach(element =>
|
|
3201
|
+
instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));
|
|
3189
3202
|
instruction.preStyleProps.forEach((stringMap, element) => {
|
|
3190
|
-
|
|
3191
|
-
if (props.length) {
|
|
3203
|
+
if (stringMap.size) {
|
|
3192
3204
|
let setVal = allPreStyleElements.get(element);
|
|
3193
3205
|
if (!setVal) {
|
|
3194
3206
|
allPreStyleElements.set(element, setVal = new Set());
|
|
3195
3207
|
}
|
|
3196
|
-
|
|
3208
|
+
stringMap.forEach((_, prop) => setVal.add(prop));
|
|
3197
3209
|
}
|
|
3198
3210
|
});
|
|
3199
3211
|
instruction.postStyleProps.forEach((stringMap, element) => {
|
|
3200
|
-
const props = Object.keys(stringMap);
|
|
3201
3212
|
let setVal = allPostStyleElements.get(element);
|
|
3202
3213
|
if (!setVal) {
|
|
3203
3214
|
allPostStyleElements.set(element, setVal = new Set());
|
|
3204
3215
|
}
|
|
3205
|
-
|
|
3216
|
+
stringMap.forEach((_, prop) => setVal.add(prop));
|
|
3206
3217
|
});
|
|
3207
3218
|
});
|
|
3208
3219
|
}
|
|
@@ -3232,7 +3243,7 @@ class TransitionAnimationEngine {
|
|
|
3232
3243
|
const element = player.element;
|
|
3233
3244
|
const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
|
|
3234
3245
|
previousPlayers.forEach(prevPlayer => {
|
|
3235
|
-
|
|
3246
|
+
getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);
|
|
3236
3247
|
prevPlayer.destroy();
|
|
3237
3248
|
});
|
|
3238
3249
|
});
|
|
@@ -3262,7 +3273,7 @@ class TransitionAnimationEngine {
|
|
|
3262
3273
|
replaceNodes.forEach(node => {
|
|
3263
3274
|
const post = postStylesMap.get(node);
|
|
3264
3275
|
const pre = preStylesMap.get(node);
|
|
3265
|
-
postStylesMap.set(node,
|
|
3276
|
+
postStylesMap.set(node, new Map([...Array.from(post?.entries() ?? []), ...Array.from(pre?.entries() ?? [])]));
|
|
3266
3277
|
});
|
|
3267
3278
|
const rootPlayers = [];
|
|
3268
3279
|
const subPlayers = [];
|
|
@@ -3456,7 +3467,7 @@ class TransitionAnimationEngine {
|
|
|
3456
3467
|
for (const timelineInstruction of instruction.timelines) {
|
|
3457
3468
|
const element = timelineInstruction.element;
|
|
3458
3469
|
const isQueriedElement = element !== rootElement;
|
|
3459
|
-
const players =
|
|
3470
|
+
const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);
|
|
3460
3471
|
const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
|
|
3461
3472
|
previousPlayers.forEach(player => {
|
|
3462
3473
|
const realPlayer = player.getRealPlayer();
|
|
@@ -3499,7 +3510,7 @@ class TransitionAnimationEngine {
|
|
|
3499
3510
|
});
|
|
3500
3511
|
const preStyles = preStylesMap.get(element);
|
|
3501
3512
|
const postStyles = postStylesMap.get(element);
|
|
3502
|
-
const keyframes = normalizeKeyframes(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
|
|
3513
|
+
const keyframes = normalizeKeyframes$1(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
|
|
3503
3514
|
const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
|
|
3504
3515
|
// this means that this particular player belongs to a sub trigger. It is
|
|
3505
3516
|
// important that we match this player up with the corresponding (@trigger.listener)
|
|
@@ -3514,7 +3525,7 @@ class TransitionAnimationEngine {
|
|
|
3514
3525
|
return player;
|
|
3515
3526
|
});
|
|
3516
3527
|
allQueriedPlayers.forEach(player => {
|
|
3517
|
-
|
|
3528
|
+
getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);
|
|
3518
3529
|
player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
|
|
3519
3530
|
});
|
|
3520
3531
|
allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
|
|
@@ -3526,7 +3537,7 @@ class TransitionAnimationEngine {
|
|
|
3526
3537
|
// this basically makes all of the callbacks for sub element animations
|
|
3527
3538
|
// be dependent on the upper players for when they finish
|
|
3528
3539
|
allSubElements.forEach(element => {
|
|
3529
|
-
|
|
3540
|
+
getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);
|
|
3530
3541
|
});
|
|
3531
3542
|
return player;
|
|
3532
3543
|
}
|
|
@@ -3546,7 +3557,7 @@ class TransitionAnimationPlayer {
|
|
|
3546
3557
|
this.element = element;
|
|
3547
3558
|
this._player = new NoopAnimationPlayer();
|
|
3548
3559
|
this._containsRealPlayer = false;
|
|
3549
|
-
this._queuedCallbacks =
|
|
3560
|
+
this._queuedCallbacks = new Map();
|
|
3550
3561
|
this.destroyed = false;
|
|
3551
3562
|
this.markedForDestroy = false;
|
|
3552
3563
|
this.disabled = false;
|
|
@@ -3557,10 +3568,10 @@ class TransitionAnimationPlayer {
|
|
|
3557
3568
|
if (this._containsRealPlayer)
|
|
3558
3569
|
return;
|
|
3559
3570
|
this._player = player;
|
|
3560
|
-
|
|
3561
|
-
|
|
3571
|
+
this._queuedCallbacks.forEach((callbacks, phase) => {
|
|
3572
|
+
callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));
|
|
3562
3573
|
});
|
|
3563
|
-
this._queuedCallbacks
|
|
3574
|
+
this._queuedCallbacks.clear();
|
|
3564
3575
|
this._containsRealPlayer = true;
|
|
3565
3576
|
this.overrideTotalTime(player.totalTime);
|
|
3566
3577
|
this.queued = false;
|
|
@@ -3580,7 +3591,7 @@ class TransitionAnimationPlayer {
|
|
|
3580
3591
|
player.onDestroy(() => this.destroy());
|
|
3581
3592
|
}
|
|
3582
3593
|
_queueEvent(name, callback) {
|
|
3583
|
-
|
|
3594
|
+
getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);
|
|
3584
3595
|
}
|
|
3585
3596
|
onDone(fn) {
|
|
3586
3597
|
if (this.queued) {
|
|
@@ -3642,29 +3653,14 @@ class TransitionAnimationPlayer {
|
|
|
3642
3653
|
}
|
|
3643
3654
|
}
|
|
3644
3655
|
function deleteOrUnsetInMap(map, key, value) {
|
|
3645
|
-
let currentValues;
|
|
3646
|
-
if (
|
|
3647
|
-
currentValues
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
const index = currentValues.indexOf(value);
|
|
3651
|
-
currentValues.splice(index, 1);
|
|
3652
|
-
}
|
|
3653
|
-
if (currentValues.length == 0) {
|
|
3654
|
-
map.delete(key);
|
|
3655
|
-
}
|
|
3656
|
+
let currentValues = map.get(key);
|
|
3657
|
+
if (currentValues) {
|
|
3658
|
+
if (currentValues.length) {
|
|
3659
|
+
const index = currentValues.indexOf(value);
|
|
3660
|
+
currentValues.splice(index, 1);
|
|
3656
3661
|
}
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
currentValues = map[key];
|
|
3660
|
-
if (currentValues) {
|
|
3661
|
-
if (currentValues.length) {
|
|
3662
|
-
const index = currentValues.indexOf(value);
|
|
3663
|
-
currentValues.splice(index, 1);
|
|
3664
|
-
}
|
|
3665
|
-
if (currentValues.length == 0) {
|
|
3666
|
-
delete map[key];
|
|
3667
|
-
}
|
|
3662
|
+
if (currentValues.length == 0) {
|
|
3663
|
+
map.delete(key);
|
|
3668
3664
|
}
|
|
3669
3665
|
}
|
|
3670
3666
|
return currentValues;
|
|
@@ -3691,9 +3687,10 @@ function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, def
|
|
|
3691
3687
|
elements.forEach(element => cloakVals.push(cloakElement(element)));
|
|
3692
3688
|
const failedElements = [];
|
|
3693
3689
|
elementPropsMap.forEach((props, element) => {
|
|
3694
|
-
const styles =
|
|
3690
|
+
const styles = new Map();
|
|
3695
3691
|
props.forEach(prop => {
|
|
3696
|
-
const value =
|
|
3692
|
+
const value = driver.computeStyle(element, prop, defaultStyle);
|
|
3693
|
+
styles.set(prop, value);
|
|
3697
3694
|
// there is no easy way to detect this because a sub element could be removed
|
|
3698
3695
|
// by a parent animation element being detached.
|
|
3699
3696
|
if (!value || value.length == 0) {
|
|
@@ -3877,13 +3874,6 @@ class AnimationEngine {
|
|
|
3877
3874
|
}
|
|
3878
3875
|
}
|
|
3879
3876
|
|
|
3880
|
-
/**
|
|
3881
|
-
* @license
|
|
3882
|
-
* Copyright Google LLC All Rights Reserved.
|
|
3883
|
-
*
|
|
3884
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
3885
|
-
* found in the LICENSE file at https://angular.io/license
|
|
3886
|
-
*/
|
|
3887
3877
|
/**
|
|
3888
3878
|
* Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
|
|
3889
3879
|
* detected.
|
|
@@ -3904,7 +3894,7 @@ function packageNonAnimatableStyles(element, styles) {
|
|
|
3904
3894
|
endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
|
|
3905
3895
|
}
|
|
3906
3896
|
}
|
|
3907
|
-
else if (styles) {
|
|
3897
|
+
else if (styles instanceof Map) {
|
|
3908
3898
|
startStyles = filterNonAnimatableStyles(styles);
|
|
3909
3899
|
}
|
|
3910
3900
|
return (startStyles || endStyles) ? new SpecialCasedStyles(element, startStyles, endStyles) :
|
|
@@ -3926,7 +3916,7 @@ class SpecialCasedStyles {
|
|
|
3926
3916
|
this._state = 0 /* Pending */;
|
|
3927
3917
|
let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
|
|
3928
3918
|
if (!initialStyles) {
|
|
3929
|
-
SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles =
|
|
3919
|
+
SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());
|
|
3930
3920
|
}
|
|
3931
3921
|
this._initialStyles = initialStyles;
|
|
3932
3922
|
}
|
|
@@ -3969,453 +3959,18 @@ class SpecialCasedStyles {
|
|
|
3969
3959
|
SpecialCasedStyles.initialStylesByElement = ( /* @__PURE__ */new WeakMap());
|
|
3970
3960
|
function filterNonAnimatableStyles(styles) {
|
|
3971
3961
|
let result = null;
|
|
3972
|
-
|
|
3973
|
-
for (let i = 0; i < props.length; i++) {
|
|
3974
|
-
const prop = props[i];
|
|
3962
|
+
styles.forEach((val, prop) => {
|
|
3975
3963
|
if (isNonAnimatableStyle(prop)) {
|
|
3976
|
-
result = result ||
|
|
3977
|
-
result
|
|
3964
|
+
result = result || new Map();
|
|
3965
|
+
result.set(prop, val);
|
|
3978
3966
|
}
|
|
3979
|
-
}
|
|
3967
|
+
});
|
|
3980
3968
|
return result;
|
|
3981
3969
|
}
|
|
3982
3970
|
function isNonAnimatableStyle(prop) {
|
|
3983
3971
|
return prop === 'display' || prop === 'position';
|
|
3984
3972
|
}
|
|
3985
3973
|
|
|
3986
|
-
/**
|
|
3987
|
-
* @license
|
|
3988
|
-
* Copyright Google LLC All Rights Reserved.
|
|
3989
|
-
*
|
|
3990
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
3991
|
-
* found in the LICENSE file at https://angular.io/license
|
|
3992
|
-
*/
|
|
3993
|
-
const ELAPSED_TIME_MAX_DECIMAL_PLACES = 3;
|
|
3994
|
-
const ANIMATION_PROP = 'animation';
|
|
3995
|
-
const ANIMATIONEND_EVENT = 'animationend';
|
|
3996
|
-
const ONE_SECOND = 1000;
|
|
3997
|
-
class ElementAnimationStyleHandler {
|
|
3998
|
-
constructor(_element, _name, _duration, _delay, _easing, _fillMode, _onDoneFn) {
|
|
3999
|
-
this._element = _element;
|
|
4000
|
-
this._name = _name;
|
|
4001
|
-
this._duration = _duration;
|
|
4002
|
-
this._delay = _delay;
|
|
4003
|
-
this._easing = _easing;
|
|
4004
|
-
this._fillMode = _fillMode;
|
|
4005
|
-
this._onDoneFn = _onDoneFn;
|
|
4006
|
-
this._finished = false;
|
|
4007
|
-
this._destroyed = false;
|
|
4008
|
-
this._startTime = 0;
|
|
4009
|
-
this._position = 0;
|
|
4010
|
-
this._eventFn = (e) => this._handleCallback(e);
|
|
4011
|
-
}
|
|
4012
|
-
apply() {
|
|
4013
|
-
applyKeyframeAnimation(this._element, `${this._duration}ms ${this._easing} ${this._delay}ms 1 normal ${this._fillMode} ${this._name}`);
|
|
4014
|
-
addRemoveAnimationEvent(this._element, this._eventFn, false);
|
|
4015
|
-
this._startTime = Date.now();
|
|
4016
|
-
}
|
|
4017
|
-
pause() {
|
|
4018
|
-
playPauseAnimation(this._element, this._name, 'paused');
|
|
4019
|
-
}
|
|
4020
|
-
resume() {
|
|
4021
|
-
playPauseAnimation(this._element, this._name, 'running');
|
|
4022
|
-
}
|
|
4023
|
-
setPosition(position) {
|
|
4024
|
-
const index = findIndexForAnimation(this._element, this._name);
|
|
4025
|
-
this._position = position * this._duration;
|
|
4026
|
-
setAnimationStyle(this._element, 'Delay', `-${this._position}ms`, index);
|
|
4027
|
-
}
|
|
4028
|
-
getPosition() {
|
|
4029
|
-
return this._position;
|
|
4030
|
-
}
|
|
4031
|
-
_handleCallback(event) {
|
|
4032
|
-
const timestamp = event._ngTestManualTimestamp || Date.now();
|
|
4033
|
-
const elapsedTime = parseFloat(event.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)) * ONE_SECOND;
|
|
4034
|
-
if (event.animationName == this._name &&
|
|
4035
|
-
Math.max(timestamp - this._startTime, 0) >= this._delay && elapsedTime >= this._duration) {
|
|
4036
|
-
this.finish();
|
|
4037
|
-
}
|
|
4038
|
-
}
|
|
4039
|
-
finish() {
|
|
4040
|
-
if (this._finished)
|
|
4041
|
-
return;
|
|
4042
|
-
this._finished = true;
|
|
4043
|
-
this._onDoneFn();
|
|
4044
|
-
addRemoveAnimationEvent(this._element, this._eventFn, true);
|
|
4045
|
-
}
|
|
4046
|
-
destroy() {
|
|
4047
|
-
if (this._destroyed)
|
|
4048
|
-
return;
|
|
4049
|
-
this._destroyed = true;
|
|
4050
|
-
this.finish();
|
|
4051
|
-
removeKeyframeAnimation(this._element, this._name);
|
|
4052
|
-
}
|
|
4053
|
-
}
|
|
4054
|
-
function playPauseAnimation(element, name, status) {
|
|
4055
|
-
const index = findIndexForAnimation(element, name);
|
|
4056
|
-
setAnimationStyle(element, 'PlayState', status, index);
|
|
4057
|
-
}
|
|
4058
|
-
function applyKeyframeAnimation(element, value) {
|
|
4059
|
-
const anim = getAnimationStyle(element, '').trim();
|
|
4060
|
-
let index = 0;
|
|
4061
|
-
if (anim.length) {
|
|
4062
|
-
index = countChars(anim, ',') + 1;
|
|
4063
|
-
value = `${anim}, ${value}`;
|
|
4064
|
-
}
|
|
4065
|
-
setAnimationStyle(element, '', value);
|
|
4066
|
-
return index;
|
|
4067
|
-
}
|
|
4068
|
-
function removeKeyframeAnimation(element, name) {
|
|
4069
|
-
const anim = getAnimationStyle(element, '');
|
|
4070
|
-
const tokens = anim.split(',');
|
|
4071
|
-
const index = findMatchingTokenIndex(tokens, name);
|
|
4072
|
-
if (index >= 0) {
|
|
4073
|
-
tokens.splice(index, 1);
|
|
4074
|
-
const newValue = tokens.join(',');
|
|
4075
|
-
setAnimationStyle(element, '', newValue);
|
|
4076
|
-
}
|
|
4077
|
-
}
|
|
4078
|
-
function findIndexForAnimation(element, value) {
|
|
4079
|
-
const anim = getAnimationStyle(element, '');
|
|
4080
|
-
if (anim.indexOf(',') > 0) {
|
|
4081
|
-
const tokens = anim.split(',');
|
|
4082
|
-
return findMatchingTokenIndex(tokens, value);
|
|
4083
|
-
}
|
|
4084
|
-
return findMatchingTokenIndex([anim], value);
|
|
4085
|
-
}
|
|
4086
|
-
function findMatchingTokenIndex(tokens, searchToken) {
|
|
4087
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
4088
|
-
if (tokens[i].indexOf(searchToken) >= 0) {
|
|
4089
|
-
return i;
|
|
4090
|
-
}
|
|
4091
|
-
}
|
|
4092
|
-
return -1;
|
|
4093
|
-
}
|
|
4094
|
-
function addRemoveAnimationEvent(element, fn, doRemove) {
|
|
4095
|
-
doRemove ? element.removeEventListener(ANIMATIONEND_EVENT, fn) :
|
|
4096
|
-
element.addEventListener(ANIMATIONEND_EVENT, fn);
|
|
4097
|
-
}
|
|
4098
|
-
function setAnimationStyle(element, name, value, index) {
|
|
4099
|
-
const prop = ANIMATION_PROP + name;
|
|
4100
|
-
if (index != null) {
|
|
4101
|
-
const oldValue = element.style[prop];
|
|
4102
|
-
if (oldValue.length) {
|
|
4103
|
-
const tokens = oldValue.split(',');
|
|
4104
|
-
tokens[index] = value;
|
|
4105
|
-
value = tokens.join(',');
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
element.style[prop] = value;
|
|
4109
|
-
}
|
|
4110
|
-
function getAnimationStyle(element, name) {
|
|
4111
|
-
return element.style[ANIMATION_PROP + name] || '';
|
|
4112
|
-
}
|
|
4113
|
-
function countChars(value, char) {
|
|
4114
|
-
let count = 0;
|
|
4115
|
-
for (let i = 0; i < value.length; i++) {
|
|
4116
|
-
const c = value.charAt(i);
|
|
4117
|
-
if (c === char)
|
|
4118
|
-
count++;
|
|
4119
|
-
}
|
|
4120
|
-
return count;
|
|
4121
|
-
}
|
|
4122
|
-
|
|
4123
|
-
const DEFAULT_FILL_MODE = 'forwards';
|
|
4124
|
-
const DEFAULT_EASING = 'linear';
|
|
4125
|
-
class CssKeyframesPlayer {
|
|
4126
|
-
constructor(element, keyframes, animationName, _duration, _delay, easing, _finalStyles, _specialStyles) {
|
|
4127
|
-
this.element = element;
|
|
4128
|
-
this.keyframes = keyframes;
|
|
4129
|
-
this.animationName = animationName;
|
|
4130
|
-
this._duration = _duration;
|
|
4131
|
-
this._delay = _delay;
|
|
4132
|
-
this._finalStyles = _finalStyles;
|
|
4133
|
-
this._specialStyles = _specialStyles;
|
|
4134
|
-
this._onDoneFns = [];
|
|
4135
|
-
this._onStartFns = [];
|
|
4136
|
-
this._onDestroyFns = [];
|
|
4137
|
-
this.currentSnapshot = {};
|
|
4138
|
-
this._state = 0;
|
|
4139
|
-
this.easing = easing || DEFAULT_EASING;
|
|
4140
|
-
this.totalTime = _duration + _delay;
|
|
4141
|
-
this._buildStyler();
|
|
4142
|
-
}
|
|
4143
|
-
onStart(fn) {
|
|
4144
|
-
this._onStartFns.push(fn);
|
|
4145
|
-
}
|
|
4146
|
-
onDone(fn) {
|
|
4147
|
-
this._onDoneFns.push(fn);
|
|
4148
|
-
}
|
|
4149
|
-
onDestroy(fn) {
|
|
4150
|
-
this._onDestroyFns.push(fn);
|
|
4151
|
-
}
|
|
4152
|
-
destroy() {
|
|
4153
|
-
this.init();
|
|
4154
|
-
if (this._state >= 4 /* DESTROYED */)
|
|
4155
|
-
return;
|
|
4156
|
-
this._state = 4 /* DESTROYED */;
|
|
4157
|
-
this._styler.destroy();
|
|
4158
|
-
this._flushStartFns();
|
|
4159
|
-
this._flushDoneFns();
|
|
4160
|
-
if (this._specialStyles) {
|
|
4161
|
-
this._specialStyles.destroy();
|
|
4162
|
-
}
|
|
4163
|
-
this._onDestroyFns.forEach(fn => fn());
|
|
4164
|
-
this._onDestroyFns = [];
|
|
4165
|
-
}
|
|
4166
|
-
_flushDoneFns() {
|
|
4167
|
-
this._onDoneFns.forEach(fn => fn());
|
|
4168
|
-
this._onDoneFns = [];
|
|
4169
|
-
}
|
|
4170
|
-
_flushStartFns() {
|
|
4171
|
-
this._onStartFns.forEach(fn => fn());
|
|
4172
|
-
this._onStartFns = [];
|
|
4173
|
-
}
|
|
4174
|
-
finish() {
|
|
4175
|
-
this.init();
|
|
4176
|
-
if (this._state >= 3 /* FINISHED */)
|
|
4177
|
-
return;
|
|
4178
|
-
this._state = 3 /* FINISHED */;
|
|
4179
|
-
this._styler.finish();
|
|
4180
|
-
this._flushStartFns();
|
|
4181
|
-
if (this._specialStyles) {
|
|
4182
|
-
this._specialStyles.finish();
|
|
4183
|
-
}
|
|
4184
|
-
this._flushDoneFns();
|
|
4185
|
-
}
|
|
4186
|
-
setPosition(value) {
|
|
4187
|
-
this._styler.setPosition(value);
|
|
4188
|
-
}
|
|
4189
|
-
getPosition() {
|
|
4190
|
-
return this._styler.getPosition();
|
|
4191
|
-
}
|
|
4192
|
-
hasStarted() {
|
|
4193
|
-
return this._state >= 2 /* STARTED */;
|
|
4194
|
-
}
|
|
4195
|
-
init() {
|
|
4196
|
-
if (this._state >= 1 /* INITIALIZED */)
|
|
4197
|
-
return;
|
|
4198
|
-
this._state = 1 /* INITIALIZED */;
|
|
4199
|
-
const elm = this.element;
|
|
4200
|
-
this._styler.apply();
|
|
4201
|
-
if (this._delay) {
|
|
4202
|
-
this._styler.pause();
|
|
4203
|
-
}
|
|
4204
|
-
}
|
|
4205
|
-
play() {
|
|
4206
|
-
this.init();
|
|
4207
|
-
if (!this.hasStarted()) {
|
|
4208
|
-
this._flushStartFns();
|
|
4209
|
-
this._state = 2 /* STARTED */;
|
|
4210
|
-
if (this._specialStyles) {
|
|
4211
|
-
this._specialStyles.start();
|
|
4212
|
-
}
|
|
4213
|
-
}
|
|
4214
|
-
this._styler.resume();
|
|
4215
|
-
}
|
|
4216
|
-
pause() {
|
|
4217
|
-
this.init();
|
|
4218
|
-
this._styler.pause();
|
|
4219
|
-
}
|
|
4220
|
-
restart() {
|
|
4221
|
-
this.reset();
|
|
4222
|
-
this.play();
|
|
4223
|
-
}
|
|
4224
|
-
reset() {
|
|
4225
|
-
this._state = 0 /* RESET */;
|
|
4226
|
-
this._styler.destroy();
|
|
4227
|
-
this._buildStyler();
|
|
4228
|
-
this._styler.apply();
|
|
4229
|
-
}
|
|
4230
|
-
_buildStyler() {
|
|
4231
|
-
this._styler = new ElementAnimationStyleHandler(this.element, this.animationName, this._duration, this._delay, this.easing, DEFAULT_FILL_MODE, () => this.finish());
|
|
4232
|
-
}
|
|
4233
|
-
/** @internal */
|
|
4234
|
-
triggerCallback(phaseName) {
|
|
4235
|
-
const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
|
|
4236
|
-
methods.forEach(fn => fn());
|
|
4237
|
-
methods.length = 0;
|
|
4238
|
-
}
|
|
4239
|
-
beforeDestroy() {
|
|
4240
|
-
this.init();
|
|
4241
|
-
const styles = {};
|
|
4242
|
-
if (this.hasStarted()) {
|
|
4243
|
-
const finished = this._state >= 3 /* FINISHED */;
|
|
4244
|
-
Object.keys(this._finalStyles).forEach(prop => {
|
|
4245
|
-
if (prop != 'offset') {
|
|
4246
|
-
styles[prop] = finished ? this._finalStyles[prop] : computeStyle(this.element, prop);
|
|
4247
|
-
}
|
|
4248
|
-
});
|
|
4249
|
-
}
|
|
4250
|
-
this.currentSnapshot = styles;
|
|
4251
|
-
}
|
|
4252
|
-
}
|
|
4253
|
-
|
|
4254
|
-
/**
|
|
4255
|
-
* @license
|
|
4256
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4257
|
-
*
|
|
4258
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
4259
|
-
* found in the LICENSE file at https://angular.io/license
|
|
4260
|
-
*/
|
|
4261
|
-
class DirectStylePlayer extends NoopAnimationPlayer {
|
|
4262
|
-
constructor(element, styles) {
|
|
4263
|
-
super();
|
|
4264
|
-
this.element = element;
|
|
4265
|
-
this._startingStyles = {};
|
|
4266
|
-
this.__initialized = false;
|
|
4267
|
-
this._styles = hypenatePropsObject(styles);
|
|
4268
|
-
}
|
|
4269
|
-
init() {
|
|
4270
|
-
if (this.__initialized || !this._startingStyles)
|
|
4271
|
-
return;
|
|
4272
|
-
this.__initialized = true;
|
|
4273
|
-
Object.keys(this._styles).forEach(prop => {
|
|
4274
|
-
this._startingStyles[prop] = this.element.style[prop];
|
|
4275
|
-
});
|
|
4276
|
-
super.init();
|
|
4277
|
-
}
|
|
4278
|
-
play() {
|
|
4279
|
-
if (!this._startingStyles)
|
|
4280
|
-
return;
|
|
4281
|
-
this.init();
|
|
4282
|
-
Object.keys(this._styles)
|
|
4283
|
-
.forEach(prop => this.element.style.setProperty(prop, this._styles[prop]));
|
|
4284
|
-
super.play();
|
|
4285
|
-
}
|
|
4286
|
-
destroy() {
|
|
4287
|
-
if (!this._startingStyles)
|
|
4288
|
-
return;
|
|
4289
|
-
Object.keys(this._startingStyles).forEach(prop => {
|
|
4290
|
-
const value = this._startingStyles[prop];
|
|
4291
|
-
if (value) {
|
|
4292
|
-
this.element.style.setProperty(prop, value);
|
|
4293
|
-
}
|
|
4294
|
-
else {
|
|
4295
|
-
this.element.style.removeProperty(prop);
|
|
4296
|
-
}
|
|
4297
|
-
});
|
|
4298
|
-
this._startingStyles = null;
|
|
4299
|
-
super.destroy();
|
|
4300
|
-
}
|
|
4301
|
-
}
|
|
4302
|
-
|
|
4303
|
-
const KEYFRAMES_NAME_PREFIX = 'gen_css_kf_';
|
|
4304
|
-
const TAB_SPACE = ' ';
|
|
4305
|
-
class CssKeyframesDriver {
|
|
4306
|
-
constructor() {
|
|
4307
|
-
this._count = 0;
|
|
4308
|
-
}
|
|
4309
|
-
validateStyleProperty(prop) {
|
|
4310
|
-
return validateStyleProperty(prop);
|
|
4311
|
-
}
|
|
4312
|
-
matchesElement(_element, _selector) {
|
|
4313
|
-
// This method is deprecated and no longer in use so we return false.
|
|
4314
|
-
return false;
|
|
4315
|
-
}
|
|
4316
|
-
containsElement(elm1, elm2) {
|
|
4317
|
-
return containsElement(elm1, elm2);
|
|
4318
|
-
}
|
|
4319
|
-
query(element, selector, multi) {
|
|
4320
|
-
return invokeQuery(element, selector, multi);
|
|
4321
|
-
}
|
|
4322
|
-
computeStyle(element, prop, defaultValue) {
|
|
4323
|
-
return window.getComputedStyle(element)[prop];
|
|
4324
|
-
}
|
|
4325
|
-
buildKeyframeElement(element, name, keyframes) {
|
|
4326
|
-
keyframes = keyframes.map(kf => hypenatePropsObject(kf));
|
|
4327
|
-
let keyframeStr = `@keyframes ${name} {\n`;
|
|
4328
|
-
let tab = '';
|
|
4329
|
-
keyframes.forEach(kf => {
|
|
4330
|
-
tab = TAB_SPACE;
|
|
4331
|
-
const offset = parseFloat(kf['offset']);
|
|
4332
|
-
keyframeStr += `${tab}${offset * 100}% {\n`;
|
|
4333
|
-
tab += TAB_SPACE;
|
|
4334
|
-
Object.keys(kf).forEach(prop => {
|
|
4335
|
-
const value = kf[prop];
|
|
4336
|
-
switch (prop) {
|
|
4337
|
-
case 'offset':
|
|
4338
|
-
return;
|
|
4339
|
-
case 'easing':
|
|
4340
|
-
if (value) {
|
|
4341
|
-
keyframeStr += `${tab}animation-timing-function: ${value};\n`;
|
|
4342
|
-
}
|
|
4343
|
-
return;
|
|
4344
|
-
default:
|
|
4345
|
-
keyframeStr += `${tab}${prop}: ${value};\n`;
|
|
4346
|
-
return;
|
|
4347
|
-
}
|
|
4348
|
-
});
|
|
4349
|
-
keyframeStr += `${tab}}\n`;
|
|
4350
|
-
});
|
|
4351
|
-
keyframeStr += `}\n`;
|
|
4352
|
-
const kfElm = document.createElement('style');
|
|
4353
|
-
kfElm.textContent = keyframeStr;
|
|
4354
|
-
return kfElm;
|
|
4355
|
-
}
|
|
4356
|
-
animate(element, keyframes, duration, delay, easing, previousPlayers = [], scrubberAccessRequested) {
|
|
4357
|
-
if ((typeof ngDevMode === 'undefined' || ngDevMode) && scrubberAccessRequested) {
|
|
4358
|
-
notifyFaultyScrubber();
|
|
4359
|
-
}
|
|
4360
|
-
const previousCssKeyframePlayers = previousPlayers.filter(player => player instanceof CssKeyframesPlayer);
|
|
4361
|
-
const previousStyles = {};
|
|
4362
|
-
if (allowPreviousPlayerStylesMerge(duration, delay)) {
|
|
4363
|
-
previousCssKeyframePlayers.forEach(player => {
|
|
4364
|
-
let styles = player.currentSnapshot;
|
|
4365
|
-
Object.keys(styles).forEach(prop => previousStyles[prop] = styles[prop]);
|
|
4366
|
-
});
|
|
4367
|
-
}
|
|
4368
|
-
keyframes = balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles);
|
|
4369
|
-
const finalStyles = flattenKeyframesIntoStyles(keyframes);
|
|
4370
|
-
// if there is no animation then there is no point in applying
|
|
4371
|
-
// styles and waiting for an event to get fired. This causes lag.
|
|
4372
|
-
// It's better to just directly apply the styles to the element
|
|
4373
|
-
// via the direct styling animation player.
|
|
4374
|
-
if (duration == 0) {
|
|
4375
|
-
return new DirectStylePlayer(element, finalStyles);
|
|
4376
|
-
}
|
|
4377
|
-
const animationName = `${KEYFRAMES_NAME_PREFIX}${this._count++}`;
|
|
4378
|
-
const kfElm = this.buildKeyframeElement(element, animationName, keyframes);
|
|
4379
|
-
const nodeToAppendKfElm = findNodeToAppendKeyframeElement(element);
|
|
4380
|
-
nodeToAppendKfElm.appendChild(kfElm);
|
|
4381
|
-
const specialStyles = packageNonAnimatableStyles(element, keyframes);
|
|
4382
|
-
const player = new CssKeyframesPlayer(element, keyframes, animationName, duration, delay, easing, finalStyles, specialStyles);
|
|
4383
|
-
player.onDestroy(() => removeElement(kfElm));
|
|
4384
|
-
return player;
|
|
4385
|
-
}
|
|
4386
|
-
}
|
|
4387
|
-
function findNodeToAppendKeyframeElement(element) {
|
|
4388
|
-
const rootNode = element.getRootNode?.();
|
|
4389
|
-
if (typeof ShadowRoot !== 'undefined' && rootNode instanceof ShadowRoot) {
|
|
4390
|
-
return rootNode;
|
|
4391
|
-
}
|
|
4392
|
-
return document.head;
|
|
4393
|
-
}
|
|
4394
|
-
function flattenKeyframesIntoStyles(keyframes) {
|
|
4395
|
-
let flatKeyframes = {};
|
|
4396
|
-
if (keyframes) {
|
|
4397
|
-
const kfs = Array.isArray(keyframes) ? keyframes : [keyframes];
|
|
4398
|
-
kfs.forEach(kf => {
|
|
4399
|
-
Object.keys(kf).forEach(prop => {
|
|
4400
|
-
if (prop == 'offset' || prop == 'easing')
|
|
4401
|
-
return;
|
|
4402
|
-
flatKeyframes[prop] = kf[prop];
|
|
4403
|
-
});
|
|
4404
|
-
});
|
|
4405
|
-
}
|
|
4406
|
-
return flatKeyframes;
|
|
4407
|
-
}
|
|
4408
|
-
function removeElement(node) {
|
|
4409
|
-
node.parentNode.removeChild(node);
|
|
4410
|
-
}
|
|
4411
|
-
let warningIssued = false;
|
|
4412
|
-
function notifyFaultyScrubber() {
|
|
4413
|
-
if (warningIssued)
|
|
4414
|
-
return;
|
|
4415
|
-
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.');
|
|
4416
|
-
warningIssued = true;
|
|
4417
|
-
}
|
|
4418
|
-
|
|
4419
3974
|
class WebAnimationsPlayer {
|
|
4420
3975
|
constructor(element, keyframes, options, _specialStyles) {
|
|
4421
3976
|
this.element = element;
|
|
@@ -4431,7 +3986,7 @@ class WebAnimationsPlayer {
|
|
|
4431
3986
|
this._destroyed = false;
|
|
4432
3987
|
this.time = 0;
|
|
4433
3988
|
this.parentPlayer = null;
|
|
4434
|
-
this.currentSnapshot =
|
|
3989
|
+
this.currentSnapshot = new Map();
|
|
4435
3990
|
this._duration = options['duration'];
|
|
4436
3991
|
this._delay = options['delay'] || 0;
|
|
4437
3992
|
this.time = this._duration + this._delay;
|
|
@@ -4454,7 +4009,7 @@ class WebAnimationsPlayer {
|
|
|
4454
4009
|
const keyframes = this.keyframes;
|
|
4455
4010
|
this.domPlayer =
|
|
4456
4011
|
this._triggerWebAnimation(this.element, keyframes, this.options);
|
|
4457
|
-
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] :
|
|
4012
|
+
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();
|
|
4458
4013
|
this.domPlayer.addEventListener('finish', () => this._onFinish());
|
|
4459
4014
|
}
|
|
4460
4015
|
_preparePlayerBeforeStart() {
|
|
@@ -4466,11 +4021,18 @@ class WebAnimationsPlayer {
|
|
|
4466
4021
|
this.domPlayer.pause();
|
|
4467
4022
|
}
|
|
4468
4023
|
}
|
|
4024
|
+
_convertKeyframesToObject(keyframes) {
|
|
4025
|
+
const kfs = [];
|
|
4026
|
+
keyframes.forEach(frame => {
|
|
4027
|
+
kfs.push(Object.fromEntries(frame));
|
|
4028
|
+
});
|
|
4029
|
+
return kfs;
|
|
4030
|
+
}
|
|
4469
4031
|
/** @internal */
|
|
4470
4032
|
_triggerWebAnimation(element, keyframes, options) {
|
|
4471
4033
|
// jscompiler doesn't seem to know animate is a native property because it's not fully
|
|
4472
4034
|
// supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
|
|
4473
|
-
return element['animate'](keyframes, options);
|
|
4035
|
+
return element['animate'](this._convertKeyframesToObject(keyframes), options);
|
|
4474
4036
|
}
|
|
4475
4037
|
onStart(fn) {
|
|
4476
4038
|
this._onStartFns.push(fn);
|
|
@@ -4548,15 +4110,15 @@ class WebAnimationsPlayer {
|
|
|
4548
4110
|
return this._delay + this._duration;
|
|
4549
4111
|
}
|
|
4550
4112
|
beforeDestroy() {
|
|
4551
|
-
const styles =
|
|
4113
|
+
const styles = new Map();
|
|
4552
4114
|
if (this.hasStarted()) {
|
|
4553
4115
|
// note: this code is invoked only when the `play` function was called prior to this
|
|
4554
4116
|
// (thus `hasStarted` returns true), this implies that the code that initializes
|
|
4555
4117
|
// `_finalKeyframe` has also been executed and the non-null assertion can be safely used here
|
|
4556
4118
|
const finalKeyframe = this._finalKeyframe;
|
|
4557
|
-
|
|
4558
|
-
if (prop
|
|
4559
|
-
styles
|
|
4119
|
+
finalKeyframe.forEach((val, prop) => {
|
|
4120
|
+
if (prop !== 'offset') {
|
|
4121
|
+
styles.set(prop, this._finished ? val : computeStyle(this.element, prop));
|
|
4560
4122
|
}
|
|
4561
4123
|
});
|
|
4562
4124
|
}
|
|
@@ -4564,17 +4126,13 @@ class WebAnimationsPlayer {
|
|
|
4564
4126
|
}
|
|
4565
4127
|
/** @internal */
|
|
4566
4128
|
triggerCallback(phaseName) {
|
|
4567
|
-
const methods = phaseName
|
|
4129
|
+
const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;
|
|
4568
4130
|
methods.forEach(fn => fn());
|
|
4569
4131
|
methods.length = 0;
|
|
4570
4132
|
}
|
|
4571
4133
|
}
|
|
4572
4134
|
|
|
4573
4135
|
class WebAnimationsDriver {
|
|
4574
|
-
constructor() {
|
|
4575
|
-
this._isNativeImpl = /\{\s*\[native\s+code\]\s*\}/.test(getElementAnimateFn().toString());
|
|
4576
|
-
this._cssKeyframesDriver = new CssKeyframesDriver();
|
|
4577
|
-
}
|
|
4578
4136
|
validateStyleProperty(prop) {
|
|
4579
4137
|
return validateStyleProperty(prop);
|
|
4580
4138
|
}
|
|
@@ -4591,14 +4149,7 @@ class WebAnimationsDriver {
|
|
|
4591
4149
|
computeStyle(element, prop, defaultValue) {
|
|
4592
4150
|
return window.getComputedStyle(element)[prop];
|
|
4593
4151
|
}
|
|
4594
|
-
|
|
4595
|
-
this._isNativeImpl = supported;
|
|
4596
|
-
}
|
|
4597
|
-
animate(element, keyframes, duration, delay, easing, previousPlayers = [], scrubberAccessRequested) {
|
|
4598
|
-
const useKeyframes = !scrubberAccessRequested && !this._isNativeImpl;
|
|
4599
|
-
if (useKeyframes) {
|
|
4600
|
-
return this._cssKeyframesDriver.animate(element, keyframes, duration, delay, easing, previousPlayers);
|
|
4601
|
-
}
|
|
4152
|
+
animate(element, keyframes, duration, delay, easing, previousPlayers = []) {
|
|
4602
4153
|
const fill = delay == 0 ? 'both' : 'forwards';
|
|
4603
4154
|
const playerOptions = { duration, delay, fill };
|
|
4604
4155
|
// we check for this to avoid having a null|undefined value be present
|
|
@@ -4606,26 +4157,19 @@ class WebAnimationsDriver {
|
|
|
4606
4157
|
if (easing) {
|
|
4607
4158
|
playerOptions['easing'] = easing;
|
|
4608
4159
|
}
|
|
4609
|
-
const previousStyles =
|
|
4160
|
+
const previousStyles = new Map();
|
|
4610
4161
|
const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);
|
|
4611
4162
|
if (allowPreviousPlayerStylesMerge(duration, delay)) {
|
|
4612
4163
|
previousWebAnimationPlayers.forEach(player => {
|
|
4613
|
-
|
|
4614
|
-
Object.keys(styles).forEach(prop => previousStyles[prop] = styles[prop]);
|
|
4164
|
+
player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));
|
|
4615
4165
|
});
|
|
4616
4166
|
}
|
|
4617
|
-
|
|
4618
|
-
|
|
4619
|
-
const specialStyles = packageNonAnimatableStyles(element,
|
|
4620
|
-
return new WebAnimationsPlayer(element,
|
|
4167
|
+
let _keyframes = normalizeKeyframes(keyframes).map(styles => copyStyles(styles));
|
|
4168
|
+
_keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);
|
|
4169
|
+
const specialStyles = packageNonAnimatableStyles(element, _keyframes);
|
|
4170
|
+
return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);
|
|
4621
4171
|
}
|
|
4622
4172
|
}
|
|
4623
|
-
function supportsWebAnimations() {
|
|
4624
|
-
return typeof getElementAnimateFn() === 'function';
|
|
4625
|
-
}
|
|
4626
|
-
function getElementAnimateFn() {
|
|
4627
|
-
return (isBrowser() && Element.prototype['animate']) || {};
|
|
4628
|
-
}
|
|
4629
4173
|
|
|
4630
4174
|
/**
|
|
4631
4175
|
* @license
|
|
@@ -4663,5 +4207,5 @@ function getElementAnimateFn() {
|
|
|
4663
4207
|
* Generated bundle index. Do not edit.
|
|
4664
4208
|
*/
|
|
4665
4209
|
|
|
4666
|
-
export { AnimationDriver, Animation as ɵAnimation, AnimationEngine as ɵAnimationEngine, AnimationStyleNormalizer as ɵAnimationStyleNormalizer,
|
|
4210
|
+
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, normalizeKeyframes as ɵnormalizeKeyframes, validateStyleProperty as ɵvalidateStyleProperty };
|
|
4667
4211
|
//# sourceMappingURL=browser.mjs.map
|