refactor(animations): support browser animation rendering (#14578)
This commit is contained in:
committed by
Igor Minar
parent
88755b0dae
commit
830393d234
@@ -7,6 +7,7 @@ cd `dirname $0`
|
||||
PACKAGES=(core
|
||||
compiler
|
||||
common
|
||||
animations
|
||||
forms
|
||||
platform-browser
|
||||
platform-browser-dynamic
|
||||
@@ -14,7 +15,6 @@ PACKAGES=(core
|
||||
platform-server
|
||||
platform-webworker
|
||||
platform-webworker-dynamic
|
||||
animation
|
||||
upgrade
|
||||
router
|
||||
compiler-cli
|
||||
@@ -161,6 +161,10 @@ do
|
||||
JS_STATIC_PATH_ES5=${DEST_MODULE}/${PACKAGE}/static.es5.js
|
||||
JS_UPGRADE_PATH=${DEST_MODULE}/${PACKAGE}/upgrade.js
|
||||
JS_UPGRADE_PATH_ES5=${DEST_MODULE}/${PACKAGE}/upgrade.es5.js
|
||||
JS_ANIMATIONS_PATH=${DEST_MODULE}/${PACKAGE}/animations.js
|
||||
JS_ANIMATIONS_PATH_ES5=${DEST_MODULE}/${PACKAGE}/animations.es5.js
|
||||
JS_ANIMATIONS_TESTING_PATH=${DEST_MODULE}/${PACKAGE}/animations/testing.js
|
||||
JS_ANIMATIONS_TESTING_PATH_ES5=${DEST_MODULE}/${PACKAGE}/animations/testing.es5.js
|
||||
|
||||
# UMD/ES5
|
||||
UMD_ES5_PATH=${DEST_BUNDLES}/${PACKAGE}.umd.js
|
||||
@@ -170,6 +174,9 @@ do
|
||||
UMD_ES5_MIN_PATH=${DEST_BUNDLES}/${PACKAGE}.umd.min.js
|
||||
UMD_STATIC_ES5_MIN_PATH=${DEST_BUNDLES}/${PACKAGE}-static.umd.min.js
|
||||
UMD_UPGRADE_ES5_MIN_PATH=${DEST_BUNDLES}/${PACKAGE}-upgrade.umd.min.js
|
||||
UMD_ANIMATIONS_ES5_PATH=${DEST_BUNDLES}/${PACKAGE}-animations.umd.js
|
||||
UMD_ANIMATIONS_ES5_MIN_PATH=${DEST_BUNDLES}/${PACKAGE}-animations.umd.min.js
|
||||
UMD_ANIMATIONS_TESTING_ES5_PATH=${DEST_BUNDLES}/${PACKAGE}-animations-testing.umd.js
|
||||
|
||||
if [[ ${PACKAGE} != router ]]; then
|
||||
LICENSE_BANNER=${PWD}/modules/@angular/license-banner.txt
|
||||
@@ -218,6 +225,16 @@ do
|
||||
$TSC -p ${SRCDIR}/tsconfig-testing.json
|
||||
fi
|
||||
|
||||
if [[ -e ${SRCDIR}/tsconfig-animations.json ]]; then
|
||||
echo "====== [${PACKAGE}]: COMPILING (ANIMATIONS): ${TSC} -p ${SRCDIR}/tsconfig-animations.json"
|
||||
$TSC -p ${SRCDIR}/tsconfig-animations.json
|
||||
|
||||
if [[ -e ${SRCDIR}/tsconfig-animations-testing.json ]]; then
|
||||
echo "====== [${PACKAGE}]: COMPILING (ANIMATION TESTING): ${TSC} -p ${SRCDIR}/tsconfig-animations-testing.json"
|
||||
$TSC -p ${SRCDIR}/tsconfig-animations-testing.json
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -e ${SRCDIR}/tsconfig-static.json ]]; then
|
||||
echo "====== [${PACKAGE}]: COMPILING (STATIC): ${TSC} -p ${SRCDIR}/tsconfig-static.json"
|
||||
$TSC -p ${SRCDIR}/tsconfig-static.json
|
||||
@@ -357,6 +374,58 @@ do
|
||||
mv ${UMD_UPGRADE_ES5_PATH}.tmp ${UMD_UPGRADE_ES5_PATH}
|
||||
$UGLIFYJS -c --screw-ie8 --comments -o ${UMD_UPGRADE_ES5_MIN_PATH} ${UMD_UPGRADE_ES5_PATH}
|
||||
fi
|
||||
|
||||
if [[ -d animations ]]; then
|
||||
echo "====== Rollup ${PACKAGE} animations"
|
||||
../../../node_modules/.bin/rollup -i ${DESTDIR}/animations/index.js -o ${DESTDIR}/animations.tmp.js
|
||||
|
||||
echo "====== Downleveling ${PACKAGE} ANIMATIONS to ES5/UMD"
|
||||
[[ -e ${SRCDIR}/.babelrc-animations ]] && cp ${SRCDIR}/.babelrc-animations ${DESTDIR}/.babelrc
|
||||
$BABELJS ${DESTDIR}/animations.tmp.js -o ${UMD_ANIMATIONS_ES5_PATH}
|
||||
rm -f ${DESTDIR}/.babelrc
|
||||
|
||||
echo "====== Move ${PACKAGE} animations typings"
|
||||
rsync -a --exclude=*.js --exclude=*.js.map ${DESTDIR}/animations/ ${DESTDIR}/typings/animations
|
||||
mv ${DESTDIR}/typings/animations/index.d.ts ${DESTDIR}/typings/animations/animations.d.ts
|
||||
mv ${DESTDIR}/typings/animations/index.metadata.json ${DESTDIR}/typings/animations/animations.metadata.json
|
||||
|
||||
echo "====== Rollup ${PACKAGE} animations/testing"
|
||||
../../../node_modules/.bin/rollup -i ${DESTDIR}/animations/testing/index.js -o ${DESTDIR}/animations-testing.tmp.js
|
||||
|
||||
echo "====== Downleveling ${PACKAGE} ANIMATIONS TESTING to ES5/UMD"
|
||||
[[ -e ${SRCDIR}/.babelrc-animations-testing ]] && cp ${SRCDIR}/.babelrc-animations-testing ${DESTDIR}/.babelrc
|
||||
$BABELJS ${DESTDIR}/animations-testing.tmp.js -o ${UMD_ANIMATIONS_TESTING_ES5_PATH}
|
||||
rm -f ${DESTDIR}/.babelrc
|
||||
|
||||
echo "====== Move ${PACKAGE} animations testing typings"
|
||||
rsync -a --exclude=*.js --exclude=*.js.map ${DESTDIR}/animations/testing/ ${DESTDIR}/typings/animations/testing
|
||||
mv ${DESTDIR}/typings/animations/testing/index.d.ts ${DESTDIR}/typings/animations/testing/testing.d.ts
|
||||
mv ${DESTDIR}/typings/animations/testing/index.metadata.json ${DESTDIR}/typings/animations/testing/testing.metadata.json
|
||||
|
||||
rm -rf ${DESTDIR}/animations
|
||||
|
||||
mkdir ${DESTDIR}/animations && [[ -d ${DEST_MODULE}/${PACKAGE} ]] || mkdir ${DEST_MODULE}/${PACKAGE}
|
||||
mkdir ${DESTDIR}/animations/testing
|
||||
|
||||
getPackageContents "${PACKAGE}" "animations" > ${DESTDIR}/animations/package.json
|
||||
|
||||
echo '{"typings": "../../typings/animations/testing/testing.d.ts", "main": "../../bundles/platform-browser-animations-testing.umd.js", "module": "../../@angular/platform-browser/animations/testing.es5.js", "es2015": "../../@angular/platform-browser/animations/testing.js"}' > ${DESTDIR}/animations/testing/package.json
|
||||
|
||||
mv ${DESTDIR}/animations.tmp.js ${JS_ANIMATIONS_PATH}
|
||||
$BABELJS ${JS_ANIMATIONS_PATH} -o ${JS_ANIMATIONS_PATH_ES5}
|
||||
cat ${LICENSE_BANNER} > ${UMD_ANIMATIONS_ES5_PATH}.tmp
|
||||
cat ${UMD_ANIMATIONS_ES5_PATH} >> ${UMD_ANIMATIONS_ES5_PATH}.tmp
|
||||
mv ${UMD_ANIMATIONS_ES5_PATH}.tmp ${UMD_ANIMATIONS_ES5_PATH}
|
||||
$UGLIFYJS -c --screw-ie8 --comments -o ${UMD_ANIMATIONS_ES5_MIN_PATH} ${UMD_ANIMATIONS_ES5_PATH}
|
||||
|
||||
mkdir ${DEST_MODULE}/${PACKAGE}/animations
|
||||
|
||||
mv ${DESTDIR}/animations-testing.tmp.js ${JS_ANIMATIONS_TESTING_PATH}
|
||||
$BABELJS ${JS_ANIMATIONS_TESTING_PATH} -o ${JS_ANIMATIONS_TESTING_PATH_ES5}
|
||||
cat ${LICENSE_BANNER} > ${UMD_ANIMATIONS_TESTING_ES5_PATH}.tmp
|
||||
cat ${UMD_ANIMATIONS_TESTING_ES5_PATH} >> ${UMD_ANIMATIONS_TESTING_ES5_PATH}.tmp
|
||||
mv ${UMD_ANIMATIONS_TESTING_ES5_PATH}.tmp ${UMD_ANIMATIONS_TESTING_ES5_PATH}
|
||||
fi
|
||||
) 2>&1 | grep -v "as external dependency"
|
||||
|
||||
fi
|
||||
|
||||
+1
-1
@@ -36,4 +36,4 @@ gulp.task('tools:build', loadTask('tools-build'));
|
||||
gulp.task('check-cycle', loadTask('check-cycle'));
|
||||
gulp.task('serve', loadTask('serve', 'default'));
|
||||
gulp.task('serve-examples', loadTask('serve', 'examples'));
|
||||
gulp.task('changelog', loadTask('changelog'));
|
||||
gulp.task('changelog', loadTask('changelog'));
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"name": "@angular/animation",
|
||||
"version": "0.0.0-PLACEHOLDER",
|
||||
"description": "Angular - animation integration with web-animations",
|
||||
"main": "./bundles/animation.umd.js",
|
||||
"module": "./@angular/animation.es5.js",
|
||||
"es2015": "./@angular/animation.js",
|
||||
"typings": "./typings/animation.d.ts",
|
||||
"author": "angular",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@angular/core": "0.0.0-PLACEHOLDER"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.git"
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
export {AnimationModule} from './animation_module';
|
||||
export {Animation} from './dsl/animation';
|
||||
export {AUTO_STYLE, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationSequenceMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, animate, group, keyframes, sequence, state, style, transition} from './dsl/animation_metadata';
|
||||
export {AnimationTrigger, trigger} from './dsl/animation_trigger';
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {NgModule, ɵTransitionEngine} from '@angular/core';
|
||||
import {AnimationStyleNormalizer} from './dsl/style_normalization/animation_style_normalizer';
|
||||
import {WebAnimationsStyleNormalizer} from './dsl/style_normalization/web_animations_style_normalizer';
|
||||
import {AnimationDriver, NoOpAnimationDriver} from './engine/animation_driver';
|
||||
import {DomAnimationTransitionEngine} from './engine/dom_animation_transition_engine';
|
||||
import {WebAnimationsDriver, supportsWebAnimations} from './engine/web_animations/web_animations_driver';
|
||||
|
||||
export function resolveDefaultAnimationDriver(): AnimationDriver {
|
||||
if (supportsWebAnimations()) {
|
||||
return new WebAnimationsDriver();
|
||||
}
|
||||
return new NoOpAnimationDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* The module that includes all animation code such as `style()`, `animate()`, `trigger()`, etc...
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
@NgModule({
|
||||
providers: [
|
||||
{provide: AnimationDriver, useFactory: resolveDefaultAnimationDriver},
|
||||
{provide: AnimationStyleNormalizer, useClass: WebAnimationsStyleNormalizer},
|
||||
{provide: ɵTransitionEngine, useClass: DomAnimationTransitionEngine}
|
||||
]
|
||||
})
|
||||
export class AnimationModule {
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as meta from './animation_metadata';
|
||||
|
||||
export interface AnimationDslVisitor {
|
||||
visitState(ast: meta.AnimationStateMetadata, context: any): any;
|
||||
visitTransition(ast: meta.AnimationTransitionMetadata, context: any): any;
|
||||
visitSequence(ast: meta.AnimationSequenceMetadata, context: any): any;
|
||||
visitGroup(ast: meta.AnimationGroupMetadata, context: any): any;
|
||||
visitAnimate(ast: meta.AnimationAnimateMetadata, context: any): any;
|
||||
visitStyle(ast: meta.AnimationStyleMetadata, context: any): any;
|
||||
visitKeyframeSequence(ast: meta.AnimationKeyframesSequenceMetadata, context: any): any;
|
||||
}
|
||||
|
||||
export function visitAnimationNode(
|
||||
visitor: AnimationDslVisitor, node: meta.AnimationMetadata, context: any) {
|
||||
switch (node.type) {
|
||||
case meta.AnimationMetadataType.State:
|
||||
return visitor.visitState(<meta.AnimationStateMetadata>node, context);
|
||||
case meta.AnimationMetadataType.Transition:
|
||||
return visitor.visitTransition(<meta.AnimationTransitionMetadata>node, context);
|
||||
case meta.AnimationMetadataType.Sequence:
|
||||
return visitor.visitSequence(<meta.AnimationSequenceMetadata>node, context);
|
||||
case meta.AnimationMetadataType.Group:
|
||||
return visitor.visitGroup(<meta.AnimationGroupMetadata>node, context);
|
||||
case meta.AnimationMetadataType.Animate:
|
||||
return visitor.visitAnimate(<meta.AnimationAnimateMetadata>node, context);
|
||||
case meta.AnimationMetadataType.KeyframeSequence:
|
||||
return visitor.visitKeyframeSequence(<meta.AnimationKeyframesSequenceMetadata>node, context);
|
||||
case meta.AnimationMetadataType.Style:
|
||||
return visitor.visitStyle(<meta.AnimationStyleMetadata>node, context);
|
||||
default:
|
||||
throw new Error(`Unable to resolve animation metadata node #${node.type}`);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {AnimationPlayer, ɵNoOpAnimationPlayer} from '@angular/core';
|
||||
import {StyleData} from '../common/style_data';
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export class NoOpAnimationDriver implements AnimationDriver {
|
||||
animate(
|
||||
element: any, keyframes: StyleData[], duration: number, delay: number, easing: string,
|
||||
previousPlayers: AnimationPlayer[] = []): AnimationPlayer {
|
||||
return new ɵNoOpAnimationPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export abstract class AnimationDriver {
|
||||
static NOOP: AnimationDriver = new NoOpAnimationDriver();
|
||||
abstract animate(
|
||||
element: any, keyframes: StyleData[], duration: number, delay: number, easing: string,
|
||||
previousPlayers?: AnimationPlayer[]): AnimationPlayer;
|
||||
}
|
||||
@@ -1,235 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AnimationPlayer, Injectable, ɵAnimationGroupPlayer, ɵNoOpAnimationPlayer, ɵTransitionEngine} from '@angular/core';
|
||||
import {StyleData} from '../common/style_data';
|
||||
import {AnimationTimelineInstruction} from '../dsl/animation_timeline_instruction';
|
||||
import {AnimationTransitionInstruction} from '../dsl/animation_transition_instruction';
|
||||
import {AnimationStyleNormalizer} from '../dsl/style_normalization/animation_style_normalizer';
|
||||
|
||||
import {AnimationDriver} from './animation_driver';
|
||||
import {AnimationEngineInstruction, AnimationTransitionInstructionType} from './animation_engine_instruction';
|
||||
|
||||
export declare type AnimationPlayerTuple = {
|
||||
element: any; player: AnimationPlayer;
|
||||
};
|
||||
|
||||
@Injectable()
|
||||
export class DomAnimationTransitionEngine extends ɵTransitionEngine {
|
||||
private _flaggedInserts = new Set<any>();
|
||||
private _queuedRemovals: any[] = [];
|
||||
private _queuedAnimations: AnimationPlayerTuple[] = [];
|
||||
private _activeElementAnimations = new Map<any, AnimationPlayer[]>();
|
||||
private _activeTransitionAnimations = new Map<any, {[triggerName: string]: AnimationPlayer}>();
|
||||
|
||||
constructor(private _driver: AnimationDriver, private _normalizer: AnimationStyleNormalizer) {
|
||||
super();
|
||||
}
|
||||
|
||||
insertNode(container: any, element: any) {
|
||||
container.appendChild(element);
|
||||
this._flaggedInserts.add(element);
|
||||
}
|
||||
|
||||
removeNode(element: any) { this._queuedRemovals.push(element); }
|
||||
|
||||
process(element: any, instructions: AnimationEngineInstruction[]): AnimationPlayer {
|
||||
const players = instructions.map(instruction => {
|
||||
if (instruction.type == AnimationTransitionInstructionType.TransitionAnimation) {
|
||||
return this._handleTransitionAnimation(
|
||||
element, <AnimationTransitionInstruction>instruction);
|
||||
}
|
||||
if (instruction.type == AnimationTransitionInstructionType.TimelineAnimation) {
|
||||
return this._handleTimelineAnimation(
|
||||
element, <AnimationTimelineInstruction>instruction, []);
|
||||
}
|
||||
return new ɵNoOpAnimationPlayer();
|
||||
});
|
||||
return optimizeGroupPlayer(players);
|
||||
}
|
||||
|
||||
private _handleTransitionAnimation(element: any, instruction: AnimationTransitionInstruction):
|
||||
AnimationPlayer {
|
||||
const triggerName = instruction.triggerName;
|
||||
const elmTransitionMap = getOrSetAsInMap(this._activeTransitionAnimations, element, {});
|
||||
|
||||
let previousPlayers: AnimationPlayer[];
|
||||
if (instruction.isRemovalTransition) {
|
||||
// we make a copy of the array because the actual source array is modified
|
||||
// each time a player is finished/destroyed (the forEach loop would fail otherwise)
|
||||
previousPlayers = copyArray(this._activeElementAnimations.get(element));
|
||||
} else {
|
||||
previousPlayers = [];
|
||||
const existingPlayer = elmTransitionMap[triggerName];
|
||||
if (existingPlayer) {
|
||||
previousPlayers.push(existingPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
// it's important to do this step before destroying the players
|
||||
// so that the onDone callback below won't fire before this
|
||||
eraseStyles(element, instruction.fromStyles);
|
||||
|
||||
// we first run this so that the previous animation player
|
||||
// data can be passed into the successive animation players
|
||||
const players = instruction.timelines.map(
|
||||
timelineInstruction => this._buildPlayer(element, timelineInstruction, previousPlayers));
|
||||
|
||||
previousPlayers.forEach(previousPlayer => previousPlayer.destroy());
|
||||
|
||||
const player = optimizeGroupPlayer(players);
|
||||
player.onDone(() => {
|
||||
player.destroy();
|
||||
const elmTransitionMap = this._activeTransitionAnimations.get(element);
|
||||
if (elmTransitionMap) {
|
||||
delete elmTransitionMap[triggerName];
|
||||
if (Object.keys(elmTransitionMap).length == 0) {
|
||||
this._activeTransitionAnimations.delete(element);
|
||||
}
|
||||
}
|
||||
deleteFromArrayMap(this._activeElementAnimations, element, player);
|
||||
setStyles(element, instruction.toStyles);
|
||||
});
|
||||
|
||||
this._queuePlayer(element, player);
|
||||
elmTransitionMap[triggerName] = player;
|
||||
|
||||
return player;
|
||||
}
|
||||
|
||||
private _handleTimelineAnimation(
|
||||
element: any, instruction: AnimationTimelineInstruction,
|
||||
previousPlayers: AnimationPlayer[]): AnimationPlayer {
|
||||
const player = this._buildPlayer(element, instruction, previousPlayers);
|
||||
player.onDestroy(() => { deleteFromArrayMap(this._activeElementAnimations, element, player); });
|
||||
this._queuePlayer(element, player);
|
||||
return player;
|
||||
}
|
||||
|
||||
private _buildPlayer(
|
||||
element: any, instruction: AnimationTimelineInstruction,
|
||||
previousPlayers: AnimationPlayer[]): AnimationPlayer {
|
||||
return this._driver.animate(
|
||||
element, this._normalizeKeyframes(instruction.keyframes), instruction.duration,
|
||||
instruction.delay, instruction.easing, previousPlayers);
|
||||
}
|
||||
|
||||
private _normalizeKeyframes(keyframes: StyleData[]): StyleData[] {
|
||||
const errors: string[] = [];
|
||||
const normalizedKeyframes: StyleData[] = [];
|
||||
keyframes.forEach(kf => {
|
||||
const normalizedKeyframe: StyleData = {};
|
||||
Object.keys(kf).forEach(prop => {
|
||||
let normalizedProp = prop;
|
||||
let normalizedValue = kf[prop];
|
||||
if (prop != 'offset') {
|
||||
normalizedProp = this._normalizer.normalizePropertyName(prop, errors);
|
||||
normalizedValue =
|
||||
this._normalizer.normalizeStyleValue(prop, normalizedProp, kf[prop], errors);
|
||||
}
|
||||
normalizedKeyframe[normalizedProp] = normalizedValue;
|
||||
});
|
||||
normalizedKeyframes.push(normalizedKeyframe);
|
||||
});
|
||||
if (errors.length) {
|
||||
const LINE_START = '\n - ';
|
||||
throw new Error(
|
||||
`Unable to animate due to the following errors:${LINE_START}${errors.join(LINE_START)}`);
|
||||
}
|
||||
return normalizedKeyframes;
|
||||
}
|
||||
|
||||
private _queuePlayer(element: any, player: AnimationPlayer) {
|
||||
const tuple = <AnimationPlayerTuple>{element, player};
|
||||
this._queuedAnimations.push(tuple);
|
||||
player.init();
|
||||
|
||||
const elementAnimations = getOrSetAsInMap(this._activeElementAnimations, element, []);
|
||||
elementAnimations.push(player);
|
||||
}
|
||||
|
||||
triggerAnimations() {
|
||||
while (this._queuedAnimations.length) {
|
||||
const {player, element} = this._queuedAnimations.shift();
|
||||
// in the event that an animation throws an error then we do
|
||||
// not want to re-run animations on any previous animations
|
||||
// if they have already been kicked off beforehand
|
||||
if (!player.hasStarted()) {
|
||||
player.play();
|
||||
}
|
||||
}
|
||||
|
||||
this._queuedRemovals.forEach(element => {
|
||||
if (this._flaggedInserts.has(element)) return;
|
||||
|
||||
let parent = element;
|
||||
let players: AnimationPlayer[];
|
||||
while (parent = parent.parentNode) {
|
||||
const match = this._activeElementAnimations.get(parent);
|
||||
if (match) {
|
||||
players = match;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (players) {
|
||||
optimizeGroupPlayer(players).onDone(() => remove(element));
|
||||
} else {
|
||||
if (element.parentNode) {
|
||||
remove(element);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this._queuedRemovals = [];
|
||||
this._flaggedInserts.clear();
|
||||
}
|
||||
}
|
||||
|
||||
function getOrSetAsInMap(map: Map<any, any>, key: any, defaultValue: any) {
|
||||
let value = map.get(key);
|
||||
if (!value) {
|
||||
map.set(key, value = defaultValue);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function deleteFromArrayMap(map: Map<any, any[]>, key: any, value: any) {
|
||||
let arr = map.get(key);
|
||||
if (arr) {
|
||||
const index = arr.indexOf(value);
|
||||
if (index >= 0) {
|
||||
arr.splice(index, 1);
|
||||
if (arr.length == 0) {
|
||||
map.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setStyles(element: any, styles: StyleData) {
|
||||
Object.keys(styles).forEach(prop => { element.style[prop] = styles[prop]; });
|
||||
}
|
||||
|
||||
function eraseStyles(element: any, styles: StyleData) {
|
||||
Object.keys(styles).forEach(prop => {
|
||||
// IE requires '' instead of null
|
||||
// see https://github.com/angular/angular/issues/7916
|
||||
element.style[prop] = '';
|
||||
});
|
||||
}
|
||||
|
||||
function optimizeGroupPlayer(players: AnimationPlayer[]): AnimationPlayer {
|
||||
return players.length == 1 ? players[0] : new ɵAnimationGroupPlayer(players);
|
||||
}
|
||||
|
||||
function copyArray(source: any[]): any[] {
|
||||
return source ? source.splice(0) : [];
|
||||
}
|
||||
|
||||
function remove(element: any) {
|
||||
element.parentNode.removeChild(element);
|
||||
}
|
||||
-470
File diff suppressed because it is too large
Load Diff
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {AnimationPlayer, ɵNoOpAnimationPlayer} from '@angular/core';
|
||||
import {StyleData} from '../src/common/style_data';
|
||||
import {AnimationDriver} from '../src/engine/animation_driver';
|
||||
|
||||
export class MockAnimationDriver implements AnimationDriver {
|
||||
static log: AnimationPlayer[] = [];
|
||||
|
||||
animate(
|
||||
element: any, keyframes: StyleData[], duration: number, delay: number, easing: string,
|
||||
previousPlayers: AnimationPlayer[] = []): AnimationPlayer {
|
||||
const player =
|
||||
new MockAnimationPlayer(element, keyframes, duration, delay, easing, previousPlayers);
|
||||
MockAnimationDriver.log.push(<AnimationPlayer>player);
|
||||
return <AnimationPlayer>player;
|
||||
}
|
||||
}
|
||||
|
||||
export class MockAnimationPlayer extends ɵNoOpAnimationPlayer {
|
||||
constructor(
|
||||
public element: any, public keyframes: StyleData[], public duration: number,
|
||||
public delay: number, public easing: string, public previousPlayers: AnimationPlayer[]) {
|
||||
super();
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"extends": "./tsconfig-build",
|
||||
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../dist/packages-dist/animation",
|
||||
"paths": {
|
||||
"@angular/core": ["../../../dist/packages-dist/core/"],
|
||||
"@angular/animation": ["../../../dist/packages-dist/animation/"]
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"testing/index.ts",
|
||||
"../../../node_modules/zone.js/dist/zone.js.d.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"strictMetadataEmit": true
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
"plugins": [["transform-es2015-modules-umd", {
|
||||
"globals": {
|
||||
"@angular/core": "ng.core",
|
||||
"@angular/animation": "ng.animation",
|
||||
"@angular/animations": "ng.animations",
|
||||
"rxjs/Observable": "Rx",
|
||||
"rxjs/Subject": "Rx"
|
||||
},
|
||||
+1
-2
@@ -4,8 +4,7 @@
|
||||
"plugins": [["transform-es2015-modules-umd", {
|
||||
"globals": {
|
||||
"@angular/core": "ng.core",
|
||||
"@angular/animation": "ng.animation",
|
||||
"@angular/animation/testing": "ng.animation.testing",
|
||||
"@angular/animations": "ng.animations",
|
||||
"rxjs/Observable": "Rx",
|
||||
"rxjs/Subject": "Rx"
|
||||
},
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@angular/animations",
|
||||
"version": "0.0.0-PLACEHOLDER",
|
||||
"description": "Angular - animations integration with web-animationss",
|
||||
"main": "./bundles/animations.umd.js",
|
||||
"module": "./@angular/animations.es5.js",
|
||||
"es2015": "./@angular/animations.js",
|
||||
"typings": "./typings/animations.d.ts",
|
||||
"author": "angular",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@angular/core": "0.0.0-PLACEHOLDER"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/angular/angular.git"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -11,4 +11,4 @@
|
||||
* @description
|
||||
* Entry point for all public APIs of the animation package.
|
||||
*/
|
||||
export * from './src/animation';
|
||||
export * from './src/animations';
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* An instance of this class is returned as an event parameter when an animation
|
||||
* callback is captured for an animation either during the start or done phase.
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* host: {
|
||||
* '[@myAnimationTrigger]': 'someExpression',
|
||||
* '(@myAnimationTrigger.start)': 'captureStartEvent($event)',
|
||||
* '(@myAnimationTrigger.done)': 'captureDoneEvent($event)',
|
||||
* },
|
||||
* animations: [
|
||||
* trigger("myAnimationTrigger", [
|
||||
* // ...
|
||||
* ])
|
||||
* ]
|
||||
* })
|
||||
* class MyComponent {
|
||||
* someExpression: any = false;
|
||||
* captureStartEvent(event: AnimationEvent) {
|
||||
* // the toState, fromState and totalTime data is accessible from the event variable
|
||||
* }
|
||||
*
|
||||
* captureDoneEvent(event: AnimationEvent) {
|
||||
* // the toState, fromState and totalTime data is accessible from the event variable
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export interface AnimationEvent {
|
||||
fromState: string;
|
||||
toState: string;
|
||||
totalTime: number;
|
||||
phaseName: string;
|
||||
element: any;
|
||||
triggerName: string;
|
||||
}
|
||||
Regular → Executable
+76
-7
@@ -5,14 +5,20 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {StyleData} from '../common/style_data';
|
||||
export interface ɵStyleData { [key: string]: string|number; }
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export declare type AnimateTimings = {
|
||||
duration: number,
|
||||
delay: number,
|
||||
easing: string
|
||||
};
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export const enum AnimationMetadataType {
|
||||
State,
|
||||
Transition,
|
||||
@@ -33,6 +39,14 @@ export const AUTO_STYLE = '*';
|
||||
*/
|
||||
export interface AnimationMetadata { type: AnimationMetadataType; }
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export interface AnimationTriggerMetadata {
|
||||
name: string;
|
||||
definitions: AnimationMetadata[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata representing the entry of animations. Instances of this class are provided via the
|
||||
* animation DSL when the {@link state state animation function} is called.
|
||||
@@ -72,7 +86,7 @@ export interface AnimationKeyframesSequenceMetadata extends AnimationMetadata {
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export interface AnimationStyleMetadata extends AnimationMetadata {
|
||||
styles: StyleData[];
|
||||
styles: {[key: string]: string | number}[];
|
||||
offset: number;
|
||||
}
|
||||
|
||||
@@ -103,6 +117,61 @@ export interface AnimationSequenceMetadata extends AnimationMetadata { steps: An
|
||||
*/
|
||||
export interface AnimationGroupMetadata extends AnimationMetadata { steps: AnimationMetadata[]; }
|
||||
|
||||
/**
|
||||
* `trigger` is an animation-specific function that is designed to be used inside of Angular2's
|
||||
animation DSL language. If this information is new, please navigate to the {@link
|
||||
Component#animations-anchor component animations metadata page} to gain a better understanding of
|
||||
how animations in Angular2 are used.
|
||||
*
|
||||
* `trigger` Creates an animation trigger which will a list of {@link state state} and {@link
|
||||
transition transition} entries that will be evaluated when the expression bound to the trigger
|
||||
changes.
|
||||
*
|
||||
* Triggers are registered within the component annotation data under the {@link
|
||||
Component#animations-anchor animations section}. An animation trigger can be placed on an element
|
||||
within a template by referencing the name of the trigger followed by the expression value that the
|
||||
trigger is bound to (in the form of `[@triggerName]="expression"`.
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* `trigger` will create an animation trigger reference based on the provided `name` value. The
|
||||
provided `animation` value is expected to be an array consisting of {@link state state} and {@link
|
||||
transition transition} declarations.
|
||||
*
|
||||
* ```typescript
|
||||
* @Component({
|
||||
* selector: 'my-component',
|
||||
* templateUrl: 'my-component-tpl.html',
|
||||
* animations: [
|
||||
* trigger("myAnimationTrigger", [
|
||||
* state(...),
|
||||
* state(...),
|
||||
* transition(...),
|
||||
* transition(...)
|
||||
* ])
|
||||
* ]
|
||||
* })
|
||||
* class MyComponent {
|
||||
* myStatusExp = "something";
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* The template associated with this component will make use of the `myAnimationTrigger` animation
|
||||
trigger by binding to an element within its template code.
|
||||
*
|
||||
* ```html
|
||||
* <!-- somewhere inside of my-component-tpl.html -->
|
||||
* <div [@myAnimationTrigger]="myStatusExp">...</div>
|
||||
tools/gulp-tasks/validate-commit-message.js ```
|
||||
*
|
||||
* {@example core/animation/ts/dsl/animation_example.ts region='Component'}
|
||||
*
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export function trigger(name: string, definitions: AnimationMetadata[]): AnimationTriggerMetadata {
|
||||
return {name, definitions};
|
||||
}
|
||||
|
||||
/**
|
||||
* `animate` is an animation-specific function that is designed to be used inside of Angular2's
|
||||
* animation DSL language. If this information is new, please navigate to the {@link
|
||||
@@ -272,15 +341,15 @@ export function sequence(steps: AnimationMetadata[]): AnimationSequenceMetadata
|
||||
export function style(
|
||||
tokens: {[key: string]: string | number} |
|
||||
Array<{[key: string]: string | number}>): AnimationStyleMetadata {
|
||||
let input: StyleData[];
|
||||
let input: ɵStyleData[];
|
||||
let offset: number = null;
|
||||
if (Array.isArray(tokens)) {
|
||||
input = <StyleData[]>tokens;
|
||||
input = <ɵStyleData[]>tokens;
|
||||
} else {
|
||||
input = [<StyleData>tokens];
|
||||
input = [<ɵStyleData>tokens];
|
||||
}
|
||||
input.forEach(entry => {
|
||||
const entryOffset = (entry as StyleData)['offset'];
|
||||
const entryOffset = (entry as ɵStyleData)['offset'];
|
||||
if (entryOffset != null) {
|
||||
offset = offset == null ? parseFloat(<string>entryOffset) : offset;
|
||||
}
|
||||
@@ -288,7 +357,7 @@ export function style(
|
||||
return _style(offset, input);
|
||||
}
|
||||
|
||||
function _style(offset: number, styles: StyleData[]): AnimationStyleMetadata {
|
||||
function _style(offset: number, styles: ɵStyleData[]): AnimationStyleMetadata {
|
||||
return {type: AnimationMetadataType.Style, styles: styles, offset: offset};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* @module
|
||||
* @description
|
||||
* Entry point for all animation APIs of the animation package.
|
||||
*/
|
||||
export {AnimationEvent} from './animation_event';
|
||||
export {AUTO_STYLE, AnimateTimings, AnimationAnimateMetadata, AnimationGroupMetadata, AnimationKeyframesSequenceMetadata, AnimationMetadata, AnimationMetadataType, AnimationSequenceMetadata, AnimationStateMetadata, AnimationStyleMetadata, AnimationTransitionMetadata, AnimationTriggerMetadata, animate, group, keyframes, sequence, state, style, transition, trigger, ɵStyleData} from './animation_metadata';
|
||||
export {AnimationPlayer, NoOpAnimationPlayer} from './players/animation_player';
|
||||
|
||||
export * from './private_export';
|
||||
@@ -0,0 +1,109 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {scheduleMicroTask} from '../util';
|
||||
import {AnimationPlayer} from './animation_player';
|
||||
|
||||
export class AnimationGroupPlayer implements AnimationPlayer {
|
||||
private _onDoneFns: Function[] = [];
|
||||
private _onStartFns: Function[] = [];
|
||||
private _finished = false;
|
||||
private _started = false;
|
||||
private _destroyed = false;
|
||||
private _onDestroyFns: Function[] = [];
|
||||
|
||||
public parentPlayer: AnimationPlayer = null;
|
||||
|
||||
constructor(private _players: AnimationPlayer[]) {
|
||||
let count = 0;
|
||||
const total = this._players.length;
|
||||
if (total == 0) {
|
||||
scheduleMicroTask(() => this._onFinish());
|
||||
} else {
|
||||
this._players.forEach(player => {
|
||||
player.parentPlayer = this;
|
||||
player.onDone(() => {
|
||||
if (++count >= total) {
|
||||
this._onFinish();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _onFinish() {
|
||||
if (!this._finished) {
|
||||
this._finished = true;
|
||||
this._onDoneFns.forEach(fn => fn());
|
||||
this._onDoneFns = [];
|
||||
}
|
||||
}
|
||||
|
||||
init(): void { this._players.forEach(player => player.init()); }
|
||||
|
||||
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||
|
||||
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||
|
||||
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
|
||||
|
||||
hasStarted() { return this._started; }
|
||||
|
||||
play() {
|
||||
if (!this.parentPlayer) {
|
||||
this.init();
|
||||
}
|
||||
if (!this.hasStarted()) {
|
||||
this._onStartFns.forEach(fn => fn());
|
||||
this._onStartFns = [];
|
||||
this._started = true;
|
||||
}
|
||||
this._players.forEach(player => player.play());
|
||||
}
|
||||
|
||||
pause(): void { this._players.forEach(player => player.pause()); }
|
||||
|
||||
restart(): void { this._players.forEach(player => player.restart()); }
|
||||
|
||||
finish(): void {
|
||||
this._onFinish();
|
||||
this._players.forEach(player => player.finish());
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
if (!this._destroyed) {
|
||||
this._onFinish();
|
||||
this._players.forEach(player => player.destroy());
|
||||
this._destroyed = true;
|
||||
this._onDestroyFns.forEach(fn => fn());
|
||||
this._onDestroyFns = [];
|
||||
}
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._players.forEach(player => player.reset());
|
||||
this._destroyed = false;
|
||||
this._finished = false;
|
||||
this._started = false;
|
||||
}
|
||||
|
||||
setPosition(p: number): void {
|
||||
this._players.forEach(player => { player.setPosition(p); });
|
||||
}
|
||||
|
||||
getPosition(): number {
|
||||
let min = 0;
|
||||
this._players.forEach(player => {
|
||||
const p = player.getPosition();
|
||||
min = Math.min(p, min);
|
||||
});
|
||||
return min;
|
||||
}
|
||||
|
||||
get players(): AnimationPlayer[] { return this._players; }
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {scheduleMicroTask} from '../util';
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export abstract class AnimationPlayer {
|
||||
abstract onDone(fn: () => void): void;
|
||||
abstract onStart(fn: () => void): void;
|
||||
abstract onDestroy(fn: () => void): void;
|
||||
abstract init(): void;
|
||||
abstract hasStarted(): boolean;
|
||||
abstract play(): void;
|
||||
abstract pause(): void;
|
||||
abstract restart(): void;
|
||||
abstract finish(): void;
|
||||
abstract destroy(): void;
|
||||
abstract reset(): void;
|
||||
abstract setPosition(p: any /** TODO #9100 */): void;
|
||||
abstract getPosition(): number;
|
||||
get parentPlayer(): AnimationPlayer { throw new Error('NOT IMPLEMENTED: Base Class'); }
|
||||
set parentPlayer(player: AnimationPlayer) { throw new Error('NOT IMPLEMENTED: Base Class'); }
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental Animation support is experimental.
|
||||
*/
|
||||
export class NoOpAnimationPlayer implements AnimationPlayer {
|
||||
private _onDoneFns: Function[] = [];
|
||||
private _onStartFns: Function[] = [];
|
||||
private _onDestroyFns: Function[] = [];
|
||||
private _started = false;
|
||||
private _destroyed = false;
|
||||
private _finished = false;
|
||||
public parentPlayer: AnimationPlayer = null;
|
||||
constructor() { scheduleMicroTask(() => this._onFinish()); }
|
||||
private _onFinish() {
|
||||
if (!this._finished) {
|
||||
this._finished = true;
|
||||
this._onDoneFns.forEach(fn => fn());
|
||||
this._onDoneFns = [];
|
||||
}
|
||||
}
|
||||
onStart(fn: () => void): void { this._onStartFns.push(fn); }
|
||||
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
|
||||
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
|
||||
hasStarted(): boolean { return this._started; }
|
||||
init(): void {}
|
||||
play(): void {
|
||||
if (!this.hasStarted()) {
|
||||
this._onStartFns.forEach(fn => fn());
|
||||
this._onStartFns = [];
|
||||
}
|
||||
this._started = true;
|
||||
}
|
||||
pause(): void {}
|
||||
restart(): void {}
|
||||
finish(): void { this._onFinish(); }
|
||||
destroy(): void {
|
||||
if (!this._destroyed) {
|
||||
this._destroyed = true;
|
||||
this.finish();
|
||||
this._onDestroyFns.forEach(fn => fn());
|
||||
this._onDestroyFns = [];
|
||||
}
|
||||
}
|
||||
reset(): void {}
|
||||
setPosition(p: number): void {}
|
||||
getPosition(): number { return 0; }
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
export {AnimationGroupPlayer as ɵAnimationGroupPlayer} from './players/animation_group_player';
|
||||
+4
-1
@@ -5,4 +5,7 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
export interface StyleData { [key: string]: string|number; }
|
||||
export function scheduleMicroTask(cb: () => any) {
|
||||
// FIXME
|
||||
setTimeout(cb, 0);
|
||||
}
|
||||
+4
-3
@@ -6,9 +6,10 @@
|
||||
"experimentalDecorators": true,
|
||||
"module": "es2015",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "../../../dist/packages-dist/animation",
|
||||
"outDir": "../../../dist/packages-dist/animations",
|
||||
"paths": {
|
||||
"@angular/core": ["../../../dist/packages-dist/core"]
|
||||
"@angular/core": ["../../../dist/packages-dist/core"],
|
||||
"@angular/core/testing": ["../../../dist/packages-dist/core/testing"]
|
||||
},
|
||||
"rootDir": ".",
|
||||
"sourceMap": true,
|
||||
@@ -28,6 +29,6 @@
|
||||
"annotateForClosureCompiler": true,
|
||||
"strictMetadataEmit": true,
|
||||
"flatModuleOutFile": "index.js",
|
||||
"flatModuleId": "@angular/animation"
|
||||
"flatModuleId": "@angular/animations"
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ export class CompileTemplateMetadata {
|
||||
styles: string[];
|
||||
styleUrls: string[];
|
||||
externalStylesheets: CompileStylesheetMetadata[];
|
||||
animations: CompileAnimationEntryMetadata[];
|
||||
animations: any[];
|
||||
ngContentSelectors: string[];
|
||||
interpolation: [string, string];
|
||||
constructor(
|
||||
@@ -263,7 +263,7 @@ export class CompileTemplateMetadata {
|
||||
styleUrls?: string[],
|
||||
externalStylesheets?: CompileStylesheetMetadata[],
|
||||
ngContentSelectors?: string[],
|
||||
animations?: CompileAnimationEntryMetadata[],
|
||||
animations?: any[],
|
||||
interpolation?: [string, string],
|
||||
} = {}) {
|
||||
this.encapsulation = encapsulation;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
import {Compiler, ComponentFactory, Inject, Injector, ModuleWithComponentFactories, NgModuleFactory, Type, ɵgetComponentFactoryViewClass as getComponentFactoryViewClass} from '@angular/core';
|
||||
|
||||
import {AnimationCompiler} from '../animation/animation_compiler';
|
||||
import {AnimationCompiler, AnimationEntryCompileResult} from '../animation/animation_compiler';
|
||||
import {AnimationParser} from '../animation/animation_parser';
|
||||
import {CompileDirectiveMetadata, CompileIdentifierMetadata, CompileNgModuleMetadata, ProviderMeta, ProxyClass, createHostComponentMeta, identifierName} from '../compile_metadata';
|
||||
import {CompilerConfig} from '../config';
|
||||
@@ -272,7 +272,8 @@ export class JitCompiler implements Compiler {
|
||||
(r) => { externalStylesheetsByModuleUrl.set(r.meta.moduleUrl, r); });
|
||||
this._resolveStylesCompileResult(
|
||||
stylesCompileResult.componentStylesheet, externalStylesheetsByModuleUrl);
|
||||
const parsedAnimations = this._animationParser.parseComponent(compMeta);
|
||||
const parsedAnimations =
|
||||
this._compilerConfig.useViewEngine ? [] : this._animationParser.parseComponent(compMeta);
|
||||
const directives =
|
||||
template.directives.map(dir => this._metadataResolver.getDirectiveSummary(dir.reference));
|
||||
const pipes = template.ngModule.transitiveModule.pipes.map(
|
||||
@@ -280,7 +281,8 @@ export class JitCompiler implements Compiler {
|
||||
const {template: parsedTemplate, pipes: usedPipes} = this._templateParser.parse(
|
||||
compMeta, compMeta.template.template, directives, pipes, template.ngModule.schemas,
|
||||
identifierName(compMeta.type));
|
||||
const compiledAnimations =
|
||||
const compiledAnimations = this._compilerConfig.useViewEngine ?
|
||||
[] :
|
||||
this._animationCompiler.compile(identifierName(compMeta.type), parsedAnimations);
|
||||
const compileResult = this._viewCompiler.compileComponent(
|
||||
compMeta, parsedTemplate, ir.variable(stylesCompileResult.componentStylesheet.stylesVar),
|
||||
|
||||
@@ -308,9 +308,14 @@ export class CompileMetadataResolver {
|
||||
assertArrayOfStrings('styleUrls', dirMeta.styleUrls);
|
||||
assertInterpolationSymbols('interpolation', dirMeta.interpolation);
|
||||
|
||||
const animations = dirMeta.animations ?
|
||||
dirMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
|
||||
null;
|
||||
let animations: any[];
|
||||
if (this._config.useViewEngine) {
|
||||
animations = dirMeta.animations;
|
||||
} else {
|
||||
animations = dirMeta.animations ?
|
||||
dirMeta.animations.map(e => this.getAnimationEntryMetadata(e)) :
|
||||
null;
|
||||
}
|
||||
|
||||
nonNormalizedTemplateMetadata = new cpl.CompileTemplateMetadata({
|
||||
encapsulation: dirMeta.encapsulation,
|
||||
|
||||
@@ -414,6 +414,8 @@ class TemplateParseVisitor implements html.Visitor {
|
||||
private _validateElementAnimationInputOutputs(
|
||||
inputs: BoundElementPropertyAst[], outputs: BoundEventAst[],
|
||||
template: CompileTemplateSummary) {
|
||||
if (this.config.useViewEngine) return;
|
||||
|
||||
const triggerLookup = new Set<string>();
|
||||
template.animations.forEach(entry => { triggerLookup.add(entry); });
|
||||
|
||||
|
||||
@@ -49,8 +49,9 @@ export class ViewCompilerNext extends ViewCompiler {
|
||||
new o.LiteralMapExpr([
|
||||
new o.LiteralMapEntry('encapsulation', o.literal(component.template.encapsulation)),
|
||||
new o.LiteralMapEntry('styles', styles),
|
||||
// TODO: copy this from the @Component directive...
|
||||
new o.LiteralMapEntry('data', o.literalMap([])),
|
||||
new o.LiteralMapEntry('data', o.literalMap([
|
||||
['animation', convertValueToOutputAst(component.template.animations)]
|
||||
])),
|
||||
])
|
||||
]))
|
||||
.toDeclStmt(
|
||||
@@ -347,11 +348,13 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver, BuiltinConverter
|
||||
}
|
||||
const usedEvents = new Map<string, [string, string]>();
|
||||
ast.outputs.forEach((event) => {
|
||||
usedEvents.set(elementEventFullName(event.target, event.name), [event.target, event.name]);
|
||||
const en = eventName(event);
|
||||
usedEvents.set(elementEventFullName(event.target, en), [event.target, en]);
|
||||
});
|
||||
ast.directives.forEach((dirAst) => {
|
||||
dirAst.hostEvents.forEach((event) => {
|
||||
usedEvents.set(elementEventFullName(event.target, event.name), [event.target, event.name]);
|
||||
const en = eventName(event);
|
||||
usedEvents.set(elementEventFullName(event.target, en), [event.target, en]);
|
||||
});
|
||||
});
|
||||
const hostBindings: {value: AST, context: o.Expression}[] = [];
|
||||
@@ -713,7 +716,7 @@ class ViewBuilder implements TemplateAstVisitor, LocalResolver, BuiltinConverter
|
||||
if (allowDefault) {
|
||||
trueStmts.push(ALLOW_DEFAULT_VAR.set(allowDefault.and(ALLOW_DEFAULT_VAR)).toStmt());
|
||||
}
|
||||
const fullEventName = elementEventFullName(eventAst.target, eventAst.name);
|
||||
const fullEventName = elementEventFullName(eventAst.target, eventName(eventAst));
|
||||
handleEventStmts.push(
|
||||
new o.IfStmt(o.literal(fullEventName).identical(EVENT_NAME_VAR), trueStmts));
|
||||
});
|
||||
@@ -895,7 +898,7 @@ function elementBindingDefs(inputAsts: BoundElementPropertyAst[]): o.Expression[
|
||||
]);
|
||||
case PropertyBindingType.Animation:
|
||||
return o.literalArr([
|
||||
o.literal(BindingType.ElementProperty), o.literal(inputAst.name),
|
||||
o.literal(BindingType.ElementProperty), o.literal('@' + inputAst.name),
|
||||
o.literal(inputAst.securityContext)
|
||||
]);
|
||||
case PropertyBindingType.Class:
|
||||
@@ -1021,3 +1024,7 @@ function createComponentFactoryResolver(directives: DirectiveAst[]): ProviderAst
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function eventName(eventAst: BoundEventAst): string {
|
||||
return eventAst.isAnimation ? `@${eventAst.name}.${eventAst.phase}` : eventAst.name;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user