@angular/animations 13.3.0 → 14.0.0-next.10
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 +18 -32
- 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 +57 -52
- 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 +29 -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 +2 -2
- package/esm2020/browser/src/render/animation_driver.mjs +4 -4
- package/esm2020/browser/src/render/shared.mjs +24 -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 +68 -101
- package/esm2020/browser/src/render/web_animations/animatable_props_set.mjs +214 -0
- package/esm2020/browser/src/render/web_animations/web_animations_driver.mjs +17 -10
- package/esm2020/browser/src/render/web_animations/web_animations_player.mjs +16 -9
- package/esm2020/browser/src/util.mjs +40 -30
- package/esm2020/browser/src/warning_helpers.mjs +7 -2
- package/esm2020/browser/testing/src/mock_animation_driver.mjs +20 -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 +856 -15
- package/fesm2015/browser/testing.mjs.map +1 -1
- package/fesm2015/browser.mjs +605 -371
- 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 +856 -15
- package/fesm2020/browser/testing.mjs.map +1 -1
- package/fesm2020/browser.mjs +603 -371
- package/fesm2020/browser.mjs.map +1 -1
- package/package.json +3 -3
package/fesm2020/browser.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @license Angular
|
|
2
|
+
* @license Angular v14.0.0-next.10
|
|
3
3
|
* (c) 2010-2022 Google LLC. https://angular.io/
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -142,6 +142,220 @@ function transitionFailed(name, errors) {
|
|
|
142
142
|
`@${name} has failed due to:\n ${errors.map(err => err.message).join('\n- ')}`);
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
* @license
|
|
147
|
+
* Copyright Google LLC All Rights Reserved.
|
|
148
|
+
*
|
|
149
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
150
|
+
* found in the LICENSE file at https://angular.io/license
|
|
151
|
+
*/
|
|
152
|
+
/**
|
|
153
|
+
* Set of all animatable CSS properties
|
|
154
|
+
*
|
|
155
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
|
|
156
|
+
*/
|
|
157
|
+
const ANIMATABLE_PROP_SET = new Set([
|
|
158
|
+
'-moz-outline-radius',
|
|
159
|
+
'-moz-outline-radius-bottomleft',
|
|
160
|
+
'-moz-outline-radius-bottomright',
|
|
161
|
+
'-moz-outline-radius-topleft',
|
|
162
|
+
'-moz-outline-radius-topright',
|
|
163
|
+
'-ms-grid-columns',
|
|
164
|
+
'-ms-grid-rows',
|
|
165
|
+
'-webkit-line-clamp',
|
|
166
|
+
'-webkit-text-fill-color',
|
|
167
|
+
'-webkit-text-stroke',
|
|
168
|
+
'-webkit-text-stroke-color',
|
|
169
|
+
'accent-color',
|
|
170
|
+
'all',
|
|
171
|
+
'backdrop-filter',
|
|
172
|
+
'background',
|
|
173
|
+
'background-color',
|
|
174
|
+
'background-position',
|
|
175
|
+
'background-size',
|
|
176
|
+
'block-size',
|
|
177
|
+
'border',
|
|
178
|
+
'border-block-end',
|
|
179
|
+
'border-block-end-color',
|
|
180
|
+
'border-block-end-width',
|
|
181
|
+
'border-block-start',
|
|
182
|
+
'border-block-start-color',
|
|
183
|
+
'border-block-start-width',
|
|
184
|
+
'border-bottom',
|
|
185
|
+
'border-bottom-color',
|
|
186
|
+
'border-bottom-left-radius',
|
|
187
|
+
'border-bottom-right-radius',
|
|
188
|
+
'border-bottom-width',
|
|
189
|
+
'border-color',
|
|
190
|
+
'border-end-end-radius',
|
|
191
|
+
'border-end-start-radius',
|
|
192
|
+
'border-image-outset',
|
|
193
|
+
'border-image-slice',
|
|
194
|
+
'border-image-width',
|
|
195
|
+
'border-inline-end',
|
|
196
|
+
'border-inline-end-color',
|
|
197
|
+
'border-inline-end-width',
|
|
198
|
+
'border-inline-start',
|
|
199
|
+
'border-inline-start-color',
|
|
200
|
+
'border-inline-start-width',
|
|
201
|
+
'border-left',
|
|
202
|
+
'border-left-color',
|
|
203
|
+
'border-left-width',
|
|
204
|
+
'border-radius',
|
|
205
|
+
'border-right',
|
|
206
|
+
'border-right-color',
|
|
207
|
+
'border-right-width',
|
|
208
|
+
'border-start-end-radius',
|
|
209
|
+
'border-start-start-radius',
|
|
210
|
+
'border-top',
|
|
211
|
+
'border-top-color',
|
|
212
|
+
'border-top-left-radius',
|
|
213
|
+
'border-top-right-radius',
|
|
214
|
+
'border-top-width',
|
|
215
|
+
'border-width',
|
|
216
|
+
'bottom',
|
|
217
|
+
'box-shadow',
|
|
218
|
+
'caret-color',
|
|
219
|
+
'clip',
|
|
220
|
+
'clip-path',
|
|
221
|
+
'color',
|
|
222
|
+
'column-count',
|
|
223
|
+
'column-gap',
|
|
224
|
+
'column-rule',
|
|
225
|
+
'column-rule-color',
|
|
226
|
+
'column-rule-width',
|
|
227
|
+
'column-width',
|
|
228
|
+
'columns',
|
|
229
|
+
'filter',
|
|
230
|
+
'flex',
|
|
231
|
+
'flex-basis',
|
|
232
|
+
'flex-grow',
|
|
233
|
+
'flex-shrink',
|
|
234
|
+
'font',
|
|
235
|
+
'font-size',
|
|
236
|
+
'font-size-adjust',
|
|
237
|
+
'font-stretch',
|
|
238
|
+
'font-variation-settings',
|
|
239
|
+
'font-weight',
|
|
240
|
+
'gap',
|
|
241
|
+
'grid-column-gap',
|
|
242
|
+
'grid-gap',
|
|
243
|
+
'grid-row-gap',
|
|
244
|
+
'grid-template-columns',
|
|
245
|
+
'grid-template-rows',
|
|
246
|
+
'height',
|
|
247
|
+
'inline-size',
|
|
248
|
+
'input-security',
|
|
249
|
+
'inset',
|
|
250
|
+
'inset-block',
|
|
251
|
+
'inset-block-end',
|
|
252
|
+
'inset-block-start',
|
|
253
|
+
'inset-inline',
|
|
254
|
+
'inset-inline-end',
|
|
255
|
+
'inset-inline-start',
|
|
256
|
+
'left',
|
|
257
|
+
'letter-spacing',
|
|
258
|
+
'line-clamp',
|
|
259
|
+
'line-height',
|
|
260
|
+
'margin',
|
|
261
|
+
'margin-block-end',
|
|
262
|
+
'margin-block-start',
|
|
263
|
+
'margin-bottom',
|
|
264
|
+
'margin-inline-end',
|
|
265
|
+
'margin-inline-start',
|
|
266
|
+
'margin-left',
|
|
267
|
+
'margin-right',
|
|
268
|
+
'margin-top',
|
|
269
|
+
'mask',
|
|
270
|
+
'mask-border',
|
|
271
|
+
'mask-position',
|
|
272
|
+
'mask-size',
|
|
273
|
+
'max-block-size',
|
|
274
|
+
'max-height',
|
|
275
|
+
'max-inline-size',
|
|
276
|
+
'max-lines',
|
|
277
|
+
'max-width',
|
|
278
|
+
'min-block-size',
|
|
279
|
+
'min-height',
|
|
280
|
+
'min-inline-size',
|
|
281
|
+
'min-width',
|
|
282
|
+
'object-position',
|
|
283
|
+
'offset',
|
|
284
|
+
'offset-anchor',
|
|
285
|
+
'offset-distance',
|
|
286
|
+
'offset-path',
|
|
287
|
+
'offset-position',
|
|
288
|
+
'offset-rotate',
|
|
289
|
+
'opacity',
|
|
290
|
+
'order',
|
|
291
|
+
'outline',
|
|
292
|
+
'outline-color',
|
|
293
|
+
'outline-offset',
|
|
294
|
+
'outline-width',
|
|
295
|
+
'padding',
|
|
296
|
+
'padding-block-end',
|
|
297
|
+
'padding-block-start',
|
|
298
|
+
'padding-bottom',
|
|
299
|
+
'padding-inline-end',
|
|
300
|
+
'padding-inline-start',
|
|
301
|
+
'padding-left',
|
|
302
|
+
'padding-right',
|
|
303
|
+
'padding-top',
|
|
304
|
+
'perspective',
|
|
305
|
+
'perspective-origin',
|
|
306
|
+
'right',
|
|
307
|
+
'rotate',
|
|
308
|
+
'row-gap',
|
|
309
|
+
'scale',
|
|
310
|
+
'scroll-margin',
|
|
311
|
+
'scroll-margin-block',
|
|
312
|
+
'scroll-margin-block-end',
|
|
313
|
+
'scroll-margin-block-start',
|
|
314
|
+
'scroll-margin-bottom',
|
|
315
|
+
'scroll-margin-inline',
|
|
316
|
+
'scroll-margin-inline-end',
|
|
317
|
+
'scroll-margin-inline-start',
|
|
318
|
+
'scroll-margin-left',
|
|
319
|
+
'scroll-margin-right',
|
|
320
|
+
'scroll-margin-top',
|
|
321
|
+
'scroll-padding',
|
|
322
|
+
'scroll-padding-block',
|
|
323
|
+
'scroll-padding-block-end',
|
|
324
|
+
'scroll-padding-block-start',
|
|
325
|
+
'scroll-padding-bottom',
|
|
326
|
+
'scroll-padding-inline',
|
|
327
|
+
'scroll-padding-inline-end',
|
|
328
|
+
'scroll-padding-inline-start',
|
|
329
|
+
'scroll-padding-left',
|
|
330
|
+
'scroll-padding-right',
|
|
331
|
+
'scroll-padding-top',
|
|
332
|
+
'scroll-snap-coordinate',
|
|
333
|
+
'scroll-snap-destination',
|
|
334
|
+
'scrollbar-color',
|
|
335
|
+
'shape-image-threshold',
|
|
336
|
+
'shape-margin',
|
|
337
|
+
'shape-outside',
|
|
338
|
+
'tab-size',
|
|
339
|
+
'text-decoration',
|
|
340
|
+
'text-decoration-color',
|
|
341
|
+
'text-decoration-thickness',
|
|
342
|
+
'text-emphasis',
|
|
343
|
+
'text-emphasis-color',
|
|
344
|
+
'text-indent',
|
|
345
|
+
'text-shadow',
|
|
346
|
+
'text-underline-offset',
|
|
347
|
+
'top',
|
|
348
|
+
'transform',
|
|
349
|
+
'transform-origin',
|
|
350
|
+
'translate',
|
|
351
|
+
'vertical-align',
|
|
352
|
+
'visibility',
|
|
353
|
+
'width',
|
|
354
|
+
'word-spacing',
|
|
355
|
+
'z-index',
|
|
356
|
+
'zoom',
|
|
357
|
+
]);
|
|
358
|
+
|
|
145
359
|
/**
|
|
146
360
|
* @license
|
|
147
361
|
* Copyright Google LLC All Rights Reserved.
|
|
@@ -170,26 +384,26 @@ function optimizeGroupPlayer(players) {
|
|
|
170
384
|
return new ɵAnimationGroupPlayer(players);
|
|
171
385
|
}
|
|
172
386
|
}
|
|
173
|
-
function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
|
|
387
|
+
function normalizeKeyframes$1(driver, normalizer, element, keyframes, preStyles = new Map(), postStyles = new Map()) {
|
|
174
388
|
const errors = [];
|
|
175
389
|
const normalizedKeyframes = [];
|
|
176
390
|
let previousOffset = -1;
|
|
177
391
|
let previousKeyframe = null;
|
|
178
392
|
keyframes.forEach(kf => {
|
|
179
|
-
const offset = kf
|
|
393
|
+
const offset = kf.get('offset');
|
|
180
394
|
const isSameOffset = offset == previousOffset;
|
|
181
|
-
const normalizedKeyframe = (isSameOffset && previousKeyframe) ||
|
|
182
|
-
|
|
395
|
+
const normalizedKeyframe = (isSameOffset && previousKeyframe) || new Map();
|
|
396
|
+
kf.forEach((val, prop) => {
|
|
183
397
|
let normalizedProp = prop;
|
|
184
|
-
let normalizedValue =
|
|
398
|
+
let normalizedValue = val;
|
|
185
399
|
if (prop !== 'offset') {
|
|
186
400
|
normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
|
|
187
401
|
switch (normalizedValue) {
|
|
188
402
|
case ɵPRE_STYLE:
|
|
189
|
-
normalizedValue = preStyles
|
|
403
|
+
normalizedValue = preStyles.get(prop);
|
|
190
404
|
break;
|
|
191
405
|
case AUTO_STYLE:
|
|
192
|
-
normalizedValue = postStyles
|
|
406
|
+
normalizedValue = postStyles.get(prop);
|
|
193
407
|
break;
|
|
194
408
|
default:
|
|
195
409
|
normalizedValue =
|
|
@@ -197,7 +411,7 @@ function normalizeKeyframes(driver, normalizer, element, keyframes, preStyles =
|
|
|
197
411
|
break;
|
|
198
412
|
}
|
|
199
413
|
}
|
|
200
|
-
normalizedKeyframe
|
|
414
|
+
normalizedKeyframe.set(normalizedProp, normalizedValue);
|
|
201
415
|
});
|
|
202
416
|
if (!isSameOffset) {
|
|
203
417
|
normalizedKeyframes.push(normalizedKeyframe);
|
|
@@ -236,26 +450,17 @@ function copyAnimationEvent(e, phaseName, player) {
|
|
|
236
450
|
function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {
|
|
237
451
|
return { element, triggerName, fromState, toState, phaseName, totalTime, disabled: !!disabled };
|
|
238
452
|
}
|
|
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
|
-
}
|
|
453
|
+
function getOrSetDefaultValue(map, key, defaultValue) {
|
|
454
|
+
let value = map.get(key);
|
|
455
|
+
if (!value) {
|
|
456
|
+
map.set(key, value = defaultValue);
|
|
252
457
|
}
|
|
253
458
|
return value;
|
|
254
459
|
}
|
|
255
460
|
function parseTimelineCommand(command) {
|
|
256
461
|
const separatorPos = command.indexOf(':');
|
|
257
462
|
const id = command.substring(1, separatorPos);
|
|
258
|
-
const action = command.
|
|
463
|
+
const action = command.slice(separatorPos + 1);
|
|
259
464
|
return [id, action];
|
|
260
465
|
}
|
|
261
466
|
let _contains = (elm1, elm2) => false;
|
|
@@ -315,12 +520,15 @@ function validateStyleProperty(prop) {
|
|
|
315
520
|
if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {
|
|
316
521
|
result = prop in _CACHED_BODY.style;
|
|
317
522
|
if (!result && _IS_WEBKIT) {
|
|
318
|
-
const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.
|
|
523
|
+
const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.slice(1);
|
|
319
524
|
result = camelProp in _CACHED_BODY.style;
|
|
320
525
|
}
|
|
321
526
|
}
|
|
322
527
|
return result;
|
|
323
528
|
}
|
|
529
|
+
function validateWebAnimatableStyleProperty(prop) {
|
|
530
|
+
return ANIMATABLE_PROP_SET.has(prop);
|
|
531
|
+
}
|
|
324
532
|
function getBodyNode() {
|
|
325
533
|
if (typeof document != 'undefined') {
|
|
326
534
|
return document.body;
|
|
@@ -329,13 +537,13 @@ function getBodyNode() {
|
|
|
329
537
|
}
|
|
330
538
|
const containsElement = _contains;
|
|
331
539
|
const invokeQuery = _query;
|
|
332
|
-
function
|
|
333
|
-
const
|
|
334
|
-
|
|
540
|
+
function hypenatePropsKeys(original) {
|
|
541
|
+
const newMap = new Map();
|
|
542
|
+
original.forEach((val, prop) => {
|
|
335
543
|
const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
|
|
336
|
-
|
|
544
|
+
newMap.set(newProp, val);
|
|
337
545
|
});
|
|
338
|
-
return
|
|
546
|
+
return newMap;
|
|
339
547
|
}
|
|
340
548
|
|
|
341
549
|
/**
|
|
@@ -372,9 +580,9 @@ class NoopAnimationDriver {
|
|
|
372
580
|
return new NoopAnimationPlayer(duration, delay);
|
|
373
581
|
}
|
|
374
582
|
}
|
|
375
|
-
NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
376
|
-
NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "
|
|
377
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
583
|
+
NoopAnimationDriver.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.0-next.10", ngImport: i0, type: NoopAnimationDriver, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
584
|
+
NoopAnimationDriver.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.0.0-next.10", ngImport: i0, type: NoopAnimationDriver });
|
|
585
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.0-next.10", ngImport: i0, type: NoopAnimationDriver, decorators: [{
|
|
378
586
|
type: Injectable
|
|
379
587
|
}] });
|
|
380
588
|
/**
|
|
@@ -468,27 +676,41 @@ function copyObj(obj, destination = {}) {
|
|
|
468
676
|
});
|
|
469
677
|
return destination;
|
|
470
678
|
}
|
|
679
|
+
function convertToMap(obj) {
|
|
680
|
+
const styleMap = new Map();
|
|
681
|
+
Object.keys(obj).forEach(prop => {
|
|
682
|
+
const val = obj[prop];
|
|
683
|
+
styleMap.set(prop, val);
|
|
684
|
+
});
|
|
685
|
+
return styleMap;
|
|
686
|
+
}
|
|
687
|
+
function normalizeKeyframes(keyframes) {
|
|
688
|
+
if (!keyframes.length) {
|
|
689
|
+
return [];
|
|
690
|
+
}
|
|
691
|
+
if (keyframes[0] instanceof Map) {
|
|
692
|
+
return keyframes;
|
|
693
|
+
}
|
|
694
|
+
return keyframes.map(kf => convertToMap(kf));
|
|
695
|
+
}
|
|
471
696
|
function normalizeStyles(styles) {
|
|
472
|
-
const normalizedStyles =
|
|
697
|
+
const normalizedStyles = new Map();
|
|
473
698
|
if (Array.isArray(styles)) {
|
|
474
|
-
styles.forEach(data => copyStyles(data,
|
|
699
|
+
styles.forEach(data => copyStyles(data, normalizedStyles));
|
|
475
700
|
}
|
|
476
701
|
else {
|
|
477
|
-
copyStyles(styles,
|
|
702
|
+
copyStyles(styles, normalizedStyles);
|
|
478
703
|
}
|
|
479
704
|
return normalizedStyles;
|
|
480
705
|
}
|
|
481
|
-
function copyStyles(styles,
|
|
482
|
-
if (
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
// revealed from the backFill map
|
|
486
|
-
for (let prop in styles) {
|
|
487
|
-
destination[prop] = styles[prop];
|
|
706
|
+
function copyStyles(styles, destination = new Map(), backfill) {
|
|
707
|
+
if (backfill) {
|
|
708
|
+
for (let [prop, val] of backfill) {
|
|
709
|
+
destination.set(prop, val);
|
|
488
710
|
}
|
|
489
711
|
}
|
|
490
|
-
|
|
491
|
-
|
|
712
|
+
for (let [prop, val] of styles) {
|
|
713
|
+
destination.set(prop, val);
|
|
492
714
|
}
|
|
493
715
|
return destination;
|
|
494
716
|
}
|
|
@@ -524,12 +746,12 @@ function writeStyleAttribute(element) {
|
|
|
524
746
|
}
|
|
525
747
|
function setStyles(element, styles, formerStyles) {
|
|
526
748
|
if (element['style']) {
|
|
527
|
-
|
|
749
|
+
styles.forEach((val, prop) => {
|
|
528
750
|
const camelProp = dashCaseToCamelCase(prop);
|
|
529
|
-
if (formerStyles && !formerStyles.
|
|
530
|
-
formerStyles
|
|
751
|
+
if (formerStyles && !formerStyles.has(prop)) {
|
|
752
|
+
formerStyles.set(prop, element.style[camelProp]);
|
|
531
753
|
}
|
|
532
|
-
element.style[camelProp] =
|
|
754
|
+
element.style[camelProp] = val;
|
|
533
755
|
});
|
|
534
756
|
// On the server set the 'style' attribute since it's not automatically reflected.
|
|
535
757
|
if (isNode()) {
|
|
@@ -539,7 +761,7 @@ function setStyles(element, styles, formerStyles) {
|
|
|
539
761
|
}
|
|
540
762
|
function eraseStyles(element, styles) {
|
|
541
763
|
if (element['style']) {
|
|
542
|
-
|
|
764
|
+
styles.forEach((_, prop) => {
|
|
543
765
|
const camelProp = dashCaseToCamelCase(prop);
|
|
544
766
|
element.style[camelProp] = '';
|
|
545
767
|
});
|
|
@@ -585,7 +807,7 @@ function interpolateParams(value, params, errors) {
|
|
|
585
807
|
const str = original.replace(PARAM_REGEX, (_, varName) => {
|
|
586
808
|
let localVal = params[varName];
|
|
587
809
|
// this means that the value was never overridden by the data passed in by the user
|
|
588
|
-
if (
|
|
810
|
+
if (localVal == null) {
|
|
589
811
|
errors.push(invalidParamValue(varName));
|
|
590
812
|
localVal = '';
|
|
591
813
|
}
|
|
@@ -614,23 +836,19 @@ function allowPreviousPlayerStylesMerge(duration, delay) {
|
|
|
614
836
|
return duration === 0 || delay === 0;
|
|
615
837
|
}
|
|
616
838
|
function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
|
|
617
|
-
|
|
618
|
-
if (previousStyleProps.length && keyframes.length) {
|
|
839
|
+
if (previousStyles.size && keyframes.length) {
|
|
619
840
|
let startingKeyframe = keyframes[0];
|
|
620
841
|
let missingStyleProps = [];
|
|
621
|
-
|
|
622
|
-
if (!startingKeyframe.
|
|
842
|
+
previousStyles.forEach((val, prop) => {
|
|
843
|
+
if (!startingKeyframe.has(prop)) {
|
|
623
844
|
missingStyleProps.push(prop);
|
|
624
845
|
}
|
|
625
|
-
startingKeyframe
|
|
846
|
+
startingKeyframe.set(prop, val);
|
|
626
847
|
});
|
|
627
848
|
if (missingStyleProps.length) {
|
|
628
|
-
|
|
629
|
-
for (var i = 1; i < keyframes.length; i++) {
|
|
849
|
+
for (let i = 1; i < keyframes.length; i++) {
|
|
630
850
|
let kf = keyframes[i];
|
|
631
|
-
missingStyleProps.forEach(
|
|
632
|
-
kf[prop] = computeStyle(element, prop);
|
|
633
|
-
});
|
|
851
|
+
missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));
|
|
634
852
|
}
|
|
635
853
|
}
|
|
636
854
|
}
|
|
@@ -701,7 +919,12 @@ function triggerParsingWarnings(name, warnings) {
|
|
|
701
919
|
}
|
|
702
920
|
function pushUnrecognizedPropertiesWarning(warnings, props) {
|
|
703
921
|
if (ngDevMode && props.length) {
|
|
704
|
-
warnings.push(`The provided
|
|
922
|
+
warnings.push(`The following provided properties are not recognized: ${props.join(', ')}`);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
function pushNonAnimatablePropertiesWarning(warnings, props) {
|
|
926
|
+
if (props.length) {
|
|
927
|
+
warnings.push(`The following provided properties are not animatable: ${props.join(', ')}\n (see: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties)`);
|
|
705
928
|
}
|
|
706
929
|
}
|
|
707
930
|
|
|
@@ -843,12 +1066,16 @@ class AnimationAstBuilderVisitor {
|
|
|
843
1066
|
if (context.unsupportedCSSPropertiesFound.size) {
|
|
844
1067
|
pushUnrecognizedPropertiesWarning(warnings, [...context.unsupportedCSSPropertiesFound.keys()]);
|
|
845
1068
|
}
|
|
1069
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
1070
|
+
context.nonAnimatableCSSPropertiesFound.size) {
|
|
1071
|
+
pushNonAnimatablePropertiesWarning(warnings, [...context.nonAnimatableCSSPropertiesFound.keys()]);
|
|
1072
|
+
}
|
|
846
1073
|
return ast;
|
|
847
1074
|
}
|
|
848
1075
|
_resetContextStyleTimingState(context) {
|
|
849
1076
|
context.currentQuerySelector = ROOT_SELECTOR;
|
|
850
|
-
context.collectedStyles =
|
|
851
|
-
context.collectedStyles
|
|
1077
|
+
context.collectedStyles = new Map();
|
|
1078
|
+
context.collectedStyles.set(ROOT_SELECTOR, new Map());
|
|
852
1079
|
context.currentTime = 0;
|
|
853
1080
|
}
|
|
854
1081
|
visitTrigger(metadata, context) {
|
|
@@ -896,11 +1123,10 @@ class AnimationAstBuilderVisitor {
|
|
|
896
1123
|
if (styleAst.containsDynamicStyles) {
|
|
897
1124
|
const missingSubs = new Set();
|
|
898
1125
|
const params = astParams || {};
|
|
899
|
-
styleAst.styles.forEach(
|
|
900
|
-
if (
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
extractStyleParams(stylesObj[prop]).forEach(sub => {
|
|
1126
|
+
styleAst.styles.forEach(style => {
|
|
1127
|
+
if (style instanceof Map) {
|
|
1128
|
+
style.forEach(value => {
|
|
1129
|
+
extractStyleParams(value).forEach(sub => {
|
|
904
1130
|
if (!params.hasOwnProperty(sub)) {
|
|
905
1131
|
missingSubs.add(sub);
|
|
906
1132
|
}
|
|
@@ -996,37 +1222,30 @@ class AnimationAstBuilderVisitor {
|
|
|
996
1222
|
}
|
|
997
1223
|
_makeStyleAst(metadata, context) {
|
|
998
1224
|
const styles = [];
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1005
|
-
else {
|
|
1006
|
-
context.errors.push(invalidStyleValue(styleTuple));
|
|
1007
|
-
}
|
|
1225
|
+
const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
|
|
1226
|
+
for (let styleTuple of metadataStyles) {
|
|
1227
|
+
if (typeof styleTuple === 'string') {
|
|
1228
|
+
if (styleTuple === AUTO_STYLE) {
|
|
1229
|
+
styles.push(styleTuple);
|
|
1008
1230
|
}
|
|
1009
1231
|
else {
|
|
1010
|
-
|
|
1232
|
+
context.errors.push(invalidStyleValue(styleTuple));
|
|
1011
1233
|
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
styles.push(convertToMap(styleTuple));
|
|
1237
|
+
}
|
|
1016
1238
|
}
|
|
1017
1239
|
let containsDynamicStyles = false;
|
|
1018
1240
|
let collectedEasing = null;
|
|
1019
1241
|
styles.forEach(styleData => {
|
|
1020
|
-
if (
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
collectedEasing = easing;
|
|
1025
|
-
delete styleMap['easing'];
|
|
1242
|
+
if (styleData instanceof Map) {
|
|
1243
|
+
if (styleData.has('easing')) {
|
|
1244
|
+
collectedEasing = styleData.get('easing');
|
|
1245
|
+
styleData.delete('easing');
|
|
1026
1246
|
}
|
|
1027
1247
|
if (!containsDynamicStyles) {
|
|
1028
|
-
for (let
|
|
1029
|
-
const value = styleMap[prop];
|
|
1248
|
+
for (let value of styleData.values()) {
|
|
1030
1249
|
if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
|
|
1031
1250
|
containsDynamicStyles = true;
|
|
1032
1251
|
break;
|
|
@@ -1052,16 +1271,27 @@ class AnimationAstBuilderVisitor {
|
|
|
1052
1271
|
startTime -= timings.duration + timings.delay;
|
|
1053
1272
|
}
|
|
1054
1273
|
ast.styles.forEach(tuple => {
|
|
1055
|
-
if (typeof tuple
|
|
1274
|
+
if (typeof tuple === 'string')
|
|
1056
1275
|
return;
|
|
1057
|
-
|
|
1276
|
+
tuple.forEach((value, prop) => {
|
|
1058
1277
|
if (!this._driver.validateStyleProperty(prop)) {
|
|
1059
|
-
delete
|
|
1278
|
+
tuple.delete(prop);
|
|
1060
1279
|
context.unsupportedCSSPropertiesFound.add(prop);
|
|
1061
1280
|
return;
|
|
1062
1281
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1282
|
+
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
|
|
1283
|
+
this._driver.validateAnimatableStyleProperty) {
|
|
1284
|
+
if (!this._driver.validateAnimatableStyleProperty(prop)) {
|
|
1285
|
+
context.nonAnimatableCSSPropertiesFound.add(prop);
|
|
1286
|
+
// note: non animatable properties are not removed for the tuple just in case they are
|
|
1287
|
+
// categorized as non animatable but can actually be animated
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
// This is guaranteed to have a defined Map at this querySelector location making it
|
|
1292
|
+
// safe to add the assertion here. It is set as a default empty map in prior methods.
|
|
1293
|
+
const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
|
|
1294
|
+
const collectedEntry = collectedStyles.get(prop);
|
|
1065
1295
|
let updateCollectedStyle = true;
|
|
1066
1296
|
if (collectedEntry) {
|
|
1067
1297
|
if (startTime != endTime && startTime >= collectedEntry.startTime &&
|
|
@@ -1075,10 +1305,10 @@ class AnimationAstBuilderVisitor {
|
|
|
1075
1305
|
startTime = collectedEntry.startTime;
|
|
1076
1306
|
}
|
|
1077
1307
|
if (updateCollectedStyle) {
|
|
1078
|
-
collectedStyles
|
|
1308
|
+
collectedStyles.set(prop, { startTime, endTime });
|
|
1079
1309
|
}
|
|
1080
1310
|
if (context.options) {
|
|
1081
|
-
validateStyleParams(
|
|
1311
|
+
validateStyleParams(value, context.options, context.errors);
|
|
1082
1312
|
}
|
|
1083
1313
|
});
|
|
1084
1314
|
});
|
|
@@ -1167,7 +1397,7 @@ class AnimationAstBuilderVisitor {
|
|
|
1167
1397
|
const [selector, includeSelf] = normalizeSelector(metadata.selector);
|
|
1168
1398
|
context.currentQuerySelector =
|
|
1169
1399
|
parentSelector.length ? (parentSelector + ' ' + selector) : selector;
|
|
1170
|
-
|
|
1400
|
+
getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
|
|
1171
1401
|
const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
|
|
1172
1402
|
context.currentQuery = null;
|
|
1173
1403
|
context.currentQuerySelector = parentSelector;
|
|
@@ -1205,7 +1435,7 @@ function normalizeSelector(selector) {
|
|
|
1205
1435
|
// Note: the :enter and :leave aren't normalized here since those
|
|
1206
1436
|
// selectors are filled in at runtime during timeline building
|
|
1207
1437
|
selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR)
|
|
1208
|
-
.replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.
|
|
1438
|
+
.replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.slice(1))
|
|
1209
1439
|
.replace(/:animating/g, NG_ANIMATING_SELECTOR);
|
|
1210
1440
|
return [selector, hasAmpersand];
|
|
1211
1441
|
}
|
|
@@ -1222,9 +1452,10 @@ class AnimationAstBuilderContext {
|
|
|
1222
1452
|
this.currentQuerySelector = null;
|
|
1223
1453
|
this.currentAnimateTimings = null;
|
|
1224
1454
|
this.currentTime = 0;
|
|
1225
|
-
this.collectedStyles =
|
|
1455
|
+
this.collectedStyles = new Map();
|
|
1226
1456
|
this.options = null;
|
|
1227
1457
|
this.unsupportedCSSPropertiesFound = new Set();
|
|
1458
|
+
this.nonAnimatableCSSPropertiesFound = new Set();
|
|
1228
1459
|
}
|
|
1229
1460
|
}
|
|
1230
1461
|
function consumeOffset(styles) {
|
|
@@ -1233,23 +1464,20 @@ function consumeOffset(styles) {
|
|
|
1233
1464
|
let offset = null;
|
|
1234
1465
|
if (Array.isArray(styles)) {
|
|
1235
1466
|
styles.forEach(styleTuple => {
|
|
1236
|
-
if (
|
|
1467
|
+
if (styleTuple instanceof Map && styleTuple.has('offset')) {
|
|
1237
1468
|
const obj = styleTuple;
|
|
1238
|
-
offset = parseFloat(obj
|
|
1239
|
-
delete
|
|
1469
|
+
offset = parseFloat(obj.get('offset'));
|
|
1470
|
+
obj.delete('offset');
|
|
1240
1471
|
}
|
|
1241
1472
|
});
|
|
1242
1473
|
}
|
|
1243
|
-
else if (
|
|
1474
|
+
else if (styles instanceof Map && styles.has('offset')) {
|
|
1244
1475
|
const obj = styles;
|
|
1245
|
-
offset = parseFloat(obj
|
|
1246
|
-
delete
|
|
1476
|
+
offset = parseFloat(obj.get('offset'));
|
|
1477
|
+
obj.delete('offset');
|
|
1247
1478
|
}
|
|
1248
1479
|
return offset;
|
|
1249
1480
|
}
|
|
1250
|
-
function isObject(value) {
|
|
1251
|
-
return !Array.isArray(value) && typeof value == 'object';
|
|
1252
|
-
}
|
|
1253
1481
|
function constructTimingAst(value, errors) {
|
|
1254
1482
|
let timings = null;
|
|
1255
1483
|
if (value.hasOwnProperty('duration')) {
|
|
@@ -1357,7 +1585,7 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
|
|
|
1357
1585
|
* ```
|
|
1358
1586
|
*
|
|
1359
1587
|
* For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
|
|
1360
|
-
* combination of
|
|
1588
|
+
* combination of AST traversal and merge-sort-like algorithms are used.
|
|
1361
1589
|
*
|
|
1362
1590
|
* [AST Traversal]
|
|
1363
1591
|
* Each of the animation verbs, when executed, will return an string-map object representing what
|
|
@@ -1403,23 +1631,18 @@ const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
|
|
|
1403
1631
|
* from all previous animation steps. Therefore when a keyframe is created it would also be missing
|
|
1404
1632
|
* from all previous keyframes up until where it is first used. For the timeline keyframe generation
|
|
1405
1633
|
* to properly fill in the style it will place the previous value (the value from the parent
|
|
1406
|
-
* timeline) or a default value of `*` into the backFill
|
|
1407
|
-
*
|
|
1408
|
-
* value is added into the backFill then it will automatically propagate any missing values to all
|
|
1409
|
-
* keyframes. Therefore the missing `height` value will be properly filled into the already
|
|
1410
|
-
* processed keyframes.
|
|
1634
|
+
* timeline) or a default value of `*` into the backFill map. The `copyStyles` method in util.ts
|
|
1635
|
+
* handles propagating that backfill map to the styles object.
|
|
1411
1636
|
*
|
|
1412
1637
|
* When a sub-timeline is created it will have its own backFill property. This is done so that
|
|
1413
1638
|
* styles present within the sub-timeline do not accidentally seep into the previous/future timeline
|
|
1414
1639
|
* keyframes
|
|
1415
1640
|
*
|
|
1416
|
-
* (For prototypically-inherited contents to be detected a `for(i in obj)` loop must be used.)
|
|
1417
|
-
*
|
|
1418
1641
|
* [Validation]
|
|
1419
1642
|
* The code in this file is not responsible for validation. That functionality happens with within
|
|
1420
1643
|
* the `AnimationValidatorVisitor` code.
|
|
1421
1644
|
*/
|
|
1422
|
-
function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles =
|
|
1645
|
+
function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstructions, errors = []) {
|
|
1423
1646
|
return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
|
|
1424
1647
|
}
|
|
1425
1648
|
class AnimationTimelineBuilderVisitor {
|
|
@@ -1427,15 +1650,17 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1427
1650
|
subInstructions = subInstructions || new ElementInstructionMap();
|
|
1428
1651
|
const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
|
|
1429
1652
|
context.options = options;
|
|
1653
|
+
const delay = options.delay ? resolveTimingValue(options.delay) : 0;
|
|
1654
|
+
context.currentTimeline.delayNextStep(delay);
|
|
1430
1655
|
context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
|
|
1431
1656
|
visitDslNode(this, ast, context);
|
|
1432
1657
|
// this checks to see if an actual animation happened
|
|
1433
1658
|
const timelines = context.timelines.filter(timeline => timeline.containsAnimation());
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1659
|
+
// note: we just want to apply the final styles for the rootElement, so we do not
|
|
1660
|
+
// just apply the styles to the last timeline but the last timeline which
|
|
1661
|
+
// element is the root one (basically `*`-styles are replaced with the actual
|
|
1662
|
+
// state style values only for the root element)
|
|
1663
|
+
if (timelines.length && finalStyles.size) {
|
|
1439
1664
|
let lastRootTimeline;
|
|
1440
1665
|
for (let i = timelines.length - 1; i >= 0; i--) {
|
|
1441
1666
|
const timeline = timelines[i];
|
|
@@ -1448,8 +1673,9 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1448
1673
|
lastRootTimeline.setStyles([finalStyles], null, context.errors, options);
|
|
1449
1674
|
}
|
|
1450
1675
|
}
|
|
1451
|
-
return timelines.length ?
|
|
1452
|
-
|
|
1676
|
+
return timelines.length ?
|
|
1677
|
+
timelines.map(timeline => timeline.buildKeyframes()) :
|
|
1678
|
+
[createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];
|
|
1453
1679
|
}
|
|
1454
1680
|
visitTrigger(ast, context) {
|
|
1455
1681
|
// these values are not visited in this AST
|
|
@@ -1585,7 +1811,7 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1585
1811
|
const timings = context.currentAnimateTimings;
|
|
1586
1812
|
// this is a special case for when a style() call
|
|
1587
1813
|
// directly follows an animate() call (but not inside of an animate() call)
|
|
1588
|
-
if (!timings && timeline.
|
|
1814
|
+
if (!timings && timeline.hasCurrentStyleProperties()) {
|
|
1589
1815
|
timeline.forwardFrame();
|
|
1590
1816
|
}
|
|
1591
1817
|
const easing = (timings && timings.easing) || ast.easing;
|
|
@@ -1626,7 +1852,7 @@ class AnimationTimelineBuilderVisitor {
|
|
|
1626
1852
|
const delay = options.delay ? resolveTimingValue(options.delay) : 0;
|
|
1627
1853
|
if (delay &&
|
|
1628
1854
|
(context.previousNode.type === 6 /* Style */ ||
|
|
1629
|
-
(startTime == 0 && context.currentTimeline.
|
|
1855
|
+
(startTime == 0 && context.currentTimeline.hasCurrentStyleProperties()))) {
|
|
1630
1856
|
context.currentTimeline.snapshotCurrentStyles();
|
|
1631
1857
|
context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
|
|
1632
1858
|
}
|
|
@@ -1820,17 +2046,17 @@ class TimelineBuilder {
|
|
|
1820
2046
|
this.startTime = startTime;
|
|
1821
2047
|
this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
|
|
1822
2048
|
this.duration = 0;
|
|
1823
|
-
this._previousKeyframe =
|
|
1824
|
-
this._currentKeyframe =
|
|
2049
|
+
this._previousKeyframe = new Map();
|
|
2050
|
+
this._currentKeyframe = new Map();
|
|
1825
2051
|
this._keyframes = new Map();
|
|
1826
|
-
this._styleSummary =
|
|
1827
|
-
this.
|
|
1828
|
-
this.
|
|
2052
|
+
this._styleSummary = new Map();
|
|
2053
|
+
this._localTimelineStyles = new Map();
|
|
2054
|
+
this._pendingStyles = new Map();
|
|
2055
|
+
this._backFill = new Map();
|
|
1829
2056
|
this._currentEmptyStepKeyframe = null;
|
|
1830
2057
|
if (!this._elementTimelineStylesLookup) {
|
|
1831
2058
|
this._elementTimelineStylesLookup = new Map();
|
|
1832
2059
|
}
|
|
1833
|
-
this._localTimelineStyles = Object.create(this._backFill, {});
|
|
1834
2060
|
this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
|
|
1835
2061
|
if (!this._globalTimelineStyles) {
|
|
1836
2062
|
this._globalTimelineStyles = this._localTimelineStyles;
|
|
@@ -1843,13 +2069,13 @@ class TimelineBuilder {
|
|
|
1843
2069
|
case 0:
|
|
1844
2070
|
return false;
|
|
1845
2071
|
case 1:
|
|
1846
|
-
return this.
|
|
2072
|
+
return this.hasCurrentStyleProperties();
|
|
1847
2073
|
default:
|
|
1848
2074
|
return true;
|
|
1849
2075
|
}
|
|
1850
2076
|
}
|
|
1851
|
-
|
|
1852
|
-
return
|
|
2077
|
+
hasCurrentStyleProperties() {
|
|
2078
|
+
return this._currentKeyframe.size > 0;
|
|
1853
2079
|
}
|
|
1854
2080
|
get currentTime() {
|
|
1855
2081
|
return this.startTime + this.duration;
|
|
@@ -1859,7 +2085,7 @@ class TimelineBuilder {
|
|
|
1859
2085
|
// and that style() step is the very first style() value in the animation
|
|
1860
2086
|
// then we need to make a copy of the keyframe [0, copy, 1] so that the delay
|
|
1861
2087
|
// properly applies the style() values to work with the stagger...
|
|
1862
|
-
const hasPreStyleStep = this._keyframes.size
|
|
2088
|
+
const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;
|
|
1863
2089
|
if (this.duration || hasPreStyleStep) {
|
|
1864
2090
|
this.forwardTime(this.currentTime + delay);
|
|
1865
2091
|
if (hasPreStyleStep) {
|
|
@@ -1880,7 +2106,7 @@ class TimelineBuilder {
|
|
|
1880
2106
|
}
|
|
1881
2107
|
this._currentKeyframe = this._keyframes.get(this.duration);
|
|
1882
2108
|
if (!this._currentKeyframe) {
|
|
1883
|
-
this._currentKeyframe =
|
|
2109
|
+
this._currentKeyframe = new Map();
|
|
1884
2110
|
this._keyframes.set(this.duration, this._currentKeyframe);
|
|
1885
2111
|
}
|
|
1886
2112
|
}
|
|
@@ -1894,16 +2120,16 @@ class TimelineBuilder {
|
|
|
1894
2120
|
this._loadKeyframe();
|
|
1895
2121
|
}
|
|
1896
2122
|
_updateStyle(prop, value) {
|
|
1897
|
-
this._localTimelineStyles
|
|
1898
|
-
this._globalTimelineStyles
|
|
1899
|
-
this._styleSummary
|
|
2123
|
+
this._localTimelineStyles.set(prop, value);
|
|
2124
|
+
this._globalTimelineStyles.set(prop, value);
|
|
2125
|
+
this._styleSummary.set(prop, { time: this.currentTime, value });
|
|
1900
2126
|
}
|
|
1901
2127
|
allowOnlyTimelineStyles() {
|
|
1902
2128
|
return this._currentEmptyStepKeyframe !== this._currentKeyframe;
|
|
1903
2129
|
}
|
|
1904
2130
|
applyEmptyStep(easing) {
|
|
1905
2131
|
if (easing) {
|
|
1906
|
-
this._previousKeyframe
|
|
2132
|
+
this._previousKeyframe.set('easing', easing);
|
|
1907
2133
|
}
|
|
1908
2134
|
// special case for animate(duration):
|
|
1909
2135
|
// all missing styles are filled with a `*` value then
|
|
@@ -1911,51 +2137,45 @@ class TimelineBuilder {
|
|
|
1911
2137
|
// keyframe then they will override the overridden styles
|
|
1912
2138
|
// We use `_globalTimelineStyles` here because there may be
|
|
1913
2139
|
// styles in previous keyframes that are not present in this timeline
|
|
1914
|
-
|
|
1915
|
-
this._backFill
|
|
1916
|
-
this._currentKeyframe
|
|
1917
|
-
}
|
|
2140
|
+
for (let [prop, value] of this._globalTimelineStyles) {
|
|
2141
|
+
this._backFill.set(prop, value || AUTO_STYLE);
|
|
2142
|
+
this._currentKeyframe.set(prop, AUTO_STYLE);
|
|
2143
|
+
}
|
|
1918
2144
|
this._currentEmptyStepKeyframe = this._currentKeyframe;
|
|
1919
2145
|
}
|
|
1920
2146
|
setStyles(input, easing, errors, options) {
|
|
1921
2147
|
if (easing) {
|
|
1922
|
-
this._previousKeyframe
|
|
2148
|
+
this._previousKeyframe.set('easing', easing);
|
|
1923
2149
|
}
|
|
1924
2150
|
const params = (options && options.params) || {};
|
|
1925
2151
|
const styles = flattenStyles(input, this._globalTimelineStyles);
|
|
1926
|
-
|
|
1927
|
-
const val = interpolateParams(
|
|
1928
|
-
this._pendingStyles
|
|
1929
|
-
if (!this._localTimelineStyles.
|
|
1930
|
-
this._backFill
|
|
1931
|
-
this._globalTimelineStyles[prop] :
|
|
1932
|
-
AUTO_STYLE;
|
|
2152
|
+
for (let [prop, value] of styles) {
|
|
2153
|
+
const val = interpolateParams(value, params, errors);
|
|
2154
|
+
this._pendingStyles.set(prop, val);
|
|
2155
|
+
if (!this._localTimelineStyles.has(prop)) {
|
|
2156
|
+
this._backFill.set(prop, this._globalTimelineStyles.get(prop) || AUTO_STYLE);
|
|
1933
2157
|
}
|
|
1934
2158
|
this._updateStyle(prop, val);
|
|
1935
|
-
}
|
|
2159
|
+
}
|
|
1936
2160
|
}
|
|
1937
2161
|
applyStylesToKeyframe() {
|
|
1938
|
-
|
|
1939
|
-
const props = Object.keys(styles);
|
|
1940
|
-
if (props.length == 0)
|
|
2162
|
+
if (this._pendingStyles.size == 0)
|
|
1941
2163
|
return;
|
|
1942
|
-
this._pendingStyles
|
|
1943
|
-
|
|
1944
|
-
const val = styles[prop];
|
|
1945
|
-
this._currentKeyframe[prop] = val;
|
|
2164
|
+
this._pendingStyles.forEach((val, prop) => {
|
|
2165
|
+
this._currentKeyframe.set(prop, val);
|
|
1946
2166
|
});
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
2167
|
+
this._pendingStyles.clear();
|
|
2168
|
+
this._localTimelineStyles.forEach((val, prop) => {
|
|
2169
|
+
if (!this._currentKeyframe.has(prop)) {
|
|
2170
|
+
this._currentKeyframe.set(prop, val);
|
|
1950
2171
|
}
|
|
1951
2172
|
});
|
|
1952
2173
|
}
|
|
1953
2174
|
snapshotCurrentStyles() {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
this._pendingStyles[prop] = val;
|
|
2175
|
+
for (let [prop, val] of this._localTimelineStyles) {
|
|
2176
|
+
this._pendingStyles.set(prop, val);
|
|
1957
2177
|
this._updateStyle(prop, val);
|
|
1958
|
-
}
|
|
2178
|
+
}
|
|
1959
2179
|
}
|
|
1960
2180
|
getFinalKeyframe() {
|
|
1961
2181
|
return this._keyframes.get(this.duration);
|
|
@@ -1968,9 +2188,8 @@ class TimelineBuilder {
|
|
|
1968
2188
|
return properties;
|
|
1969
2189
|
}
|
|
1970
2190
|
mergeTimelineCollectedStyles(timeline) {
|
|
1971
|
-
|
|
1972
|
-
const details0 = this._styleSummary
|
|
1973
|
-
const details1 = timeline._styleSummary[prop];
|
|
2191
|
+
timeline._styleSummary.forEach((details1, prop) => {
|
|
2192
|
+
const details0 = this._styleSummary.get(prop);
|
|
1974
2193
|
if (!details0 || details1.time > details0.time) {
|
|
1975
2194
|
this._updateStyle(prop, details1.value);
|
|
1976
2195
|
}
|
|
@@ -1983,18 +2202,17 @@ class TimelineBuilder {
|
|
|
1983
2202
|
const isEmpty = this._keyframes.size === 1 && this.duration === 0;
|
|
1984
2203
|
let finalKeyframes = [];
|
|
1985
2204
|
this._keyframes.forEach((keyframe, time) => {
|
|
1986
|
-
const finalKeyframe = copyStyles(keyframe,
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
if (value == ɵPRE_STYLE) {
|
|
2205
|
+
const finalKeyframe = copyStyles(keyframe, new Map(), this._backFill);
|
|
2206
|
+
finalKeyframe.forEach((value, prop) => {
|
|
2207
|
+
if (value === ɵPRE_STYLE) {
|
|
1990
2208
|
preStyleProps.add(prop);
|
|
1991
2209
|
}
|
|
1992
|
-
else if (value
|
|
2210
|
+
else if (value === AUTO_STYLE) {
|
|
1993
2211
|
postStyleProps.add(prop);
|
|
1994
2212
|
}
|
|
1995
2213
|
});
|
|
1996
2214
|
if (!isEmpty) {
|
|
1997
|
-
finalKeyframe
|
|
2215
|
+
finalKeyframe.set('offset', time / this.duration);
|
|
1998
2216
|
}
|
|
1999
2217
|
finalKeyframes.push(finalKeyframe);
|
|
2000
2218
|
});
|
|
@@ -2003,9 +2221,9 @@ class TimelineBuilder {
|
|
|
2003
2221
|
// special case for a 0-second animation (which is designed just to place styles onscreen)
|
|
2004
2222
|
if (isEmpty) {
|
|
2005
2223
|
const kf0 = finalKeyframes[0];
|
|
2006
|
-
const kf1 =
|
|
2007
|
-
kf0
|
|
2008
|
-
kf1
|
|
2224
|
+
const kf1 = new Map(kf0);
|
|
2225
|
+
kf0.set('offset', 0);
|
|
2226
|
+
kf1.set('offset', 1);
|
|
2009
2227
|
finalKeyframes = [kf0, kf1];
|
|
2010
2228
|
}
|
|
2011
2229
|
return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
|
|
@@ -2031,11 +2249,11 @@ class SubTimelineBuilder extends TimelineBuilder {
|
|
|
2031
2249
|
const totalTime = duration + delay;
|
|
2032
2250
|
const startingGap = delay / totalTime;
|
|
2033
2251
|
// the original starting keyframe now starts once the delay is done
|
|
2034
|
-
const newFirstKeyframe = copyStyles(keyframes[0]
|
|
2035
|
-
newFirstKeyframe
|
|
2252
|
+
const newFirstKeyframe = copyStyles(keyframes[0]);
|
|
2253
|
+
newFirstKeyframe.set('offset', 0);
|
|
2036
2254
|
newKeyframes.push(newFirstKeyframe);
|
|
2037
|
-
const oldFirstKeyframe = copyStyles(keyframes[0]
|
|
2038
|
-
oldFirstKeyframe
|
|
2255
|
+
const oldFirstKeyframe = copyStyles(keyframes[0]);
|
|
2256
|
+
oldFirstKeyframe.set('offset', roundOffset(startingGap));
|
|
2039
2257
|
newKeyframes.push(oldFirstKeyframe);
|
|
2040
2258
|
/*
|
|
2041
2259
|
When the keyframe is stretched then it means that the delay before the animation
|
|
@@ -2054,10 +2272,10 @@ class SubTimelineBuilder extends TimelineBuilder {
|
|
|
2054
2272
|
// offsets between 1 ... n -1 are all warped by the keyframe stretch
|
|
2055
2273
|
const limit = keyframes.length - 1;
|
|
2056
2274
|
for (let i = 1; i <= limit; i++) {
|
|
2057
|
-
let kf = copyStyles(keyframes[i]
|
|
2058
|
-
const oldOffset = kf
|
|
2275
|
+
let kf = copyStyles(keyframes[i]);
|
|
2276
|
+
const oldOffset = kf.get('offset');
|
|
2059
2277
|
const timeAtKeyframe = delay + oldOffset * duration;
|
|
2060
|
-
kf
|
|
2278
|
+
kf.set('offset', roundOffset(timeAtKeyframe / totalTime));
|
|
2061
2279
|
newKeyframes.push(kf);
|
|
2062
2280
|
}
|
|
2063
2281
|
// the new starting keyframe should be added at the start
|
|
@@ -2074,17 +2292,17 @@ function roundOffset(offset, decimalPoints = 3) {
|
|
|
2074
2292
|
return Math.round(offset * mult) / mult;
|
|
2075
2293
|
}
|
|
2076
2294
|
function flattenStyles(input, allStyles) {
|
|
2077
|
-
const styles =
|
|
2295
|
+
const styles = new Map();
|
|
2078
2296
|
let allProperties;
|
|
2079
2297
|
input.forEach(token => {
|
|
2080
2298
|
if (token === '*') {
|
|
2081
|
-
allProperties = allProperties ||
|
|
2082
|
-
|
|
2083
|
-
styles
|
|
2084
|
-
}
|
|
2299
|
+
allProperties = allProperties || allStyles.keys();
|
|
2300
|
+
for (let prop of allProperties) {
|
|
2301
|
+
styles.set(prop, AUTO_STYLE);
|
|
2302
|
+
}
|
|
2085
2303
|
}
|
|
2086
2304
|
else {
|
|
2087
|
-
copyStyles(token,
|
|
2305
|
+
copyStyles(token, styles);
|
|
2088
2306
|
}
|
|
2089
2307
|
});
|
|
2090
2308
|
return styles;
|
|
@@ -2150,6 +2368,37 @@ class NoopAnimationStyleNormalizer {
|
|
|
2150
2368
|
* Use of this source code is governed by an MIT-style license that can be
|
|
2151
2369
|
* found in the LICENSE file at https://angular.io/license
|
|
2152
2370
|
*/
|
|
2371
|
+
const DIMENSIONAL_PROP_SET = new Set([
|
|
2372
|
+
'width',
|
|
2373
|
+
'height',
|
|
2374
|
+
'minWidth',
|
|
2375
|
+
'minHeight',
|
|
2376
|
+
'maxWidth',
|
|
2377
|
+
'maxHeight',
|
|
2378
|
+
'left',
|
|
2379
|
+
'top',
|
|
2380
|
+
'bottom',
|
|
2381
|
+
'right',
|
|
2382
|
+
'fontSize',
|
|
2383
|
+
'outlineWidth',
|
|
2384
|
+
'outlineOffset',
|
|
2385
|
+
'paddingTop',
|
|
2386
|
+
'paddingLeft',
|
|
2387
|
+
'paddingBottom',
|
|
2388
|
+
'paddingRight',
|
|
2389
|
+
'marginTop',
|
|
2390
|
+
'marginLeft',
|
|
2391
|
+
'marginBottom',
|
|
2392
|
+
'marginRight',
|
|
2393
|
+
'borderRadius',
|
|
2394
|
+
'borderWidth',
|
|
2395
|
+
'borderTopWidth',
|
|
2396
|
+
'borderLeftWidth',
|
|
2397
|
+
'borderRightWidth',
|
|
2398
|
+
'borderBottomWidth',
|
|
2399
|
+
'textIndent',
|
|
2400
|
+
'perspective'
|
|
2401
|
+
]);
|
|
2153
2402
|
class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
2154
2403
|
normalizePropertyName(propertyName, errors) {
|
|
2155
2404
|
return dashCaseToCamelCase(propertyName);
|
|
@@ -2157,7 +2406,7 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
|
2157
2406
|
normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
|
|
2158
2407
|
let unit = '';
|
|
2159
2408
|
const strVal = value.toString().trim();
|
|
2160
|
-
if (
|
|
2409
|
+
if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {
|
|
2161
2410
|
if (typeof value === 'number') {
|
|
2162
2411
|
unit = 'px';
|
|
2163
2412
|
}
|
|
@@ -2171,14 +2420,14 @@ class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
|
|
|
2171
2420
|
return strVal + unit;
|
|
2172
2421
|
}
|
|
2173
2422
|
}
|
|
2174
|
-
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'
|
|
2175
|
-
.split(',')))();
|
|
2176
|
-
function makeBooleanMap(keys) {
|
|
2177
|
-
const map = {};
|
|
2178
|
-
keys.forEach(key => map[key] = true);
|
|
2179
|
-
return map;
|
|
2180
|
-
}
|
|
2181
2423
|
|
|
2424
|
+
/**
|
|
2425
|
+
* @license
|
|
2426
|
+
* Copyright Google LLC All Rights Reserved.
|
|
2427
|
+
*
|
|
2428
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
2429
|
+
* found in the LICENSE file at https://angular.io/license
|
|
2430
|
+
*/
|
|
2182
2431
|
function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
|
|
2183
2432
|
return {
|
|
2184
2433
|
type: 0 /* TransitionAnimation */,
|
|
@@ -2209,10 +2458,11 @@ class AnimationTransitionFactory {
|
|
|
2209
2458
|
return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
|
|
2210
2459
|
}
|
|
2211
2460
|
buildStyles(stateName, params, errors) {
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2461
|
+
let styler = this._stateStyles.get('*');
|
|
2462
|
+
if (stateName !== undefined) {
|
|
2463
|
+
styler = this._stateStyles.get(stateName?.toString()) || styler;
|
|
2464
|
+
}
|
|
2465
|
+
return styler ? styler.buildStyles(params, errors) : new Map();
|
|
2216
2466
|
}
|
|
2217
2467
|
build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
|
|
2218
2468
|
const errors = [];
|
|
@@ -2225,7 +2475,10 @@ class AnimationTransitionFactory {
|
|
|
2225
2475
|
const preStyleMap = new Map();
|
|
2226
2476
|
const postStyleMap = new Map();
|
|
2227
2477
|
const isRemoval = nextState === 'void';
|
|
2228
|
-
const animationOptions = {
|
|
2478
|
+
const animationOptions = {
|
|
2479
|
+
params: applyParamDefaults(nextAnimationParams, transitionAnimationParams),
|
|
2480
|
+
delay: this.ast.options?.delay,
|
|
2481
|
+
};
|
|
2229
2482
|
const timelines = skipAstBuild ?
|
|
2230
2483
|
[] :
|
|
2231
2484
|
buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
|
|
@@ -2238,10 +2491,10 @@ class AnimationTransitionFactory {
|
|
|
2238
2491
|
}
|
|
2239
2492
|
timelines.forEach(tl => {
|
|
2240
2493
|
const elm = tl.element;
|
|
2241
|
-
const preProps =
|
|
2242
|
-
tl.preStyleProps.forEach(prop => preProps
|
|
2243
|
-
const postProps =
|
|
2244
|
-
tl.postStyleProps.forEach(prop => postProps
|
|
2494
|
+
const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());
|
|
2495
|
+
tl.preStyleProps.forEach(prop => preProps.add(prop));
|
|
2496
|
+
const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());
|
|
2497
|
+
tl.postStyleProps.forEach(prop => postProps.add(prop));
|
|
2245
2498
|
if (elm !== element) {
|
|
2246
2499
|
queriedElements.add(elm);
|
|
2247
2500
|
}
|
|
@@ -2253,6 +2506,15 @@ class AnimationTransitionFactory {
|
|
|
2253
2506
|
function oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {
|
|
2254
2507
|
return matchFns.some(fn => fn(currentState, nextState, element, params));
|
|
2255
2508
|
}
|
|
2509
|
+
function applyParamDefaults(userParams, defaults) {
|
|
2510
|
+
const result = copyObj(defaults);
|
|
2511
|
+
for (const key in userParams) {
|
|
2512
|
+
if (userParams.hasOwnProperty(key) && userParams[key] != null) {
|
|
2513
|
+
result[key] = userParams[key];
|
|
2514
|
+
}
|
|
2515
|
+
}
|
|
2516
|
+
return result;
|
|
2517
|
+
}
|
|
2256
2518
|
class AnimationStateStyles {
|
|
2257
2519
|
constructor(styles, defaultParams, normalizer) {
|
|
2258
2520
|
this.styles = styles;
|
|
@@ -2260,25 +2522,23 @@ class AnimationStateStyles {
|
|
|
2260
2522
|
this.normalizer = normalizer;
|
|
2261
2523
|
}
|
|
2262
2524
|
buildStyles(params, errors) {
|
|
2263
|
-
const finalStyles =
|
|
2525
|
+
const finalStyles = new Map();
|
|
2264
2526
|
const combinedParams = copyObj(this.defaultParams);
|
|
2265
2527
|
Object.keys(params).forEach(key => {
|
|
2266
2528
|
const value = params[key];
|
|
2267
|
-
if (value
|
|
2529
|
+
if (value !== null) {
|
|
2268
2530
|
combinedParams[key] = value;
|
|
2269
2531
|
}
|
|
2270
2532
|
});
|
|
2271
2533
|
this.styles.styles.forEach(value => {
|
|
2272
2534
|
if (typeof value !== 'string') {
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
let val = styleObj[prop];
|
|
2276
|
-
if (val.length > 1) {
|
|
2535
|
+
value.forEach((val, prop) => {
|
|
2536
|
+
if (val) {
|
|
2277
2537
|
val = interpolateParams(val, combinedParams, errors);
|
|
2278
2538
|
}
|
|
2279
2539
|
const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);
|
|
2280
2540
|
val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);
|
|
2281
|
-
finalStyles
|
|
2541
|
+
finalStyles.set(normalizedProp, val);
|
|
2282
2542
|
});
|
|
2283
2543
|
}
|
|
2284
2544
|
});
|
|
@@ -2295,10 +2555,10 @@ class AnimationTrigger {
|
|
|
2295
2555
|
this.ast = ast;
|
|
2296
2556
|
this._normalizer = _normalizer;
|
|
2297
2557
|
this.transitionFactories = [];
|
|
2298
|
-
this.states =
|
|
2558
|
+
this.states = new Map();
|
|
2299
2559
|
ast.states.forEach(ast => {
|
|
2300
2560
|
const defaultParams = (ast.options && ast.options.params) || {};
|
|
2301
|
-
this.states
|
|
2561
|
+
this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));
|
|
2302
2562
|
});
|
|
2303
2563
|
balanceProperties(this.states, 'true', '1');
|
|
2304
2564
|
balanceProperties(this.states, 'false', '0');
|
|
@@ -2331,14 +2591,14 @@ function createFallbackTransition(triggerName, states, normalizer) {
|
|
|
2331
2591
|
};
|
|
2332
2592
|
return new AnimationTransitionFactory(triggerName, transition, states);
|
|
2333
2593
|
}
|
|
2334
|
-
function balanceProperties(
|
|
2335
|
-
if (
|
|
2336
|
-
if (!
|
|
2337
|
-
|
|
2594
|
+
function balanceProperties(stateMap, key1, key2) {
|
|
2595
|
+
if (stateMap.has(key1)) {
|
|
2596
|
+
if (!stateMap.has(key2)) {
|
|
2597
|
+
stateMap.set(key2, stateMap.get(key1));
|
|
2338
2598
|
}
|
|
2339
2599
|
}
|
|
2340
|
-
else if (
|
|
2341
|
-
|
|
2600
|
+
else if (stateMap.has(key2)) {
|
|
2601
|
+
stateMap.set(key1, stateMap.get(key2));
|
|
2342
2602
|
}
|
|
2343
2603
|
}
|
|
2344
2604
|
|
|
@@ -2355,8 +2615,8 @@ class TimelineAnimationEngine {
|
|
|
2355
2615
|
this.bodyNode = bodyNode;
|
|
2356
2616
|
this._driver = _driver;
|
|
2357
2617
|
this._normalizer = _normalizer;
|
|
2358
|
-
this._animations =
|
|
2359
|
-
this._playersById =
|
|
2618
|
+
this._animations = new Map();
|
|
2619
|
+
this._playersById = new Map();
|
|
2360
2620
|
this.players = [];
|
|
2361
2621
|
}
|
|
2362
2622
|
register(id, metadata) {
|
|
@@ -2370,24 +2630,24 @@ class TimelineAnimationEngine {
|
|
|
2370
2630
|
if (warnings.length) {
|
|
2371
2631
|
warnRegister(warnings);
|
|
2372
2632
|
}
|
|
2373
|
-
this._animations
|
|
2633
|
+
this._animations.set(id, ast);
|
|
2374
2634
|
}
|
|
2375
2635
|
}
|
|
2376
2636
|
_buildPlayer(i, preStyles, postStyles) {
|
|
2377
2637
|
const element = i.element;
|
|
2378
|
-
const keyframes = normalizeKeyframes(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
|
|
2638
|
+
const keyframes = normalizeKeyframes$1(this._driver, this._normalizer, element, i.keyframes, preStyles, postStyles);
|
|
2379
2639
|
return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
|
|
2380
2640
|
}
|
|
2381
2641
|
create(id, element, options = {}) {
|
|
2382
2642
|
const errors = [];
|
|
2383
|
-
const ast = this._animations
|
|
2643
|
+
const ast = this._animations.get(id);
|
|
2384
2644
|
let instructions;
|
|
2385
2645
|
const autoStylesMap = new Map();
|
|
2386
2646
|
if (ast) {
|
|
2387
|
-
instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME,
|
|
2647
|
+
instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);
|
|
2388
2648
|
instructions.forEach(inst => {
|
|
2389
|
-
const styles =
|
|
2390
|
-
inst.postStyleProps.forEach(prop => styles
|
|
2649
|
+
const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());
|
|
2650
|
+
inst.postStyleProps.forEach(prop => styles.set(prop, null));
|
|
2391
2651
|
});
|
|
2392
2652
|
}
|
|
2393
2653
|
else {
|
|
@@ -2398,16 +2658,16 @@ class TimelineAnimationEngine {
|
|
|
2398
2658
|
throw createAnimationFailed(errors);
|
|
2399
2659
|
}
|
|
2400
2660
|
autoStylesMap.forEach((styles, element) => {
|
|
2401
|
-
|
|
2402
|
-
styles
|
|
2661
|
+
styles.forEach((_, prop) => {
|
|
2662
|
+
styles.set(prop, this._driver.computeStyle(element, prop, AUTO_STYLE));
|
|
2403
2663
|
});
|
|
2404
2664
|
});
|
|
2405
2665
|
const players = instructions.map(i => {
|
|
2406
2666
|
const styles = autoStylesMap.get(i.element);
|
|
2407
|
-
return this._buildPlayer(i,
|
|
2667
|
+
return this._buildPlayer(i, new Map(), styles);
|
|
2408
2668
|
});
|
|
2409
2669
|
const player = optimizeGroupPlayer(players);
|
|
2410
|
-
this._playersById
|
|
2670
|
+
this._playersById.set(id, player);
|
|
2411
2671
|
player.onDestroy(() => this.destroy(id));
|
|
2412
2672
|
this.players.push(player);
|
|
2413
2673
|
return player;
|
|
@@ -2415,14 +2675,14 @@ class TimelineAnimationEngine {
|
|
|
2415
2675
|
destroy(id) {
|
|
2416
2676
|
const player = this._getPlayer(id);
|
|
2417
2677
|
player.destroy();
|
|
2418
|
-
|
|
2678
|
+
this._playersById.delete(id);
|
|
2419
2679
|
const index = this.players.indexOf(player);
|
|
2420
2680
|
if (index >= 0) {
|
|
2421
2681
|
this.players.splice(index, 1);
|
|
2422
2682
|
}
|
|
2423
2683
|
}
|
|
2424
2684
|
_getPlayer(id) {
|
|
2425
|
-
const player = this._playersById
|
|
2685
|
+
const player = this._playersById.get(id);
|
|
2426
2686
|
if (!player) {
|
|
2427
2687
|
throw missingPlayer(id);
|
|
2428
2688
|
}
|
|
@@ -2544,14 +2804,14 @@ class AnimationTransitionNamespace {
|
|
|
2544
2804
|
this.hostElement = hostElement;
|
|
2545
2805
|
this._engine = _engine;
|
|
2546
2806
|
this.players = [];
|
|
2547
|
-
this._triggers =
|
|
2807
|
+
this._triggers = new Map();
|
|
2548
2808
|
this._queue = [];
|
|
2549
2809
|
this._elementListeners = new Map();
|
|
2550
2810
|
this._hostClassName = 'ng-tns-' + id;
|
|
2551
2811
|
addClass(hostElement, this._hostClassName);
|
|
2552
2812
|
}
|
|
2553
2813
|
listen(element, name, phase, callback) {
|
|
2554
|
-
if (!this._triggers.
|
|
2814
|
+
if (!this._triggers.has(name)) {
|
|
2555
2815
|
throw missingTrigger(phase, name);
|
|
2556
2816
|
}
|
|
2557
2817
|
if (phase == null || phase.length == 0) {
|
|
@@ -2560,14 +2820,14 @@ class AnimationTransitionNamespace {
|
|
|
2560
2820
|
if (!isTriggerEventValid(phase)) {
|
|
2561
2821
|
throw unsupportedTriggerEvent(phase, name);
|
|
2562
2822
|
}
|
|
2563
|
-
const listeners =
|
|
2823
|
+
const listeners = getOrSetDefaultValue(this._elementListeners, element, []);
|
|
2564
2824
|
const data = { name, phase, callback };
|
|
2565
2825
|
listeners.push(data);
|
|
2566
|
-
const triggersWithStates =
|
|
2567
|
-
if (!triggersWithStates.
|
|
2826
|
+
const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());
|
|
2827
|
+
if (!triggersWithStates.has(name)) {
|
|
2568
2828
|
addClass(element, NG_TRIGGER_CLASSNAME);
|
|
2569
2829
|
addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
|
|
2570
|
-
triggersWithStates
|
|
2830
|
+
triggersWithStates.set(name, DEFAULT_STATE_VALUE);
|
|
2571
2831
|
}
|
|
2572
2832
|
return () => {
|
|
2573
2833
|
// the event listener is removed AFTER the flush has occurred such
|
|
@@ -2578,24 +2838,24 @@ class AnimationTransitionNamespace {
|
|
|
2578
2838
|
if (index >= 0) {
|
|
2579
2839
|
listeners.splice(index, 1);
|
|
2580
2840
|
}
|
|
2581
|
-
if (!this._triggers
|
|
2582
|
-
delete
|
|
2841
|
+
if (!this._triggers.has(name)) {
|
|
2842
|
+
triggersWithStates.delete(name);
|
|
2583
2843
|
}
|
|
2584
2844
|
});
|
|
2585
2845
|
};
|
|
2586
2846
|
}
|
|
2587
2847
|
register(name, ast) {
|
|
2588
|
-
if (this._triggers
|
|
2848
|
+
if (this._triggers.has(name)) {
|
|
2589
2849
|
// throw
|
|
2590
2850
|
return false;
|
|
2591
2851
|
}
|
|
2592
2852
|
else {
|
|
2593
|
-
this._triggers
|
|
2853
|
+
this._triggers.set(name, ast);
|
|
2594
2854
|
return true;
|
|
2595
2855
|
}
|
|
2596
2856
|
}
|
|
2597
2857
|
_getTrigger(name) {
|
|
2598
|
-
const trigger = this._triggers
|
|
2858
|
+
const trigger = this._triggers.get(name);
|
|
2599
2859
|
if (!trigger) {
|
|
2600
2860
|
throw unregisteredTrigger(name);
|
|
2601
2861
|
}
|
|
@@ -2608,15 +2868,15 @@ class AnimationTransitionNamespace {
|
|
|
2608
2868
|
if (!triggersWithStates) {
|
|
2609
2869
|
addClass(element, NG_TRIGGER_CLASSNAME);
|
|
2610
2870
|
addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
|
|
2611
|
-
this._engine.statesByElement.set(element, triggersWithStates =
|
|
2871
|
+
this._engine.statesByElement.set(element, triggersWithStates = new Map());
|
|
2612
2872
|
}
|
|
2613
|
-
let fromState = triggersWithStates
|
|
2873
|
+
let fromState = triggersWithStates.get(triggerName);
|
|
2614
2874
|
const toState = new StateValue(value, this.id);
|
|
2615
2875
|
const isObj = value && value.hasOwnProperty('value');
|
|
2616
2876
|
if (!isObj && fromState) {
|
|
2617
2877
|
toState.absorbOptions(fromState.options);
|
|
2618
2878
|
}
|
|
2619
|
-
triggersWithStates
|
|
2879
|
+
triggersWithStates.set(triggerName, toState);
|
|
2620
2880
|
if (!fromState) {
|
|
2621
2881
|
fromState = DEFAULT_STATE_VALUE;
|
|
2622
2882
|
}
|
|
@@ -2646,7 +2906,7 @@ class AnimationTransitionNamespace {
|
|
|
2646
2906
|
}
|
|
2647
2907
|
return;
|
|
2648
2908
|
}
|
|
2649
|
-
const playersOnElement =
|
|
2909
|
+
const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);
|
|
2650
2910
|
playersOnElement.forEach(player => {
|
|
2651
2911
|
// only remove the player if it is queued on the EXACT same trigger/namespace
|
|
2652
2912
|
// we only also deal with queued players here because if the animation has
|
|
@@ -2690,10 +2950,8 @@ class AnimationTransitionNamespace {
|
|
|
2690
2950
|
return player;
|
|
2691
2951
|
}
|
|
2692
2952
|
deregister(name) {
|
|
2693
|
-
|
|
2694
|
-
this._engine.statesByElement.forEach(
|
|
2695
|
-
delete stateMap[name];
|
|
2696
|
-
});
|
|
2953
|
+
this._triggers.delete(name);
|
|
2954
|
+
this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));
|
|
2697
2955
|
this._elementListeners.forEach((listeners, element) => {
|
|
2698
2956
|
this._elementListeners.set(element, listeners.filter(entry => {
|
|
2699
2957
|
return entry.name != name;
|
|
@@ -2736,11 +2994,11 @@ class AnimationTransitionNamespace {
|
|
|
2736
2994
|
const previousTriggersValues = new Map();
|
|
2737
2995
|
if (triggerStates) {
|
|
2738
2996
|
const players = [];
|
|
2739
|
-
|
|
2740
|
-
previousTriggersValues.set(triggerName,
|
|
2997
|
+
triggerStates.forEach((state, triggerName) => {
|
|
2998
|
+
previousTriggersValues.set(triggerName, state.value);
|
|
2741
2999
|
// this check is here in the event that an element is removed
|
|
2742
3000
|
// twice (both on the host level and the component level)
|
|
2743
|
-
if (this._triggers
|
|
3001
|
+
if (this._triggers.has(triggerName)) {
|
|
2744
3002
|
const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
|
|
2745
3003
|
if (player) {
|
|
2746
3004
|
players.push(player);
|
|
@@ -2769,9 +3027,9 @@ class AnimationTransitionNamespace {
|
|
|
2769
3027
|
if (visitedTriggers.has(triggerName))
|
|
2770
3028
|
return;
|
|
2771
3029
|
visitedTriggers.add(triggerName);
|
|
2772
|
-
const trigger = this._triggers
|
|
3030
|
+
const trigger = this._triggers.get(triggerName);
|
|
2773
3031
|
const transition = trigger.fallbackTransition;
|
|
2774
|
-
const fromState = elementStates
|
|
3032
|
+
const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;
|
|
2775
3033
|
const toState = new StateValue(VOID_VALUE);
|
|
2776
3034
|
const player = new TransitionAnimationPlayer(this.id, triggerName, element);
|
|
2777
3035
|
this._engine.totalQueuedPlayers++;
|
|
@@ -2958,35 +3216,20 @@ class TransitionAnimationEngine {
|
|
|
2958
3216
|
const limit = namespaceList.length - 1;
|
|
2959
3217
|
if (limit >= 0) {
|
|
2960
3218
|
let found = false;
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
found = true;
|
|
2974
|
-
break;
|
|
2975
|
-
}
|
|
2976
|
-
ancestor = this.driver.getParentElement(ancestor);
|
|
2977
|
-
}
|
|
2978
|
-
}
|
|
2979
|
-
else {
|
|
2980
|
-
// Slow path for backwards compatibility if the driver does not implement
|
|
2981
|
-
// `getParentElement`, to be removed once `getParentElement` is a required method.
|
|
2982
|
-
for (let i = limit; i >= 0; i--) {
|
|
2983
|
-
const nextNamespace = namespaceList[i];
|
|
2984
|
-
if (this.driver.containsElement(nextNamespace.hostElement, hostElement)) {
|
|
2985
|
-
namespaceList.splice(i + 1, 0, ns);
|
|
2986
|
-
found = true;
|
|
2987
|
-
break;
|
|
2988
|
-
}
|
|
3219
|
+
// Find the closest ancestor with an existing namespace so we can then insert `ns` after it,
|
|
3220
|
+
// establishing a top-down ordering of namespaces in `this._namespaceList`.
|
|
3221
|
+
let ancestor = this.driver.getParentElement(hostElement);
|
|
3222
|
+
while (ancestor) {
|
|
3223
|
+
const ancestorNs = namespacesByHostElement.get(ancestor);
|
|
3224
|
+
if (ancestorNs) {
|
|
3225
|
+
// An animation namespace has been registered for this ancestor, so we insert `ns`
|
|
3226
|
+
// right after it to establish top-down ordering of animation namespaces.
|
|
3227
|
+
const index = namespaceList.indexOf(ancestorNs);
|
|
3228
|
+
namespaceList.splice(index + 1, 0, ns);
|
|
3229
|
+
found = true;
|
|
3230
|
+
break;
|
|
2989
3231
|
}
|
|
3232
|
+
ancestor = this.driver.getParentElement(ancestor);
|
|
2990
3233
|
}
|
|
2991
3234
|
if (!found) {
|
|
2992
3235
|
// No namespace exists that is an ancestor of `ns`, so `ns` is inserted at the front to
|
|
@@ -3040,11 +3283,9 @@ class TransitionAnimationEngine {
|
|
|
3040
3283
|
const namespaces = new Set();
|
|
3041
3284
|
const elementStates = this.statesByElement.get(element);
|
|
3042
3285
|
if (elementStates) {
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
if (nsId) {
|
|
3047
|
-
const ns = this._fetchNamespace(nsId);
|
|
3286
|
+
for (let stateValue of elementStates.values()) {
|
|
3287
|
+
if (stateValue.namespaceId) {
|
|
3288
|
+
const ns = this._fetchNamespace(stateValue.namespaceId);
|
|
3048
3289
|
if (ns) {
|
|
3049
3290
|
namespaces.add(ns);
|
|
3050
3291
|
}
|
|
@@ -3351,8 +3592,10 @@ class TransitionAnimationEngine {
|
|
|
3351
3592
|
// we need to restore the previous trigger value since the element has
|
|
3352
3593
|
// only been moved and hasn't actually left the DOM
|
|
3353
3594
|
const triggersWithStates = this.statesByElement.get(entry.element);
|
|
3354
|
-
if (triggersWithStates && triggersWithStates
|
|
3355
|
-
triggersWithStates
|
|
3595
|
+
if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {
|
|
3596
|
+
const state = triggersWithStates.get(entry.triggerName);
|
|
3597
|
+
state.value = previousValue;
|
|
3598
|
+
triggersWithStates.set(entry.triggerName, state);
|
|
3356
3599
|
}
|
|
3357
3600
|
}
|
|
3358
3601
|
player.destroy();
|
|
@@ -3402,24 +3645,22 @@ class TransitionAnimationEngine {
|
|
|
3402
3645
|
subTimelines.append(element, instruction.timelines);
|
|
3403
3646
|
const tuple = { instruction, player, element };
|
|
3404
3647
|
queuedInstructions.push(tuple);
|
|
3405
|
-
instruction.queriedElements.forEach(element =>
|
|
3648
|
+
instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));
|
|
3406
3649
|
instruction.preStyleProps.forEach((stringMap, element) => {
|
|
3407
|
-
|
|
3408
|
-
if (props.length) {
|
|
3650
|
+
if (stringMap.size) {
|
|
3409
3651
|
let setVal = allPreStyleElements.get(element);
|
|
3410
3652
|
if (!setVal) {
|
|
3411
3653
|
allPreStyleElements.set(element, setVal = new Set());
|
|
3412
3654
|
}
|
|
3413
|
-
|
|
3655
|
+
stringMap.forEach((_, prop) => setVal.add(prop));
|
|
3414
3656
|
}
|
|
3415
3657
|
});
|
|
3416
3658
|
instruction.postStyleProps.forEach((stringMap, element) => {
|
|
3417
|
-
const props = Object.keys(stringMap);
|
|
3418
3659
|
let setVal = allPostStyleElements.get(element);
|
|
3419
3660
|
if (!setVal) {
|
|
3420
3661
|
allPostStyleElements.set(element, setVal = new Set());
|
|
3421
3662
|
}
|
|
3422
|
-
|
|
3663
|
+
stringMap.forEach((_, prop) => setVal.add(prop));
|
|
3423
3664
|
});
|
|
3424
3665
|
});
|
|
3425
3666
|
}
|
|
@@ -3448,7 +3689,7 @@ class TransitionAnimationEngine {
|
|
|
3448
3689
|
const element = player.element;
|
|
3449
3690
|
const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
|
|
3450
3691
|
previousPlayers.forEach(prevPlayer => {
|
|
3451
|
-
|
|
3692
|
+
getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);
|
|
3452
3693
|
prevPlayer.destroy();
|
|
3453
3694
|
});
|
|
3454
3695
|
});
|
|
@@ -3478,7 +3719,7 @@ class TransitionAnimationEngine {
|
|
|
3478
3719
|
replaceNodes.forEach(node => {
|
|
3479
3720
|
const post = postStylesMap.get(node);
|
|
3480
3721
|
const pre = preStylesMap.get(node);
|
|
3481
|
-
postStylesMap.set(node,
|
|
3722
|
+
postStylesMap.set(node, new Map([...Array.from(post?.entries() ?? []), ...Array.from(pre?.entries() ?? [])]));
|
|
3482
3723
|
});
|
|
3483
3724
|
const rootPlayers = [];
|
|
3484
3725
|
const subPlayers = [];
|
|
@@ -3672,7 +3913,7 @@ class TransitionAnimationEngine {
|
|
|
3672
3913
|
for (const timelineInstruction of instruction.timelines) {
|
|
3673
3914
|
const element = timelineInstruction.element;
|
|
3674
3915
|
const isQueriedElement = element !== rootElement;
|
|
3675
|
-
const players =
|
|
3916
|
+
const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);
|
|
3676
3917
|
const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
|
|
3677
3918
|
previousPlayers.forEach(player => {
|
|
3678
3919
|
const realPlayer = player.getRealPlayer();
|
|
@@ -3715,7 +3956,7 @@ class TransitionAnimationEngine {
|
|
|
3715
3956
|
});
|
|
3716
3957
|
const preStyles = preStylesMap.get(element);
|
|
3717
3958
|
const postStyles = postStylesMap.get(element);
|
|
3718
|
-
const keyframes = normalizeKeyframes(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
|
|
3959
|
+
const keyframes = normalizeKeyframes$1(this.driver, this._normalizer, element, timelineInstruction.keyframes, preStyles, postStyles);
|
|
3719
3960
|
const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
|
|
3720
3961
|
// this means that this particular player belongs to a sub trigger. It is
|
|
3721
3962
|
// important that we match this player up with the corresponding (@trigger.listener)
|
|
@@ -3730,7 +3971,7 @@ class TransitionAnimationEngine {
|
|
|
3730
3971
|
return player;
|
|
3731
3972
|
});
|
|
3732
3973
|
allQueriedPlayers.forEach(player => {
|
|
3733
|
-
|
|
3974
|
+
getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);
|
|
3734
3975
|
player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
|
|
3735
3976
|
});
|
|
3736
3977
|
allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
|
|
@@ -3742,7 +3983,7 @@ class TransitionAnimationEngine {
|
|
|
3742
3983
|
// this basically makes all of the callbacks for sub element animations
|
|
3743
3984
|
// be dependent on the upper players for when they finish
|
|
3744
3985
|
allSubElements.forEach(element => {
|
|
3745
|
-
|
|
3986
|
+
getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);
|
|
3746
3987
|
});
|
|
3747
3988
|
return player;
|
|
3748
3989
|
}
|
|
@@ -3762,7 +4003,7 @@ class TransitionAnimationPlayer {
|
|
|
3762
4003
|
this.element = element;
|
|
3763
4004
|
this._player = new NoopAnimationPlayer();
|
|
3764
4005
|
this._containsRealPlayer = false;
|
|
3765
|
-
this._queuedCallbacks =
|
|
4006
|
+
this._queuedCallbacks = new Map();
|
|
3766
4007
|
this.destroyed = false;
|
|
3767
4008
|
this.markedForDestroy = false;
|
|
3768
4009
|
this.disabled = false;
|
|
@@ -3773,10 +4014,10 @@ class TransitionAnimationPlayer {
|
|
|
3773
4014
|
if (this._containsRealPlayer)
|
|
3774
4015
|
return;
|
|
3775
4016
|
this._player = player;
|
|
3776
|
-
|
|
3777
|
-
|
|
4017
|
+
this._queuedCallbacks.forEach((callbacks, phase) => {
|
|
4018
|
+
callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));
|
|
3778
4019
|
});
|
|
3779
|
-
this._queuedCallbacks
|
|
4020
|
+
this._queuedCallbacks.clear();
|
|
3780
4021
|
this._containsRealPlayer = true;
|
|
3781
4022
|
this.overrideTotalTime(player.totalTime);
|
|
3782
4023
|
this.queued = false;
|
|
@@ -3796,7 +4037,7 @@ class TransitionAnimationPlayer {
|
|
|
3796
4037
|
player.onDestroy(() => this.destroy());
|
|
3797
4038
|
}
|
|
3798
4039
|
_queueEvent(name, callback) {
|
|
3799
|
-
|
|
4040
|
+
getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);
|
|
3800
4041
|
}
|
|
3801
4042
|
onDone(fn) {
|
|
3802
4043
|
if (this.queued) {
|
|
@@ -3858,29 +4099,14 @@ class TransitionAnimationPlayer {
|
|
|
3858
4099
|
}
|
|
3859
4100
|
}
|
|
3860
4101
|
function deleteOrUnsetInMap(map, key, value) {
|
|
3861
|
-
let currentValues;
|
|
3862
|
-
if (
|
|
3863
|
-
currentValues
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
const index = currentValues.indexOf(value);
|
|
3867
|
-
currentValues.splice(index, 1);
|
|
3868
|
-
}
|
|
3869
|
-
if (currentValues.length == 0) {
|
|
3870
|
-
map.delete(key);
|
|
3871
|
-
}
|
|
4102
|
+
let currentValues = map.get(key);
|
|
4103
|
+
if (currentValues) {
|
|
4104
|
+
if (currentValues.length) {
|
|
4105
|
+
const index = currentValues.indexOf(value);
|
|
4106
|
+
currentValues.splice(index, 1);
|
|
3872
4107
|
}
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
currentValues = map[key];
|
|
3876
|
-
if (currentValues) {
|
|
3877
|
-
if (currentValues.length) {
|
|
3878
|
-
const index = currentValues.indexOf(value);
|
|
3879
|
-
currentValues.splice(index, 1);
|
|
3880
|
-
}
|
|
3881
|
-
if (currentValues.length == 0) {
|
|
3882
|
-
delete map[key];
|
|
3883
|
-
}
|
|
4108
|
+
if (currentValues.length == 0) {
|
|
4109
|
+
map.delete(key);
|
|
3884
4110
|
}
|
|
3885
4111
|
}
|
|
3886
4112
|
return currentValues;
|
|
@@ -3907,9 +4133,10 @@ function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, def
|
|
|
3907
4133
|
elements.forEach(element => cloakVals.push(cloakElement(element)));
|
|
3908
4134
|
const failedElements = [];
|
|
3909
4135
|
elementPropsMap.forEach((props, element) => {
|
|
3910
|
-
const styles =
|
|
4136
|
+
const styles = new Map();
|
|
3911
4137
|
props.forEach(prop => {
|
|
3912
|
-
const value =
|
|
4138
|
+
const value = driver.computeStyle(element, prop, defaultStyle);
|
|
4139
|
+
styles.set(prop, value);
|
|
3913
4140
|
// there is no easy way to detect this because a sub element could be removed
|
|
3914
4141
|
// by a parent animation element being detached.
|
|
3915
4142
|
if (!value || value.length == 0) {
|
|
@@ -4097,13 +4324,6 @@ class AnimationEngine {
|
|
|
4097
4324
|
}
|
|
4098
4325
|
}
|
|
4099
4326
|
|
|
4100
|
-
/**
|
|
4101
|
-
* @license
|
|
4102
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4103
|
-
*
|
|
4104
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
4105
|
-
* found in the LICENSE file at https://angular.io/license
|
|
4106
|
-
*/
|
|
4107
4327
|
/**
|
|
4108
4328
|
* Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
|
|
4109
4329
|
* detected.
|
|
@@ -4124,7 +4344,7 @@ function packageNonAnimatableStyles(element, styles) {
|
|
|
4124
4344
|
endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
|
|
4125
4345
|
}
|
|
4126
4346
|
}
|
|
4127
|
-
else if (styles) {
|
|
4347
|
+
else if (styles instanceof Map) {
|
|
4128
4348
|
startStyles = filterNonAnimatableStyles(styles);
|
|
4129
4349
|
}
|
|
4130
4350
|
return (startStyles || endStyles) ? new SpecialCasedStyles(element, startStyles, endStyles) :
|
|
@@ -4146,7 +4366,7 @@ class SpecialCasedStyles {
|
|
|
4146
4366
|
this._state = 0 /* Pending */;
|
|
4147
4367
|
let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
|
|
4148
4368
|
if (!initialStyles) {
|
|
4149
|
-
SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles =
|
|
4369
|
+
SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());
|
|
4150
4370
|
}
|
|
4151
4371
|
this._initialStyles = initialStyles;
|
|
4152
4372
|
}
|
|
@@ -4189,14 +4409,12 @@ class SpecialCasedStyles {
|
|
|
4189
4409
|
SpecialCasedStyles.initialStylesByElement = ( /* @__PURE__ */new WeakMap());
|
|
4190
4410
|
function filterNonAnimatableStyles(styles) {
|
|
4191
4411
|
let result = null;
|
|
4192
|
-
|
|
4193
|
-
for (let i = 0; i < props.length; i++) {
|
|
4194
|
-
const prop = props[i];
|
|
4412
|
+
styles.forEach((val, prop) => {
|
|
4195
4413
|
if (isNonAnimatableStyle(prop)) {
|
|
4196
|
-
result = result ||
|
|
4197
|
-
result
|
|
4414
|
+
result = result || new Map();
|
|
4415
|
+
result.set(prop, val);
|
|
4198
4416
|
}
|
|
4199
|
-
}
|
|
4417
|
+
});
|
|
4200
4418
|
return result;
|
|
4201
4419
|
}
|
|
4202
4420
|
function isNonAnimatableStyle(prop) {
|
|
@@ -4218,7 +4436,7 @@ class WebAnimationsPlayer {
|
|
|
4218
4436
|
this._destroyed = false;
|
|
4219
4437
|
this.time = 0;
|
|
4220
4438
|
this.parentPlayer = null;
|
|
4221
|
-
this.currentSnapshot =
|
|
4439
|
+
this.currentSnapshot = new Map();
|
|
4222
4440
|
this._duration = options['duration'];
|
|
4223
4441
|
this._delay = options['delay'] || 0;
|
|
4224
4442
|
this.time = this._duration + this._delay;
|
|
@@ -4241,7 +4459,7 @@ class WebAnimationsPlayer {
|
|
|
4241
4459
|
const keyframes = this.keyframes;
|
|
4242
4460
|
this.domPlayer =
|
|
4243
4461
|
this._triggerWebAnimation(this.element, keyframes, this.options);
|
|
4244
|
-
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] :
|
|
4462
|
+
this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();
|
|
4245
4463
|
this.domPlayer.addEventListener('finish', () => this._onFinish());
|
|
4246
4464
|
}
|
|
4247
4465
|
_preparePlayerBeforeStart() {
|
|
@@ -4253,11 +4471,18 @@ class WebAnimationsPlayer {
|
|
|
4253
4471
|
this.domPlayer.pause();
|
|
4254
4472
|
}
|
|
4255
4473
|
}
|
|
4474
|
+
_convertKeyframesToObject(keyframes) {
|
|
4475
|
+
const kfs = [];
|
|
4476
|
+
keyframes.forEach(frame => {
|
|
4477
|
+
kfs.push(Object.fromEntries(frame));
|
|
4478
|
+
});
|
|
4479
|
+
return kfs;
|
|
4480
|
+
}
|
|
4256
4481
|
/** @internal */
|
|
4257
4482
|
_triggerWebAnimation(element, keyframes, options) {
|
|
4258
4483
|
// jscompiler doesn't seem to know animate is a native property because it's not fully
|
|
4259
4484
|
// supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
|
|
4260
|
-
return element['animate'](keyframes, options);
|
|
4485
|
+
return element['animate'](this._convertKeyframesToObject(keyframes), options);
|
|
4261
4486
|
}
|
|
4262
4487
|
onStart(fn) {
|
|
4263
4488
|
this._onStartFns.push(fn);
|
|
@@ -4335,15 +4560,15 @@ class WebAnimationsPlayer {
|
|
|
4335
4560
|
return this._delay + this._duration;
|
|
4336
4561
|
}
|
|
4337
4562
|
beforeDestroy() {
|
|
4338
|
-
const styles =
|
|
4563
|
+
const styles = new Map();
|
|
4339
4564
|
if (this.hasStarted()) {
|
|
4340
4565
|
// note: this code is invoked only when the `play` function was called prior to this
|
|
4341
4566
|
// (thus `hasStarted` returns true), this implies that the code that initializes
|
|
4342
4567
|
// `_finalKeyframe` has also been executed and the non-null assertion can be safely used here
|
|
4343
4568
|
const finalKeyframe = this._finalKeyframe;
|
|
4344
|
-
|
|
4345
|
-
if (prop
|
|
4346
|
-
styles
|
|
4569
|
+
finalKeyframe.forEach((val, prop) => {
|
|
4570
|
+
if (prop !== 'offset') {
|
|
4571
|
+
styles.set(prop, this._finished ? val : computeStyle(this.element, prop));
|
|
4347
4572
|
}
|
|
4348
4573
|
});
|
|
4349
4574
|
}
|
|
@@ -4351,7 +4576,7 @@ class WebAnimationsPlayer {
|
|
|
4351
4576
|
}
|
|
4352
4577
|
/** @internal */
|
|
4353
4578
|
triggerCallback(phaseName) {
|
|
4354
|
-
const methods = phaseName
|
|
4579
|
+
const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;
|
|
4355
4580
|
methods.forEach(fn => fn());
|
|
4356
4581
|
methods.length = 0;
|
|
4357
4582
|
}
|
|
@@ -4361,6 +4586,14 @@ class WebAnimationsDriver {
|
|
|
4361
4586
|
validateStyleProperty(prop) {
|
|
4362
4587
|
return validateStyleProperty(prop);
|
|
4363
4588
|
}
|
|
4589
|
+
validateAnimatableStyleProperty(prop) {
|
|
4590
|
+
// Perform actual validation in dev mode only, in prod mode this check is a noop.
|
|
4591
|
+
if (ngDevMode) {
|
|
4592
|
+
const cssProp = camelCaseToDashCase(prop);
|
|
4593
|
+
return validateWebAnimatableStyleProperty(cssProp);
|
|
4594
|
+
}
|
|
4595
|
+
return true;
|
|
4596
|
+
}
|
|
4364
4597
|
matchesElement(_element, _selector) {
|
|
4365
4598
|
// This method is deprecated and no longer in use so we return false.
|
|
4366
4599
|
return false;
|
|
@@ -4385,18 +4618,17 @@ class WebAnimationsDriver {
|
|
|
4385
4618
|
if (easing) {
|
|
4386
4619
|
playerOptions['easing'] = easing;
|
|
4387
4620
|
}
|
|
4388
|
-
const previousStyles =
|
|
4621
|
+
const previousStyles = new Map();
|
|
4389
4622
|
const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);
|
|
4390
4623
|
if (allowPreviousPlayerStylesMerge(duration, delay)) {
|
|
4391
4624
|
previousWebAnimationPlayers.forEach(player => {
|
|
4392
|
-
|
|
4393
|
-
Object.keys(styles).forEach(prop => previousStyles[prop] = styles[prop]);
|
|
4625
|
+
player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));
|
|
4394
4626
|
});
|
|
4395
4627
|
}
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
const specialStyles = packageNonAnimatableStyles(element,
|
|
4399
|
-
return new WebAnimationsPlayer(element,
|
|
4628
|
+
let _keyframes = normalizeKeyframes(keyframes).map(styles => copyStyles(styles));
|
|
4629
|
+
_keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);
|
|
4630
|
+
const specialStyles = packageNonAnimatableStyles(element, _keyframes);
|
|
4631
|
+
return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);
|
|
4400
4632
|
}
|
|
4401
4633
|
}
|
|
4402
4634
|
|
|
@@ -4436,5 +4668,5 @@ class WebAnimationsDriver {
|
|
|
4436
4668
|
* Generated bundle index. Do not edit.
|
|
4437
4669
|
*/
|
|
4438
4670
|
|
|
4439
|
-
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, validateStyleProperty as ɵvalidateStyleProperty };
|
|
4671
|
+
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 };
|
|
4440
4672
|
//# sourceMappingURL=browser.mjs.map
|