perf: delete pre-view-engine core, compiler, platform-browser, etc code (#14788)

After the introduction of the view engine, we can drop a lot of code that is not used any more.

This should reduce the size of the app bundles because a lot of this code was not being properly tree-shaken by today's tools even though it was dead code.
This commit is contained in:
Tobias Bosch
2017-02-27 23:08:19 -08:00
committed by Igor Minar
parent e58cb7ba08
commit 126fda2613
151 changed files with 1283 additions and 14864 deletions

View File

@ -9,9 +9,6 @@
import {CommonModule, PlatformLocation, ɵPLATFORM_BROWSER_ID as PLATFORM_BROWSER_ID} from '@angular/common';
import {APP_ID, ApplicationModule, ErrorHandler, ModuleWithProviders, NgModule, Optional, PLATFORM_ID, PLATFORM_INITIALIZER, PlatformRef, Provider, RendererFactoryV2, RootRenderer, Sanitizer, SkipSelf, Testability, createPlatformFactory, platformCore} from '@angular/core';
import {AnimationDriver} from '../src/dom/animation_driver';
import {WebAnimationsDriver} from '../src/dom/web_animations_driver';
import {BrowserDomAdapter} from './browser/browser_adapter';
import {BrowserPlatformLocation} from './browser/location/browser_platform_location';
import {Meta} from './browser/meta';
@ -20,7 +17,7 @@ import {BrowserGetTestability} from './browser/testability';
import {Title} from './browser/title';
import {ELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
import {getDOM} from './dom/dom_adapter';
import {DomRendererFactoryV2, DomRootRenderer, DomRootRenderer_} from './dom/dom_renderer';
import {DomRendererFactoryV2} from './dom/dom_renderer';
import {DOCUMENT} from './dom/dom_tokens';
import {DomEventsPlugin} from './dom/events/dom_events';
import {EVENT_MANAGER_PLUGINS, EventManager} from './dom/events/event_manager';
@ -66,13 +63,6 @@ export function _document(): any {
return document;
}
export function _resolveDefaultAnimationDriver(): AnimationDriver {
if (getDOM().supportsWebAnimation()) {
return new WebAnimationsDriver();
}
return AnimationDriver.NOOP;
}
/**
* The ng module for the browser.
*
@ -86,12 +76,9 @@ export function _resolveDefaultAnimationDriver(): AnimationDriver {
{provide: EVENT_MANAGER_PLUGINS, useClass: KeyEventsPlugin, multi: true},
{provide: EVENT_MANAGER_PLUGINS, useClass: HammerGesturesPlugin, multi: true},
{provide: HAMMER_GESTURE_CONFIG, useClass: HammerGestureConfig},
{provide: DomRootRenderer, useClass: DomRootRenderer_},
{provide: RootRenderer, useExisting: DomRootRenderer},
DomRendererFactoryV2,
{provide: RendererFactoryV2, useExisting: DomRendererFactoryV2},
{provide: SharedStylesHost, useExisting: DomSharedStylesHost},
{provide: AnimationDriver, useFactory: _resolveDefaultAnimationDriver},
DomSharedStylesHost,
Testability,
EventManager,

View File

@ -1,33 +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, ɵAnimationKeyframe as AnimationKeyframe, ɵAnimationStyles as AnimationStyles, ɵNoOpAnimationPlayer as NoOpAnimationPlayer} from '@angular/core';
/**
* @experimental
*/
export class NoOpAnimationDriver implements AnimationDriver {
animate(
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
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, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
duration: number, delay: number, easing: string,
previousPlayers?: AnimationPlayer[]): AnimationPlayer;
}

View File

@ -10,7 +10,6 @@ import * as core from '@angular/core';
import {StringMapWrapper} from '../../facade/collection';
import {getDOM} from '../dom_adapter';
import {DomRendererFactoryV2, DomRootRenderer} from '../dom_renderer';
const CORE_TOKENS = {
'ApplicationRef': core.ApplicationRef,
@ -37,20 +36,13 @@ export class NgProbeToken {
constructor(public name: string, public token: any) {}
}
export function _createConditionalRootRenderer(
rootRenderer: any, extraTokens: NgProbeToken[], coreTokens: core.NgProbeToken[]) {
return core.isDevMode() ?
_createRootRenderer(rootRenderer, (extraTokens || []).concat(coreTokens || [])) :
rootRenderer;
}
function _createRootRenderer(rootRenderer: any, extraTokens: NgProbeToken[]) {
export function _createNgProbe(extraTokens: NgProbeToken[], coreTokens: core.NgProbeToken[]): any {
const tokens = (extraTokens || []).concat(coreTokens || []);
getDOM().setGlobalVar(INSPECT_GLOBAL_NAME, inspectNativeElement);
getDOM().setGlobalVar(
CORE_TOKENS_GLOBAL_NAME,
StringMapWrapper.merge(CORE_TOKENS, _ngProbeTokensToMap(extraTokens || [])));
return new core.ɵDebugDomRootRenderer(rootRenderer);
StringMapWrapper.merge(CORE_TOKENS, _ngProbeTokensToMap(tokens || [])));
return () => inspectNativeElement;
}
function _ngProbeTokensToMap(tokens: NgProbeToken[]): {[name: string]: any} {
@ -62,12 +54,12 @@ function _ngProbeTokensToMap(tokens: NgProbeToken[]): {[name: string]: any} {
*/
export const ELEMENT_PROBE_PROVIDERS: core.Provider[] = [
{
provide: core.RootRenderer,
useFactory: _createConditionalRootRenderer,
provide: core.APP_INITIALIZER,
useFactory: _createNgProbe,
deps: [
DomRootRenderer,
[NgProbeToken, new core.Optional()],
[core.NgProbeToken, new core.Optional()],
],
multi: true,
},
];

View File

@ -1,19 +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 interface DomAnimatePlayer {
cancel(): void;
play(): void;
pause(): void;
finish(): void;
onfinish: Function;
position: number;
currentTime: number;
addEventListener(eventName: string, handler: (event: any) => any): any;
dispatchEvent(eventName: string): any;
}

View File

@ -6,11 +6,10 @@
* found in the LICENSE file at https://angular.io/license
*/
import {APP_ID, Inject, Injectable, RenderComponentType, Renderer, RendererFactoryV2, RendererTypeV2, RendererV2, RootRenderer, ViewEncapsulation, ɵAnimationKeyframe as AnimationKeyframe, ɵAnimationPlayer as AnimationPlayer, ɵAnimationStyles as AnimationStyles, ɵDirectRenderer as DirectRenderer, ɵNoOpAnimationPlayer as NoOpAnimationPlayer, ɵRenderDebugInfo as RenderDebugInfo} from '@angular/core';
import {APP_ID, Inject, Injectable, RenderComponentType, Renderer, RendererFactoryV2, RendererTypeV2, RendererV2, RootRenderer, ViewEncapsulation} from '@angular/core';
import {isPresent, stringify} from '../facade/lang';
import {AnimationDriver} from './animation_driver';
import {DOCUMENT} from './dom_tokens';
import {EventManager} from './events/event_manager';
import {DomSharedStylesHost} from './shared_styles_host';
@ -21,290 +20,6 @@ export const NAMESPACE_URIS: {[ns: string]: string} = {
'xhtml': 'http://www.w3.org/1999/xhtml',
'xml': 'http://www.w3.org/XML/1998/namespace'
};
const TEMPLATE_COMMENT_TEXT = 'template bindings={}';
const TEMPLATE_BINDINGS_EXP = /^template bindings=(.*)$/;
export abstract class DomRootRenderer implements RootRenderer {
protected registeredComponents: Map<string, DomRenderer> = new Map<string, DomRenderer>();
constructor(
public document: Document, public eventManager: EventManager,
public sharedStylesHost: DomSharedStylesHost, public animationDriver: AnimationDriver,
public appId: string) {}
renderComponent(componentProto: RenderComponentType): Renderer {
let renderer = this.registeredComponents.get(componentProto.id);
if (!renderer) {
renderer = new DomRenderer(
this, componentProto, this.animationDriver, `${this.appId}-${componentProto.id}`);
this.registeredComponents.set(componentProto.id, renderer);
}
return renderer;
}
}
@Injectable()
export class DomRootRenderer_ extends DomRootRenderer {
constructor(
@Inject(DOCUMENT) _document: any, _eventManager: EventManager,
sharedStylesHost: DomSharedStylesHost, animationDriver: AnimationDriver,
@Inject(APP_ID) appId: string) {
super(_document, _eventManager, sharedStylesHost, animationDriver, appId);
throw new Error(
'RootRenderer is no longer supported. Please use the `RendererFactoryV2` instead!');
}
}
export const DIRECT_DOM_RENDERER: DirectRenderer = {
remove(node: Text | Comment | Element) {
if (node.parentNode) {
node.parentNode.removeChild(node);
}
},
appendChild(node: Node, parent: Element) { parent.appendChild(node);},
insertBefore(node: Node, refNode: Node) { refNode.parentNode.insertBefore(node, refNode);},
nextSibling(node: Node) { return node.nextSibling;},
parentElement(node: Node): Element{return node.parentNode as Element;}
};
export class DomRenderer implements Renderer {
private _contentAttr: string;
private _hostAttr: string;
private _styles: string[];
directRenderer: DirectRenderer = DIRECT_DOM_RENDERER;
constructor(
private _rootRenderer: DomRootRenderer, private componentProto: RenderComponentType,
private _animationDriver: AnimationDriver, styleShimId: string) {
this._styles = flattenStyles(styleShimId, componentProto.styles, []);
if (componentProto.encapsulation !== ViewEncapsulation.Native) {
this._rootRenderer.sharedStylesHost.addStyles(this._styles);
}
if (this.componentProto.encapsulation === ViewEncapsulation.Emulated) {
this._contentAttr = shimContentAttribute(styleShimId);
this._hostAttr = shimHostAttribute(styleShimId);
} else {
this._contentAttr = null;
this._hostAttr = null;
}
}
selectRootElement(selectorOrNode: string|Element, debugInfo: RenderDebugInfo): Element {
let el: Element;
if (typeof selectorOrNode === 'string') {
el = this._rootRenderer.document.querySelector(selectorOrNode);
if (!el) {
throw new Error(`The selector "${selectorOrNode}" did not match any elements`);
}
} else {
el = selectorOrNode;
}
while (el.firstChild) {
el.removeChild(el.firstChild);
}
return el;
}
createElement(parent: Element|DocumentFragment, name: string, debugInfo: RenderDebugInfo):
Element {
let el: Element;
if (isNamespaced(name)) {
const nsAndName = splitNamespace(name);
el = document.createElementNS((NAMESPACE_URIS)[nsAndName[0]], nsAndName[1]);
} else {
el = document.createElement(name);
}
if (this._contentAttr) {
el.setAttribute(this._contentAttr, '');
}
if (parent) {
parent.appendChild(el);
}
return el;
}
createViewRoot(hostElement: Element): Element|DocumentFragment {
let nodesParent: Element|DocumentFragment;
if (this.componentProto.encapsulation === ViewEncapsulation.Native) {
nodesParent = (hostElement as any).createShadowRoot();
this._rootRenderer.sharedStylesHost.addHost(nodesParent);
for (let i = 0; i < this._styles.length; i++) {
const styleEl = document.createElement('style');
styleEl.textContent = this._styles[i];
nodesParent.appendChild(styleEl);
}
} else {
if (this._hostAttr) {
hostElement.setAttribute(this._hostAttr, '');
}
nodesParent = hostElement;
}
return nodesParent;
}
createTemplateAnchor(parentElement: Element|DocumentFragment, debugInfo: RenderDebugInfo):
Comment {
const comment = document.createComment(TEMPLATE_COMMENT_TEXT);
if (parentElement) {
parentElement.appendChild(comment);
}
return comment;
}
createText(parentElement: Element|DocumentFragment, value: string, debugInfo: RenderDebugInfo):
any {
const node = document.createTextNode(value);
if (parentElement) {
parentElement.appendChild(node);
}
return node;
}
projectNodes(parentElement: Element|DocumentFragment, nodes: Node[]) {
if (!parentElement) return;
appendNodes(parentElement, nodes);
}
attachViewAfter(node: Node, viewRootNodes: Node[]) { moveNodesAfterSibling(node, viewRootNodes); }
detachView(viewRootNodes: (Element|Text|Comment)[]) {
for (let i = 0; i < viewRootNodes.length; i++) {
const node = viewRootNodes[i];
if (node.parentNode) {
node.parentNode.removeChild(node);
}
}
}
destroyView(hostElement: Element|DocumentFragment, viewAllNodes: Node[]) {
if (this.componentProto.encapsulation === ViewEncapsulation.Native && hostElement) {
this._rootRenderer.sharedStylesHost.removeHost((hostElement as any).shadowRoot);
}
}
listen(renderElement: any, name: string, callback: Function): Function {
return this._rootRenderer.eventManager.addEventListener(
renderElement, name, decoratePreventDefault(callback));
}
listenGlobal(target: string, name: string, callback: Function): Function {
return this._rootRenderer.eventManager.addGlobalEventListener(
target, name, decoratePreventDefault(callback));
}
setElementProperty(
renderElement: Element|DocumentFragment, propertyName: string, propertyValue: any): void {
(renderElement as any)[propertyName] = propertyValue;
}
setElementAttribute(renderElement: Element, attributeName: string, attributeValue: string): void {
let attrNs: string;
let attrNameWithoutNs = attributeName;
if (isNamespaced(attributeName)) {
const nsAndName = splitNamespace(attributeName);
attrNameWithoutNs = nsAndName[1];
attributeName = nsAndName[0] + ':' + nsAndName[1];
attrNs = NAMESPACE_URIS[nsAndName[0]];
}
if (isPresent(attributeValue)) {
if (attrNs) {
renderElement.setAttributeNS(attrNs, attributeName, attributeValue);
} else {
renderElement.setAttribute(attributeName, attributeValue);
}
} else {
if (isPresent(attrNs)) {
renderElement.removeAttributeNS(attrNs, attrNameWithoutNs);
} else {
renderElement.removeAttribute(attributeName);
}
}
}
setBindingDebugInfo(renderElement: Element, propertyName: string, propertyValue: string): void {
if (renderElement.nodeType === Node.COMMENT_NODE) {
const existingBindings =
renderElement.nodeValue.replace(/\n/g, '').match(TEMPLATE_BINDINGS_EXP);
const parsedBindings = JSON.parse(existingBindings[1]);
parsedBindings[propertyName] = propertyValue;
renderElement.nodeValue =
TEMPLATE_COMMENT_TEXT.replace('{}', JSON.stringify(parsedBindings, null, 2));
} else {
// Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
propertyName = propertyName.replace(/\$/g, '_');
this.setElementAttribute(renderElement, propertyName, propertyValue);
}
}
setElementClass(renderElement: Element, className: string, isAdd: boolean): void {
if (isAdd) {
renderElement.classList.add(className);
} else {
renderElement.classList.remove(className);
}
}
setElementStyle(renderElement: HTMLElement, styleName: string, styleValue: string): void {
if (isPresent(styleValue)) {
(renderElement.style as any)[styleName] = stringify(styleValue);
} else {
// IE requires '' instead of null
// see https://github.com/angular/angular/issues/7916
(renderElement.style as any)[styleName] = '';
}
}
invokeElementMethod(renderElement: Element, methodName: string, args: any[]): void {
(renderElement as any)[methodName].apply(renderElement, args);
}
setText(renderNode: Text, text: string): void { renderNode.nodeValue = text; }
animate(
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
duration: number, delay: number, easing: string,
previousPlayers: AnimationPlayer[] = []): AnimationPlayer {
if (this._rootRenderer.document.body.contains(element)) {
return this._animationDriver.animate(
element, startingStyles, keyframes, duration, delay, easing, previousPlayers);
}
return new NoOpAnimationPlayer();
}
}
function moveNodesAfterSibling(sibling: Node, nodes: Node[]) {
const parent = sibling.parentNode;
if (nodes.length > 0 && parent) {
const nextSibling = sibling.nextSibling;
if (nextSibling) {
for (let i = 0; i < nodes.length; i++) {
parent.insertBefore(nodes[i], nextSibling);
}
} else {
for (let i = 0; i < nodes.length; i++) {
parent.appendChild(nodes[i]);
}
}
}
}
function appendNodes(parent: Element | DocumentFragment, nodes: Node[]) {
for (let i = 0; i < nodes.length; i++) {
parent.appendChild(nodes[i]);
}
}
function decoratePreventDefault(eventHandler: Function): Function {
return (event: any) => {
const allowDefaultBehavior = eventHandler(event);
if (allowDefaultBehavior === false) {
// TODO(tbosch): move preventDefault into event plugins...
event.preventDefault();
event.returnValue = false;
}
};
}
const COMPONENT_REGEX = /%COMP%/g;
export const COMPONENT_VARIABLE = '%COMP%';
@ -334,18 +49,17 @@ export function flattenStyles(
return target;
}
const NS_PREFIX_RE = /^:([^:]+):(.+)$/;
export function isNamespaced(name: string) {
return name[0] === ':';
function decoratePreventDefault(eventHandler: Function): Function {
return (event: any) => {
const allowDefaultBehavior = eventHandler(event);
if (allowDefaultBehavior === false) {
// TODO(tbosch): move preventDefault into event plugins...
event.preventDefault();
event.returnValue = false;
}
};
}
export function splitNamespace(name: string): string[] {
const match = name.match(NS_PREFIX_RE);
return [match[1], match[2]];
}
@Injectable()
export class DomRendererFactoryV2 implements RendererFactoryV2 {
private rendererByCompId = new Map<string, RendererV2>();

View File

@ -1,81 +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, ɵAnimationKeyframe as AnimationKeyframe, ɵAnimationStyles as AnimationStyles} from '@angular/core';
import {isPresent} from '../facade/lang';
import {AnimationDriver} from './animation_driver';
import {WebAnimationsPlayer} from './web_animations_player';
export class WebAnimationsDriver implements AnimationDriver {
animate(
element: any, startingStyles: AnimationStyles, keyframes: AnimationKeyframe[],
duration: number, delay: number, easing: string,
previousPlayers: AnimationPlayer[] = []): WebAnimationsPlayer {
let formattedSteps: {[key: string]: string | number}[] = [];
let startingStyleLookup: {[key: string]: string | number} = {};
if (isPresent(startingStyles)) {
startingStyleLookup = _populateStyles(startingStyles, {});
}
keyframes.forEach((keyframe: AnimationKeyframe) => {
const data = _populateStyles(keyframe.styles, startingStyleLookup);
data['offset'] = Math.max(0, Math.min(1, keyframe.offset));
formattedSteps.push(data);
});
// Styling passed into element.animate() must always be balanced.
// The special cases below can occur if only style() calls exist
// within an animation or when a style() calls are used prior
// to a group() animation being issued or if the renderer is
// invoked by the user directly.
if (formattedSteps.length == 0) {
formattedSteps = [startingStyleLookup, startingStyleLookup];
} else if (formattedSteps.length == 1) {
const start = startingStyleLookup;
const end = formattedSteps[0];
end['offset'] = null;
formattedSteps = [start, end];
}
const playerOptions: {[key: string]: string | number} = {
'duration': duration,
'delay': delay,
'fill': 'both' // we use `both` because it allows for styling at 0% to work with `delay`
};
// we check for this to avoid having a null|undefined value be present
// for the easing (which results in an error for certain browsers #9752)
if (easing) {
playerOptions['easing'] = easing;
}
// there may be a chance a NoOp player is returned depending
// on when the previous animation was cancelled
previousPlayers = previousPlayers.filter(filterWebAnimationPlayerFn);
return new WebAnimationsPlayer(
element, formattedSteps, playerOptions, <WebAnimationsPlayer[]>previousPlayers);
}
}
function _populateStyles(styles: AnimationStyles, defaultStyles: {[key: string]: string | number}):
{[key: string]: string | number} {
const data: {[key: string]: string | number} = {};
styles.styles.forEach(
(entry) => { Object.keys(entry).forEach(prop => { data[prop] = entry[prop]; }); });
Object.keys(defaultStyles).forEach(prop => {
if (!isPresent(data[prop])) {
data[prop] = defaultStyles[prop];
}
});
return data;
}
function filterWebAnimationPlayerFn(player: AnimationPlayer) {
return player instanceof WebAnimationsPlayer;
}

View File

@ -1,200 +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 {AUTO_STYLE, ɵAnimationPlayer as AnimationPlayer} from '@angular/core';
import {isPresent} from '../facade/lang';
import {getDOM} from './dom_adapter';
import {DomAnimatePlayer} from './dom_animate_player';
export class WebAnimationsPlayer implements AnimationPlayer {
private _onDoneFns: Function[] = [];
private _onStartFns: Function[] = [];
private _onDestroyFns: Function[] = [];
private _player: DomAnimatePlayer;
private _duration: number;
private _initialized = false;
private _finished = false;
private _started = false;
private _destroyed = false;
private _finalKeyframe: {[key: string]: string | number};
public parentPlayer: AnimationPlayer = null;
public previousStyles: {[styleName: string]: string | number};
constructor(
public element: any, public keyframes: {[key: string]: string | number}[],
public options: {[key: string]: string | number},
previousPlayers: WebAnimationsPlayer[] = []) {
this._duration = <number>options['duration'];
this.previousStyles = {};
previousPlayers.forEach(player => {
let styles = player._captureStyles();
Object.keys(styles).forEach(prop => this.previousStyles[prop] = styles[prop]);
});
}
private _onFinish() {
if (!this._finished) {
this._finished = true;
this._onDoneFns.forEach(fn => fn());
this._onDoneFns = [];
}
}
init(): void {
if (this._initialized) return;
this._initialized = true;
const keyframes = this.keyframes.map(styles => {
const formattedKeyframe: {[key: string]: string | number} = {};
Object.keys(styles).forEach((prop, index) => {
let value = styles[prop];
if (value == AUTO_STYLE) {
value = _computeStyle(this.element, prop);
}
if (value != undefined) {
formattedKeyframe[prop] = value;
}
});
return formattedKeyframe;
});
const previousStyleProps = Object.keys(this.previousStyles);
if (previousStyleProps.length) {
let startingKeyframe = keyframes[0];
let missingStyleProps: string[] = [];
previousStyleProps.forEach(prop => {
if (!isPresent(startingKeyframe[prop])) {
missingStyleProps.push(prop);
}
startingKeyframe[prop] = this.previousStyles[prop];
});
if (missingStyleProps.length) {
const self = this;
// tslint:disable-next-line
for (var i = 1; i < keyframes.length; i++) {
let kf = keyframes[i];
// tslint:disable-next-line
missingStyleProps.forEach(function(prop) {
kf[prop] = _computeStyle(self.element, prop);
});
}
}
}
this._player = this._triggerWebAnimation(this.element, keyframes, this.options);
this._finalKeyframe = _copyKeyframeStyles(keyframes[keyframes.length - 1]);
// this is required so that the player doesn't start to animate right away
this._resetDomPlayerState();
this._player.addEventListener('finish', () => this._onFinish());
}
/** @internal */
_triggerWebAnimation(element: any, keyframes: any[], options: any): DomAnimatePlayer {
// jscompiler doesn't seem to know animate is a native property because it's not fully
// supported yet across common browsers (we polyfill it for Edge/Safari) [CL #143630929]
return <DomAnimatePlayer>element['animate'](keyframes, options);
}
get domPlayer() { return this._player; }
onStart(fn: () => void): void { this._onStartFns.push(fn); }
onDone(fn: () => void): void { this._onDoneFns.push(fn); }
onDestroy(fn: () => void): void { this._onDestroyFns.push(fn); }
play(): void {
this.init();
if (!this.hasStarted()) {
this._onStartFns.forEach(fn => fn());
this._onStartFns = [];
this._started = true;
}
this._player.play();
}
pause(): void {
this.init();
this._player.pause();
}
finish(): void {
this.init();
this._onFinish();
this._player.finish();
}
reset(): void {
this._resetDomPlayerState();
this._destroyed = false;
this._finished = false;
this._started = false;
}
private _resetDomPlayerState() {
if (this._player) {
this._player.cancel();
}
}
restart(): void {
this.reset();
this.play();
}
hasStarted(): boolean { return this._started; }
destroy(): void {
if (!this._destroyed) {
this._resetDomPlayerState();
this._onFinish();
this._destroyed = true;
this._onDestroyFns.forEach(fn => fn());
this._onDestroyFns = [];
}
}
get totalTime(): number { return this._duration; }
setPosition(p: number): void { this._player.currentTime = p * this.totalTime; }
getPosition(): number { return this._player.currentTime / this.totalTime; }
private _captureStyles(): {[prop: string]: string | number} {
const styles: {[key: string]: string | number} = {};
if (this.hasStarted()) {
Object.keys(this._finalKeyframe).forEach(prop => {
if (prop != 'offset') {
styles[prop] =
this._finished ? this._finalKeyframe[prop] : _computeStyle(this.element, prop);
}
});
}
return styles;
}
}
function _computeStyle(element: any, prop: string): string {
return getDOM().getComputedStyle(element)[prop];
}
function _copyKeyframeStyles(styles: {[style: string]: string | number}):
{[style: string]: string | number} {
const newStyles: {[style: string]: string | number} = {};
Object.keys(styles).forEach(prop => {
if (prop != 'offset') {
newStyles[prop] = styles[prop];
}
});
return newStyles;
}

View File

@ -10,7 +10,6 @@ export {BrowserModule, platformBrowser} from './browser';
export {Meta, MetaDefinition} from './browser/meta';
export {Title} from './browser/title';
export {disableDebugTools, enableDebugTools} from './browser/tools/tools';
export {AnimationDriver} from './dom/animation_driver';
export {By} from './dom/debug/by';
export {NgProbeToken} from './dom/debug/ng_probe';
export {DOCUMENT} from './dom/dom_tokens';

View File

@ -13,9 +13,8 @@ export {TRANSITION_ID as ɵTRANSITION_ID} from './browser/server-transition';
export {BrowserGetTestability as ɵBrowserGetTestability} from './browser/testability';
export {ELEMENT_PROBE_PROVIDERS as ɵELEMENT_PROBE_PROVIDERS} from './dom/debug/ng_probe';
export {DomAdapter as ɵDomAdapter, getDOM as ɵgetDOM, setRootDomAdapter as ɵsetRootDomAdapter} from './dom/dom_adapter';
export {DomRendererFactoryV2 as ɵDomRendererFactoryV2, DomRootRenderer as ɵDomRootRenderer, DomRootRenderer_ as ɵDomRootRenderer_, NAMESPACE_URIS as ɵNAMESPACE_URIS, flattenStyles as ɵflattenStyles, isNamespaced as ɵisNamespaced, shimContentAttribute as ɵshimContentAttribute, shimHostAttribute as ɵshimHostAttribute, splitNamespace as ɵsplitNamespace} from './dom/dom_renderer';
export {DomRendererFactoryV2 as ɵDomRendererFactoryV2, NAMESPACE_URIS as ɵNAMESPACE_URIS, flattenStyles as ɵflattenStyles, shimContentAttribute as ɵshimContentAttribute, shimHostAttribute as ɵshimHostAttribute} from './dom/dom_renderer';
export {DomEventsPlugin as ɵDomEventsPlugin} from './dom/events/dom_events';
export {HammerGesturesPlugin as ɵHammerGesturesPlugin} from './dom/events/hammer_gestures';
export {KeyEventsPlugin as ɵKeyEventsPlugin} from './dom/events/key_events';
export {DomSharedStylesHost as ɵDomSharedStylesHost, SharedStylesHost as ɵSharedStylesHost} from './dom/shared_styles_host';
export {WebAnimationsDriver as ɵWebAnimationsDriver} from './dom/web_animations_driver';