chore(format): update to latest formatter

Closes #7958
This commit is contained in:
Alex Eagle 2016-04-07 17:17:50 -07:00 committed by Alex Eagle
parent 83b8f59297
commit 03627aa84d
527 changed files with 13975 additions and 19252 deletions

File diff suppressed because it is too large Load Diff

View File

@ -78,7 +78,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $rootRouter) {
result = this.currentController.$routerCanReuse(nextInstruction, this.currentInstruction); result = this.currentController.$routerCanReuse(nextInstruction, this.currentInstruction);
} else { } else {
result = nextInstruction === this.currentInstruction || result = nextInstruction === this.currentInstruction ||
angular.equals(nextInstruction.params, this.currentInstruction.params); angular.equals(nextInstruction.params, this.currentInstruction.params);
} }
return $q.when(result); return $q.when(result);
} }
@ -110,7 +110,7 @@ function ngOutletDirective($animate, $q: ng.IQService, $rootRouter) {
} }
this.controller.$$template = '<' + dashCase(componentName) + ' $router="::$$router"></' + this.controller.$$template = '<' + dashCase(componentName) + ' $router="::$$router"></' +
dashCase(componentName) + '>'; dashCase(componentName) + '>';
this.controller.$$router = this.router.childRouter(instruction.componentType); this.controller.$$router = this.router.childRouter(instruction.componentType);
this.controller.$$outlet = this; this.controller.$$outlet = this;
@ -165,8 +165,8 @@ function routerTriggerDirective($q) {
var currentComponent = outlet.currentController = var currentComponent = outlet.currentController =
element.controller(ngOutletCtrl.$$componentName); element.controller(ngOutletCtrl.$$componentName);
if (currentComponent.$routerOnActivate) { if (currentComponent.$routerOnActivate) {
promise = $q.when(currentComponent.$routerOnActivate(outlet.currentInstruction, promise = $q.when(currentComponent.$routerOnActivate(
outlet.previousInstruction)); outlet.currentInstruction, outlet.previousInstruction));
} }
promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject); promise.then(outlet.deferredActivation.resolve, outlet.deferredActivation.reject);
} }
@ -213,14 +213,15 @@ function ngLinkDirective($rootRouter, $parse) {
function getLink(params) { function getLink(params) {
navigationInstruction = router.generate(params); navigationInstruction = router.generate(params);
scope.$watch(function() { return router.isRouteActive(navigationInstruction); }, scope.$watch(
function(active) { function() { return router.isRouteActive(navigationInstruction); },
if (active) { function(active) {
element.addClass('ng-link-active'); if (active) {
} else { element.addClass('ng-link-active');
element.removeClass('ng-link-active'); } else {
} element.removeClass('ng-link-active');
}); }
});
const navigationHref = navigationInstruction.toLinkUrl(); const navigationHref = navigationInstruction.toLinkUrl();
return $rootRouter._location.prepareExternalUrl(navigationHref); return $rootRouter._location.prepareExternalUrl(navigationHref);
@ -232,8 +233,8 @@ function ngLinkDirective($rootRouter, $parse) {
let params = routeParamsGetter(); let params = routeParamsGetter();
element.attr('href', getLink(params)); element.attr('href', getLink(params));
} else { } else {
scope.$watch(() => routeParamsGetter(scope), params => element.attr('href', getLink(params)), scope.$watch(
true); () => routeParamsGetter(scope), params => element.attr('href', getLink(params)), true);
} }
element.on('click', event => { element.on('click', event => {

View File

@ -10,13 +10,7 @@ export * from './src/core/di';
export * from './src/facade/facade'; export * from './src/facade/facade';
export {enableProdMode} from 'angular2/src/facade/lang'; export {enableProdMode} from 'angular2/src/facade/lang';
export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref'; export {platform, createNgZone, PlatformRef, ApplicationRef} from './src/core/application_ref';
export { export {APP_ID, APP_COMPONENT, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER} from './src/core/application_tokens';
APP_ID,
APP_COMPONENT,
APP_INITIALIZER,
PACKAGE_ROOT_URL,
PLATFORM_INITIALIZER
} from './src/core/application_tokens';
export * from './src/core/zone'; export * from './src/core/zone';
export * from './src/core/render'; export * from './src/core/render';
export * from './src/core/linker'; export * from './src/core/linker';

View File

@ -20,7 +20,7 @@ expect(door.lock instanceof Lock).toBe(true);
// #enddocregion // #enddocregion
// #docregion resolve_forward_ref // #docregion resolve_forward_ref
var ref = forwardRef(() => "refValue"); var ref = forwardRef(() => 'refValue');
expect(resolveForwardRef(ref)).toEqual("refValue"); expect(resolveForwardRef(ref)).toEqual('refValue');
expect(resolveForwardRef("regularValue")).toEqual("regularValue"); expect(resolveForwardRef('regularValue')).toEqual('regularValue');
// #enddocregion // #enddocregion

View File

@ -27,7 +27,7 @@ export class AsyncPipeExample {
if (this.arrived) { if (this.arrived) {
this.reset(); this.reset();
} else { } else {
this.resolve("hi there!"); this.resolve('hi there!');
this.arrived = true; this.arrived = true;
} }
} }
@ -35,7 +35,7 @@ export class AsyncPipeExample {
// #enddocregion // #enddocregion
// #docregion AsyncPipeObservable // #docregion AsyncPipeObservable
@Component({selector: "task-cmp", template: "Time: {{ time | async }}"}) @Component({selector: 'task-cmp', template: 'Time: {{ time | async }}'})
class Task { class Task {
time = new Observable<number>((observer: Subscriber<number>) => { time = new Observable<number>((observer: Subscriber<number>) => {
setInterval(() => observer.next(new Date().getTime()), 500); setInterval(() => observer.next(new Date().getTime()), 500);

View File

@ -1,12 +1,6 @@
import {provide, Component} from 'angular2/core'; import {provide, Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import { import {CanActivate, RouteConfig, ComponentInstruction, APP_BASE_HREF, ROUTER_DIRECTIVES} from 'angular2/router';
CanActivate,
RouteConfig,
ComponentInstruction,
APP_BASE_HREF,
ROUTER_DIRECTIVES
} from 'angular2/router';
function checkIfWeHavePermission(instruction: ComponentInstruction) { function checkIfWeHavePermission(instruction: ComponentInstruction) {
return instruction.params['id'] == '1'; return instruction.params['id'] == '1';

View File

@ -1,13 +1,6 @@
import {provide, Component} from 'angular2/core'; import {provide, Component} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import { import {CanDeactivate, RouteConfig, RouteParams, ComponentInstruction, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
CanDeactivate,
RouteConfig,
RouteParams,
ComponentInstruction,
ROUTER_DIRECTIVES,
APP_BASE_HREF
} from 'angular2/router';
// #docregion routerCanDeactivate // #docregion routerCanDeactivate
@Component({ @Component({

View File

@ -1,12 +1,6 @@
import {Component, provide} from 'angular2/core'; import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import { import {OnActivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
OnActivate,
ComponentInstruction,
RouteConfig,
ROUTER_DIRECTIVES,
APP_BASE_HREF
} from 'angular2/router';
// #docregion routerOnActivate // #docregion routerOnActivate
@Component({template: `Child`}) @Component({template: `Child`})

View File

@ -1,12 +1,6 @@
import {Component, Injectable, provide} from 'angular2/core'; import {Component, Injectable, provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import { import {OnDeactivate, ComponentInstruction, RouteConfig, ROUTER_DIRECTIVES, APP_BASE_HREF} from 'angular2/router';
OnDeactivate,
ComponentInstruction,
RouteConfig,
ROUTER_DIRECTIVES,
APP_BASE_HREF
} from 'angular2/router';
@Injectable() @Injectable()
@ -57,7 +51,6 @@ class AppCmp {
export function main() { export function main() {
return bootstrap(AppCmp, [ return bootstrap(AppCmp, [
provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_deactivate'}), provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/on_deactivate'}), LogService
LogService
]); ]);
} }

View File

@ -1,15 +1,6 @@
import {Component, provide} from 'angular2/core'; import {Component, provide} from 'angular2/core';
import {bootstrap} from 'angular2/platform/browser'; import {bootstrap} from 'angular2/platform/browser';
import { import {CanActivate, RouteConfig, ComponentInstruction, ROUTER_DIRECTIVES, APP_BASE_HREF, CanReuse, RouteParams, OnReuse} from 'angular2/router';
CanActivate,
RouteConfig,
ComponentInstruction,
ROUTER_DIRECTIVES,
APP_BASE_HREF,
CanReuse,
RouteParams,
OnReuse
} from 'angular2/router';
// #docregion reuseCmp // #docregion reuseCmp
@ -53,6 +44,6 @@ class AppCmp {
export function main() { export function main() {
return bootstrap(AppCmp, return bootstrap(
[provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/reuse'})]); AppCmp, [provide(APP_BASE_HREF, {useValue: '/angular2/examples/router/ts/reuse'})]);
} }

View File

@ -1,15 +1,4 @@
import { import {describe, fdescribe, xdescribe, it, fit, xit, beforeEach, afterEach, beforeEachProviders, inject} from 'angular2/testing';
describe,
fdescribe,
xdescribe,
it,
fit,
xit,
beforeEach,
afterEach,
beforeEachProviders,
inject
} from 'angular2/testing';
import {provide} from 'angular2/core'; import {provide} from 'angular2/core';
var db: any; var db: any;
@ -30,8 +19,9 @@ fdescribe('some component', () => {
// This test will run. // This test will run.
}); });
}); });
describe('another component', describe('another component', () => {
() => { it('also has a test', () => { throw 'This test will not run.'; }); }); it('also has a test', () => { throw 'This test will not run.'; });
});
// #enddocregion // #enddocregion
// #docregion xdescribe // #docregion xdescribe
@ -73,9 +63,10 @@ describe('some component', () => {
// #docregion beforeEachProviders // #docregion beforeEachProviders
describe('some component', () => { describe('some component', () => {
beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]); beforeEachProviders(() => [provide(MyService, {useClass: MyMockService})]);
it('uses MyService', inject([MyService], (service: MyMockService) => { it('uses MyService', inject(
// service is an instance of MyMockService. [MyService], (service: MyMockService) => {
})); // service is an instance of MyMockService.
}));
}); });
// #enddocregion // #enddocregion

View File

@ -16,12 +16,7 @@ import {BaseResponseOptions, ResponseOptions} from './src/http/base_response_opt
export {Request} from './src/http/static_request'; export {Request} from './src/http/static_request';
export {Response} from './src/http/static_response'; export {Response} from './src/http/static_response';
export { export {RequestOptionsArgs, ResponseOptionsArgs, Connection, ConnectionBackend} from './src/http/interfaces';
RequestOptionsArgs,
ResponseOptionsArgs,
Connection,
ConnectionBackend
} from './src/http/interfaces';
export {BrowserXhr} from './src/http/backends/browser_xhr'; export {BrowserXhr} from './src/http/backends/browser_xhr';
export {BaseRequestOptions, RequestOptions} from './src/http/base_request_options'; export {BaseRequestOptions, RequestOptions} from './src/http/base_request_options';
@ -155,16 +150,13 @@ export {URLSearchParams} from './src/http/url_search_params';
export const HTTP_PROVIDERS: any[] = [ export const HTTP_PROVIDERS: any[] = [
// TODO(pascal): use factory type annotations once supported in DI // TODO(pascal): use factory type annotations once supported in DI
// issue: https://github.com/angular/angular/issues/3183 // issue: https://github.com/angular/angular/issues/3183
provide(Http, provide(Http, {
{ useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) =>
useFactory: (xhrBackend: XHRBackend, requestOptions: RequestOptions) => new Http(xhrBackend, requestOptions),
new Http(xhrBackend, requestOptions), deps: [XHRBackend, RequestOptions]
deps: [XHRBackend, RequestOptions] }),
}), BrowserXhr, provide(RequestOptions, {useClass: BaseRequestOptions}),
BrowserXhr, provide(ResponseOptions, {useClass: BaseResponseOptions}), XHRBackend
provide(RequestOptions, {useClass: BaseRequestOptions}),
provide(ResponseOptions, {useClass: BaseResponseOptions}),
XHRBackend
]; ];
/** /**
@ -284,14 +276,12 @@ export const HTTP_BINDINGS = HTTP_PROVIDERS;
export const JSONP_PROVIDERS: any[] = [ export const JSONP_PROVIDERS: any[] = [
// TODO(pascal): use factory type annotations once supported in DI // TODO(pascal): use factory type annotations once supported in DI
// issue: https://github.com/angular/angular/issues/3183 // issue: https://github.com/angular/angular/issues/3183
provide(Jsonp, provide(Jsonp, {
{ useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) =>
useFactory: (jsonpBackend: JSONPBackend, requestOptions: RequestOptions) => new Jsonp(jsonpBackend, requestOptions),
new Jsonp(jsonpBackend, requestOptions), deps: [JSONPBackend, RequestOptions]
deps: [JSONPBackend, RequestOptions] }),
}), BrowserJsonp, provide(RequestOptions, {useClass: BaseRequestOptions}),
BrowserJsonp,
provide(RequestOptions, {useClass: BaseRequestOptions}),
provide(ResponseOptions, {useClass: BaseResponseOptions}), provide(ResponseOptions, {useClass: BaseResponseOptions}),
provide(JSONPBackend, {useClass: JSONPBackend_}) provide(JSONPBackend, {useClass: JSONPBackend_})
]; ];

View File

@ -1,7 +1 @@
export { export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/core/profile/profile';
wtfCreateScope,
wtfLeave,
wtfStartTimeRange,
wtfEndTimeRange,
WtfScopeFn
} from './src/core/profile/profile';

View File

@ -1,27 +1,12 @@
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint'; export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
export { export {BROWSER_PROVIDERS, CACHED_TEMPLATE_PROVIDER, ELEMENT_PROBE_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE, inspectNativeElement, BrowserDomAdapter, By, Title, DOCUMENT, enableDebugTools, disableDebugTools} from 'angular2/src/platform/browser_common';
BROWSER_PROVIDERS,
CACHED_TEMPLATE_PROVIDER,
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
inspectNativeElement,
BrowserDomAdapter,
By,
Title,
DOCUMENT,
enableDebugTools,
disableDebugTools
} from 'angular2/src/platform/browser_common';
import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang'; import {Type, isPresent, CONST_EXPR} from 'angular2/src/facade/lang';
import { import {BROWSER_PROVIDERS, BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
BROWSER_PROVIDERS,
BROWSER_APP_COMMON_PROVIDERS
} from 'angular2/src/platform/browser_common';
import {COMPILER_PROVIDERS} from 'angular2/compiler'; import {COMPILER_PROVIDERS} from 'angular2/compiler';
import {ComponentRef, platform, reflector} from 'angular2/core'; import {ComponentRef, platform, reflector} from 'angular2/core';
import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities'; import {ReflectionCapabilities} from 'angular2/src/core/reflection/reflection_capabilities';
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl"; import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
import {XHR} from 'angular2/compiler'; import {XHR} from 'angular2/compiler';
import {Provider} from 'angular2/src/core/di'; import {Provider} from 'angular2/src/core/di';

View File

@ -1,21 +1,8 @@
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint'; export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';
export { export {BROWSER_PROVIDERS, ELEMENT_PROBE_PROVIDERS, ELEMENT_PROBE_PROVIDERS_PROD_MODE, inspectNativeElement, BrowserDomAdapter, By, Title, enableDebugTools, disableDebugTools} from 'angular2/src/platform/browser_common';
BROWSER_PROVIDERS,
ELEMENT_PROBE_PROVIDERS,
ELEMENT_PROBE_PROVIDERS_PROD_MODE,
inspectNativeElement,
BrowserDomAdapter,
By,
Title,
enableDebugTools,
disableDebugTools
} from 'angular2/src/platform/browser_common';
import {Type, isPresent} from 'angular2/src/facade/lang'; import {Type, isPresent} from 'angular2/src/facade/lang';
import { import {BROWSER_PROVIDERS, BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
BROWSER_PROVIDERS,
BROWSER_APP_COMMON_PROVIDERS
} from 'angular2/src/platform/browser_common';
import {ComponentRef, platform} from 'angular2/core'; import {ComponentRef, platform} from 'angular2/core';
/** /**
@ -29,9 +16,9 @@ export const BROWSER_APP_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
/** /**
* See {@link bootstrap} for more information. * See {@link bootstrap} for more information.
*/ */
export function bootstrapStatic(appComponentType: Type, export function bootstrapStatic(
customProviders?: Array<any /*Type | Provider | any[]*/>, appComponentType: Type, customProviders?: Array<any /*Type | Provider | any[]*/>,
initReflector?: Function): Promise<ComponentRef> { initReflector?: Function): Promise<ComponentRef> {
if (isPresent(initReflector)) { if (isPresent(initReflector)) {
initReflector(); initReflector();
} }

View File

@ -6,10 +6,6 @@ export {DomRenderer} from 'angular2/src/platform/dom/dom_renderer';
export {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens'; export {DOCUMENT} from 'angular2/src/platform/dom/dom_tokens';
export {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host'; export {SharedStylesHost, DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
export {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events'; export {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
export { export {EVENT_MANAGER_PLUGINS, EventManager, EventManagerPlugin} from 'angular2/src/platform/dom/events/event_manager';
EVENT_MANAGER_PLUGINS,
EventManager,
EventManagerPlugin
} from 'angular2/src/platform/dom/events/event_manager';
export * from 'angular2/src/platform/dom/debug/by'; export * from 'angular2/src/platform/dom/debug/by';
export * from 'angular2/src/platform/dom/debug/ng_probe'; export * from 'angular2/src/platform/dom/debug/ng_probe';

View File

@ -1,7 +1,4 @@
import { import {TEST_BROWSER_STATIC_PLATFORM_PROVIDERS, ADDITIONAL_TEST_BROWSER_PROVIDERS} from 'angular2/platform/testing/browser_static';
TEST_BROWSER_STATIC_PLATFORM_PROVIDERS,
ADDITIONAL_TEST_BROWSER_PROVIDERS
} from 'angular2/platform/testing/browser_static';
import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser'; import {BROWSER_APP_PROVIDERS} from 'angular2/platform/browser';
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';

View File

@ -1,12 +1,4 @@
import { import {APP_ID, DirectiveResolver, NgZone, Provider, ViewResolver, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER} from 'angular2/core';
APP_ID,
DirectiveResolver,
NgZone,
Provider,
ViewResolver,
PLATFORM_COMMON_PROVIDERS,
PLATFORM_INITIALIZER
} from 'angular2/core';
import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common'; import {BROWSER_APP_COMMON_PROVIDERS} from 'angular2/src/platform/browser_common';
import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter'; import {BrowserDomAdapter} from 'angular2/src/platform/browser/browser_adapter';
@ -18,7 +10,7 @@ import {MockLocationStrategy} from 'angular2/src/mock/mock_location_strategy';
import {LocationStrategy} from 'angular2/src/router/location/location_strategy'; import {LocationStrategy} from 'angular2/src/router/location/location_strategy';
import {MockNgZone} from 'angular2/src/mock/ng_zone_mock'; import {MockNgZone} from 'angular2/src/mock/ng_zone_mock';
import {XHRImpl} from "angular2/src/platform/browser/xhr_impl"; import {XHRImpl} from 'angular2/src/platform/browser/xhr_impl';
import {XHR} from 'angular2/compiler'; import {XHR} from 'angular2/compiler';
import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder'; import {TestComponentBuilder} from 'angular2/src/testing/test_component_builder';
@ -63,7 +55,6 @@ export const ADDITIONAL_TEST_BROWSER_PROVIDERS: Array<any /*Type | Provider | an
*/ */
export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> = export const TEST_BROWSER_STATIC_APPLICATION_PROVIDERS: Array<any /*Type | Provider | any[]*/> =
CONST_EXPR([ CONST_EXPR([
BROWSER_APP_COMMON_PROVIDERS, BROWSER_APP_COMMON_PROVIDERS, new Provider(XHR, {useClass: XHRImpl}),
new Provider(XHR, {useClass: XHRImpl}),
ADDITIONAL_TEST_BROWSER_PROVIDERS ADDITIONAL_TEST_BROWSER_PROVIDERS
]); ]);

View File

@ -1,14 +1,4 @@
import { import {APP_ID, DirectiveResolver, NgZone, Provider, ViewResolver, PLATFORM_COMMON_PROVIDERS, PLATFORM_INITIALIZER, APPLICATION_COMMON_PROVIDERS, Renderer} from 'angular2/core';
APP_ID,
DirectiveResolver,
NgZone,
Provider,
ViewResolver,
PLATFORM_COMMON_PROVIDERS,
PLATFORM_INITIALIZER,
APPLICATION_COMMON_PROVIDERS,
Renderer
} from 'angular2/core';
import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter'; import {Parse5DomAdapter} from 'angular2/src/platform/server/parse5_adapter';
import {AnimationBuilder} from 'angular2/src/animate/animation_builder'; import {AnimationBuilder} from 'angular2/src/animate/animation_builder';
@ -30,11 +20,7 @@ import {RootRenderer} from 'angular2/src/core/render/api';
import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer'; import {DomRootRenderer, DomRootRenderer_} from 'angular2/src/platform/dom/dom_renderer';
import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host'; import {DomSharedStylesHost} from 'angular2/src/platform/dom/shared_styles_host';
import { import {EventManager, EVENT_MANAGER_PLUGINS, ELEMENT_PROBE_PROVIDERS} from 'angular2/platform/common_dom';
EventManager,
EVENT_MANAGER_PLUGINS,
ELEMENT_PROBE_PROVIDERS
} from 'angular2/platform/common_dom';
import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events'; import {DomEventsPlugin} from 'angular2/src/platform/dom/events/dom_events';
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';

View File

@ -1,19 +1,7 @@
export { export {WORKER_APP_PLATFORM, WORKER_APP_APPLICATION_COMMON} from 'angular2/src/platform/worker_app_common';
WORKER_APP_PLATFORM,
WORKER_APP_APPLICATION_COMMON
} from 'angular2/src/platform/worker_app_common';
export {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app'; export {WORKER_APP_APPLICATION} from 'angular2/src/platform/worker_app';
export { export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from 'angular2/src/web_workers/shared/client_message_broker';
ClientMessageBroker, export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from 'angular2/src/web_workers/shared/service_message_broker';
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from 'angular2/src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from 'angular2/src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer'; export {PRIMITIVE} from 'angular2/src/web_workers/shared/serializer';
export * from 'angular2/src/web_workers/shared/message_bus'; export * from 'angular2/src/web_workers/shared/message_bus';
export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint'; export {AngularEntrypoint} from 'angular2/src/core/angular_entrypoint';

View File

@ -1,21 +1,7 @@
export { export {WORKER_SCRIPT, WORKER_RENDER_PLATFORM, initializeGenericWorkerRenderer, WORKER_RENDER_APPLICATION_COMMON} from 'angular2/src/platform/worker_render_common';
WORKER_SCRIPT,
WORKER_RENDER_PLATFORM,
initializeGenericWorkerRenderer,
WORKER_RENDER_APPLICATION_COMMON
} from 'angular2/src/platform/worker_render_common';
export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render'; export {WORKER_RENDER_APPLICATION, WebWorkerInstance} from 'angular2/src/platform/worker_render';
export { export {ClientMessageBroker, ClientMessageBrokerFactory, FnArg, UiArguments} from '../src/web_workers/shared/client_message_broker';
ClientMessageBroker, export {ReceivedMessage, ServiceMessageBroker, ServiceMessageBrokerFactory} from '../src/web_workers/shared/service_message_broker';
ClientMessageBrokerFactory,
FnArg,
UiArguments
} from '../src/web_workers/shared/client_message_broker';
export {
ReceivedMessage,
ServiceMessageBroker,
ServiceMessageBrokerFactory
} from '../src/web_workers/shared/service_message_broker';
export {PRIMITIVE} from '../src/web_workers/shared/serializer'; export {PRIMITIVE} from '../src/web_workers/shared/serializer';
export * from '../src/web_workers/shared/message_bus'; export * from '../src/web_workers/shared/message_bus';
import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render'; import {WORKER_RENDER_APPLICATION} from 'angular2/src/platform/worker_render';

View File

@ -1,10 +1,4 @@
import { import {DateWrapper, StringWrapper, RegExpWrapper, NumberWrapper, isPresent} from 'angular2/src/facade/lang';
DateWrapper,
StringWrapper,
RegExpWrapper,
NumberWrapper,
isPresent
} from 'angular2/src/facade/lang';
import {Math} from 'angular2/src/facade/math'; import {Math} from 'angular2/src/facade/math';
import {camelCaseToDashCase} from 'angular2/src/platform/dom/util'; import {camelCaseToDashCase} from 'angular2/src/platform/dom/util';
import {StringMapWrapper} from 'angular2/src/facade/collection'; import {StringMapWrapper} from 'angular2/src/facade/collection';
@ -47,8 +41,9 @@ export class Animation {
* @param data * @param data
* @param browserDetails * @param browserDetails
*/ */
constructor(public element: HTMLElement, public data: CssAnimationOptions, constructor(
public browserDetails: BrowserDetails) { public element: HTMLElement, public data: CssAnimationOptions,
public browserDetails: BrowserDetails) {
this.startTime = DateWrapper.toMillis(DateWrapper.now()); this.startTime = DateWrapper.toMillis(DateWrapper.now());
this._stringPrefix = DOM.getAnimationPrefix(); this._stringPrefix = DOM.getAnimationPrefix();
this.setup(); this.setup();
@ -80,15 +75,16 @@ export class Animation {
this.removeClasses(this.data.classesToRemove); this.removeClasses(this.data.classesToRemove);
if (this.data.toStyles != null) this.applyStyles(this.data.toStyles); if (this.data.toStyles != null) this.applyStyles(this.data.toStyles);
var computedStyles = DOM.getComputedStyle(this.element); var computedStyles = DOM.getComputedStyle(this.element);
this.computedDelay = this.computedDelay = Math.max(
Math.max(this.parseDurationString( this.parseDurationString(
computedStyles.getPropertyValue(this._stringPrefix + 'transition-delay')), computedStyles.getPropertyValue(this._stringPrefix + 'transition-delay')),
this.parseDurationString( this.parseDurationString(
this.element.style.getPropertyValue(this._stringPrefix + 'transition-delay'))); this.element.style.getPropertyValue(this._stringPrefix + 'transition-delay')));
this.computedDuration = Math.max(this.parseDurationString(computedStyles.getPropertyValue( this.computedDuration = Math.max(
this._stringPrefix + 'transition-duration')), this.parseDurationString(
this.parseDurationString(this.element.style.getPropertyValue( computedStyles.getPropertyValue(this._stringPrefix + 'transition-duration')),
this._stringPrefix + 'transition-duration'))); this.parseDurationString(
this.element.style.getPropertyValue(this._stringPrefix + 'transition-duration')));
this.addEvents(); this.addEvents();
} }

View File

@ -47,13 +47,5 @@ import {NgPlural, NgPluralCase} from './ng_plural';
* ``` * ```
*/ */
export const CORE_DIRECTIVES: Type[] = CONST_EXPR([ export const CORE_DIRECTIVES: Type[] = CONST_EXPR([
NgClass, NgClass, NgFor, NgIf, NgStyle, NgSwitch, NgSwitchWhen, NgSwitchDefault, NgPlural, NgPluralCase
NgFor,
NgIf,
NgStyle,
NgSwitch,
NgSwitchWhen,
NgSwitchDefault,
NgPlural,
NgPluralCase
]); ]);

View File

@ -1,17 +1,5 @@
import {isPresent, isString, isArray} from 'angular2/src/facade/lang'; import {isPresent, isString, isArray} from 'angular2/src/facade/lang';
import { import {DoCheck, OnDestroy, Directive, ElementRef, IterableDiffers, KeyValueDiffers, Renderer, IterableDiffer, KeyValueDiffer, CollectionChangeRecord, KeyValueChangeRecord} from 'angular2/core';
DoCheck,
OnDestroy,
Directive,
ElementRef,
IterableDiffers,
KeyValueDiffers,
Renderer,
IterableDiffer,
KeyValueDiffer,
CollectionChangeRecord,
KeyValueChangeRecord
} from 'angular2/core';
import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collection'; import {StringMapWrapper, isListLikeIterable} from 'angular2/src/facade/collection';
/** /**
@ -78,10 +66,11 @@ export class NgClass implements DoCheck, OnDestroy {
private _iterableDiffer: IterableDiffer; private _iterableDiffer: IterableDiffer;
private _keyValueDiffer: KeyValueDiffer; private _keyValueDiffer: KeyValueDiffer;
private _initialClasses: string[] = []; private _initialClasses: string[] = [];
private _rawClass: string[] | Set<string>; private _rawClass: string[]|Set<string>;
constructor(private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers, constructor(
private _ngEl: ElementRef, private _renderer: Renderer) {} private _iterableDiffers: IterableDiffers, private _keyValueDiffers: KeyValueDiffers,
private _ngEl: ElementRef, private _renderer: Renderer) {}
set initialClasses(v: string) { set initialClasses(v: string) {
this._applyInitialClasses(true); this._applyInitialClasses(true);
@ -90,14 +79,14 @@ export class NgClass implements DoCheck, OnDestroy {
this._applyClasses(this._rawClass, false); this._applyClasses(this._rawClass, false);
} }
set rawClass(v: string | string[] | Set<string>| {[key: string]: any}) { set rawClass(v: string|string[]|Set<string>|{[key: string]: any}) {
this._cleanupClasses(this._rawClass); this._cleanupClasses(this._rawClass);
if (isString(v)) { if (isString(v)) {
v = (<string>v).split(' '); v = (<string>v).split(' ');
} }
this._rawClass = <string[] | Set<string>>v; this._rawClass = <string[]|Set<string>>v;
this._iterableDiffer = null; this._iterableDiffer = null;
this._keyValueDiffer = null; this._keyValueDiffer = null;
if (isPresent(v)) { if (isPresent(v)) {
@ -126,7 +115,7 @@ export class NgClass implements DoCheck, OnDestroy {
ngOnDestroy(): void { this._cleanupClasses(this._rawClass); } ngOnDestroy(): void { this._cleanupClasses(this._rawClass); }
private _cleanupClasses(rawClassVal: string[] | Set<string>| {[key: string]: any}): void { private _cleanupClasses(rawClassVal: string[]|Set<string>|{[key: string]: any}): void {
this._applyClasses(rawClassVal, true); this._applyClasses(rawClassVal, true);
this._applyInitialClasses(false); this._applyInitialClasses(false);
} }
@ -154,18 +143,18 @@ export class NgClass implements DoCheck, OnDestroy {
this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup)); this._initialClasses.forEach(className => this._toggleClass(className, !isCleanup));
} }
private _applyClasses(rawClassVal: string[] | Set<string>| {[key: string]: any}, private _applyClasses(
isCleanup: boolean) { rawClassVal: string[]|Set<string>|{[key: string]: any}, isCleanup: boolean) {
if (isPresent(rawClassVal)) { if (isPresent(rawClassVal)) {
if (isArray(rawClassVal)) { if (isArray(rawClassVal)) {
(<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup)); (<string[]>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
} else if (rawClassVal instanceof Set) { } else if (rawClassVal instanceof Set) {
(<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup)); (<Set<string>>rawClassVal).forEach(className => this._toggleClass(className, !isCleanup));
} else { } else {
StringMapWrapper.forEach(<{[k: string]: any}>rawClassVal, StringMapWrapper.forEach(
(expVal: any, className: string) => { <{[k: string]: any}>rawClassVal, (expVal: any, className: string) => {
if (isPresent(expVal)) this._toggleClass(className, !isCleanup); if (isPresent(expVal)) this._toggleClass(className, !isCleanup);
}); });
} }
} }
} }

View File

@ -1,20 +1,7 @@
import { import {DoCheck, Directive, ChangeDetectorRef, IterableDiffer, IterableDiffers, ViewContainerRef, TemplateRef, EmbeddedViewRef, TrackByFn} from 'angular2/core';
DoCheck,
Directive,
ChangeDetectorRef,
IterableDiffer,
IterableDiffers,
ViewContainerRef,
TemplateRef,
EmbeddedViewRef,
TrackByFn
} from 'angular2/core';
import {isPresent, isBlank, stringify, getTypeNameForDebugging} from 'angular2/src/facade/lang'; import {isPresent, isBlank, stringify, getTypeNameForDebugging} from 'angular2/src/facade/lang';
import { import {DefaultIterableDiffer, CollectionChangeRecord} from '../../core/change_detection/differs/default_iterable_differ';
DefaultIterableDiffer, import {BaseException} from '../../facade/exceptions';
CollectionChangeRecord
} from "../../core/change_detection/differs/default_iterable_differ";
import {BaseException} from "../../facade/exceptions";
/** /**
* The `NgFor` directive instantiates a template once per item from an iterable. The context for * The `NgFor` directive instantiates a template once per item from an iterable. The context for
@ -75,8 +62,9 @@ export class NgFor implements DoCheck {
_ngForTrackBy: TrackByFn; _ngForTrackBy: TrackByFn;
private _differ: IterableDiffer; private _differ: IterableDiffer;
constructor(private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef, constructor(
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {} private _viewContainer: ViewContainerRef, private _templateRef: TemplateRef,
private _iterableDiffers: IterableDiffers, private _cdr: ChangeDetectorRef) {}
set ngForOf(value: any) { set ngForOf(value: any) {
this._ngForOf = value; this._ngForOf = value;
@ -109,16 +97,19 @@ export class NgFor implements DoCheck {
// TODO(rado): check if change detection can produce a change record that is // TODO(rado): check if change detection can produce a change record that is
// easier to consume than current. // easier to consume than current.
var recordViewTuples: RecordViewTuple[] = []; var recordViewTuples: RecordViewTuple[] = [];
changes.forEachRemovedItem((removedRecord: CollectionChangeRecord) => changes.forEachRemovedItem(
recordViewTuples.push(new RecordViewTuple(removedRecord, null))); (removedRecord: CollectionChangeRecord) =>
recordViewTuples.push(new RecordViewTuple(removedRecord, null)));
changes.forEachMovedItem((movedRecord: CollectionChangeRecord) => changes.forEachMovedItem(
recordViewTuples.push(new RecordViewTuple(movedRecord, null))); (movedRecord: CollectionChangeRecord) =>
recordViewTuples.push(new RecordViewTuple(movedRecord, null)));
var insertTuples = this._bulkRemove(recordViewTuples); var insertTuples = this._bulkRemove(recordViewTuples);
changes.forEachAddedItem((addedRecord: CollectionChangeRecord) => changes.forEachAddedItem(
insertTuples.push(new RecordViewTuple(addedRecord, null))); (addedRecord: CollectionChangeRecord) =>
insertTuples.push(new RecordViewTuple(addedRecord, null)));
this._bulkInsert(insertTuples); this._bulkInsert(insertTuples);
@ -146,8 +137,9 @@ export class NgFor implements DoCheck {
} }
private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] { private _bulkRemove(tuples: RecordViewTuple[]): RecordViewTuple[] {
tuples.sort((a: RecordViewTuple, b: RecordViewTuple) => tuples.sort(
a.record.previousIndex - b.record.previousIndex); (a: RecordViewTuple, b: RecordViewTuple) =>
a.record.previousIndex - b.record.previousIndex);
var movedTuples: RecordViewTuple[] = []; var movedTuples: RecordViewTuple[] = [];
for (var i = tuples.length - 1; i >= 0; i--) { for (var i = tuples.length - 1; i >= 0; i--) {
var tuple = tuples[i]; var tuple = tuples[i];

View File

@ -1,13 +1,4 @@
import { import {Directive, ViewContainerRef, TemplateRef, ContentChildren, QueryList, Attribute, AfterContentInit, Input} from 'angular2/core';
Directive,
ViewContainerRef,
TemplateRef,
ContentChildren,
QueryList,
Attribute,
AfterContentInit,
Input
} from 'angular2/core';
import {isPresent, NumberWrapper} from 'angular2/src/facade/lang'; import {isPresent, NumberWrapper} from 'angular2/src/facade/lang';
import {Map} from 'angular2/src/facade/collection'; import {Map} from 'angular2/src/facade/collection';
import {SwitchView} from './ng_switch'; import {SwitchView} from './ng_switch';
@ -76,8 +67,9 @@ export abstract class NgLocalization { abstract getPluralCategory(value: any): s
export class NgPluralCase { export class NgPluralCase {
/** @internal */ /** @internal */
_view: SwitchView; _view: SwitchView;
constructor(@Attribute('ngPluralCase') public value: string, template: TemplateRef, constructor(
viewContainer: ViewContainerRef) { @Attribute('ngPluralCase') public value: string, template: TemplateRef,
viewContainer: ViewContainerRef) {
this._view = new SwitchView(viewContainer, template); this._view = new SwitchView(viewContainer, template);
} }
} }
@ -135,7 +127,7 @@ export class NgPlural implements AfterContentInit {
} }
/** @internal */ /** @internal */
_isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === "="; } _isValueView(pluralCase: NgPluralCase): boolean { return pluralCase.value[0] === '='; }
/** @internal */ /** @internal */
_formatValue(pluralCase: NgPluralCase): any { _formatValue(pluralCase: NgPluralCase): any {

View File

@ -1,13 +1,6 @@
import { import {DoCheck, KeyValueDiffer, KeyValueDiffers, ElementRef, Directive, Renderer} from 'angular2/core';
DoCheck,
KeyValueDiffer,
KeyValueDiffers,
ElementRef,
Directive,
Renderer
} from 'angular2/core';
import {isPresent, isBlank, print} from 'angular2/src/facade/lang'; import {isPresent, isBlank, print} from 'angular2/src/facade/lang';
import {KeyValueChangeRecord} from "../../core/change_detection/differs/default_keyvalue_differ"; import {KeyValueChangeRecord} from '../../core/change_detection/differs/default_keyvalue_differ';
/** /**
* The `NgStyle` directive changes styles based on a result of expression evaluation. * The `NgStyle` directive changes styles based on a result of expression evaluation.
@ -67,8 +60,8 @@ export class NgStyle implements DoCheck {
/** @internal */ /** @internal */
_differ: KeyValueDiffer; _differ: KeyValueDiffer;
constructor(private _differs: KeyValueDiffers, private _ngEl: ElementRef, constructor(
private _renderer: Renderer) {} private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer) {}
set rawStyle(v: {[key: string]: string}) { set rawStyle(v: {[key: string]: string}) {
this._rawStyle = v; this._rawStyle = v;

View File

@ -175,8 +175,8 @@ export class NgSwitchWhen {
_view: SwitchView; _view: SwitchView;
private _switch: NgSwitch; private _switch: NgSwitch;
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, constructor(
@Host() ngSwitch: NgSwitch) { viewContainer: ViewContainerRef, templateRef: TemplateRef, @Host() ngSwitch: NgSwitch) {
this._switch = ngSwitch; this._switch = ngSwitch;
this._view = new SwitchView(viewContainer, templateRef); this._view = new SwitchView(viewContainer, templateRef);
} }
@ -195,8 +195,8 @@ export class NgSwitchWhen {
*/ */
@Directive({selector: '[ngSwitchDefault]'}) @Directive({selector: '[ngSwitchDefault]'})
export class NgSwitchDefault { export class NgSwitchDefault {
constructor(viewContainer: ViewContainerRef, templateRef: TemplateRef, constructor(
@Host() sswitch: NgSwitch) { viewContainer: ViewContainerRef, templateRef: TemplateRef, @Host() sswitch: NgSwitch) {
sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef)); sswitch._registerView(_WHEN_DEFAULT, new SwitchView(viewContainer, templateRef));
} }
} }

View File

@ -27,19 +27,10 @@ export {ControlValueAccessor, NG_VALUE_ACCESSOR} from './forms/directives/contro
export {DefaultValueAccessor} from './forms/directives/default_value_accessor'; export {DefaultValueAccessor} from './forms/directives/default_value_accessor';
export {NgControlStatus} from './forms/directives/ng_control_status'; export {NgControlStatus} from './forms/directives/ng_control_status';
export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor'; export {CheckboxControlValueAccessor} from './forms/directives/checkbox_value_accessor';
export { export {NgSelectOption, SelectControlValueAccessor} from './forms/directives/select_control_value_accessor';
NgSelectOption,
SelectControlValueAccessor
} from './forms/directives/select_control_value_accessor';
export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives'; export {FORM_DIRECTIVES, RadioButtonState} from './forms/directives';
export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators'; export {NG_VALIDATORS, NG_ASYNC_VALIDATORS, Validators} from './forms/validators';
export { export {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, Validator} from './forms/directives/validators';
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator,
Validator
} from './forms/directives/validators';
export {FormBuilder} from './forms/form_builder'; export {FormBuilder} from './forms/form_builder';
import {FormBuilder} from './forms/form_builder'; import {FormBuilder} from './forms/form_builder';
import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor'; import {RadioControlRegistry} from './forms/directives/radio_control_value_accessor';

View File

@ -10,16 +10,8 @@ import {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor
import {NumberValueAccessor} from './directives/number_value_accessor'; import {NumberValueAccessor} from './directives/number_value_accessor';
import {RadioControlValueAccessor} from './directives/radio_control_value_accessor'; import {RadioControlValueAccessor} from './directives/radio_control_value_accessor';
import {NgControlStatus} from './directives/ng_control_status'; import {NgControlStatus} from './directives/ng_control_status';
import { import {SelectControlValueAccessor, NgSelectOption} from './directives/select_control_value_accessor';
SelectControlValueAccessor, import {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator} from './directives/validators';
NgSelectOption
} from './directives/select_control_value_accessor';
import {
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator
} from './directives/validators';
export {NgControlName} from './directives/ng_control_name'; export {NgControlName} from './directives/ng_control_name';
export {NgFormControl} from './directives/ng_form_control'; export {NgFormControl} from './directives/ng_form_control';
@ -29,22 +21,11 @@ export {NgFormModel} from './directives/ng_form_model';
export {NgForm} from './directives/ng_form'; export {NgForm} from './directives/ng_form';
export {DefaultValueAccessor} from './directives/default_value_accessor'; export {DefaultValueAccessor} from './directives/default_value_accessor';
export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor'; export {CheckboxControlValueAccessor} from './directives/checkbox_value_accessor';
export { export {RadioControlValueAccessor, RadioButtonState} from './directives/radio_control_value_accessor';
RadioControlValueAccessor,
RadioButtonState
} from './directives/radio_control_value_accessor';
export {NumberValueAccessor} from './directives/number_value_accessor'; export {NumberValueAccessor} from './directives/number_value_accessor';
export {NgControlStatus} from './directives/ng_control_status'; export {NgControlStatus} from './directives/ng_control_status';
export { export {SelectControlValueAccessor, NgSelectOption} from './directives/select_control_value_accessor';
SelectControlValueAccessor, export {RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator} from './directives/validators';
NgSelectOption
} from './directives/select_control_value_accessor';
export {
RequiredValidator,
MinLengthValidator,
MaxLengthValidator,
PatternValidator
} from './directives/validators';
export {NgControl} from './directives/ng_control'; export {NgControl} from './directives/ng_control';
export {ControlValueAccessor} from './directives/control_value_accessor'; export {ControlValueAccessor} from './directives/control_value_accessor';
@ -65,24 +46,12 @@ export {ControlValueAccessor} from './directives/control_value_accessor';
* ``` * ```
*/ */
export const FORM_DIRECTIVES: Type[] = CONST_EXPR([ export const FORM_DIRECTIVES: Type[] = CONST_EXPR([
NgControlName, NgControlName, NgControlGroup,
NgControlGroup,
NgFormControl, NgFormControl, NgModel, NgFormModel, NgForm,
NgModel,
NgFormModel,
NgForm,
NgSelectOption, NgSelectOption, DefaultValueAccessor, NumberValueAccessor, CheckboxControlValueAccessor,
DefaultValueAccessor, SelectControlValueAccessor, RadioControlValueAccessor, NgControlStatus,
NumberValueAccessor,
CheckboxControlValueAccessor,
SelectControlValueAccessor,
RadioControlValueAccessor,
NgControlStatus,
RequiredValidator, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator
MinLengthValidator,
MaxLengthValidator,
PatternValidator
]); ]);

View File

@ -31,4 +31,4 @@ export interface ControlValueAccessor {
* *
* See {@link DefaultValueAccessor} for how to implement one. * See {@link DefaultValueAccessor} for how to implement one.
*/ */
export const NG_VALUE_ACCESSOR: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValueAccessor")); export const NG_VALUE_ACCESSOR: OpaqueToken = CONST_EXPR(new OpaqueToken('NgValueAccessor'));

View File

@ -1,15 +1,4 @@
import { import {OnInit, OnDestroy, Directive, Optional, Inject, Host, SkipSelf, forwardRef, Provider, Self} from 'angular2/core';
OnInit,
OnDestroy,
Directive,
Optional,
Inject,
Host,
SkipSelf,
forwardRef,
Provider,
Self
} from 'angular2/core';
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
import {ControlContainer} from './control_container'; import {ControlContainer} from './control_container';
@ -78,9 +67,10 @@ export class NgControlGroup extends ControlContainer implements OnInit,
/** @internal */ /** @internal */
_parent: ControlContainer; _parent: ControlContainer;
constructor(@Host() @SkipSelf() parent: ControlContainer, constructor(
@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[], @Host() @SkipSelf() parent: ControlContainer,
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) { @Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
super(); super();
this._parent = parent; this._parent = parent;
} }

View File

@ -1,31 +1,12 @@
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import { import {OnChanges, OnDestroy, SimpleChange, Query, Directive, forwardRef, Host, SkipSelf, Provider, Inject, Optional, Self} from 'angular2/core';
OnChanges,
OnDestroy,
SimpleChange,
Query,
Directive,
forwardRef,
Host,
SkipSelf,
Provider,
Inject,
Optional,
Self
} from 'angular2/core';
import {ControlContainer} from './control_container'; import {ControlContainer} from './control_container';
import {NgControl} from './ng_control'; import {NgControl} from './ng_control';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
import { import {controlPath, composeValidators, composeAsyncValidators, isPropertyUpdated, selectValueAccessor} from './shared';
controlPath,
composeValidators,
composeAsyncValidators,
isPropertyUpdated,
selectValueAccessor
} from './shared';
import {Control} from '../model'; import {Control} from '../model';
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators'; import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
import {ValidatorFn, AsyncValidatorFn} from './validators'; import {ValidatorFn, AsyncValidatorFn} from './validators';
@ -111,35 +92,37 @@ export class NgControlName extends NgControl implements OnChanges,
/* Array<Validator|Function> */ any[], /* Array<Validator|Function> */ any[],
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) @Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
valueAccessors: ControlValueAccessor[]) { valueAccessors: ControlValueAccessor[]) {
super(); super();
this.valueAccessor = selectValueAccessor(this, valueAccessors); this.valueAccessor = selectValueAccessor(this, valueAccessors);
} }
ngOnChanges(changes: {[key: string]: SimpleChange}) { ngOnChanges(changes: {[key: string]: SimpleChange}) {
if (!this._added) { if (!this._added) {
this.formDirective.addControl(this); this.formDirective.addControl(this);
this._added = true; this._added = true;
} }
if (isPropertyUpdated(changes, this.viewModel)) { if (isPropertyUpdated(changes, this.viewModel)) {
this.viewModel = this.model; this.viewModel = this.model;
this.formDirective.updateModel(this, this.model); this.formDirective.updateModel(this, this.model);
} }
} }
ngOnDestroy(): void { this.formDirective.removeControl(this); } ngOnDestroy(): void { this.formDirective.removeControl(this); }
viewToModelUpdate(newValue: any): void { viewToModelUpdate(newValue: any): void {
this.viewModel = newValue; this.viewModel = newValue;
ObservableWrapper.callEmit(this.update, newValue); ObservableWrapper.callEmit(this.update, newValue);
} }
get path(): string[] { return controlPath(this.name, this._parent); } get path(): string[] { return controlPath(this.name, this._parent); }
get formDirective(): any { return this._parent.formDirective; } get formDirective(): any { return this._parent.formDirective; }
get validator(): ValidatorFn { return composeValidators(this._validators); } get validator(): ValidatorFn { return composeValidators(this._validators); }
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); } get asyncValidator(): AsyncValidatorFn {
return composeAsyncValidators(this._asyncValidators);
}
get control(): Control { return this.formDirective.getControl(this); } get control(): Control { return this.formDirective.getControl(this); }
} }

View File

@ -1,9 +1,4 @@
import { import {PromiseWrapper, ObservableWrapper, EventEmitter, PromiseCompleter} from 'angular2/src/facade/async';
PromiseWrapper,
ObservableWrapper,
EventEmitter,
PromiseCompleter
} from 'angular2/src/facade/async';
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang'; import {isPresent, isBlank, CONST_EXPR} from 'angular2/src/facade/lang';
import {Directive, forwardRef, Provider, Optional, Inject, Self} from 'angular2/core'; import {Directive, forwardRef, Provider, Optional, Inject, Self} from 'angular2/core';
@ -90,11 +85,12 @@ export class NgForm extends ControlContainer implements Form {
form: ControlGroup; form: ControlGroup;
ngSubmit = new EventEmitter(); ngSubmit = new EventEmitter();
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) validators: any[], constructor(
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) { @Optional() @Self() @Inject(NG_VALIDATORS) validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) asyncValidators: any[]) {
super(); super();
this.form = new ControlGroup({}, null, composeValidators(validators), this.form = new ControlGroup(
composeAsyncValidators(asyncValidators)); {}, null, composeValidators(validators), composeAsyncValidators(asyncValidators));
} }
get formDirective(): Form { return this; } get formDirective(): Form { return this; }

View File

@ -1,28 +1,12 @@
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
import {StringMapWrapper} from 'angular2/src/facade/collection'; import {StringMapWrapper} from 'angular2/src/facade/collection';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import { import {OnChanges, SimpleChange, Query, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
OnChanges,
SimpleChange,
Query,
Directive,
forwardRef,
Provider,
Inject,
Optional,
Self
} from 'angular2/core';
import {NgControl} from './ng_control'; import {NgControl} from './ng_control';
import {Control} from '../model'; import {Control} from '../model';
import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators'; import {Validators, NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
import { import {setUpControl, composeValidators, composeAsyncValidators, isPropertyUpdated, selectValueAccessor} from './shared';
setUpControl,
composeValidators,
composeAsyncValidators,
isPropertyUpdated,
selectValueAccessor
} from './shared';
import {ValidatorFn, AsyncValidatorFn} from './validators'; import {ValidatorFn, AsyncValidatorFn} from './validators';
const formControlBinding = const formControlBinding =
@ -94,35 +78,37 @@ export class NgFormControl extends NgControl implements OnChanges {
/* Array<Validator|Function> */ any[], /* Array<Validator|Function> */ any[],
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) @Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
valueAccessors: ControlValueAccessor[]) { valueAccessors: ControlValueAccessor[]) {
super(); super();
this.valueAccessor = selectValueAccessor(this, valueAccessors); this.valueAccessor = selectValueAccessor(this, valueAccessors);
} }
ngOnChanges(changes: {[key: string]: SimpleChange}): void { ngOnChanges(changes: {[key: string]: SimpleChange}): void {
if (this._isControlChanged(changes)) { if (this._isControlChanged(changes)) {
setUpControl(this.form, this); setUpControl(this.form, this);
this.form.updateValueAndValidity({emitEvent: false}); this.form.updateValueAndValidity({emitEvent: false});
} }
if (isPropertyUpdated(changes, this.viewModel)) { if (isPropertyUpdated(changes, this.viewModel)) {
this.form.updateValue(this.model); this.form.updateValue(this.model);
this.viewModel = this.model; this.viewModel = this.model;
} }
} }
get path(): string[] { return []; } get path(): string[] { return []; }
get validator(): ValidatorFn { return composeValidators(this._validators); } get validator(): ValidatorFn { return composeValidators(this._validators); }
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); } get asyncValidator(): AsyncValidatorFn {
return composeAsyncValidators(this._asyncValidators);
}
get control(): Control { return this.form; } get control(): Control { return this.form; }
viewToModelUpdate(newValue: any): void { viewToModelUpdate(newValue: any): void {
this.viewModel = newValue; this.viewModel = newValue;
ObservableWrapper.callEmit(this.update, newValue); ObservableWrapper.callEmit(this.update, newValue);
} }
private _isControlChanged(changes: {[key: string]: any}): boolean { private _isControlChanged(changes: {[key: string]: any}): boolean {
return StringMapWrapper.contains(changes, "form"); return StringMapWrapper.contains(changes, 'form');
} }
} }

View File

@ -1,16 +1,7 @@
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async'; import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
import { import {SimpleChange, OnChanges, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
SimpleChange,
OnChanges,
Directive,
forwardRef,
Provider,
Inject,
Optional,
Self
} from 'angular2/core';
import {NgControl} from './ng_control'; import {NgControl} from './ng_control';
import {NgControlGroup} from './ng_control_group'; import {NgControlGroup} from './ng_control_group';
import {ControlContainer} from './control_container'; import {ControlContainer} from './control_container';
@ -108,13 +99,14 @@ export class NgFormModel extends ControlContainer implements Form,
directives: NgControl[] = []; directives: NgControl[] = [];
ngSubmit = new EventEmitter(); ngSubmit = new EventEmitter();
constructor(@Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[], constructor(
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) { @Optional() @Self() @Inject(NG_VALIDATORS) private _validators: any[],
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[]) {
super(); super();
} }
ngOnChanges(changes: {[key: string]: SimpleChange}): void { ngOnChanges(changes: {[key: string]: SimpleChange}): void {
if (StringMapWrapper.contains(changes, "form")) { if (StringMapWrapper.contains(changes, 'form')) {
var sync = composeValidators(this._validators); var sync = composeValidators(this._validators);
this.form.validator = Validators.compose([this.form.validator, sync]); this.form.validator = Validators.compose([this.form.validator, sync]);

View File

@ -1,26 +1,11 @@
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async'; import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
import { import {OnChanges, SimpleChange, Directive, forwardRef, Provider, Inject, Optional, Self} from 'angular2/core';
OnChanges,
SimpleChange,
Directive,
forwardRef,
Provider,
Inject,
Optional,
Self
} from 'angular2/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from './control_value_accessor';
import {NgControl} from './ng_control'; import {NgControl} from './ng_control';
import {Control} from '../model'; import {Control} from '../model';
import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators'; import {NG_VALIDATORS, NG_ASYNC_VALIDATORS} from '../validators';
import { import {setUpControl, isPropertyUpdated, selectValueAccessor, composeValidators, composeAsyncValidators} from './shared';
setUpControl,
isPropertyUpdated,
selectValueAccessor,
composeValidators,
composeAsyncValidators
} from './shared';
import {ValidatorFn, AsyncValidatorFn} from './validators'; import {ValidatorFn, AsyncValidatorFn} from './validators';
const formControlBinding = const formControlBinding =
@ -67,33 +52,35 @@ export class NgModel extends NgControl implements OnChanges {
@Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[], @Optional() @Self() @Inject(NG_ASYNC_VALIDATORS) private _asyncValidators: any[],
@Optional() @Self() @Inject(NG_VALUE_ACCESSOR) @Optional() @Self() @Inject(NG_VALUE_ACCESSOR)
valueAccessors: ControlValueAccessor[]) { valueAccessors: ControlValueAccessor[]) {
super(); super();
this.valueAccessor = selectValueAccessor(this, valueAccessors); this.valueAccessor = selectValueAccessor(this, valueAccessors);
} }
ngOnChanges(changes: {[key: string]: SimpleChange}) { ngOnChanges(changes: {[key: string]: SimpleChange}) {
if (!this._added) { if (!this._added) {
setUpControl(this._control, this); setUpControl(this._control, this);
this._control.updateValueAndValidity({emitEvent: false}); this._control.updateValueAndValidity({emitEvent: false});
this._added = true; this._added = true;
} }
if (isPropertyUpdated(changes, this.viewModel)) { if (isPropertyUpdated(changes, this.viewModel)) {
this._control.updateValue(this.model); this._control.updateValue(this.model);
this.viewModel = this.model; this.viewModel = this.model;
} }
} }
get control(): Control { return this._control; } get control(): Control { return this._control; }
get path(): string[] { return []; } get path(): string[] { return []; }
get validator(): ValidatorFn { return composeValidators(this._validators); } get validator(): ValidatorFn { return composeValidators(this._validators); }
get asyncValidator(): AsyncValidatorFn { return composeAsyncValidators(this._asyncValidators); } get asyncValidator(): AsyncValidatorFn {
return composeAsyncValidators(this._asyncValidators);
}
viewToModelUpdate(newValue: any): void { viewToModelUpdate(newValue: any): void {
this.viewModel = newValue; this.viewModel = newValue;
ObservableWrapper.callEmit(this.update, newValue); ObservableWrapper.callEmit(this.update, newValue);
} }
} }

View File

@ -1,4 +1,4 @@
import {AbstractControl} from "../model"; import {AbstractControl} from '../model';
import {Validator, ValidatorFn, AsyncValidatorFn} from './validators'; import {Validator, ValidatorFn, AsyncValidatorFn} from './validators';
export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn { export function normalizeValidator(validator: ValidatorFn | Validator): ValidatorFn {

View File

@ -1,21 +1,5 @@
import { import {Directive, ElementRef, Renderer, Self, forwardRef, Provider, Attribute, Input, OnInit, OnDestroy, Injector, Injectable} from 'angular2/core';
Directive, import {NG_VALUE_ACCESSOR, ControlValueAccessor} from 'angular2/src/common/forms/directives/control_value_accessor';
ElementRef,
Renderer,
Self,
forwardRef,
Provider,
Attribute,
Input,
OnInit,
OnDestroy,
Injector,
Injectable
} from 'angular2/core';
import {
NG_VALUE_ACCESSOR,
ControlValueAccessor
} from 'angular2/src/common/forms/directives/control_value_accessor';
import {NgControl} from 'angular2/src/common/forms/directives/ng_control'; import {NgControl} from 'angular2/src/common/forms/directives/ng_control';
import {CONST_EXPR, looseIdentical, isPresent} from 'angular2/src/facade/lang'; import {CONST_EXPR, looseIdentical, isPresent} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
@ -98,8 +82,9 @@ export class RadioControlValueAccessor implements ControlValueAccessor,
onChange = () => {}; onChange = () => {};
onTouched = () => {}; onTouched = () => {};
constructor(private _renderer: Renderer, private _elementRef: ElementRef, constructor(
private _registry: RadioControlRegistry, private _injector: Injector) {} private _renderer: Renderer, private _elementRef: ElementRef,
private _registry: RadioControlRegistry, private _injector: Injector) {}
ngOnInit(): void { ngOnInit(): void {
this._control = this._injector.get(NgControl); this._control = this._injector.get(NgControl);

View File

@ -1,23 +1,6 @@
import { import {Directive, Renderer, forwardRef, Provider, ElementRef, Input, Host, OnDestroy, Optional} from 'angular2/core';
Directive,
Renderer,
forwardRef,
Provider,
ElementRef,
Input,
Host,
OnDestroy,
Optional
} from 'angular2/core';
import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor'; import {NG_VALUE_ACCESSOR, ControlValueAccessor} from './control_value_accessor';
import { import {CONST_EXPR, StringWrapper, isPrimitive, isPresent, isBlank, looseIdentical} from 'angular2/src/facade/lang';
CONST_EXPR,
StringWrapper,
isPrimitive,
isPresent,
isBlank,
looseIdentical
} from 'angular2/src/facade/lang';
import {MapWrapper} from 'angular2/src/facade/collection'; import {MapWrapper} from 'angular2/src/facade/collection';
@ -26,12 +9,12 @@ const SELECT_VALUE_ACCESSOR = CONST_EXPR(new Provider(
function _buildValueString(id: string, value: any): string { function _buildValueString(id: string, value: any): string {
if (isBlank(id)) return `${value}`; if (isBlank(id)) return `${value}`;
if (!isPrimitive(value)) value = "Object"; if (!isPrimitive(value)) value = 'Object';
return StringWrapper.slice(`${id}: ${value}`, 0, 50); return StringWrapper.slice(`${id}: ${value}`, 0, 50);
} }
function _extractId(valueString: string): string { function _extractId(valueString: string): string {
return valueString.split(":")[0]; return valueString.split(':')[0];
} }
/** /**
@ -98,8 +81,9 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
export class NgSelectOption implements OnDestroy { export class NgSelectOption implements OnDestroy {
id: string; id: string;
constructor(private _element: ElementRef, private _renderer: Renderer, constructor(
@Optional() @Host() private _select: SelectControlValueAccessor) { private _element: ElementRef, private _renderer: Renderer,
@Optional() @Host() private _select: SelectControlValueAccessor) {
if (isPresent(this._select)) this.id = this._select._registerOption(); if (isPresent(this._select)) this.id = this._select._registerOption();
} }

View File

@ -25,8 +25,8 @@ export function controlPath(name: string, parent: ControlContainer): string[] {
} }
export function setUpControl(control: Control, dir: NgControl): void { export function setUpControl(control: Control, dir: NgControl): void {
if (isBlank(control)) _throwError(dir, "Cannot find control"); if (isBlank(control)) _throwError(dir, 'Cannot find control');
if (isBlank(dir.valueAccessor)) _throwError(dir, "No value accessor for"); if (isBlank(dir.valueAccessor)) _throwError(dir, 'No value accessor for');
control.validator = Validators.compose([control.validator, dir.validator]); control.validator = Validators.compose([control.validator, dir.validator]);
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]); control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
@ -47,13 +47,13 @@ export function setUpControl(control: Control, dir: NgControl): void {
} }
export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) { export function setUpControlGroup(control: ControlGroup, dir: NgControlGroup) {
if (isBlank(control)) _throwError(dir, "Cannot find control"); if (isBlank(control)) _throwError(dir, 'Cannot find control');
control.validator = Validators.compose([control.validator, dir.validator]); control.validator = Validators.compose([control.validator, dir.validator]);
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]); control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
} }
function _throwError(dir: AbstractControlDirective, message: string): void { function _throwError(dir: AbstractControlDirective, message: string): void {
var path = dir.path.join(" -> "); var path = dir.path.join(' -> ');
throw new BaseException(`${message} '${path}'`); throw new BaseException(`${message} '${path}'`);
} }
@ -61,23 +61,23 @@ export function composeValidators(validators: /* Array<Validator|Function> */ an
return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null; return isPresent(validators) ? Validators.compose(validators.map(normalizeValidator)) : null;
} }
export function composeAsyncValidators( export function composeAsyncValidators(validators: /* Array<Validator|Function> */ any[]):
validators: /* Array<Validator|Function> */ any[]): AsyncValidatorFn { AsyncValidatorFn {
return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) : return isPresent(validators) ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
null; null;
} }
export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean { export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
if (!StringMapWrapper.contains(changes, "model")) return false; if (!StringMapWrapper.contains(changes, 'model')) return false;
var change = changes["model"]; var change = changes['model'];
if (change.isFirstChange()) return true; if (change.isFirstChange()) return true;
return !looseIdentical(viewModel, change.currentValue); return !looseIdentical(viewModel, change.currentValue);
} }
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented // TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
export function selectValueAccessor(dir: NgControl, export function selectValueAccessor(
valueAccessors: ControlValueAccessor[]): ControlValueAccessor { dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
if (isBlank(valueAccessors)) return null; if (isBlank(valueAccessors)) return null;
var defaultAccessor: ControlValueAccessor; var defaultAccessor: ControlValueAccessor;
@ -87,17 +87,17 @@ export function selectValueAccessor(dir: NgControl,
if (hasConstructor(v, DefaultValueAccessor)) { if (hasConstructor(v, DefaultValueAccessor)) {
defaultAccessor = v; defaultAccessor = v;
} else if (hasConstructor(v, CheckboxControlValueAccessor) || } else if (
hasConstructor(v, NumberValueAccessor) || hasConstructor(v, CheckboxControlValueAccessor) || hasConstructor(v, NumberValueAccessor) ||
hasConstructor(v, SelectControlValueAccessor) || hasConstructor(v, SelectControlValueAccessor) ||
hasConstructor(v, RadioControlValueAccessor)) { hasConstructor(v, RadioControlValueAccessor)) {
if (isPresent(builtinAccessor)) if (isPresent(builtinAccessor))
_throwError(dir, "More than one built-in value accessor matches"); _throwError(dir, 'More than one built-in value accessor matches');
builtinAccessor = v; builtinAccessor = v;
} else { } else {
if (isPresent(customAccessor)) if (isPresent(customAccessor))
_throwError(dir, "More than one custom value accessor matches"); _throwError(dir, 'More than one custom value accessor matches');
customAccessor = v; customAccessor = v;
} }
}); });
@ -106,6 +106,6 @@ export function selectValueAccessor(dir: NgControl,
if (isPresent(builtinAccessor)) return builtinAccessor; if (isPresent(builtinAccessor)) return builtinAccessor;
if (isPresent(defaultAccessor)) return defaultAccessor; if (isPresent(defaultAccessor)) return defaultAccessor;
_throwError(dir, "No valid value accessor for"); _throwError(dir, 'No valid value accessor for');
return null; return null;
} }

View File

@ -3,7 +3,7 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
import {Validators, NG_VALIDATORS} from '../validators'; import {Validators, NG_VALIDATORS} from '../validators';
import {AbstractControl} from '../model'; import {AbstractControl} from '../model';
import * as modelModule from '../model'; import * as modelModule from '../model';
import {NumberWrapper} from "angular2/src/facade/lang"; import {NumberWrapper} from 'angular2/src/facade/lang';
@ -74,7 +74,7 @@ const MIN_LENGTH_VALIDATOR = CONST_EXPR(
export class MinLengthValidator implements Validator { export class MinLengthValidator implements Validator {
private _validator: ValidatorFn; private _validator: ValidatorFn;
constructor(@Attribute("minlength") minLength: string) { constructor(@Attribute('minlength') minLength: string) {
this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10)); this._validator = Validators.minLength(NumberWrapper.parseInt(minLength, 10));
} }
@ -102,7 +102,7 @@ const MAX_LENGTH_VALIDATOR = CONST_EXPR(
export class MaxLengthValidator implements Validator { export class MaxLengthValidator implements Validator {
private _validator: ValidatorFn; private _validator: ValidatorFn;
constructor(@Attribute("maxlength") maxLength: string) { constructor(@Attribute('maxlength') maxLength: string) {
this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10)); this._validator = Validators.maxLength(NumberWrapper.parseInt(maxLength, 10));
} }
@ -131,7 +131,7 @@ const PATTERN_VALIDATOR = CONST_EXPR(
export class PatternValidator implements Validator { export class PatternValidator implements Validator {
private _validator: ValidatorFn; private _validator: ValidatorFn;
constructor(@Attribute("pattern") pattern: string) { constructor(@Attribute('pattern') pattern: string) {
this._validator = Validators.pattern(pattern); this._validator = Validators.pattern(pattern);
} }

View File

@ -54,21 +54,21 @@ export class FormBuilder {
* *
* See the {@link ControlGroup} constructor for more details. * See the {@link ControlGroup} constructor for more details.
*/ */
group(controlsConfig: {[key: string]: any}, group(controlsConfig: {[key: string]: any}, extra: {[key: string]: any} = null):
extra: {[key: string]: any} = null): modelModule.ControlGroup { modelModule.ControlGroup {
var controls = this._reduceControls(controlsConfig); var controls = this._reduceControls(controlsConfig);
var optionals = <{[key: string]: boolean}>( var optionals = <{[key: string]: boolean}>(
isPresent(extra) ? StringMapWrapper.get(extra, "optionals") : null); isPresent(extra) ? StringMapWrapper.get(extra, 'optionals') : null);
var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, "validator") : null; var validator: ValidatorFn = isPresent(extra) ? StringMapWrapper.get(extra, 'validator') : null;
var asyncValidator: AsyncValidatorFn = var asyncValidator: AsyncValidatorFn =
isPresent(extra) ? StringMapWrapper.get(extra, "asyncValidator") : null; isPresent(extra) ? StringMapWrapper.get(extra, 'asyncValidator') : null;
return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator); return new modelModule.ControlGroup(controls, optionals, validator, asyncValidator);
} }
/** /**
* Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`. * Construct a new {@link Control} with the given `value`,`validator`, and `asyncValidator`.
*/ */
control(value: Object, validator: ValidatorFn = null, control(value: Object, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null):
asyncValidator: AsyncValidatorFn = null): modelModule.Control { modelModule.Control {
return new modelModule.Control(value, validator, asyncValidator); return new modelModule.Control(value, validator, asyncValidator);
} }
@ -76,15 +76,16 @@ export class FormBuilder {
* Construct an array of {@link Control}s from the given `controlsConfig` array of * Construct an array of {@link Control}s from the given `controlsConfig` array of
* configuration, with the given optional `validator` and `asyncValidator`. * configuration, with the given optional `validator` and `asyncValidator`.
*/ */
array(controlsConfig: any[], validator: ValidatorFn = null, array(
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray { controlsConfig: any[], validator: ValidatorFn = null,
asyncValidator: AsyncValidatorFn = null): modelModule.ControlArray {
var controls = controlsConfig.map(c => this._createControl(c)); var controls = controlsConfig.map(c => this._createControl(c));
return new modelModule.ControlArray(controls, validator, asyncValidator); return new modelModule.ControlArray(controls, validator, asyncValidator);
} }
/** @internal */ /** @internal */
_reduceControls(controlsConfig: {[k: string]: _reduceControls(controlsConfig: {[k: string]: any}):
any}): {[key: string]: modelModule.AbstractControl} { {[key: string]: modelModule.AbstractControl} {
var controls: {[key: string]: modelModule.AbstractControl} = {}; var controls: {[key: string]: modelModule.AbstractControl} = {};
StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => { StringMapWrapper.forEach(controlsConfig, (controlConfig: any, controlName: string) => {
controls[controlName] = this._createControl(controlConfig); controls[controlName] = this._createControl(controlConfig);

View File

@ -7,42 +7,41 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
/** /**
* Indicates that a Control is valid, i.e. that no errors exist in the input value. * Indicates that a Control is valid, i.e. that no errors exist in the input value.
*/ */
export const VALID = "VALID"; export const VALID = 'VALID';
/** /**
* Indicates that a Control is invalid, i.e. that an error exists in the input value. * Indicates that a Control is invalid, i.e. that an error exists in the input value.
*/ */
export const INVALID = "INVALID"; export const INVALID = 'INVALID';
/** /**
* Indicates that a Control is pending, i.e. that async validation is occurring and * Indicates that a Control is pending, i.e. that async validation is occurring and
* errors are not yet available for the input value. * errors are not yet available for the input value.
*/ */
export const PENDING = "PENDING"; export const PENDING = 'PENDING';
export function isControl(control: Object): boolean { export function isControl(control: Object): boolean {
return control instanceof AbstractControl; return control instanceof AbstractControl;
} }
function _find(control: AbstractControl, path: Array<string | number>| string) { function _find(control: AbstractControl, path: Array<string|number>| string) {
if (isBlank(path)) return null; if (isBlank(path)) return null;
if (!(path instanceof Array)) { if (!(path instanceof Array)) {
path = (<string>path).split("/"); path = (<string>path).split('/');
} }
if (path instanceof Array && ListWrapper.isEmpty(path)) return null; if (path instanceof Array && ListWrapper.isEmpty(path)) return null;
return (<Array<string | number>>path) return (<Array<string|number>>path).reduce((v, name) => {
.reduce((v, name) => { if (v instanceof ControlGroup) {
if (v instanceof ControlGroup) { return isPresent(v.controls[name]) ? v.controls[name] : null;
return isPresent(v.controls[name]) ? v.controls[name] : null; } else if (v instanceof ControlArray) {
} else if (v instanceof ControlArray) { var index = <number>name;
var index = <number>name; return isPresent(v.at(index)) ? v.at(index) : null;
return isPresent(v.at(index)) ? v.at(index) : null; } else {
} else { return null;
return null; }
} }, control);
}, control);
} }
function toObservable(r: any): Observable<any> { function toObservable(r: any): Observable<any> {
@ -62,7 +61,7 @@ export abstract class AbstractControl {
private _errors: {[key: string]: any}; private _errors: {[key: string]: any};
private _pristine: boolean = true; private _pristine: boolean = true;
private _touched: boolean = false; private _touched: boolean = false;
private _parent: ControlGroup | ControlArray; private _parent: ControlGroup|ControlArray;
private _asyncValidationSubscription: any; private _asyncValidationSubscription: any;
constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {} constructor(public validator: ValidatorFn, public asyncValidator: AsyncValidatorFn) {}
@ -112,10 +111,10 @@ export abstract class AbstractControl {
} }
} }
setParent(parent: ControlGroup | ControlArray): void { this._parent = parent; } setParent(parent: ControlGroup|ControlArray): void { this._parent = parent; }
updateValueAndValidity( updateValueAndValidity({onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}):
{onlySelf, emitEvent}: {onlySelf?: boolean, emitEvent?: boolean} = {}): void { void {
onlySelf = normalizeBool(onlySelf); onlySelf = normalizeBool(onlySelf);
emitEvent = isPresent(emitEvent) ? emitEvent : true; emitEvent = isPresent(emitEvent) ? emitEvent : true;
@ -196,7 +195,7 @@ export abstract class AbstractControl {
} }
} }
find(path: Array<string | number>| string): AbstractControl { return _find(this, path); } find(path: Array<string|number>|string): AbstractControl { return _find(this, path); }
getError(errorCode: string, path: string[] = null): any { getError(errorCode: string, path: string[] = null): any {
var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this; var control = isPresent(path) && !ListWrapper.isEmpty(path) ? this.find(path) : this;
@ -271,8 +270,8 @@ export class Control extends AbstractControl {
/** @internal */ /** @internal */
_onChange: Function; _onChange: Function;
constructor(value: any = null, validator: ValidatorFn = null, constructor(
asyncValidator: AsyncValidatorFn = null) { value: any = null, validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
super(validator, asyncValidator); super(validator, asyncValidator);
this._value = value; this._value = value;
this.updateValueAndValidity({onlySelf: true, emitEvent: false}); this.updateValueAndValidity({onlySelf: true, emitEvent: false});
@ -335,9 +334,9 @@ export class Control extends AbstractControl {
export class ControlGroup extends AbstractControl { export class ControlGroup extends AbstractControl {
private _optionals: {[key: string]: boolean}; private _optionals: {[key: string]: boolean};
constructor(public controls: {[key: string]: AbstractControl}, constructor(
optionals: {[key: string]: boolean} = null, validator: ValidatorFn = null, public controls: {[key: string]: AbstractControl}, optionals: {[key: string]: boolean} = null,
asyncValidator: AsyncValidatorFn = null) { validator: ValidatorFn = null, asyncValidator: AsyncValidatorFn = null) {
super(validator, asyncValidator); super(validator, asyncValidator);
this._optionals = isPresent(optionals) ? optionals : {}; this._optionals = isPresent(optionals) ? optionals : {};
this._initObservables(); this._initObservables();
@ -450,8 +449,9 @@ export class ControlGroup extends AbstractControl {
* ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview)) * ### Example ([live demo](http://plnkr.co/edit/23DESOpbNnBpBHZt1BR4?p=preview))
*/ */
export class ControlArray extends AbstractControl { export class ControlArray extends AbstractControl {
constructor(public controls: AbstractControl[], validator: ValidatorFn = null, constructor(
asyncValidator: AsyncValidatorFn = null) { public controls: AbstractControl[], validator: ValidatorFn = null,
asyncValidator: AsyncValidatorFn = null) {
super(validator, asyncValidator); super(validator, asyncValidator);
this._initObservables(); this._initObservables();
this._setParentForControls(); this._setParentForControls();

View File

@ -16,7 +16,7 @@ import {ValidatorFn, AsyncValidatorFn} from './directives/validators';
* *
* {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'} * {@example core/forms/ts/ng_validators/ng_validators.ts region='ng_validators'}
*/ */
export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValidators")); export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken('NgValidators'));
/** /**
* Providers for asynchronous validators to be used for {@link Control}s * Providers for asynchronous validators to be used for {@link Control}s
@ -26,7 +26,7 @@ export const NG_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgValidato
* *
* See {@link NG_VALIDATORS} for more details. * See {@link NG_VALIDATORS} for more details.
*/ */
export const NG_ASYNC_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken("NgAsyncValidators")); export const NG_ASYNC_VALIDATORS: OpaqueToken = CONST_EXPR(new OpaqueToken('NgAsyncValidators'));
/** /**
* Provides a set of validators used by form controls. * Provides a set of validators used by form controls.
@ -45,9 +45,9 @@ export class Validators {
* Validator that requires controls to have a non-empty value. * Validator that requires controls to have a non-empty value.
*/ */
static required(control: modelModule.AbstractControl): {[key: string]: boolean} { static required(control: modelModule.AbstractControl): {[key: string]: boolean} {
return isBlank(control.value) || (isString(control.value) && control.value == "") ? return isBlank(control.value) || (isString(control.value) && control.value == '') ?
{"required": true} : {'required': true} :
null; null;
} }
/** /**
@ -58,8 +58,8 @@ export class Validators {
if (isPresent(Validators.required(control))) return null; if (isPresent(Validators.required(control))) return null;
var v: string = control.value; var v: string = control.value;
return v.length < minLength ? return v.length < minLength ?
{"minlength": {"requiredLength": minLength, "actualLength": v.length}} : {'minlength': {'requiredLength': minLength, 'actualLength': v.length}} :
null; null;
}; };
} }
@ -71,8 +71,8 @@ export class Validators {
if (isPresent(Validators.required(control))) return null; if (isPresent(Validators.required(control))) return null;
var v: string = control.value; var v: string = control.value;
return v.length > maxLength ? return v.length > maxLength ?
{"maxlength": {"requiredLength": maxLength, "actualLength": v.length}} : {'maxlength': {'requiredLength': maxLength, 'actualLength': v.length}} :
null; null;
}; };
} }
@ -85,7 +85,7 @@ export class Validators {
let regex = new RegExp(`^${pattern}$`); let regex = new RegExp(`^${pattern}$`);
let v: string = control.value; let v: string = control.value;
return regex.test(v) ? null : return regex.test(v) ? null :
{"pattern": {"requiredPattern": `^${pattern}$`, "actualValue": v}}; {'pattern': {'requiredPattern': `^${pattern}$`, 'actualValue': v}};
}; };
} }
@ -124,13 +124,13 @@ function _convertToPromise(obj: any): any {
return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj); return PromiseWrapper.isPromise(obj) ? obj : ObservableWrapper.toPromise(obj);
} }
function _executeValidators(control: modelModule.AbstractControl, function _executeValidators(
validators: ValidatorFn[]): any[] { control: modelModule.AbstractControl, validators: ValidatorFn[]): any[] {
return validators.map(v => v(control)); return validators.map(v => v(control));
} }
function _executeAsyncValidators(control: modelModule.AbstractControl, function _executeAsyncValidators(
validators: AsyncValidatorFn[]): any[] { control: modelModule.AbstractControl, validators: AsyncValidatorFn[]): any[] {
return validators.map(v => v(control)); return validators.map(v => v(control));
} }

View File

@ -1,13 +1,6 @@
import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang'; import {isBlank, isPresent, isPromise, CONST} from 'angular2/src/facade/lang';
import {ObservableWrapper, Observable, EventEmitter} from 'angular2/src/facade/async'; import {ObservableWrapper, Observable, EventEmitter} from 'angular2/src/facade/async';
import { import {Pipe, Injectable, ChangeDetectorRef, OnDestroy, PipeTransform, WrappedValue} from 'angular2/core';
Pipe,
Injectable,
ChangeDetectorRef,
OnDestroy,
PipeTransform,
WrappedValue
} from 'angular2/core';
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception'; import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';
@ -64,7 +57,7 @@ export class AsyncPipe implements PipeTransform, OnDestroy {
/** @internal */ /** @internal */
_subscription: Object = null; _subscription: Object = null;
/** @internal */ /** @internal */
_obj: Observable<any>| Promise<any>| EventEmitter<any> = null; _obj: Observable<any>|Promise<any>|EventEmitter<any> = null;
private _strategy: any = null; private _strategy: any = null;
/** @internal */ /** @internal */
public _ref: ChangeDetectorRef; public _ref: ChangeDetectorRef;
@ -76,7 +69,7 @@ export class AsyncPipe implements PipeTransform, OnDestroy {
} }
} }
transform(obj: Observable<any>| Promise<any>| EventEmitter<any>, args?: any[]): any { transform(obj: Observable<any>|Promise<any>|EventEmitter<any>, args?: any[]): any {
if (isBlank(this._obj)) { if (isBlank(this._obj)) {
if (isPresent(obj)) { if (isPresent(obj)) {
this._subscribe(obj); this._subscribe(obj);
@ -99,7 +92,7 @@ export class AsyncPipe implements PipeTransform, OnDestroy {
} }
/** @internal */ /** @internal */
_subscribe(obj: Observable<any>| Promise<any>| EventEmitter<any>): void { _subscribe(obj: Observable<any>|Promise<any>|EventEmitter<any>): void {
this._obj = obj; this._obj = obj;
this._strategy = this._selectStrategy(obj); this._strategy = this._selectStrategy(obj);
this._subscription = this._strategy.createSubscription( this._subscription = this._strategy.createSubscription(
@ -107,7 +100,7 @@ export class AsyncPipe implements PipeTransform, OnDestroy {
} }
/** @internal */ /** @internal */
_selectStrategy(obj: Observable<any>| Promise<any>| EventEmitter<any>): any { _selectStrategy(obj: Observable<any>|Promise<any>|EventEmitter<any>): any {
if (isPromise(obj)) { if (isPromise(obj)) {
return _promiseStrategy; return _promiseStrategy;
} else if (ObservableWrapper.isObservable(obj)) { } else if (ObservableWrapper.isObservable(obj)) {

View File

@ -23,16 +23,6 @@ import {CONST_EXPR} from 'angular2/src/facade/lang';
* property of the `@Component` decorator. * property of the `@Component` decorator.
*/ */
export const COMMON_PIPES = CONST_EXPR([ export const COMMON_PIPES = CONST_EXPR([
AsyncPipe, AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe,
UpperCasePipe, CurrencyPipe, DatePipe, ReplacePipe, I18nPluralPipe, I18nSelectPipe
LowerCasePipe,
JsonPipe,
SlicePipe,
DecimalPipe,
PercentPipe,
CurrencyPipe,
DatePipe,
ReplacePipe,
I18nPluralPipe,
I18nSelectPipe
]); ]);

View File

@ -1,13 +1,4 @@
import { import {isDate, isNumber, isPresent, Date, DateWrapper, CONST, isBlank, FunctionWrapper} from 'angular2/src/facade/lang';
isDate,
isNumber,
isPresent,
Date,
DateWrapper,
CONST,
isBlank,
FunctionWrapper
} from 'angular2/src/facade/lang';
import {DateFormatter} from 'angular2/src/facade/intl'; import {DateFormatter} from 'angular2/src/facade/intl';
import {PipeTransform, WrappedValue, Pipe, Injectable} from 'angular2/core'; import {PipeTransform, WrappedValue, Pipe, Injectable} from 'angular2/core';
import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';

View File

@ -1,10 +1,4 @@
import { import {CONST, isStringMap, StringWrapper, isPresent, RegExpWrapper} from 'angular2/src/facade/lang';
CONST,
isStringMap,
StringWrapper,
isPresent,
RegExpWrapper
} from 'angular2/src/facade/lang';
import {Injectable, PipeTransform, Pipe} from 'angular2/core'; import {Injectable, PipeTransform, Pipe} from 'angular2/core';
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception'; import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';

View File

@ -1,13 +1,4 @@
import { import {isNumber, isPresent, isBlank, StringWrapper, NumberWrapper, RegExpWrapper, CONST, FunctionWrapper} from 'angular2/src/facade/lang';
isNumber,
isPresent,
isBlank,
StringWrapper,
NumberWrapper,
RegExpWrapper,
CONST,
FunctionWrapper
} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions'; import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {NumberFormatter, NumberFormatStyle} from 'angular2/src/facade/intl'; import {NumberFormatter, NumberFormatStyle} from 'angular2/src/facade/intl';
import {Injectable, PipeTransform, WrappedValue, Pipe} from 'angular2/core'; import {Injectable, PipeTransform, WrappedValue, Pipe} from 'angular2/core';
@ -25,8 +16,9 @@ var _re = RegExpWrapper.create('^(\\d+)?\\.((\\d+)(\\-(\\d+))?)?$');
@Injectable() @Injectable()
export class NumberPipe { export class NumberPipe {
/** @internal */ /** @internal */
static _format(value: number, style: NumberFormatStyle, digits: string, currency: string = null, static _format(
currencyAsSymbol: boolean = false): string { value: number, style: NumberFormatStyle, digits: string, currency: string = null,
currencyAsSymbol: boolean = false): string {
if (isBlank(value)) return null; if (isBlank(value)) return null;
if (!isNumber(value)) { if (!isNumber(value)) {
throw new InvalidPipeArgumentException(NumberPipe, value); throw new InvalidPipeArgumentException(NumberPipe, value);
@ -147,7 +139,7 @@ export class CurrencyPipe extends NumberPipe implements PipeTransform {
var currencyCode: string = isPresent(args) && args.length > 0 ? args[0] : 'USD'; var currencyCode: string = isPresent(args) && args.length > 0 ? args[0] : 'USD';
var symbolDisplay: boolean = isPresent(args) && args.length > 1 ? args[1] : false; var symbolDisplay: boolean = isPresent(args) && args.length > 1 ? args[1] : false;
var digits: string = isPresent(args) && args.length > 2 ? args[2] : null; var digits: string = isPresent(args) && args.length > 2 ? args[2] : null;
return NumberPipe._format(value, NumberFormatStyle.Currency, digits, currencyCode, return NumberPipe._format(
symbolDisplay); value, NumberFormatStyle.Currency, digits, currencyCode, symbolDisplay);
} }
} }

View File

@ -1,11 +1,4 @@
import { import {isBlank, isString, isNumber, isFunction, RegExpWrapper, StringWrapper} from 'angular2/src/facade/lang';
isBlank,
isString,
isNumber,
isFunction,
RegExpWrapper,
StringWrapper
} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {Injectable, PipeTransform, Pipe} from 'angular2/core'; import {Injectable, PipeTransform, Pipe} from 'angular2/core';
import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception'; import {InvalidPipeArgumentException} from './invalid_pipe_argument_exception';

View File

@ -2,34 +2,10 @@ import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {isPresent, isBlank} from 'angular2/src/facade/lang'; import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {reflector} from 'angular2/src/core/reflection/reflection'; import {reflector} from 'angular2/src/core/reflection/reflection';
import { import {DirectiveIndex, BindingRecord, DirectiveRecord, ChangeDetectionStrategy, ChangeDetectorDefinition, ChangeDetectorGenConfig, ASTWithSource} from 'angular2/src/core/change_detection/change_detection';
DirectiveIndex,
BindingRecord,
DirectiveRecord,
ChangeDetectionStrategy,
ChangeDetectorDefinition,
ChangeDetectorGenConfig,
ASTWithSource
} from 'angular2/src/core/change_detection/change_detection';
import {CompileDirectiveMetadata, CompileTypeMetadata} from './directive_metadata'; import {CompileDirectiveMetadata, CompileTypeMetadata} from './directive_metadata';
import { import {TemplateAst, ElementAst, BoundTextAst, PropertyBindingType, DirectiveAst, TemplateAstVisitor, templateVisitAll, NgContentAst, EmbeddedTemplateAst, VariableAst, BoundElementPropertyAst, BoundEventAst, BoundDirectivePropertyAst, AttrAst, TextAst} from './template_ast';
TemplateAst,
ElementAst,
BoundTextAst,
PropertyBindingType,
DirectiveAst,
TemplateAstVisitor,
templateVisitAll,
NgContentAst,
EmbeddedTemplateAst,
VariableAst,
BoundElementPropertyAst,
BoundEventAst,
BoundDirectivePropertyAst,
AttrAst,
TextAst
} from './template_ast';
import {LifecycleHooks} from 'angular2/src/core/linker/interfaces'; import {LifecycleHooks} from 'angular2/src/core/linker/interfaces';
export function createChangeDetectorDefinitions( export function createChangeDetectorDefinitions(
@ -50,8 +26,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
eventRecords: BindingRecord[] = []; eventRecords: BindingRecord[] = [];
directiveRecords: DirectiveRecord[] = []; directiveRecords: DirectiveRecord[] = [];
constructor(public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[], constructor(
public strategy: ChangeDetectionStrategy) { public parent: ProtoViewVisitor, public allVisitors: ProtoViewVisitor[],
public strategy: ChangeDetectionStrategy) {
this.viewIndex = allVisitors.length; this.viewIndex = allVisitors.length;
allVisitors.push(this); allVisitors.push(this);
} }
@ -96,10 +73,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
} }
visitEvent(ast: BoundEventAst, directiveRecord: DirectiveRecord): any { visitEvent(ast: BoundEventAst, directiveRecord: DirectiveRecord): any {
var bindingRecord = var bindingRecord = isPresent(directiveRecord) ?
isPresent(directiveRecord) ? BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) :
BindingRecord.createForHostEvent(ast.handler, ast.fullName, directiveRecord) : BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
BindingRecord.createForEvent(ast.handler, ast.fullName, this.boundElementCount - 1);
this.eventRecords.push(bindingRecord); this.eventRecords.push(bindingRecord);
return null; return null;
} }
@ -109,25 +85,21 @@ class ProtoViewVisitor implements TemplateAstVisitor {
var dirIndex = isPresent(directiveRecord) ? directiveRecord.directiveIndex : null; var dirIndex = isPresent(directiveRecord) ? directiveRecord.directiveIndex : null;
var bindingRecord; var bindingRecord;
if (ast.type === PropertyBindingType.Property) { if (ast.type === PropertyBindingType.Property) {
bindingRecord = bindingRecord = isPresent(dirIndex) ?
isPresent(dirIndex) ? BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) :
BindingRecord.createForHostProperty(dirIndex, ast.value, ast.name) : BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
BindingRecord.createForElementProperty(ast.value, boundElementIndex, ast.name);
} else if (ast.type === PropertyBindingType.Attribute) { } else if (ast.type === PropertyBindingType.Attribute) {
bindingRecord = bindingRecord = isPresent(dirIndex) ?
isPresent(dirIndex) ? BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) :
BindingRecord.createForHostAttribute(dirIndex, ast.value, ast.name) : BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
BindingRecord.createForElementAttribute(ast.value, boundElementIndex, ast.name);
} else if (ast.type === PropertyBindingType.Class) { } else if (ast.type === PropertyBindingType.Class) {
bindingRecord = bindingRecord = isPresent(dirIndex) ?
isPresent(dirIndex) ? BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) :
BindingRecord.createForHostClass(dirIndex, ast.value, ast.name) : BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
BindingRecord.createForElementClass(ast.value, boundElementIndex, ast.name);
} else if (ast.type === PropertyBindingType.Style) { } else if (ast.type === PropertyBindingType.Style) {
bindingRecord = bindingRecord = isPresent(dirIndex) ?
isPresent(dirIndex) ? BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) :
BindingRecord.createForHostStyle(dirIndex, ast.value, ast.name, ast.unit) : BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
BindingRecord.createForElementStyle(ast.value, boundElementIndex, ast.name, ast.unit);
} }
this.bindingRecords.push(bindingRecord); this.bindingRecords.push(bindingRecord);
return null; return null;
@ -195,8 +167,9 @@ class ProtoViewVisitor implements TemplateAstVisitor {
} }
function createChangeDefinitions(pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata, function createChangeDefinitions(
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] { pvVisitors: ProtoViewVisitor[], componentType: CompileTypeMetadata,
genConfig: ChangeDetectorGenConfig): ChangeDetectorDefinition[] {
var pvVariableNames = _collectNestedProtoViewsVariableNames(pvVisitors); var pvVariableNames = _collectNestedProtoViewsVariableNames(pvVisitors);
return pvVisitors.map(pvVisitor => { return pvVisitors.map(pvVisitor => {
var id = `${componentType.name}_${pvVisitor.viewIndex}`; var id = `${componentType.name}_${pvVisitor.viewIndex}`;

View File

@ -1,8 +1,6 @@
import {CompileTypeMetadata} from './directive_metadata'; import {CompileTypeMetadata} from './directive_metadata';
import {SourceExpressions, moduleRef} from './source_module'; import {SourceExpressions, moduleRef} from './source_module';
import { import {ChangeDetectorJITGenerator} from 'angular2/src/core/change_detection/change_detection_jit_generator';
ChangeDetectorJITGenerator
} from 'angular2/src/core/change_detection/change_detection_jit_generator';
import {AbstractChangeDetector} from 'angular2/src/core/change_detection/abstract_change_detector'; import {AbstractChangeDetector} from 'angular2/src/core/change_detection/abstract_change_detector';
import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util'; import {ChangeDetectionUtil} from 'angular2/src/core/change_detection/change_detection_util';
import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants'; import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants';
@ -10,21 +8,16 @@ import {ChangeDetectorState} from 'angular2/src/core/change_detection/constants'
import {createChangeDetectorDefinitions} from './change_definition_factory'; import {createChangeDetectorDefinitions} from './change_definition_factory';
import {IS_DART, isJsObject, CONST_EXPR} from 'angular2/src/facade/lang'; import {IS_DART, isJsObject, CONST_EXPR} from 'angular2/src/facade/lang';
import { import {ChangeDetectorGenConfig, ChangeDetectorDefinition, DynamicProtoChangeDetector, ChangeDetectionStrategy} from 'angular2/src/core/change_detection/change_detection';
ChangeDetectorGenConfig,
ChangeDetectorDefinition,
DynamicProtoChangeDetector,
ChangeDetectionStrategy
} from 'angular2/src/core/change_detection/change_detection';
import {TemplateAst} from './template_ast'; import {TemplateAst} from './template_ast';
import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen'; import {Codegen} from 'angular2/src/transform/template_compiler/change_detector_codegen';
import {MODULE_SUFFIX} from './util'; import {MODULE_SUFFIX} from './util';
import {Injectable} from 'angular2/src/core/di'; import {Injectable} from 'angular2/src/core/di';
const ABSTRACT_CHANGE_DETECTOR = "AbstractChangeDetector"; const ABSTRACT_CHANGE_DETECTOR = 'AbstractChangeDetector';
const UTIL = "ChangeDetectionUtil"; const UTIL = 'ChangeDetectionUtil';
const CHANGE_DETECTOR_STATE = "ChangeDetectorState"; const CHANGE_DETECTOR_STATE = 'ChangeDetectorState';
export const CHANGE_DETECTION_JIT_IMPORTS = CONST_EXPR({ export const CHANGE_DETECTION_JIT_IMPORTS = CONST_EXPR({
'AbstractChangeDetector': AbstractChangeDetector, 'AbstractChangeDetector': AbstractChangeDetector,
@ -45,12 +38,13 @@ var CONSTANTS_MODULE =
export class ChangeDetectionCompiler { export class ChangeDetectionCompiler {
constructor(private _genConfig: ChangeDetectorGenConfig) {} constructor(private _genConfig: ChangeDetectorGenConfig) {}
compileComponentRuntime(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy, compileComponentRuntime(
parsedTemplate: TemplateAst[]): Function[] { componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
parsedTemplate: TemplateAst[]): Function[] {
var changeDetectorDefinitions = var changeDetectorDefinitions =
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate); createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
return changeDetectorDefinitions.map(definition => return changeDetectorDefinitions.map(
this._createChangeDetectorFactory(definition)); definition => this._createChangeDetectorFactory(definition));
} }
private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function { private _createChangeDetectorFactory(definition: ChangeDetectorDefinition): Function {
@ -58,8 +52,9 @@ export class ChangeDetectionCompiler {
return () => proto.instantiate(); return () => proto.instantiate();
} }
compileComponentCodeGen(componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy, compileComponentCodeGen(
parsedTemplate: TemplateAst[]): SourceExpressions { componentType: CompileTypeMetadata, strategy: ChangeDetectionStrategy,
parsedTemplate: TemplateAst[]): SourceExpressions {
var changeDetectorDefinitions = var changeDetectorDefinitions =
createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate); createChangeDetectorDefinitions(componentType, strategy, this._genConfig, parsedTemplate);
var factories = []; var factories = [];
@ -74,8 +69,8 @@ export class ChangeDetectionCompiler {
codegen = new Codegen(PREGEN_PROTO_CHANGE_DETECTOR_MODULE); codegen = new Codegen(PREGEN_PROTO_CHANGE_DETECTOR_MODULE);
var className = `_${definition.id}`; var className = `_${definition.id}`;
var typeRef = (index === 0 && componentType.isHost) ? var typeRef = (index === 0 && componentType.isHost) ?
'dynamic' : 'dynamic' :
`${moduleRef(componentType.moduleUrl)}${componentType.name}`; `${moduleRef(componentType.moduleUrl)}${componentType.name}`;
codegen.generate(typeRef, className, definition); codegen.generate(typeRef, className, definition);
factories.push(`${className}.newChangeDetector`); factories.push(`${className}.newChangeDetector`);
sourcePart = codegen.toString(); sourcePart = codegen.toString();

View File

@ -1,10 +1,6 @@
import {RuntimeCompiler_} from "./runtime_compiler"; import {RuntimeCompiler_} from './runtime_compiler';
export {TemplateCompiler} from './template_compiler'; export {TemplateCompiler} from './template_compiler';
export { export {CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata} from './directive_metadata';
CompileDirectiveMetadata,
CompileTypeMetadata,
CompileTemplateMetadata
} from './directive_metadata';
export {SourceModule, SourceWithImports} from './source_module'; export {SourceModule, SourceWithImports} from './source_module';
export {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from 'angular2/src/core/platform_directives_and_pipes'; export {PLATFORM_DIRECTIVES, PLATFORM_PIPES} from 'angular2/src/core/platform_directives_and_pipes';
export * from 'angular2/src/compiler/template_ast'; export * from 'angular2/src/compiler/template_ast';
@ -36,23 +32,12 @@ function _createChangeDetectorGenConfig() {
* A set of providers that provide `RuntimeCompiler` and its dependencies to use for * A set of providers that provide `RuntimeCompiler` and its dependencies to use for
* template compilation. * template compilation.
*/ */
export const COMPILER_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([ export const COMPILER_PROVIDERS: Array<Type|Provider|any[]> = CONST_EXPR([
Lexer, Lexer, Parser, HtmlParser, TemplateParser, TemplateNormalizer, RuntimeMetadataResolver,
Parser, DEFAULT_PACKAGE_URL_PROVIDER, StyleCompiler, ProtoViewCompiler, ViewCompiler,
HtmlParser,
TemplateParser,
TemplateNormalizer,
RuntimeMetadataResolver,
DEFAULT_PACKAGE_URL_PROVIDER,
StyleCompiler,
ProtoViewCompiler,
ViewCompiler,
ChangeDetectionCompiler, ChangeDetectionCompiler,
new Provider(ChangeDetectorGenConfig, {useFactory: _createChangeDetectorGenConfig, deps: []}), new Provider(ChangeDetectorGenConfig, {useFactory: _createChangeDetectorGenConfig, deps: []}),
TemplateCompiler, TemplateCompiler, new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}),
new Provider(RuntimeCompiler, {useClass: RuntimeCompiler_}), new Provider(Compiler, {useExisting: RuntimeCompiler}), DomElementSchemaRegistry,
new Provider(Compiler, {useExisting: RuntimeCompiler}), new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}), UrlResolver
DomElementSchemaRegistry,
new Provider(ElementSchemaRegistry, {useExisting: DomElementSchemaRegistry}),
UrlResolver
]); ]);

View File

@ -1,65 +1,9 @@
import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from "angular2/src/facade/lang"; import {NumberWrapper, StringWrapper, isPresent, resolveEnumToken} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import { import {isWhitespace, $EOF, $HASH, $TILDA, $CARET, $PERCENT, $$, $_, $COLON, $SQ, $DQ, $EQ, $SLASH, $BACKSLASH, $PERIOD, $STAR, $PLUS, $LPAREN, $RPAREN, $LBRACE, $RBRACE, $LBRACKET, $RBRACKET, $PIPE, $COMMA, $SEMICOLON, $MINUS, $BANG, $QUESTION, $AT, $AMPERSAND, $GT, $a, $A, $z, $Z, $0, $9, $FF, $CR, $LF, $VTAB} from 'angular2/src/compiler/chars';
isWhitespace,
$EOF,
$HASH,
$TILDA,
$CARET,
$PERCENT,
$$,
$_,
$COLON,
$SQ,
$DQ,
$EQ,
$SLASH,
$BACKSLASH,
$PERIOD,
$STAR,
$PLUS,
$LPAREN,
$RPAREN,
$LBRACE,
$RBRACE,
$LBRACKET,
$RBRACKET,
$PIPE,
$COMMA,
$SEMICOLON,
$MINUS,
$BANG,
$QUESTION,
$AT,
$AMPERSAND,
$GT,
$a,
$A,
$z,
$Z,
$0,
$9,
$FF,
$CR,
$LF,
$VTAB
} from "angular2/src/compiler/chars";
export { export {$EOF, $AT, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isWhitespace} from 'angular2/src/compiler/chars';
$EOF,
$AT,
$RBRACE,
$LBRACE,
$LBRACKET,
$RBRACKET,
$LPAREN,
$RPAREN,
$COMMA,
$COLON,
$SEMICOLON,
isWhitespace
} from "angular2/src/compiler/chars";
export enum CssTokenType { export enum CssTokenType {
EOF, EOF,
@ -94,35 +38,37 @@ export class LexedCssResult {
constructor(public error: CssScannerError, public token: CssToken) {} constructor(public error: CssScannerError, public token: CssToken) {}
} }
export function generateErrorMessage(input: string, message: string, errorValue: string, export function generateErrorMessage(
index: number, row: number, column: number): string { input: string, message: string, errorValue: string, index: number, row: number,
column: number): string {
return `${message} at column ${row}:${column} in expression [` + return `${message} at column ${row}:${column} in expression [` +
findProblemCode(input, errorValue, index, column) + ']'; findProblemCode(input, errorValue, index, column) + ']';
} }
export function findProblemCode(input: string, errorValue: string, index: number, export function findProblemCode(
column: number): string { input: string, errorValue: string, index: number, column: number): string {
var endOfProblemLine = index; var endOfProblemLine = index;
var current = charCode(input, index); var current = charCode(input, index);
while (current > 0 && !isNewline(current)) { while (current > 0 && !isNewline(current)) {
current = charCode(input, ++endOfProblemLine); current = charCode(input, ++endOfProblemLine);
} }
var choppedString = input.substring(0, endOfProblemLine); var choppedString = input.substring(0, endOfProblemLine);
var pointerPadding = ""; var pointerPadding = '';
for (var i = 0; i < column; i++) { for (var i = 0; i < column; i++) {
pointerPadding += " "; pointerPadding += ' ';
} }
var pointerString = ""; var pointerString = '';
for (var i = 0; i < errorValue.length; i++) { for (var i = 0; i < errorValue.length; i++) {
pointerString += "^"; pointerString += '^';
} }
return choppedString + "\n" + pointerPadding + pointerString + "\n"; return choppedString + '\n' + pointerPadding + pointerString + '\n';
} }
export class CssToken { export class CssToken {
numValue: number; numValue: number;
constructor(public index: number, public column: number, public line: number, constructor(
public type: CssTokenType, public strValue: string) { public index: number, public column: number, public line: number, public type: CssTokenType,
public strValue: string) {
this.numValue = charCode(strValue, 0); this.numValue = charCode(strValue, 0);
} }
} }
@ -248,7 +194,7 @@ export class CssScanner {
var next = output.token; var next = output.token;
if (!isPresent(next)) { if (!isPresent(next)) {
next = new CssToken(0, 0, 0, CssTokenType.EOF, "end of file"); next = new CssToken(0, 0, 0, CssTokenType.EOF, 'end of file');
} }
var isMatchingType; var isMatchingType;
@ -265,16 +211,17 @@ export class CssScanner {
var error = null; var error = null;
if (!isMatchingType || (isPresent(value) && value != next.strValue)) { if (!isMatchingType || (isPresent(value) && value != next.strValue)) {
var errorMessage = resolveEnumToken(CssTokenType, next.type) + " does not match expected " + var errorMessage = resolveEnumToken(CssTokenType, next.type) + ' does not match expected ' +
resolveEnumToken(CssTokenType, type) + " value"; resolveEnumToken(CssTokenType, type) + ' value';
if (isPresent(value)) { if (isPresent(value)) {
errorMessage += ' ("' + next.strValue + '" should match "' + value + '")'; errorMessage += ' ("' + next.strValue + '" should match "' + value + '")';
} }
error = new CssScannerError( error = new CssScannerError(
next, generateErrorMessage(this.input, errorMessage, next.strValue, previousIndex, next, generateErrorMessage(
previousLine, previousColumn)); this.input, errorMessage, next.strValue, previousIndex, previousLine,
previousColumn));
} }
return new LexedCssResult(error, next); return new LexedCssResult(error, next);
@ -354,8 +301,8 @@ export class CssScanner {
} }
scanComment(): CssToken { scanComment(): CssToken {
if (this.assertCondition(isCommentStart(this.peek, this.peekPeek), if (this.assertCondition(
"Expected comment start value")) { isCommentStart(this.peek, this.peekPeek), 'Expected comment start value')) {
return null; return null;
} }
@ -392,8 +339,8 @@ export class CssScanner {
} }
scanString(): CssToken { scanString(): CssToken {
if (this.assertCondition(isStringStart(this.peek, this.peekPeek), if (this.assertCondition(
"Unexpected non-string starting value")) { isStringStart(this.peek, this.peekPeek), 'Unexpected non-string starting value')) {
return null; return null;
} }
@ -412,7 +359,7 @@ export class CssScanner {
this.advance(); this.advance();
} }
if (this.assertCondition(this.peek == target, "Unterminated quote")) { if (this.assertCondition(this.peek == target, 'Unterminated quote')) {
return null; return null;
} }
this.advance(); this.advance();
@ -442,8 +389,8 @@ export class CssScanner {
} }
scanIdentifier(): CssToken { scanIdentifier(): CssToken {
if (this.assertCondition(isIdentifierStart(this.peek, this.peekPeek), if (this.assertCondition(
'Expected identifier starting value')) { isIdentifierStart(this.peek, this.peekPeek), 'Expected identifier starting value')) {
return null; return null;
} }
@ -469,8 +416,9 @@ export class CssScanner {
scanCharacter(): CssToken { scanCharacter(): CssToken {
var start = this.index; var start = this.index;
var startingColumn = this.column; var startingColumn = this.column;
if (this.assertCondition(isValidCssCharacter(this.peek, this._currentMode), if (this.assertCondition(
charStr(this.peek) + ' is not a valid CSS character')) { isValidCssCharacter(this.peek, this._currentMode),
charStr(this.peek) + ' is not a valid CSS character')) {
return null; return null;
} }
@ -557,12 +505,12 @@ function isIdentifierStart(code: number, next: number): boolean {
} }
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH || return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
target == $MINUS || target == $_; target == $MINUS || target == $_;
} }
function isIdentifierPart(target: number): boolean { function isIdentifierPart(target: number): boolean {
return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH || return ($a <= target && target <= $z) || ($A <= target && target <= $Z) || target == $BACKSLASH ||
target == $MINUS || target == $_ || isDigit(target); target == $MINUS || target == $_ || isDigit(target);
} }
function isValidPseudoSelectorCharacter(code: number): boolean { function isValidPseudoSelectorCharacter(code: number): boolean {

View File

@ -1,40 +1,10 @@
import { import {ParseSourceSpan, ParseSourceFile, ParseLocation, ParseError} from 'angular2/src/compiler/parse_util';
ParseSourceSpan,
ParseSourceFile,
ParseLocation,
ParseError
} from "angular2/src/compiler/parse_util";
import { import {bitWiseOr, bitWiseAnd, NumberWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang';
bitWiseOr,
bitWiseAnd,
NumberWrapper,
StringWrapper,
isPresent
} from "angular2/src/facade/lang";
import { import {CssLexerMode, CssToken, CssTokenType, CssScanner, CssScannerError, generateErrorMessage, $AT, $EOF, $RBRACE, $LBRACE, $LBRACKET, $RBRACKET, $LPAREN, $RPAREN, $COMMA, $COLON, $SEMICOLON, isNewline} from 'angular2/src/compiler/css/lexer';
CssLexerMode,
CssToken,
CssTokenType,
CssScanner,
CssScannerError,
generateErrorMessage,
$AT,
$EOF,
$RBRACE,
$LBRACE,
$LBRACKET,
$RBRACKET,
$LPAREN,
$RPAREN,
$COMMA,
$COLON,
$SEMICOLON,
isNewline
} from "angular2/src/compiler/css/lexer";
export {CssToken} from "angular2/src/compiler/css/lexer"; export {CssToken} from 'angular2/src/compiler/css/lexer';
export enum BlockType { export enum BlockType {
Import, Import,
@ -60,7 +30,7 @@ const SEMICOLON_DELIM = 32;
const NEWLINE_DELIM = 64; const NEWLINE_DELIM = 64;
const RPAREN_DELIM = 128; const RPAREN_DELIM = 128;
function mergeTokens(tokens: CssToken[], separator: string = ""): CssToken { function mergeTokens(tokens: CssToken[], separator: string = ''): CssToken {
var mainToken = tokens[0]; var mainToken = tokens[0];
var str = mainToken.strValue; var str = mainToken.strValue;
for (var i = 1; i < tokens.length; i++) { for (var i = 1; i < tokens.length; i++) {
@ -205,8 +175,9 @@ export class CssParser {
var token = this._scan(); var token = this._scan();
this._assertCondition(token.type == CssTokenType.AtKeyword, this._assertCondition(
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token); token.type == CssTokenType.AtKeyword,
`The CSS Rule ${token.strValue} is not a valid [@] rule.`, token);
var block, type = this._resolveBlockType(token); var block, type = this._resolveBlockType(token);
switch (type) { switch (type) {
@ -245,11 +216,12 @@ export class CssParser {
default: default:
var listOfTokens = []; var listOfTokens = [];
this._scanner.setMode(CssLexerMode.ALL); this._scanner.setMode(CssLexerMode.ALL);
this._error(generateErrorMessage( this._error(
this._scanner.input, generateErrorMessage(
`The CSS "at" rule "${token.strValue}" is not allowed to used here`, this._scanner.input,
token.strValue, token.index, token.line, token.column), `The CSS "at" rule "${token.strValue}" is not allowed to used here`, token.strValue,
token); token.index, token.line, token.column),
token);
this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM])) this._collectUntilDelim(bitWiseOr([delimiters, LBRACE_DELIM, SEMICOLON_DELIM]))
.forEach((token) => { listOfTokens.push(token); }); .forEach((token) => { listOfTokens.push(token); });
@ -403,7 +375,7 @@ export class CssParser {
// contains an inner selector that needs to be parsed // contains an inner selector that needs to be parsed
// in isolation // in isolation
if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) && if (this._scanner.getMode() == CssLexerMode.PSEUDO_SELECTOR && isPresent(previousToken) &&
previousToken.numValue == $COLON && token.strValue == "not" && previousToken.numValue == $COLON && token.strValue == 'not' &&
this._scanner.peek == $LPAREN) { this._scanner.peek == $LPAREN) {
selectorCssTokens.push(token); selectorCssTokens.push(token);
selectorCssTokens.push(this._consume(CssTokenType.Character, '(')); selectorCssTokens.push(this._consume(CssTokenType.Character, '('));
@ -453,7 +425,7 @@ export class CssParser {
this._scanner.setMode(CssLexerMode.STYLE_VALUE); this._scanner.setMode(CssLexerMode.STYLE_VALUE);
var strValue = ""; var strValue = '';
var tokens = []; var tokens = [];
var previous: CssToken; var previous: CssToken;
while (!characterContainsDelimiter(this._scanner.peek, delimiters)) { while (!characterContainsDelimiter(this._scanner.peek, delimiters)) {
@ -493,9 +465,9 @@ export class CssParser {
this._consume(CssTokenType.Character, ';'); this._consume(CssTokenType.Character, ';');
} else if (code != $RBRACE) { } else if (code != $RBRACE) {
this._error( this._error(
generateErrorMessage(this._scanner.input, generateErrorMessage(
`The CSS key/value definition did not end with a semicolon`, this._scanner.input, `The CSS key/value definition did not end with a semicolon`,
previous.strValue, previous.index, previous.line, previous.column), previous.strValue, previous.index, previous.line, previous.column),
previous); previous);
} }
@ -592,7 +564,7 @@ export class CssParser {
remainingTokens.forEach((token) => { propStr.push(token.strValue); }); remainingTokens.forEach((token) => { propStr.push(token.strValue); });
} }
prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(" ")); prop = new CssToken(prop.index, prop.column, prop.line, prop.type, propStr.join(' '));
} }
// this means we've reached the end of the definition and/or block // this means we've reached the end of the definition and/or block
@ -608,10 +580,11 @@ export class CssParser {
if (parseValue) { if (parseValue) {
value = this._parseValue(delimiters); value = this._parseValue(delimiters);
} else { } else {
this._error(generateErrorMessage(this._scanner.input, this._error(
`The CSS property was not paired with a style value`, generateErrorMessage(
prop.strValue, prop.index, prop.line, prop.column), this._scanner.input, `The CSS property was not paired with a style value`,
prop); prop.strValue, prop.index, prop.line, prop.column),
prop);
} }
return new CssDefinitionAST(prop, value); return new CssDefinitionAST(prop, value);
@ -629,8 +602,8 @@ export class CssParser {
/** @internal */ /** @internal */
_error(message: string, problemToken: CssToken) { _error(message: string, problemToken: CssToken) {
var length = problemToken.strValue.length; var length = problemToken.strValue.length;
var error = CssParseError.create(this._file, 0, problemToken.line, problemToken.column, length, var error = CssParseError.create(
message); this._file, 0, problemToken.line, problemToken.column, length, message);
this._errors.push(error); this._errors.push(error);
} }
} }
@ -657,7 +630,7 @@ export class CssKeyframeRuleAST extends CssBlockRuleAST {
export class CssKeyframeDefinitionAST extends CssBlockRuleAST { export class CssKeyframeDefinitionAST extends CssBlockRuleAST {
public steps; public steps;
constructor(_steps: CssToken[], block: CssBlockAST) { constructor(_steps: CssToken[], block: CssBlockAST) {
super(BlockType.Keyframes, block, mergeTokens(_steps, ",")); super(BlockType.Keyframes, block, mergeTokens(_steps, ','));
this.steps = _steps; this.steps = _steps;
} }
visit(visitor: CssASTVisitor, context?: any) { visit(visitor: CssASTVisitor, context?: any) {
@ -669,10 +642,11 @@ export class CssBlockDefinitionRuleAST extends CssBlockRuleAST {
public strValue: string; public strValue: string;
constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) { constructor(type: BlockType, public query: CssToken[], block: CssBlockAST) {
super(type, block); super(type, block);
this.strValue = query.map(token => token.strValue).join(""); this.strValue = query.map(token => token.strValue).join('');
var firstCssToken: CssToken = query[0]; var firstCssToken: CssToken = query[0];
this.name = new CssToken(firstCssToken.index, firstCssToken.column, firstCssToken.line, this.name = new CssToken(
CssTokenType.Identifier, this.strValue); firstCssToken.index, firstCssToken.column, firstCssToken.line, CssTokenType.Identifier,
this.strValue);
} }
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); } visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssBlock(this.block, context); }
} }
@ -692,7 +666,7 @@ export class CssSelectorRuleAST extends CssBlockRuleAST {
constructor(public selectors: CssSelectorAST[], block: CssBlockAST) { constructor(public selectors: CssSelectorAST[], block: CssBlockAST) {
super(BlockType.Selector, block); super(BlockType.Selector, block);
this.strValue = selectors.map(selector => selector.strValue).join(","); this.strValue = selectors.map(selector => selector.strValue).join(',');
} }
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); } visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelectorRule(this, context); }
@ -707,7 +681,7 @@ export class CssSelectorAST extends CssAST {
public strValue; public strValue;
constructor(public tokens: CssToken[], public isComplex: boolean = false) { constructor(public tokens: CssToken[], public isComplex: boolean = false) {
super(); super();
this.strValue = tokens.map(token => token.strValue).join(""); this.strValue = tokens.map(token => token.strValue).join('');
} }
visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); } visit(visitor: CssASTVisitor, context?: any) { visitor.visitCssSelector(this, context); }
} }
@ -723,12 +697,13 @@ export class CssStyleSheetAST extends CssAST {
} }
export class CssParseError extends ParseError { export class CssParseError extends ParseError {
static create(file: ParseSourceFile, offset: number, line: number, col: number, length: number, static create(
errMsg: string): CssParseError { file: ParseSourceFile, offset: number, line: number, col: number, length: number,
errMsg: string): CssParseError {
var start = new ParseLocation(file, offset, line, col); var start = new ParseLocation(file, offset, line, col);
var end = new ParseLocation(file, offset, line, col + length); var end = new ParseLocation(file, offset, line, col + length);
var span = new ParseSourceSpan(start, end); var span = new ParseSourceSpan(start, end);
return new CssParseError(span, "CSS Parse Error: " + errMsg); return new CssParseError(span, 'CSS Parse Error: ' + errMsg);
} }
constructor(span: ParseSourceSpan, message: string) { super(span, message); } constructor(span: ParseSourceSpan, message: string) { super(span, message); }

View File

@ -1,23 +1,7 @@
import { import {isPresent, isBlank, isNumber, isBoolean, normalizeBool, normalizeBlank, serializeEnum, Type, isString, RegExpWrapper, StringWrapper, isArray} from 'angular2/src/facade/lang';
isPresent,
isBlank,
isNumber,
isBoolean,
normalizeBool,
normalizeBlank,
serializeEnum,
Type,
isString,
RegExpWrapper,
StringWrapper,
isArray
} from 'angular2/src/facade/lang';
import {unimplemented} from 'angular2/src/facade/exceptions'; import {unimplemented} from 'angular2/src/facade/exceptions';
import {StringMapWrapper} from 'angular2/src/facade/collection'; import {StringMapWrapper} from 'angular2/src/facade/collection';
import { import {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from 'angular2/src/core/change_detection/change_detection';
ChangeDetectionStrategy,
CHANGE_DETECTION_STRATEGY_VALUES
} from 'angular2/src/core/change_detection/change_detection';
import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view'; import {ViewEncapsulation, VIEW_ENCAPSULATION_VALUES} from 'angular2/src/core/metadata/view';
import {CssSelector} from 'angular2/src/compiler/selector'; import {CssSelector} from 'angular2/src/compiler/selector';
import {splitAtColon} from './util'; import {splitAtColon} from './util';
@ -105,7 +89,7 @@ export class CompileDiDependencyMetadata {
isOptional: boolean; isOptional: boolean;
query: CompileQueryMetadata; query: CompileQueryMetadata;
viewQuery: CompileQueryMetadata; viewQuery: CompileQueryMetadata;
token: CompileIdentifierMetadata | string; token: CompileIdentifierMetadata|string;
constructor({isAttribute, isSelf, isHost, isSkipSelf, isOptional, query, viewQuery, token}: { constructor({isAttribute, isSelf, isHost, isSkipSelf, isOptional, query, viewQuery, token}: {
isAttribute?: boolean, isAttribute?: boolean,
@ -115,7 +99,7 @@ export class CompileDiDependencyMetadata {
isOptional?: boolean, isOptional?: boolean,
query?: CompileQueryMetadata, query?: CompileQueryMetadata,
viewQuery?: CompileQueryMetadata, viewQuery?: CompileQueryMetadata,
token?: CompileIdentifierMetadata | string token?: CompileIdentifierMetadata|string
} = {}) { } = {}) {
this.isAttribute = normalizeBool(isAttribute); this.isAttribute = normalizeBool(isAttribute);
this.isSelf = normalizeBool(isSelf); this.isSelf = normalizeBool(isSelf);
@ -156,10 +140,10 @@ export class CompileDiDependencyMetadata {
} }
export class CompileProviderMetadata { export class CompileProviderMetadata {
token: CompileIdentifierMetadata | string; token: CompileIdentifierMetadata|string;
useClass: CompileTypeMetadata; useClass: CompileTypeMetadata;
useValue: any; useValue: any;
useExisting: CompileIdentifierMetadata | string; useExisting: CompileIdentifierMetadata|string;
useFactory: CompileFactoryMetadata; useFactory: CompileFactoryMetadata;
deps: CompileDiDependencyMetadata[]; deps: CompileDiDependencyMetadata[];
multi: boolean; multi: boolean;
@ -168,7 +152,7 @@ export class CompileProviderMetadata {
token?: CompileIdentifierMetadata | string, token?: CompileIdentifierMetadata | string,
useClass?: CompileTypeMetadata, useClass?: CompileTypeMetadata,
useValue?: any, useValue?: any,
useExisting?: CompileIdentifierMetadata | string, useExisting?: CompileIdentifierMetadata|string,
useFactory?: CompileFactoryMetadata, useFactory?: CompileFactoryMetadata,
deps?: CompileDiDependencyMetadata[], deps?: CompileDiDependencyMetadata[],
multi?: boolean multi?: boolean
@ -323,13 +307,13 @@ export class CompileTypeMetadata implements CompileIdentifierMetadata, CompileMe
} }
export class CompileQueryMetadata { export class CompileQueryMetadata {
selectors: Array<CompileIdentifierMetadata | string>; selectors: Array<CompileIdentifierMetadata|string>;
descendants: boolean; descendants: boolean;
first: boolean; first: boolean;
propertyName: string; propertyName: string;
constructor({selectors, descendants, first, propertyName}: { constructor({selectors, descendants, first, propertyName}: {
selectors?: Array<CompileIdentifierMetadata | string>, selectors?: Array<CompileIdentifierMetadata|string>,
descendants?: boolean, descendants?: boolean,
first?: boolean, first?: boolean,
propertyName?: string propertyName?: string
@ -389,8 +373,8 @@ export class CompileTemplateMetadata {
static fromJson(data: {[key: string]: any}): CompileTemplateMetadata { static fromJson(data: {[key: string]: any}): CompileTemplateMetadata {
return new CompileTemplateMetadata({ return new CompileTemplateMetadata({
encapsulation: isPresent(data['encapsulation']) ? encapsulation: isPresent(data['encapsulation']) ?
VIEW_ENCAPSULATION_VALUES[data['encapsulation']] : VIEW_ENCAPSULATION_VALUES[data['encapsulation']] :
data['encapsulation'], data['encapsulation'],
template: data['template'], template: data['template'],
templateUrl: data['templateUrl'], templateUrl: data['templateUrl'],
styles: data['styles'], styles: data['styles'],
@ -401,8 +385,8 @@ export class CompileTemplateMetadata {
toJson(): {[key: string]: any} { toJson(): {[key: string]: any} {
return { return {
'encapsulation': 'encapsulation': isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) :
isPresent(this.encapsulation) ? serializeEnum(this.encapsulation) : this.encapsulation, this.encapsulation,
'template': this.template, 'template': this.template,
'templateUrl': this.templateUrl, 'templateUrl': this.templateUrl,
'styles': this.styles, 'styles': this.styles,
@ -416,27 +400,27 @@ export class CompileTemplateMetadata {
* Metadata regarding compilation of a directive. * Metadata regarding compilation of a directive.
*/ */
export class CompileDirectiveMetadata implements CompileMetadataWithType { export class CompileDirectiveMetadata implements CompileMetadataWithType {
static create({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, static create(
outputs, host, lifecycleHooks, providers, viewProviders, queries, viewQueries, {type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
template}: { host, lifecycleHooks, providers, viewProviders, queries, viewQueries, template}: {
type?: CompileTypeMetadata, type?: CompileTypeMetadata,
isComponent?: boolean, isComponent?: boolean,
dynamicLoadable?: boolean, dynamicLoadable?: boolean,
selector?: string, selector?: string,
exportAs?: string, exportAs?: string,
changeDetection?: ChangeDetectionStrategy, changeDetection?: ChangeDetectionStrategy,
inputs?: string[], inputs?: string[],
outputs?: string[], outputs?: string[],
host?: {[key: string]: string}, host?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[], lifecycleHooks?: LifecycleHooks[],
providers?: providers?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>, Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewProviders?: viewProviders?:
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>, Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
queries?: CompileQueryMetadata[], queries?: CompileQueryMetadata[],
viewQueries?: CompileQueryMetadata[], viewQueries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata template?: CompileTemplateMetadata
} = {}): CompileDirectiveMetadata { } = {}): CompileDirectiveMetadata {
var hostListeners: {[key: string]: string} = {}; var hostListeners: {[key: string]: string} = {};
var hostProperties: {[key: string]: string} = {}; var hostProperties: {[key: string]: string} = {};
var hostAttributes: {[key: string]: string} = {}; var hostAttributes: {[key: string]: string} = {};
@ -503,34 +487,35 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
hostProperties: {[key: string]: string}; hostProperties: {[key: string]: string};
hostAttributes: {[key: string]: string}; hostAttributes: {[key: string]: string};
lifecycleHooks: LifecycleHooks[]; lifecycleHooks: LifecycleHooks[];
providers: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>; providers: Array<CompileProviderMetadata|CompileTypeMetadata|any[]>;
viewProviders: Array<CompileProviderMetadata | CompileTypeMetadata | any[]>; viewProviders: Array<CompileProviderMetadata|CompileTypeMetadata|any[]>;
queries: CompileQueryMetadata[]; queries: CompileQueryMetadata[];
viewQueries: CompileQueryMetadata[]; viewQueries: CompileQueryMetadata[];
template: CompileTemplateMetadata; template: CompileTemplateMetadata;
constructor({type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, constructor(
outputs, hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers, {type, isComponent, dynamicLoadable, selector, exportAs, changeDetection, inputs, outputs,
viewProviders, queries, viewQueries, template}: { hostListeners, hostProperties, hostAttributes, lifecycleHooks, providers, viewProviders,
type?: CompileTypeMetadata, queries, viewQueries, template}: {
isComponent?: boolean, type?: CompileTypeMetadata,
dynamicLoadable?: boolean, isComponent?: boolean,
selector?: string, dynamicLoadable?: boolean,
exportAs?: string, selector?: string,
changeDetection?: ChangeDetectionStrategy, exportAs?: string,
inputs?: {[key: string]: string}, changeDetection?: ChangeDetectionStrategy,
outputs?: {[key: string]: string}, inputs?: {[key: string]: string},
hostListeners?: {[key: string]: string}, outputs?: {[key: string]: string},
hostProperties?: {[key: string]: string}, hostListeners?: {[key: string]: string},
hostAttributes?: {[key: string]: string}, hostProperties?: {[key: string]: string},
lifecycleHooks?: LifecycleHooks[], hostAttributes?: {[key: string]: string},
providers?: lifecycleHooks?: LifecycleHooks[],
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>, providers?:
viewProviders?: Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
Array<CompileProviderMetadata | CompileTypeMetadata | CompileIdentifierMetadata | any[]>, viewProviders?:
queries?: CompileQueryMetadata[], Array<CompileProviderMetadata|CompileTypeMetadata|CompileIdentifierMetadata|any[]>,
viewQueries?: CompileQueryMetadata[], queries?: CompileQueryMetadata[],
template?: CompileTemplateMetadata viewQueries?: CompileQueryMetadata[],
} = {}) { template?: CompileTemplateMetadata
} = {}) {
this.type = type; this.type = type;
this.isComponent = isComponent; this.isComponent = isComponent;
this.dynamicLoadable = dynamicLoadable; this.dynamicLoadable = dynamicLoadable;
@ -560,8 +545,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
exportAs: data['exportAs'], exportAs: data['exportAs'],
type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'], type: isPresent(data['type']) ? CompileTypeMetadata.fromJson(data['type']) : data['type'],
changeDetection: isPresent(data['changeDetection']) ? changeDetection: isPresent(data['changeDetection']) ?
CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] : CHANGE_DETECTION_STRATEGY_VALUES[data['changeDetection']] :
data['changeDetection'], data['changeDetection'],
inputs: data['inputs'], inputs: data['inputs'],
outputs: data['outputs'], outputs: data['outputs'],
hostListeners: data['hostListeners'], hostListeners: data['hostListeners'],
@ -606,8 +591,8 @@ export class CompileDirectiveMetadata implements CompileMetadataWithType {
/** /**
* Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector. * Construct {@link CompileDirectiveMetadata} from {@link ComponentTypeMetadata} and a selector.
*/ */
export function createHostComponentMeta(componentType: CompileTypeMetadata, export function createHostComponentMeta(
componentSelector: string): CompileDirectiveMetadata { componentType: CompileTypeMetadata, componentSelector: string): CompileDirectiveMetadata {
var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate(); var template = CssSelector.parse(componentSelector)[0].getMatchingElementTemplate();
return CompileDirectiveMetadata.create({ return CompileDirectiveMetadata.create({
type: new CompileTypeMetadata({ type: new CompileTypeMetadata({
@ -638,8 +623,9 @@ export class CompilePipeMetadata implements CompileMetadataWithType {
type: CompileTypeMetadata; type: CompileTypeMetadata;
name: string; name: string;
pure: boolean; pure: boolean;
constructor({type, name, constructor({type, name, pure}: {type?: CompileTypeMetadata,
pure}: {type?: CompileTypeMetadata, name?: string, pure?: boolean} = {}) { name?: string,
pure?: boolean} = {}) {
this.type = type; this.type = type;
this.name = name; this.name = name;
this.pure = normalizeBool(pure); this.pure = normalizeBool(pure);
@ -677,7 +663,7 @@ function arrayFromJson(obj: any[], fn: (a: {[key: string]: any}) => any): any {
return isBlank(obj) ? null : obj.map(o => objFromJson(o, fn)); return isBlank(obj) ? null : obj.map(o => objFromJson(o, fn));
} }
function arrayToJson(obj: any[]): string | {[key: string]: any} { function arrayToJson(obj: any[]): string|{[key: string]: any} {
return isBlank(obj) ? null : obj.map(objToJson); return isBlank(obj) ? null : obj.map(objToJson);
} }
@ -687,7 +673,7 @@ function objFromJson(obj: any, fn: (a: {[key: string]: any}) => any): any {
return fn(obj); return fn(obj);
} }
function objToJson(obj: any): string | {[key: string]: any} { function objToJson(obj: any): string|{[key: string]: any} {
if (isArray(obj)) return arrayToJson(obj); if (isArray(obj)) return arrayToJson(obj);
if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj; if (isString(obj) || isBlank(obj) || isBoolean(obj) || isNumber(obj)) return obj;
return obj.toJson(); return obj.toJson();

View File

@ -18,9 +18,10 @@ export class HtmlAttrAst implements HtmlAst {
} }
export class HtmlElementAst implements HtmlAst { export class HtmlElementAst implements HtmlAst {
constructor(public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[], constructor(
public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan, public name: string, public attrs: HtmlAttrAst[], public children: HtmlAst[],
public endSourceSpan: ParseSourceSpan) {} public sourceSpan: ParseSourceSpan, public startSourceSpan: ParseSourceSpan,
public endSourceSpan: ParseSourceSpan) {}
visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); } visit(visitor: HtmlAstVisitor, context: any): any { return visitor.visitElement(this, context); }
} }

View File

@ -1,11 +1,4 @@
import { import {StringWrapper, NumberWrapper, isPresent, isBlank, CONST_EXPR, serializeEnum} from 'angular2/src/facade/lang';
StringWrapper,
NumberWrapper,
isPresent,
isBlank,
CONST_EXPR,
serializeEnum
} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util'; import {ParseLocation, ParseError, ParseSourceFile, ParseSourceSpan} from './parse_util';
import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags'; import {getHtmlTagDefinition, HtmlTagContentType, NAMED_ENTITIES} from './html_tags';
@ -29,8 +22,8 @@ export enum HtmlTokenType {
} }
export class HtmlToken { export class HtmlToken {
constructor(public type: HtmlTokenType, public parts: string[], constructor(
public sourceSpan: ParseSourceSpan) {} public type: HtmlTokenType, public parts: string[], public sourceSpan: ParseSourceSpan) {}
} }
export class HtmlTokenError extends ParseError { export class HtmlTokenError extends ParseError {
@ -191,8 +184,8 @@ class _HtmlTokenizer {
if (isBlank(end)) { if (isBlank(end)) {
end = this._getLocation(); end = this._getLocation();
} }
var token = new HtmlToken(this.currentTokenType, parts, var token = new HtmlToken(
new ParseSourceSpan(this.currentTokenStart, end)); this.currentTokenType, parts, new ParseSourceSpan(this.currentTokenStart, end));
this.tokens.push(token); this.tokens.push(token);
this.currentTokenStart = null; this.currentTokenStart = null;
this.currentTokenType = null; this.currentTokenType = null;
@ -239,8 +232,8 @@ class _HtmlTokenizer {
private _requireCharCode(charCode: number) { private _requireCharCode(charCode: number) {
var location = this._getLocation(); var location = this._getLocation();
if (!this._attemptCharCode(charCode)) { if (!this._attemptCharCode(charCode)) {
throw this._createError(unexpectedCharacterErrorMsg(this.peek), throw this._createError(
this._getSpan(location, location)); unexpectedCharacterErrorMsg(this.peek), this._getSpan(location, location));
} }
} }
@ -335,12 +328,12 @@ class _HtmlTokenizer {
} }
} }
private _consumeRawText(decodeEntities: boolean, firstCharOfEnd: number, private _consumeRawText(
attemptEndRest: Function): HtmlToken { decodeEntities: boolean, firstCharOfEnd: number, attemptEndRest: Function): HtmlToken {
var tagCloseStart; var tagCloseStart;
var textStart = this._getLocation(); var textStart = this._getLocation();
this._beginToken(decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT, this._beginToken(
textStart); decodeEntities ? HtmlTokenType.ESCAPABLE_RAW_TEXT : HtmlTokenType.RAW_TEXT, textStart);
var parts = []; var parts = [];
while (true) { while (true) {
tagCloseStart = this._getLocation(); tagCloseStart = this._getLocation();
@ -543,7 +536,7 @@ function isWhitespace(code: number): boolean {
function isNameEnd(code: number): boolean { function isNameEnd(code: number): boolean {
return isWhitespace(code) || code === $GT || code === $SLASH || code === $SQ || code === $DQ || return isWhitespace(code) || code === $GT || code === $SLASH || code === $SQ || code === $DQ ||
code === $EQ; code === $EQ;
} }
function isPrefixEnd(code: number): boolean { function isPrefixEnd(code: number): boolean {

View File

@ -1,13 +1,4 @@
import { import {isPresent, isBlank, StringWrapper, stringify, assertionsEnabled, StringJoiner, serializeEnum, CONST_EXPR} from 'angular2/src/facade/lang';
isPresent,
isBlank,
StringWrapper,
stringify,
assertionsEnabled,
StringJoiner,
serializeEnum,
CONST_EXPR
} from 'angular2/src/facade/lang';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
@ -35,8 +26,9 @@ export class HtmlParser {
parse(sourceContent: string, sourceUrl: string): HtmlParseTreeResult { parse(sourceContent: string, sourceUrl: string): HtmlParseTreeResult {
var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl); var tokensAndErrors = tokenizeHtml(sourceContent, sourceUrl);
var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build(); var treeAndErrors = new TreeBuilder(tokensAndErrors.tokens).build();
return new HtmlParseTreeResult(treeAndErrors.rootNodes, (<ParseError[]>tokensAndErrors.errors) return new HtmlParseTreeResult(
.concat(treeAndErrors.errors)); treeAndErrors.rootNodes,
(<ParseError[]>tokensAndErrors.errors).concat(treeAndErrors.errors));
} }
} }
@ -63,9 +55,9 @@ class TreeBuilder {
} else if (this.peek.type === HtmlTokenType.COMMENT_START) { } else if (this.peek.type === HtmlTokenType.COMMENT_START) {
this._closeVoidElement(); this._closeVoidElement();
this._consumeComment(this._advance()); this._consumeComment(this._advance());
} else if (this.peek.type === HtmlTokenType.TEXT || } else if (
this.peek.type === HtmlTokenType.RAW_TEXT || this.peek.type === HtmlTokenType.TEXT || this.peek.type === HtmlTokenType.RAW_TEXT ||
this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) { this.peek.type === HtmlTokenType.ESCAPABLE_RAW_TEXT) {
this._closeVoidElement(); this._closeVoidElement();
this._consumeText(this._advance()); this._consumeText(this._advance());
} else { } else {
@ -174,8 +166,8 @@ class TreeBuilder {
var tagDef = getHtmlTagDefinition(el.name); var tagDef = getHtmlTagDefinition(el.name);
var parentEl = this._getParentElement(); var parentEl = this._getParentElement();
if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) { if (tagDef.requireExtraParent(isPresent(parentEl) ? parentEl.name : null)) {
var newParent = new HtmlElementAst(tagDef.parentToAdd, [], [el], el.sourceSpan, var newParent = new HtmlElementAst(
el.startSourceSpan, el.endSourceSpan); tagDef.parentToAdd, [], [el], el.sourceSpan, el.startSourceSpan, el.endSourceSpan);
this._addToParent(newParent); this._addToParent(newParent);
this.elementStack.push(newParent); this.elementStack.push(newParent);
this.elementStack.push(el); this.elementStack.push(el);
@ -192,12 +184,12 @@ class TreeBuilder {
this._getParentElement().endSourceSpan = endTagToken.sourceSpan; this._getParentElement().endSourceSpan = endTagToken.sourceSpan;
if (getHtmlTagDefinition(fullName).isVoid) { if (getHtmlTagDefinition(fullName).isVoid) {
this.errors.push( this.errors.push(HtmlTreeError.create(
HtmlTreeError.create(fullName, endTagToken.sourceSpan, fullName, endTagToken.sourceSpan,
`Void elements do not have end tags "${endTagToken.parts[1]}"`)); `Void elements do not have end tags "${endTagToken.parts[1]}"`));
} else if (!this._popElement(fullName)) { } else if (!this._popElement(fullName)) {
this.errors.push(HtmlTreeError.create(fullName, endTagToken.sourceSpan, this.errors.push(HtmlTreeError.create(
`Unexpected closing tag "${endTagToken.parts[1]}"`)); fullName, endTagToken.sourceSpan, `Unexpected closing tag "${endTagToken.parts[1]}"`));
} }
} }
@ -242,8 +234,8 @@ class TreeBuilder {
} }
} }
function getElementFullName(prefix: string, localName: string, function getElementFullName(
parentElement: HtmlElementAst): string { prefix: string, localName: string, parentElement: HtmlElementAst): string {
if (isBlank(prefix)) { if (isBlank(prefix)) {
prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix; prefix = getHtmlTagDefinition(localName).implicitNamespacePrefix;
if (isBlank(prefix) && isPresent(parentElement)) { if (isBlank(prefix) && isPresent(parentElement)) {

View File

@ -1,10 +1,4 @@
import { import {isPresent, isBlank, normalizeBool, RegExpWrapper, CONST_EXPR} from 'angular2/src/facade/lang';
isPresent,
isBlank,
normalizeBool,
RegExpWrapper,
CONST_EXPR
} from 'angular2/src/facade/lang';
// see http://www.w3.org/TR/html51/syntax.html#named-character-references // see http://www.w3.org/TR/html51/syntax.html#named-character-references
// see https://html.spec.whatwg.org/multipage/entities.json // see https://html.spec.whatwg.org/multipage/entities.json
@ -281,16 +275,17 @@ export class HtmlTagDefinition {
public isVoid: boolean; public isVoid: boolean;
public ignoreFirstLf: boolean; public ignoreFirstLf: boolean;
constructor({closedByChildren, requiredParents, implicitNamespacePrefix, contentType, constructor(
closedByParent, isVoid, ignoreFirstLf}: { {closedByChildren, requiredParents, implicitNamespacePrefix, contentType, closedByParent,
closedByChildren?: string[], isVoid, ignoreFirstLf}: {
closedByParent?: boolean, closedByChildren?: string[],
requiredParents?: string[], closedByParent?: boolean,
implicitNamespacePrefix?: string, requiredParents?: string[],
contentType?: HtmlTagContentType, implicitNamespacePrefix?: string,
isVoid?: boolean, contentType?: HtmlTagContentType,
ignoreFirstLf?: boolean isVoid?: boolean,
} = {}) { ignoreFirstLf?: boolean
} = {}) {
if (isPresent(closedByChildren) && closedByChildren.length > 0) { if (isPresent(closedByChildren) && closedByChildren.length > 0) {
closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true); closedByChildren.forEach(tagName => this.closedByChildren[tagName] = true);
} }
@ -342,32 +337,9 @@ var TAG_DEFINITIONS: {[key: string]: HtmlTagDefinition} = {
'wbr': new HtmlTagDefinition({isVoid: true}), 'wbr': new HtmlTagDefinition({isVoid: true}),
'p': new HtmlTagDefinition({ 'p': new HtmlTagDefinition({
closedByChildren: [ closedByChildren: [
'address', 'address', 'article', 'aside', 'blockquote', 'div', 'dl', 'fieldset', 'footer', 'form',
'article', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'header', 'hgroup', 'hr',
'aside', 'main', 'nav', 'ol', 'p', 'pre', 'section', 'table', 'ul'
'blockquote',
'div',
'dl',
'fieldset',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'header',
'hgroup',
'hr',
'main',
'nav',
'ol',
'p',
'pre',
'section',
'table',
'ul'
], ],
closedByParent: true closedByParent: true
}), }),

View File

@ -1,21 +1,8 @@
import {Injectable, Provider, provide} from 'angular2/src/core/di'; import {Injectable, Provider, provide} from 'angular2/src/core/di';
import { import {StringWrapper, RegExpWrapper, CONST_EXPR, isBlank, isPresent} from 'angular2/src/facade/lang';
StringWrapper,
RegExpWrapper,
CONST_EXPR,
isBlank,
isPresent
} from 'angular2/src/facade/lang';
import { import {HtmlAstVisitor, HtmlAttrAst, HtmlElementAst, HtmlTextAst, HtmlCommentAst, HtmlAst} from './html_ast';
HtmlAstVisitor,
HtmlAttrAst,
HtmlElementAst,
HtmlTextAst,
HtmlCommentAst,
HtmlAst
} from './html_ast';
import {HtmlParser, HtmlParseTreeResult} from './html_parser'; import {HtmlParser, HtmlParseTreeResult} from './html_parser';
import {dashCaseToCamelCase, camelCaseToDashCase} from './util'; import {dashCaseToCamelCase, camelCaseToDashCase} from './util';
@ -50,8 +37,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
this.visitingTemplateEl = ast.name.toLowerCase() == 'template'; this.visitingTemplateEl = ast.name.toLowerCase() == 'template';
let attrs = ast.attrs.map(attr => attr.visit(this, null)); let attrs = ast.attrs.map(attr => attr.visit(this, null));
let children = ast.children.map(child => child.visit(this, null)); let children = ast.children.map(child => child.visit(this, null));
return new HtmlElementAst(ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan, return new HtmlElementAst(
ast.endSourceSpan); ast.name, attrs, children, ast.sourceSpan, ast.startSourceSpan, ast.endSourceSpan);
} }
visitAttr(originalAst: HtmlAttrAst, context: any): HtmlAttrAst { visitAttr(originalAst: HtmlAttrAst, context: any): HtmlAttrAst {
@ -103,8 +90,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
} }
return attrName == ast.name && attrValue == ast.value ? return attrName == ast.name && attrValue == ast.value ?
ast : ast :
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan); new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
} }
private _rewriteTemplateAttribute(ast: HtmlAttrAst): HtmlAttrAst { private _rewriteTemplateAttribute(ast: HtmlAttrAst): HtmlAttrAst {
@ -115,8 +102,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
name = 'template'; name = 'template';
// rewrite the directive selector // rewrite the directive selector
value = StringWrapper.replaceAllMapped(value, TEMPLATE_SELECTOR_REGEXP, value = StringWrapper.replaceAllMapped(
(m) => { return dashCaseToCamelCase(m[1]); }); value, TEMPLATE_SELECTOR_REGEXP, (m) => { return dashCaseToCamelCase(m[1]); });
// rewrite the var declarations // rewrite the var declarations
value = StringWrapper.replaceAllMapped(value, VARIABLE_TPL_BINDING_REGEXP, m => { value = StringWrapper.replaceAllMapped(value, VARIABLE_TPL_BINDING_REGEXP, m => {
@ -142,8 +129,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
} else if (isPresent(m[2])) { } else if (isPresent(m[2])) {
attrName = `[(${dashCaseToCamelCase(m[2])})]`; attrName = `[(${dashCaseToCamelCase(m[2])})]`;
} else if (isPresent(m[3])) { } else if (isPresent(m[3])) {
let prop = StringWrapper.replaceAllMapped(m[3], SPECIAL_PREFIXES_REGEXP, let prop = StringWrapper.replaceAllMapped(
(m) => { return m[1].toLowerCase() + '.'; }); m[3], SPECIAL_PREFIXES_REGEXP, (m) => { return m[1].toLowerCase() + '.'; });
if (prop.startsWith('class.') || prop.startsWith('attr.') || prop.startsWith('style.')) { if (prop.startsWith('class.') || prop.startsWith('attr.') || prop.startsWith('style.')) {
attrName = `[${prop}]`; attrName = `[${prop}]`;
@ -157,8 +144,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
} }
return attrName == ast.name && attrValue == ast.value ? return attrName == ast.name && attrValue == ast.value ?
ast : ast :
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan); new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
} }
private _rewriteStar(ast: HtmlAttrAst): HtmlAttrAst { private _rewriteStar(ast: HtmlAttrAst): HtmlAttrAst {
@ -174,8 +161,8 @@ export class LegacyHtmlAstTransformer implements HtmlAstVisitor {
} }
return attrName == ast.name && attrValue == ast.value ? return attrName == ast.name && attrValue == ast.value ?
ast : ast :
new HtmlAttrAst(attrName, attrValue, ast.sourceSpan); new HtmlAttrAst(attrName, attrValue, ast.sourceSpan);
} }
private _rewriteInterpolation(ast: HtmlAttrAst): HtmlAttrAst { private _rewriteInterpolation(ast: HtmlAttrAst): HtmlAttrAst {
@ -218,7 +205,7 @@ export class LegacyHtmlParser extends HtmlParser {
let rootNodes = htmlParseTreeResult.rootNodes.map(node => node.visit(transformer, null)); let rootNodes = htmlParseTreeResult.rootNodes.map(node => node.visit(transformer, null));
return transformer.rewrittenAst.length > 0 ? return transformer.rewrittenAst.length > 0 ?
new HtmlParseTreeResult(rootNodes, htmlParseTreeResult.errors) : new HtmlParseTreeResult(rootNodes, htmlParseTreeResult.errors) :
htmlParseTreeResult; htmlParseTreeResult;
} }
} }

View File

@ -1,6 +1,7 @@
export class ParseLocation { export class ParseLocation {
constructor(public file: ParseSourceFile, public offset: number, public line: number, constructor(
public col: number) {} public file: ParseSourceFile, public offset: number, public line: number,
public col: number) {}
toString(): string { return `${this.file.url}@${this.line}:${this.col}`; } toString(): string { return `${this.file.url}@${this.line}:${this.col}`; }
} }
@ -33,7 +34,7 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxStart > 0) { while (ctxLen < 100 && ctxStart > 0) {
ctxStart--; ctxStart--;
ctxLen++; ctxLen++;
if (source[ctxStart] == "\n") { if (source[ctxStart] == '\n') {
if (++ctxLines == 3) { if (++ctxLines == 3) {
break; break;
} }
@ -45,7 +46,7 @@ export abstract class ParseError {
while (ctxLen < 100 && ctxEnd < source.length - 1) { while (ctxLen < 100 && ctxEnd < source.length - 1) {
ctxEnd++; ctxEnd++;
ctxLen++; ctxLen++;
if (source[ctxEnd] == "\n") { if (source[ctxEnd] == '\n') {
if (++ctxLines == 3) { if (++ctxLines == 3) {
break; break;
} }
@ -53,7 +54,7 @@ export abstract class ParseError {
} }
let context = source.substring(ctxStart, this.span.start.offset) + '[ERROR ->]' + let context = source.substring(ctxStart, this.span.start.offset) + '[ERROR ->]' +
source.substring(this.span.start.offset, ctxEnd + 1); source.substring(this.span.start.offset, ctxEnd + 1);
return `${this.msg} ("${context}"): ${this.span.start}`; return `${this.msg} ("${context}"): ${this.span.start}`;
} }

View File

@ -1,54 +1,13 @@
import { import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
isPresent, import {SetWrapper, StringMapWrapper, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
isBlank, import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
Type, import {CompileTypeMetadata, CompileDirectiveMetadata, CompilePipeMetadata} from './directive_metadata';
isString,
StringWrapper,
IS_DART,
CONST_EXPR
} from 'angular2/src/facade/lang';
import {
SetWrapper,
StringMapWrapper,
ListWrapper,
MapWrapper
} from 'angular2/src/facade/collection';
import {
TemplateAst,
TemplateAstVisitor,
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
BoundTextAst,
TextAst,
DirectiveAst,
BoundDirectivePropertyAst,
templateVisitAll
} from './template_ast';
import {
CompileTypeMetadata,
CompileDirectiveMetadata,
CompilePipeMetadata
} from './directive_metadata';
import {SourceExpressions, SourceExpression, moduleRef} from './source_module'; import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
import {AppProtoView, AppView} from 'angular2/src/core/linker/view'; import {AppProtoView, AppView} from 'angular2/src/core/linker/view';
import {ViewType} from 'angular2/src/core/linker/view_type'; import {ViewType} from 'angular2/src/core/linker/view_type';
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element'; import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache'; import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
import { import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, codeGenStringMap, Expression, Statement} from './util';
escapeSingleQuoteString,
codeGenConstConstructorCall,
codeGenValueFn,
codeGenFnHeader,
MODULE_SUFFIX,
codeGenStringMap,
Expression,
Statement
} from './util';
import {Injectable} from 'angular2/src/core/di'; import {Injectable} from 'angular2/src/core/di';
export const PROTO_VIEW_JIT_IMPORTS = CONST_EXPR( export const PROTO_VIEW_JIT_IMPORTS = CONST_EXPR(
@ -74,19 +33,20 @@ const STYLE_ATTR = 'style';
export class ProtoViewCompiler { export class ProtoViewCompiler {
constructor() {} constructor() {}
compileProtoViewRuntime(metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata, compileProtoViewRuntime(
template: TemplateAst[], pipes: CompilePipeMetadata[]): metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
CompileProtoViews<AppProtoView, AppProtoElement, any> { template: TemplateAst[],
pipes: CompilePipeMetadata[]): CompileProtoViews<AppProtoView, AppProtoElement, any> {
var protoViewFactory = new RuntimeProtoViewFactory(metadataCache, component, pipes); var protoViewFactory = new RuntimeProtoViewFactory(metadataCache, component, pipes);
var allProtoViews = []; var allProtoViews = [];
protoViewFactory.createCompileProtoView(template, [], [], allProtoViews); protoViewFactory.createCompileProtoView(template, [], [], allProtoViews);
return new CompileProtoViews<AppProtoView, AppProtoElement, any>([], allProtoViews); return new CompileProtoViews<AppProtoView, AppProtoElement, any>([], allProtoViews);
} }
compileProtoViewCodeGen(resolvedMetadataCacheExpr: Expression, compileProtoViewCodeGen(
component: CompileDirectiveMetadata, template: TemplateAst[], resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
pipes: CompilePipeMetadata[]): template: TemplateAst[],
CompileProtoViews<Expression, Expression, string> { pipes: CompilePipeMetadata[]): CompileProtoViews<Expression, Expression, string> {
var protoViewFactory = new CodeGenProtoViewFactory(resolvedMetadataCacheExpr, component, pipes); var protoViewFactory = new CodeGenProtoViewFactory(resolvedMetadataCacheExpr, component, pipes);
var allProtoViews = []; var allProtoViews = [];
var allStatements = []; var allStatements = [];
@ -97,26 +57,29 @@ export class ProtoViewCompiler {
} }
export class CompileProtoViews<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> { export class CompileProtoViews<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
constructor(public declarations: STATEMENT[], constructor(
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {} public declarations: STATEMENT[],
public protoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
} }
export class CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> { export class CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
constructor(public embeddedTemplateIndex: number, constructor(
public protoElements: CompileProtoElement<APP_PROTO_EL>[], public embeddedTemplateIndex: number,
public protoView: APP_PROTO_VIEW) {} public protoElements: CompileProtoElement<APP_PROTO_EL>[], public protoView: APP_PROTO_VIEW) {
}
} }
export class CompileProtoElement<APP_PROTO_EL> { export class CompileProtoElement<APP_PROTO_EL> {
constructor(public boundElementIndex, public attrNameAndValues: string[][], constructor(
public variableNameAndValues: string[][], public renderEvents: BoundEventAst[], public boundElementIndex, public attrNameAndValues: string[][],
public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number, public variableNameAndValues: string[][], public renderEvents: BoundEventAst[],
public appProtoEl: APP_PROTO_EL) {} public directives: CompileDirectiveMetadata[], public embeddedTemplateIndex: number,
public appProtoEl: APP_PROTO_EL) {}
} }
function visitAndReturnContext(visitor: TemplateAstVisitor, asts: TemplateAst[], function visitAndReturnContext(
context: any): any { visitor: TemplateAstVisitor, asts: TemplateAst[], context: any): any {
templateVisitAll(visitor, asts, context); templateVisitAll(visitor, asts, context);
return context; return context;
} }
@ -124,18 +87,17 @@ function visitAndReturnContext(visitor: TemplateAstVisitor, asts: TemplateAst[],
abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> { abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
constructor(public component: CompileDirectiveMetadata) {} constructor(public component: CompileDirectiveMetadata) {}
abstract createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType, abstract createAppProtoView(
templateVariableBindings: string[][], embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
targetStatements: STATEMENT[]): APP_PROTO_VIEW; targetStatements: STATEMENT[]): APP_PROTO_VIEW;
abstract createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][], abstract createAppProtoElement(
variableNameAndValues: string[][], boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
directives: CompileDirectiveMetadata[], directives: CompileDirectiveMetadata[], targetStatements: STATEMENT[]): APP_PROTO_EL;
targetStatements: STATEMENT[]): APP_PROTO_EL;
createCompileProtoView(template: TemplateAst[], templateVariableBindings: string[][], createCompileProtoView(
targetStatements: STATEMENT[], template: TemplateAst[], templateVariableBindings: string[][], targetStatements: STATEMENT[],
targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]): targetProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]):
CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> { CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL> {
var embeddedTemplateIndex = targetProtoViews.length; var embeddedTemplateIndex = targetProtoViews.length;
// Note: targetProtoViews needs to be in depth first order. // Note: targetProtoViews needs to be in depth first order.
@ -145,8 +107,8 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
this, targetStatements, targetProtoViews); this, targetStatements, targetProtoViews);
templateVisitAll(builder, template); templateVisitAll(builder, template);
var viewType = getViewType(this.component, embeddedTemplateIndex); var viewType = getViewType(this.component, embeddedTemplateIndex);
var appProtoView = this.createAppProtoView(embeddedTemplateIndex, viewType, var appProtoView = this.createAppProtoView(
templateVariableBindings, targetStatements); embeddedTemplateIndex, viewType, templateVariableBindings, targetStatements);
var cpv = new CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>( var cpv = new CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>(
embeddedTemplateIndex, builder.protoElements, appProtoView); embeddedTemplateIndex, builder.protoElements, appProtoView);
targetProtoViews[embeddedTemplateIndex] = cpv; targetProtoViews[embeddedTemplateIndex] = cpv;
@ -157,8 +119,9 @@ abstract class ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> {
class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, Statement> { class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, Statement> {
private _nextVarId: number = 0; private _nextVarId: number = 0;
constructor(public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata, constructor(
public pipes: CompilePipeMetadata[]) { public resolvedMetadataCacheExpr: Expression, component: CompileDirectiveMetadata,
public pipes: CompilePipeMetadata[]) {
super(component); super(component);
} }
@ -166,23 +129,23 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
return `appProtoView${this._nextVarId++}_${this.component.type.name}${embeddedTemplateIndex}`; return `appProtoView${this._nextVarId++}_${this.component.type.name}${embeddedTemplateIndex}`;
} }
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType, createAppProtoView(
templateVariableBindings: string[][], embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
targetStatements: Statement[]): Expression { targetStatements: Statement[]): Expression {
var protoViewVarName = this._nextProtoViewVar(embeddedTemplateIndex); var protoViewVarName = this._nextProtoViewVar(embeddedTemplateIndex);
var viewTypeExpr = codeGenViewType(viewType); var viewTypeExpr = codeGenViewType(viewType);
var pipesExpr = embeddedTemplateIndex === 0 ? var pipesExpr = embeddedTemplateIndex === 0 ?
codeGenTypesArray(this.pipes.map(pipeMeta => pipeMeta.type)) : codeGenTypesArray(this.pipes.map(pipeMeta => pipeMeta.type)) :
null; null;
var statement = var statement =
`var ${protoViewVarName} = ${APP_VIEW_MODULE_REF}AppProtoView.create(${this.resolvedMetadataCacheExpr.expression}, ${viewTypeExpr}, ${pipesExpr}, ${codeGenStringMap(templateVariableBindings)});`; `var ${protoViewVarName} = ${APP_VIEW_MODULE_REF}AppProtoView.create(${this.resolvedMetadataCacheExpr.expression}, ${viewTypeExpr}, ${pipesExpr}, ${codeGenStringMap(templateVariableBindings)});`;
targetStatements.push(new Statement(statement)); targetStatements.push(new Statement(statement));
return new Expression(protoViewVarName); return new Expression(protoViewVarName);
} }
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][], createAppProtoElement(
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[], boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
targetStatements: Statement[]): Expression { directives: CompileDirectiveMetadata[], targetStatements: Statement[]): Expression {
var varName = `appProtoEl${this._nextVarId++}_${this.component.type.name}`; var varName = `appProtoEl${this._nextVarId++}_${this.component.type.name}`;
var value = `${APP_EL_MODULE_REF}AppProtoElement.create( var value = `${APP_EL_MODULE_REF}AppProtoElement.create(
${this.resolvedMetadataCacheExpr.expression}, ${this.resolvedMetadataCacheExpr.expression},
@ -198,26 +161,29 @@ class CodeGenProtoViewFactory extends ProtoViewFactory<Expression, Expression, S
} }
class RuntimeProtoViewFactory extends ProtoViewFactory<AppProtoView, AppProtoElement, any> { class RuntimeProtoViewFactory extends ProtoViewFactory<AppProtoView, AppProtoElement, any> {
constructor(public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata, constructor(
public pipes: CompilePipeMetadata[]) { public metadataCache: ResolvedMetadataCache, component: CompileDirectiveMetadata,
public pipes: CompilePipeMetadata[]) {
super(component); super(component);
} }
createAppProtoView(embeddedTemplateIndex: number, viewType: ViewType, createAppProtoView(
templateVariableBindings: string[][], targetStatements: any[]): AppProtoView { embeddedTemplateIndex: number, viewType: ViewType, templateVariableBindings: string[][],
targetStatements: any[]): AppProtoView {
var pipes = var pipes =
embeddedTemplateIndex === 0 ? this.pipes.map(pipeMeta => pipeMeta.type.runtime) : []; embeddedTemplateIndex === 0 ? this.pipes.map(pipeMeta => pipeMeta.type.runtime) : [];
var templateVars = keyValueArrayToStringMap(templateVariableBindings); var templateVars = keyValueArrayToStringMap(templateVariableBindings);
return AppProtoView.create(this.metadataCache, viewType, pipes, templateVars); return AppProtoView.create(this.metadataCache, viewType, pipes, templateVars);
} }
createAppProtoElement(boundElementIndex: number, attrNameAndValues: string[][], createAppProtoElement(
variableNameAndValues: string[][], directives: CompileDirectiveMetadata[], boundElementIndex: number, attrNameAndValues: string[][], variableNameAndValues: string[][],
targetStatements: any[]): AppProtoElement { directives: CompileDirectiveMetadata[], targetStatements: any[]): AppProtoElement {
var attrs = keyValueArrayToStringMap(attrNameAndValues); var attrs = keyValueArrayToStringMap(attrNameAndValues);
return AppProtoElement.create(this.metadataCache, boundElementIndex, attrs, return AppProtoElement.create(
directives.map(dirMeta => dirMeta.type.runtime), this.metadataCache, boundElementIndex, attrs,
keyValueArrayToStringMap(variableNameAndValues)); directives.map(dirMeta => dirMeta.type.runtime),
keyValueArrayToStringMap(variableNameAndValues));
} }
} }
@ -226,12 +192,13 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
protoElements: CompileProtoElement<APP_PROTO_EL>[] = []; protoElements: CompileProtoElement<APP_PROTO_EL>[] = [];
boundElementCount: number = 0; boundElementCount: number = 0;
constructor(public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>, constructor(
public allStatements: STATEMENT[], public factory: ProtoViewFactory<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT>,
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {} public allStatements: STATEMENT[],
public allProtoViews: CompileProtoView<APP_PROTO_VIEW, APP_PROTO_EL>[]) {}
private _readAttrNameAndValues(directives: CompileDirectiveMetadata[], private _readAttrNameAndValues(directives: CompileDirectiveMetadata[], attrAsts: TemplateAst[]):
attrAsts: TemplateAst[]): string[][] { string[][] {
var attrs = visitAndReturnContext(this, attrAsts, {}); var attrs = visitAndReturnContext(this, attrAsts, {});
directives.forEach(directiveMeta => { directives.forEach(directiveMeta => {
StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: string, name: string) => { StringMapWrapper.forEach(directiveMeta.hostAttributes, (value: string, name: string) => {
@ -262,15 +229,17 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
var renderEvents: Map<string, BoundEventAst> = var renderEvents: Map<string, BoundEventAst> =
visitAndReturnContext(this, ast.outputs, new Map<string, BoundEventAst>()); visitAndReturnContext(this, ast.outputs, new Map<string, BoundEventAst>());
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => { ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
directiveAst.visit(this, new DirectiveContext(index, boundElementIndex, renderEvents, directiveAst.visit(
variableNameAndValues, directives)); this, new DirectiveContext(
index, boundElementIndex, renderEvents, variableNameAndValues, directives));
}); });
var renderEventArray = []; var renderEventArray = [];
renderEvents.forEach((eventAst, _) => renderEventArray.push(eventAst)); renderEvents.forEach((eventAst, _) => renderEventArray.push(eventAst));
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs); var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
this._addProtoElement(ast.isBound(), boundElementIndex, attrNameAndValues, this._addProtoElement(
variableNameAndValues, renderEventArray, directives, null); ast.isBound(), boundElementIndex, attrNameAndValues, variableNameAndValues,
renderEventArray, directives, null);
templateVisitAll(this, ast.children); templateVisitAll(this, ast.children);
return null; return null;
} }
@ -280,8 +249,8 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
var directives: CompileDirectiveMetadata[] = []; var directives: CompileDirectiveMetadata[] = [];
ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => { ListWrapper.forEachWithIndex(ast.directives, (directiveAst: DirectiveAst, index: number) => {
directiveAst.visit( directiveAst.visit(
this, new DirectiveContext(index, boundElementIndex, new Map<string, BoundEventAst>(), [], this, new DirectiveContext(
directives)); index, boundElementIndex, new Map<string, BoundEventAst>(), [], directives));
}); });
var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs); var attrNameAndValues = this._readAttrNameAndValues(directives, ast.attrs);
@ -289,19 +258,21 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]); varAst => [varAst.value.length > 0 ? varAst.value : IMPLICIT_TEMPLATE_VAR, varAst.name]);
var nestedProtoView = this.factory.createCompileProtoView( var nestedProtoView = this.factory.createCompileProtoView(
ast.children, templateVariableBindings, this.allStatements, this.allProtoViews); ast.children, templateVariableBindings, this.allStatements, this.allProtoViews);
this._addProtoElement(true, boundElementIndex, attrNameAndValues, [], [], directives, this._addProtoElement(
nestedProtoView.embeddedTemplateIndex); true, boundElementIndex, attrNameAndValues, [], [], directives,
nestedProtoView.embeddedTemplateIndex);
return null; return null;
} }
private _addProtoElement(isBound: boolean, boundElementIndex, attrNameAndValues: string[][], private _addProtoElement(
variableNameAndValues: string[][], renderEvents: BoundEventAst[], isBound: boolean, boundElementIndex, attrNameAndValues: string[][],
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) { variableNameAndValues: string[][], renderEvents: BoundEventAst[],
directives: CompileDirectiveMetadata[], embeddedTemplateIndex: number) {
var appProtoEl = null; var appProtoEl = null;
if (isBound) { if (isBound) {
appProtoEl = appProtoEl = this.factory.createAppProtoElement(
this.factory.createAppProtoElement(boundElementIndex, attrNameAndValues, boundElementIndex, attrNameAndValues, variableNameAndValues, directives,
variableNameAndValues, directives, this.allStatements); this.allStatements);
} }
var compileProtoEl = new CompileProtoElement<APP_PROTO_EL>( var compileProtoEl = new CompileProtoElement<APP_PROTO_EL>(
boundElementIndex, attrNameAndValues, variableNameAndValues, renderEvents, directives, boundElementIndex, attrNameAndValues, variableNameAndValues, renderEvents, directives,
@ -317,8 +288,9 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
visitDirective(ast: DirectiveAst, ctx: DirectiveContext): any { visitDirective(ast: DirectiveAst, ctx: DirectiveContext): any {
ctx.targetDirectives.push(ast.directive); ctx.targetDirectives.push(ast.directive);
templateVisitAll(this, ast.hostEvents, ctx.hostEventTargetAndNames); templateVisitAll(this, ast.hostEvents, ctx.hostEventTargetAndNames);
ast.exportAsVars.forEach( ast.exportAsVars.forEach(varAst => {
varAst => { ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]); }); ctx.targetVariableNameAndValues.push([varAst.name, ctx.index]);
});
return null; return null;
} }
visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any { visitEvent(ast: BoundEventAst, eventTargetAndNames: Map<string, BoundEventAst>): any {
@ -331,12 +303,14 @@ class ProtoViewBuilderVisitor<APP_PROTO_VIEW, APP_PROTO_EL, STATEMENT> implement
function mapToKeyValueArray(data: {[key: string]: string}): string[][] { function mapToKeyValueArray(data: {[key: string]: string}): string[][] {
var entryArray: string[][] = []; var entryArray: string[][] = [];
StringMapWrapper.forEach(data, StringMapWrapper.forEach(data, (value: string, name: string) => {
(value: string, name: string) => { entryArray.push([name, value]); }); entryArray.push([name, value]);
});
// We need to sort to get a defined output order // We need to sort to get a defined output order
// for tests and for caching generated artifacts... // for tests and for caching generated artifacts...
ListWrapper.sort<string[]>(entryArray, (entry1: string[], entry2: string[]) => ListWrapper.sort<string[]>(
StringWrapper.compare(entry1[0], entry2[0])); entryArray,
(entry1: string[], entry2: string[]) => StringWrapper.compare(entry1[0], entry2[0]));
var keyValueArray: string[][] = []; var keyValueArray: string[][] = [];
entryArray.forEach((entry) => { keyValueArray.push([entry[0], entry[1]]); }); entryArray.forEach((entry) => { keyValueArray.push([entry[0], entry[1]]); });
return keyValueArray; return keyValueArray;
@ -351,10 +325,11 @@ function mergeAttributeValue(attrName: string, attrValue1: string, attrValue2: s
} }
class DirectiveContext { class DirectiveContext {
constructor(public index: number, public boundElementIndex: number, constructor(
public hostEventTargetAndNames: Map<string, BoundEventAst>, public index: number, public boundElementIndex: number,
public targetVariableNameAndValues: any[][], public hostEventTargetAndNames: Map<string, BoundEventAst>,
public targetDirectives: CompileDirectiveMetadata[]) {} public targetVariableNameAndValues: any[][],
public targetDirectives: CompileDirectiveMetadata[]) {}
} }
function keyValueArrayToStringMap(keyValueArray: any[][]): {[key: string]: any} { function keyValueArrayToStringMap(keyValueArray: any[][]): {[key: string]: any} {

View File

@ -1,12 +1,5 @@
import {resolveForwardRef} from 'angular2/src/core/di'; import {resolveForwardRef} from 'angular2/src/core/di';
import { import {Type, isBlank, isPresent, isArray, stringify, RegExpWrapper} from 'angular2/src/facade/lang';
Type,
isBlank,
isPresent,
isArray,
stringify,
RegExpWrapper
} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import * as cpl from './directive_metadata'; import * as cpl from './directive_metadata';
import * as md from 'angular2/src/core/metadata/directives'; import * as md from 'angular2/src/core/metadata/directives';
@ -30,10 +23,11 @@ export class RuntimeMetadataResolver {
private _anonymousTypes = new Map<Object, number>(); private _anonymousTypes = new Map<Object, number>();
private _anonymousTypeIndex = 0; private _anonymousTypeIndex = 0;
constructor(private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver, constructor(
private _viewResolver: ViewResolver, private _directiveResolver: DirectiveResolver, private _pipeResolver: PipeResolver,
@Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[], private _viewResolver: ViewResolver,
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {} @Optional() @Inject(PLATFORM_DIRECTIVES) private _platformDirectives: Type[],
@Optional() @Inject(PLATFORM_PIPES) private _platformPipes: Type[]) {}
/** /**
* Wrap the stringify method to avoid naming things `function (arg1...) {` * Wrap the stringify method to avoid naming things `function (arg1...) {`
@ -157,7 +151,7 @@ function flattenPipes(view: ViewMetadata, platformPipes: any[]): Type[] {
return pipes; return pipes;
} }
function flattenArray(tree: any[], out: Array<Type | any[]>): void { function flattenArray(tree: any[], out: Array<Type|any[]>): void {
for (var i = 0; i < tree.length; i++) { for (var i = 0; i < tree.length; i++) {
var item = resolveForwardRef(tree[i]); var item = resolveForwardRef(tree[i]);
if (isArray(item)) { if (isArray(item)) {

View File

@ -18,8 +18,8 @@ export class DomElementSchemaRegistry extends ElementSchemaRegistry {
if (isBlank(element)) { if (isBlank(element)) {
var nsAndName = splitNsName(tagName); var nsAndName = splitNsName(tagName);
element = isPresent(nsAndName[0]) ? element = isPresent(nsAndName[0]) ?
DOM.createElementNS(NAMESPACE_URIS[nsAndName[0]], nsAndName[1]) : DOM.createElementNS(NAMESPACE_URIS[nsAndName[0]], nsAndName[1]) :
DOM.createElement(nsAndName[1]); DOM.createElement(nsAndName[1]);
this._protoElements.set(tagName, element); this._protoElements.set(tagName, element);
} }
return element; return element;

View File

@ -1,11 +1,5 @@
import {Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection';
import { import {isPresent, isBlank, RegExpWrapper, RegExpMatcherWrapper, StringWrapper} from 'angular2/src/facade/lang';
isPresent,
isBlank,
RegExpWrapper,
RegExpMatcherWrapper,
StringWrapper
} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions'; import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
const _EMPTY_ATTR_VALUE = ''; const _EMPTY_ATTR_VALUE = '';
@ -36,7 +30,7 @@ export class CssSelector {
var _addResult = (res: CssSelector[], cssSel) => { var _addResult = (res: CssSelector[], cssSel) => {
if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) && if (cssSel.notSelectors.length > 0 && isBlank(cssSel.element) &&
ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) { ListWrapper.isEmpty(cssSel.classNames) && ListWrapper.isEmpty(cssSel.attrs)) {
cssSel.element = "*"; cssSel.element = '*';
} }
res.push(cssSel); res.push(cssSel);
}; };
@ -81,7 +75,7 @@ export class CssSelector {
isElementSelector(): boolean { isElementSelector(): boolean {
return isPresent(this.element) && ListWrapper.isEmpty(this.classNames) && return isPresent(this.element) && ListWrapper.isEmpty(this.classNames) &&
ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0; ListWrapper.isEmpty(this.attrs) && this.notSelectors.length === 0;
} }
setElement(element: string = null) { this.element = element; } setElement(element: string = null) { this.element = element; }
@ -174,8 +168,8 @@ export class SelectorMatcher {
* @param cssSelector A css selector * @param cssSelector A css selector
* @param callbackCtxt An opaque object that will be given to the callback of the `match` function * @param callbackCtxt An opaque object that will be given to the callback of the `match` function
*/ */
private _addSelectable(cssSelector: CssSelector, callbackCtxt: any, private _addSelectable(
listContext: SelectorListContext) { cssSelector: CssSelector, callbackCtxt: any, listContext: SelectorListContext) {
var matcher: SelectorMatcher = this; var matcher: SelectorMatcher = this;
var element = cssSelector.element; var element = cssSelector.element;
var classNames = cssSelector.classNames; var classNames = cssSelector.classNames;
@ -229,8 +223,8 @@ export class SelectorMatcher {
} }
} }
private _addTerminal(map: Map<string, SelectorContext[]>, name: string, private _addTerminal(
selectable: SelectorContext) { map: Map<string, SelectorContext[]>, name: string, selectable: SelectorContext) {
var terminalList = map.get(name); var terminalList = map.get(name);
if (isBlank(terminalList)) { if (isBlank(terminalList)) {
terminalList = []; terminalList = [];
@ -267,7 +261,7 @@ export class SelectorMatcher {
result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result; result = this._matchTerminal(this._elementMap, element, cssSelector, matchedCallback) || result;
result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) || result = this._matchPartial(this._elementPartialMap, element, cssSelector, matchedCallback) ||
result; result;
if (isPresent(classNames)) { if (isPresent(classNames)) {
for (var index = 0; index < classNames.length; index++) { for (var index = 0; index < classNames.length; index++) {
@ -287,18 +281,18 @@ export class SelectorMatcher {
var terminalValuesMap = this._attrValueMap.get(attrName); var terminalValuesMap = this._attrValueMap.get(attrName);
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) { if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
result = this._matchTerminal(terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector, result = this._matchTerminal(
matchedCallback) || terminalValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
result; result;
} }
result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) || result = this._matchTerminal(terminalValuesMap, attrValue, cssSelector, matchedCallback) ||
result; result;
var partialValuesMap = this._attrValuePartialMap.get(attrName); var partialValuesMap = this._attrValuePartialMap.get(attrName);
if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) { if (!StringWrapper.equals(attrValue, _EMPTY_ATTR_VALUE)) {
result = this._matchPartial(partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector, result = this._matchPartial(
matchedCallback) || partialValuesMap, _EMPTY_ATTR_VALUE, cssSelector, matchedCallback) ||
result; result;
} }
result = result =
this._matchPartial(partialValuesMap, attrValue, cssSelector, matchedCallback) || result; this._matchPartial(partialValuesMap, attrValue, cssSelector, matchedCallback) || result;
@ -308,14 +302,15 @@ export class SelectorMatcher {
} }
/** @internal */ /** @internal */
_matchTerminal(map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector, _matchTerminal(
matchedCallback: (c: CssSelector, a: any) => void): boolean { map: Map<string, SelectorContext[]>, name, cssSelector: CssSelector,
matchedCallback: (c: CssSelector, a: any) => void): boolean {
if (isBlank(map) || isBlank(name)) { if (isBlank(map) || isBlank(name)) {
return false; return false;
} }
var selectables = map.get(name); var selectables = map.get(name);
var starSelectables = map.get("*"); var starSelectables = map.get('*');
if (isPresent(starSelectables)) { if (isPresent(starSelectables)) {
selectables = selectables.concat(starSelectables); selectables = selectables.concat(starSelectables);
} }
@ -332,8 +327,9 @@ export class SelectorMatcher {
} }
/** @internal */ /** @internal */
_matchPartial(map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector, _matchPartial(
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean { map: Map<string, SelectorMatcher>, name, cssSelector: CssSelector,
matchedCallback /*: (c: CssSelector, a: any) => void*/): boolean {
if (isBlank(map) || isBlank(name)) { if (isBlank(map) || isBlank(name)) {
return false; return false;
} }
@ -359,8 +355,9 @@ export class SelectorListContext {
export class SelectorContext { export class SelectorContext {
notSelectors: CssSelector[]; notSelectors: CssSelector[];
constructor(public selector: CssSelector, public cbContext: any, constructor(
public listContext: SelectorListContext) { public selector: CssSelector, public cbContext: any,
public listContext: SelectorListContext) {
this.notSelectors = selector.notSelectors; this.notSelectors = selector.notSelectors;
} }

View File

@ -1,12 +1,5 @@
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
import { import {StringWrapper, RegExp, RegExpWrapper, RegExpMatcherWrapper, isPresent, isBlank} from 'angular2/src/facade/lang';
StringWrapper,
RegExp,
RegExpWrapper,
RegExpMatcherWrapper,
isPresent,
isBlank
} from 'angular2/src/facade/lang';
/** /**
* This file is a port of shadowCSS from webcomponents.js to TypeScript. * This file is a port of shadowCSS from webcomponents.js to TypeScript.
@ -174,8 +167,8 @@ export class ShadowCss {
**/ **/
private _insertPolyfillDirectivesInCssText(cssText: string): string { private _insertPolyfillDirectivesInCssText(cssText: string): string {
// Difference with webcomponents.js: does not handle comments // Difference with webcomponents.js: does not handle comments
return StringWrapper.replaceAllMapped(cssText, _cssContentNextSelectorRe, return StringWrapper.replaceAllMapped(
function(m) { return m[1] + '{'; }); cssText, _cssContentNextSelectorRe, function(m) { return m[1] + '{'; });
} }
/* /*
@ -279,8 +272,8 @@ export class ShadowCss {
* scopeName.foo .bar { ... } * scopeName.foo .bar { ... }
*/ */
private _convertColonHostContext(cssText: string): string { private _convertColonHostContext(cssText: string): string {
return this._convertColonRule(cssText, _cssColonHostContextRe, return this._convertColonRule(
this._colonHostContextPartReplacer); cssText, _cssColonHostContextRe, this._colonHostContextPartReplacer);
} }
private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string { private _convertColonRule(cssText: string, regExp: RegExp, partReplacer: Function): string {
@ -339,8 +332,8 @@ export class ShadowCss {
}); });
} }
private _scopeSelector(selector: string, scopeSelector: string, hostSelector: string, private _scopeSelector(
strict: boolean): string { selector: string, scopeSelector: string, hostSelector: string, strict: boolean): string {
var r = [], parts = selector.split(','); var r = [], parts = selector.split(',');
for (var i = 0; i < parts.length; i++) { for (var i = 0; i < parts.length; i++) {
var p = parts[i].trim(); var p = parts[i].trim();
@ -348,8 +341,8 @@ export class ShadowCss {
var shallowPart = deepParts[0]; var shallowPart = deepParts[0];
if (this._selectorNeedsScoping(shallowPart, scopeSelector)) { if (this._selectorNeedsScoping(shallowPart, scopeSelector)) {
deepParts[0] = strict && !StringWrapper.contains(shallowPart, _polyfillHostNoCombinator) ? deepParts[0] = strict && !StringWrapper.contains(shallowPart, _polyfillHostNoCombinator) ?
this._applyStrictSelectorScope(shallowPart, scopeSelector) : this._applyStrictSelectorScope(shallowPart, scopeSelector) :
this._applySelectorScope(shallowPart, scopeSelector, hostSelector); this._applySelectorScope(shallowPart, scopeSelector, hostSelector);
} }
// replace /deep/ with a space for child selectors // replace /deep/ with a space for child selectors
r.push(deepParts.join(' ')); r.push(deepParts.join(' '));
@ -370,15 +363,15 @@ export class ShadowCss {
return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm'); return RegExpWrapper.create('^(' + scopeSelector + ')' + _selectorReSuffix, 'm');
} }
private _applySelectorScope(selector: string, scopeSelector: string, private _applySelectorScope(selector: string, scopeSelector: string, hostSelector: string):
hostSelector: string): string { string {
// Difference from webcomponentsjs: scopeSelector could not be an array // Difference from webcomponentsjs: scopeSelector could not be an array
return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector); return this._applySimpleSelectorScope(selector, scopeSelector, hostSelector);
} }
// scope via name and [is=name] // scope via name and [is=name]
private _applySimpleSelectorScope(selector: string, scopeSelector: string, private _applySimpleSelectorScope(selector: string, scopeSelector: string, hostSelector: string):
hostSelector: string): string { string {
if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) { if (isPresent(RegExpWrapper.firstMatch(_polyfillHostRe, selector))) {
var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector; var replaceBy = this.strictStyling ? `[${hostSelector}]` : scopeSelector;
selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy); selector = StringWrapper.replace(selector, _polyfillHostNoCombinator, replaceBy);
@ -397,19 +390,20 @@ export class ShadowCss {
for (var i = 0; i < splits.length; i++) { for (var i = 0; i < splits.length; i++) {
var sep = splits[i]; var sep = splits[i];
var parts = scoped.split(sep); var parts = scoped.split(sep);
scoped = parts.map(p => { scoped = parts
// remove :host since it should be unnecessary .map(p => {
var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, ''); // remove :host since it should be unnecessary
if (t.length > 0 && !ListWrapper.contains(splits, t) && var t = StringWrapper.replaceAll(p.trim(), _polyfillHostRe, '');
!StringWrapper.contains(t, attrName)) { if (t.length > 0 && !ListWrapper.contains(splits, t) &&
var re = /([^:]*)(:*)(.*)/g; !StringWrapper.contains(t, attrName)) {
var m = RegExpWrapper.firstMatch(re, t); var re = /([^:]*)(:*)(.*)/g;
if (isPresent(m)) { var m = RegExpWrapper.firstMatch(re, t);
p = m[1] + attrName + m[2] + m[3]; if (isPresent(m)) {
} p = m[1] + attrName + m[2] + m[3];
} }
return p; }
}) return p;
})
.join(sep); .join(sep);
} }
return scoped; return scoped;
@ -430,14 +424,13 @@ var _polyfillHost = '-shadowcsshost';
// note: :host-context pre-processed to -shadowcsshostcontext. // note: :host-context pre-processed to -shadowcsshostcontext.
var _polyfillHostContext = '-shadowcsscontext'; var _polyfillHostContext = '-shadowcsscontext';
var _parenSuffix = ')(?:\\((' + var _parenSuffix = ')(?:\\((' +
'(?:\\([^)(]*\\)|[^)(]*)+?' + '(?:\\([^)(]*\\)|[^)(]*)+?' +
')\\))?([^,{]*)'; ')\\))?([^,{]*)';
var _cssColonHostRe = RegExpWrapper.create('(' + _polyfillHost + _parenSuffix, 'im'); var _cssColonHostRe = RegExpWrapper.create('(' + _polyfillHost + _parenSuffix, 'im');
var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im'); var _cssColonHostContextRe = RegExpWrapper.create('(' + _polyfillHostContext + _parenSuffix, 'im');
var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator'; var _polyfillHostNoCombinator = _polyfillHost + '-no-combinator';
var _shadowDOMSelectorsRe = [ var _shadowDOMSelectorsRe = [
/::shadow/g, /::shadow/g, /::content/g,
/::content/g,
// Deprecated selectors // Deprecated selectors
// TODO(vicb): see https://github.com/angular/clang-format/issues/16 // TODO(vicb): see https://github.com/angular/clang-format/issues/16
// clang-format off // clang-format off

View File

@ -1,30 +1,6 @@
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import { import {isArray, isBlank, isNumber, isPresent, isPrimitive, isString, Type} from 'angular2/src/facade/lang';
isArray, import {AttributeMetadata, DirectiveMetadata, ComponentMetadata, ContentChildrenMetadata, ContentChildMetadata, InputMetadata, HostBindingMetadata, HostListenerMetadata, OutputMetadata, PipeMetadata, ViewMetadata, ViewChildMetadata, ViewChildrenMetadata, ViewQueryMetadata, QueryMetadata,} from 'angular2/src/core/metadata';
isBlank,
isNumber,
isPresent,
isPrimitive,
isString,
Type
} from 'angular2/src/facade/lang';
import {
AttributeMetadata,
DirectiveMetadata,
ComponentMetadata,
ContentChildrenMetadata,
ContentChildMetadata,
InputMetadata,
HostBindingMetadata,
HostListenerMetadata,
OutputMetadata,
PipeMetadata,
ViewMetadata,
ViewChildMetadata,
ViewChildrenMetadata,
ViewQueryMetadata,
QueryMetadata,
} from 'angular2/src/core/metadata';
/** /**
* The host of the static resolver is expected to be able to provide module metadata in the form of * The host of the static resolver is expected to be able to provide module metadata in the form of
@ -124,60 +100,62 @@ export class StaticReflector {
private initializeConversionMap(): any { private initializeConversionMap(): any {
let core_metadata = 'angular2/src/core/metadata'; let core_metadata = 'angular2/src/core/metadata';
let conversionMap = this.conversionMap; let conversionMap = this.conversionMap;
conversionMap.set(this.getStaticType(core_metadata, 'Directive'), conversionMap.set(
(moduleContext, expression) => { this.getStaticType(core_metadata, 'Directive'), (moduleContext, expression) => {
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
if (!isPresent(p0)) { if (!isPresent(p0)) {
p0 = {}; p0 = {};
} }
return new DirectiveMetadata({ return new DirectiveMetadata({
selector: p0['selector'], selector: p0['selector'],
inputs: p0['inputs'], inputs: p0['inputs'],
outputs: p0['outputs'], outputs: p0['outputs'],
events: p0['events'], events: p0['events'],
host: p0['host'], host: p0['host'],
bindings: p0['bindings'], bindings: p0['bindings'],
providers: p0['providers'], providers: p0['providers'],
exportAs: p0['exportAs'], exportAs: p0['exportAs'],
queries: p0['queries'], queries: p0['queries'],
}); });
}); });
conversionMap.set(this.getStaticType(core_metadata, 'Component'), conversionMap.set(
(moduleContext, expression) => { this.getStaticType(core_metadata, 'Component'), (moduleContext, expression) => {
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
if (!isPresent(p0)) { if (!isPresent(p0)) {
p0 = {}; p0 = {};
} }
return new ComponentMetadata({ return new ComponentMetadata({
selector: p0['selector'], selector: p0['selector'],
inputs: p0['inputs'], inputs: p0['inputs'],
outputs: p0['outputs'], outputs: p0['outputs'],
properties: p0['properties'], properties: p0['properties'],
events: p0['events'], events: p0['events'],
host: p0['host'], host: p0['host'],
exportAs: p0['exportAs'], exportAs: p0['exportAs'],
moduleId: p0['moduleId'], moduleId: p0['moduleId'],
bindings: p0['bindings'], bindings: p0['bindings'],
providers: p0['providers'], providers: p0['providers'],
viewBindings: p0['viewBindings'], viewBindings: p0['viewBindings'],
viewProviders: p0['viewProviders'], viewProviders: p0['viewProviders'],
changeDetection: p0['changeDetection'], changeDetection: p0['changeDetection'],
queries: p0['queries'], queries: p0['queries'],
templateUrl: p0['templateUrl'], templateUrl: p0['templateUrl'],
template: p0['template'], template: p0['template'],
styleUrls: p0['styleUrls'], styleUrls: p0['styleUrls'],
styles: p0['styles'], styles: p0['styles'],
directives: p0['directives'], directives: p0['directives'],
pipes: p0['pipes'], pipes: p0['pipes'],
encapsulation: p0['encapsulation'] encapsulation: p0['encapsulation']
}); });
}); });
conversionMap.set(this.getStaticType(core_metadata, 'Input'), conversionMap.set(
(moduleContext, expression) => new InputMetadata( this.getStaticType(core_metadata, 'Input'),
this.getDecoratorParameter(moduleContext, expression, 0))); (moduleContext, expression) =>
conversionMap.set(this.getStaticType(core_metadata, 'Output'), new InputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
(moduleContext, expression) => new OutputMetadata( conversionMap.set(
this.getDecoratorParameter(moduleContext, expression, 0))); this.getStaticType(core_metadata, 'Output'),
(moduleContext, expression) =>
new OutputMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => { conversionMap.set(this.getStaticType(core_metadata, 'View'), (moduleContext, expression) => {
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
if (!isPresent(p0)) { if (!isPresent(p0)) {
@ -192,9 +170,10 @@ export class StaticReflector {
styles: p0['styles'], styles: p0['styles'],
}); });
}); });
conversionMap.set(this.getStaticType(core_metadata, 'Attribute'), conversionMap.set(
(moduleContext, expression) => new AttributeMetadata( this.getStaticType(core_metadata, 'Attribute'),
this.getDecoratorParameter(moduleContext, expression, 0))); (moduleContext, expression) =>
new AttributeMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => { conversionMap.set(this.getStaticType(core_metadata, 'Query'), (moduleContext, expression) => {
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
let p1 = this.getDecoratorParameter(moduleContext, expression, 1); let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
@ -203,30 +182,34 @@ export class StaticReflector {
} }
return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first}); return new QueryMetadata(p0, {descendants: p1.descendants, first: p1.first});
}); });
conversionMap.set(this.getStaticType(core_metadata, 'ContentChildren'), conversionMap.set(
(moduleContext, expression) => new ContentChildrenMetadata( this.getStaticType(core_metadata, 'ContentChildren'),
this.getDecoratorParameter(moduleContext, expression, 0))); (moduleContext, expression) =>
conversionMap.set(this.getStaticType(core_metadata, 'ContentChild'), new ContentChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
(moduleContext, expression) => new ContentChildMetadata( conversionMap.set(
this.getDecoratorParameter(moduleContext, expression, 0))); this.getStaticType(core_metadata, 'ContentChild'),
conversionMap.set(this.getStaticType(core_metadata, 'ViewChildren'), (moduleContext, expression) =>
(moduleContext, expression) => new ViewChildrenMetadata( new ContentChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
this.getDecoratorParameter(moduleContext, expression, 0))); conversionMap.set(
conversionMap.set(this.getStaticType(core_metadata, 'ViewChild'), this.getStaticType(core_metadata, 'ViewChildren'),
(moduleContext, expression) => new ViewChildMetadata( (moduleContext, expression) =>
this.getDecoratorParameter(moduleContext, expression, 0))); new ViewChildrenMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
conversionMap.set(this.getStaticType(core_metadata, 'ViewQuery'), conversionMap.set(
(moduleContext, expression) => { this.getStaticType(core_metadata, 'ViewChild'),
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); (moduleContext, expression) =>
let p1 = this.getDecoratorParameter(moduleContext, expression, 1); new ViewChildMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
if (!isPresent(p1)) { conversionMap.set(
p1 = {}; this.getStaticType(core_metadata, 'ViewQuery'), (moduleContext, expression) => {
} let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
return new ViewQueryMetadata(p0, { let p1 = this.getDecoratorParameter(moduleContext, expression, 1);
descendants: p1['descendants'], if (!isPresent(p1)) {
first: p1['first'], p1 = {};
}); }
}); return new ViewQueryMetadata(p0, {
descendants: p1['descendants'],
first: p1['first'],
});
});
conversionMap.set(this.getStaticType(core_metadata, 'Pipe'), (moduleContext, expression) => { conversionMap.set(this.getStaticType(core_metadata, 'Pipe'), (moduleContext, expression) => {
let p0 = this.getDecoratorParameter(moduleContext, expression, 0); let p0 = this.getDecoratorParameter(moduleContext, expression, 0);
if (!isPresent(p0)) { if (!isPresent(p0)) {
@ -237,13 +220,15 @@ export class StaticReflector {
pure: p0['pure'], pure: p0['pure'],
}); });
}); });
conversionMap.set(this.getStaticType(core_metadata, 'HostBinding'), conversionMap.set(
(moduleContext, expression) => new HostBindingMetadata( this.getStaticType(core_metadata, 'HostBinding'),
this.getDecoratorParameter(moduleContext, expression, 0))); (moduleContext, expression) =>
conversionMap.set(this.getStaticType(core_metadata, 'HostListener'), new HostBindingMetadata(this.getDecoratorParameter(moduleContext, expression, 0)));
(moduleContext, expression) => new HostListenerMetadata( conversionMap.set(
this.getDecoratorParameter(moduleContext, expression, 0), this.getStaticType(core_metadata, 'HostListener'),
this.getDecoratorParameter(moduleContext, expression, 1))); (moduleContext, expression) => new HostListenerMetadata(
this.getDecoratorParameter(moduleContext, expression, 0),
this.getDecoratorParameter(moduleContext, expression, 1)));
return null; return null;
} }
@ -264,8 +249,8 @@ export class StaticReflector {
return null; return null;
} }
private getDecoratorParameter(moduleContext: string, expression: {[key: string]: any}, private getDecoratorParameter(
index: number): any { moduleContext: string, expression: {[key: string]: any}, index: number): any {
if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) && if (isMetadataSymbolicCallExpression(expression) && isPresent(expression['arguments']) &&
(<any[]>expression['arguments']).length <= index + 1) { (<any[]>expression['arguments']).length <= index + 1) {
return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]); return this.simplify(moduleContext, (<any[]>expression['arguments'])[index]);
@ -273,14 +258,14 @@ export class StaticReflector {
return null; return null;
} }
private getPropertyMetadata(moduleContext: string, private getPropertyMetadata(moduleContext: string, value: {[key: string]: any}):
value: {[key: string]: any}): {[key: string]: any} { {[key: string]: any} {
if (isPresent(value)) { if (isPresent(value)) {
let result = {}; let result = {};
StringMapWrapper.forEach(value, (value, name) => { StringMapWrapper.forEach(value, (value, name) => {
let data = this.getMemberData(moduleContext, value); let data = this.getMemberData(moduleContext, value);
if (isPresent(data)) { if (isPresent(data)) {
let propertyData = data.filter(d => d['kind'] == "property") let propertyData = data.filter(d => d['kind'] == 'property')
.map(d => d['directives']) .map(d => d['directives'])
.reduce((p, c) => (<any[]>p).concat(<any[]>c), []); .reduce((p, c) => (<any[]>p).concat(<any[]>c), []);
if (propertyData.length != 0) { if (propertyData.length != 0) {
@ -301,12 +286,11 @@ export class StaticReflector {
for (let item of member) { for (let item of member) {
result.push({ result.push({
kind: item['__symbolic'], kind: item['__symbolic'],
directives: directives: isPresent(item['decorators']) ?
isPresent(item['decorators']) ? (<any[]>item['decorators'])
(<any[]>item['decorators']) .map(decorator => this.convertKnownDecorator(moduleContext, decorator))
.map(decorator => this.convertKnownDecorator(moduleContext, decorator)) .filter(d => isPresent(d)) :
.filter(d => isPresent(d)) : null
null
}); });
} }
} }
@ -323,7 +307,7 @@ export class StaticReflector {
} }
if (isArray(expression)) { if (isArray(expression)) {
let result = []; let result = [];
for (let item of(<any>expression)) { for (let item of (<any>expression)) {
result.push(simplify(item)); result.push(simplify(item));
} }
return result; return result;
@ -331,7 +315,7 @@ export class StaticReflector {
if (isPresent(expression)) { if (isPresent(expression)) {
if (isPresent(expression['__symbolic'])) { if (isPresent(expression['__symbolic'])) {
switch (expression['__symbolic']) { switch (expression['__symbolic']) {
case "binop": case 'binop':
let left = simplify(expression['left']); let left = simplify(expression['left']);
let right = simplify(expression['right']); let right = simplify(expression['right']);
switch (expression['operator']) { switch (expression['operator']) {
@ -377,7 +361,7 @@ export class StaticReflector {
return left % right; return left % right;
} }
return null; return null;
case "pre": case 'pre':
let operand = simplify(expression['operand']); let operand = simplify(expression['operand']);
switch (expression['operator']) { switch (expression['operator']) {
case '+': case '+':
@ -390,17 +374,17 @@ export class StaticReflector {
return ~operand; return ~operand;
} }
return null; return null;
case "index": case 'index':
let indexTarget = simplify(expression['expression']); let indexTarget = simplify(expression['expression']);
let index = simplify(expression['index']); let index = simplify(expression['index']);
if (isPresent(indexTarget) && isPrimitive(index)) return indexTarget[index]; if (isPresent(indexTarget) && isPrimitive(index)) return indexTarget[index];
return null; return null;
case "select": case 'select':
let selectTarget = simplify(expression['expression']); let selectTarget = simplify(expression['expression']);
let member = simplify(expression['member']); let member = simplify(expression['member']);
if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member]; if (isPresent(selectTarget) && isPrimitive(member)) return selectTarget[member];
return null; return null;
case "reference": case 'reference':
let referenceModuleName = let referenceModuleName =
_this.normalizeModuleName(moduleContext, expression['module']); _this.normalizeModuleName(moduleContext, expression['module']);
let referenceModule = _this.getModuleMetadata(referenceModuleName); let referenceModule = _this.getModuleMetadata(referenceModuleName);
@ -410,7 +394,7 @@ export class StaticReflector {
return _this.getStaticType(referenceModuleName, expression['name']); return _this.getStaticType(referenceModuleName, expression['name']);
} }
return _this.simplify(referenceModuleName, referenceValue); return _this.simplify(referenceModuleName, referenceValue);
case "call": case 'call':
return null; return null;
} }
return null; return null;
@ -430,7 +414,7 @@ export class StaticReflector {
if (!isPresent(moduleMetadata)) { if (!isPresent(moduleMetadata)) {
moduleMetadata = this.host.getMetadataFor(module); moduleMetadata = this.host.getMetadataFor(module);
if (!isPresent(moduleMetadata)) { if (!isPresent(moduleMetadata)) {
moduleMetadata = {__symbolic: "module", module: module, metadata: {}}; moduleMetadata = {__symbolic: 'module', module: module, metadata: {}};
} }
this.metadataCache.set(module, moduleMetadata); this.metadataCache.set(module, moduleMetadata);
} }
@ -441,7 +425,7 @@ export class StaticReflector {
let moduleMetadata = this.getModuleMetadata(type.moduleId); let moduleMetadata = this.getModuleMetadata(type.moduleId);
let result = moduleMetadata['metadata'][type.name]; let result = moduleMetadata['metadata'][type.name];
if (!isPresent(result)) { if (!isPresent(result)) {
result = {__symbolic: "class"}; result = {__symbolic: 'class'};
} }
return result; return result;
} }
@ -460,7 +444,7 @@ function isMetadataSymbolicCallExpression(expression: any): boolean {
function isMetadataSymbolicReferenceExpression(expression: any): boolean { function isMetadataSymbolicReferenceExpression(expression: any): boolean {
return !isPrimitive(expression) && !isArray(expression) && return !isPrimitive(expression) && !isArray(expression) &&
expression['__symbolic'] == 'reference'; expression['__symbolic'] == 'reference';
} }
function isClassMetadata(expression: any): boolean { function isClassMetadata(expression: any): boolean {

View File

@ -7,12 +7,7 @@ import {PromiseWrapper} from 'angular2/src/facade/async';
import {ShadowCss} from 'angular2/src/compiler/shadow_css'; import {ShadowCss} from 'angular2/src/compiler/shadow_css';
import {UrlResolver} from 'angular2/src/compiler/url_resolver'; import {UrlResolver} from 'angular2/src/compiler/url_resolver';
import {extractStyleUrls} from './style_url_resolver'; import {extractStyleUrls} from './style_url_resolver';
import { import {escapeSingleQuoteString, codeGenExportVariable, codeGenToString, MODULE_SUFFIX} from './util';
escapeSingleQuoteString,
codeGenExportVariable,
codeGenToString,
MODULE_SUFFIX
} from './util';
import {Injectable} from 'angular2/src/core/di'; import {Injectable} from 'angular2/src/core/di';
const COMPONENT_VARIABLE = '%COMP%'; const COMPONENT_VARIABLE = '%COMP%';
@ -26,11 +21,11 @@ export class StyleCompiler {
constructor(private _xhr: XHR, private _urlResolver: UrlResolver) {} constructor(private _xhr: XHR, private _urlResolver: UrlResolver) {}
compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string | any[]>> { compileComponentRuntime(template: CompileTemplateMetadata): Promise<Array<string|any[]>> {
var styles = template.styles; var styles = template.styles;
var styleAbsUrls = template.styleUrls; var styleAbsUrls = template.styleUrls;
return this._loadStyles(styles, styleAbsUrls, return this._loadStyles(
template.encapsulation === ViewEncapsulation.Emulated); styles, styleAbsUrls, template.encapsulation === ViewEncapsulation.Emulated);
} }
compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression { compileComponentCodeGen(template: CompileTemplateMetadata): SourceExpression {
@ -44,30 +39,31 @@ export class StyleCompiler {
this._styleModule( this._styleModule(
stylesheetUrl, false, stylesheetUrl, false,
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)), this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, false)),
this._styleModule(stylesheetUrl, true, this._styleCodeGen([styleWithImports.style], this._styleModule(
styleWithImports.styleUrls, true)) stylesheetUrl, true,
this._styleCodeGen([styleWithImports.style], styleWithImports.styleUrls, true))
]; ];
} }
clearCache() { this._styleCache.clear(); } clearCache() { this._styleCache.clear(); }
private _loadStyles(plainStyles: string[], absUrls: string[], private _loadStyles(plainStyles: string[], absUrls: string[], encapsulate: boolean):
encapsulate: boolean): Promise<Array<string | any[]>> { Promise<Array<string|any[]>> {
var promises: Promise<string[]>[] = absUrls.map((absUrl: string): Promise<string[]> => { var promises: Promise<string[]>[] = absUrls.map((absUrl: string): Promise<string[]> => {
var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`; var cacheKey = `${absUrl}${encapsulate ? '.shim' : ''}`;
var result: Promise<string[]> = this._styleCache.get(cacheKey); var result: Promise<string[]> = this._styleCache.get(cacheKey);
if (isBlank(result)) { if (isBlank(result)) {
result = this._xhr.get(absUrl).then((style) => { result = this._xhr.get(absUrl).then((style) => {
var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style); var styleWithImports = extractStyleUrls(this._urlResolver, absUrl, style);
return this._loadStyles([styleWithImports.style], styleWithImports.styleUrls, return this._loadStyles(
encapsulate); [styleWithImports.style], styleWithImports.styleUrls, encapsulate);
}); });
this._styleCache.set(cacheKey, result); this._styleCache.set(cacheKey, result);
} }
return result; return result;
}); });
return PromiseWrapper.all<string[]>(promises).then((nestedStyles: string[][]) => { return PromiseWrapper.all<string[]>(promises).then((nestedStyles: string[][]) => {
var result: Array<string | any[]> = var result: Array<string|any[]> =
plainStyles.map(plainStyle => this._shimIfNeeded(plainStyle, encapsulate)); plainStyles.map(plainStyle => this._shimIfNeeded(plainStyle, encapsulate));
nestedStyles.forEach(styles => result.push(styles)); nestedStyles.forEach(styles => result.push(styles));
return result; return result;
@ -87,8 +83,8 @@ export class StyleCompiler {
return new SourceExpression([], expressionSource); return new SourceExpression([], expressionSource);
} }
private _styleModule(stylesheetUrl: string, shim: boolean, private _styleModule(stylesheetUrl: string, shim: boolean, expression: SourceExpression):
expression: SourceExpression): SourceModule { SourceModule {
var moduleSource = ` var moduleSource = `
${expression.declarations.join('\n')} ${expression.declarations.join('\n')}
${codeGenExportVariable('STYLES')}${expression.expression}; ${codeGenExportVariable('STYLES')}${expression.expression};

View File

@ -18,8 +18,8 @@ export function isStyleUrlResolvable(url: string): boolean {
* Rewrites stylesheets by resolving and removing the @import urls that * Rewrites stylesheets by resolving and removing the @import urls that
* are either relative or don't have a `package:` scheme * are either relative or don't have a `package:` scheme
*/ */
export function extractStyleUrls(resolver: UrlResolver, baseUrl: string, export function extractStyleUrls(
cssText: string): StyleWithImports { resolver: UrlResolver, baseUrl: string, cssText: string): StyleWithImports {
var foundUrls = []; var foundUrls = [];
var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => { var modifiedCssText = StringWrapper.replaceAllMapped(cssText, _cssImportRe, (m) => {
var url = isPresent(m[1]) ? m[1] : m[2]; var url = isPresent(m[1]) ? m[1] : m[2];

View File

@ -22,8 +22,8 @@ export interface TemplateAst {
* A segment of text within the template. * A segment of text within the template.
*/ */
export class TextAst implements TemplateAst { export class TextAst implements TemplateAst {
constructor(public value: string, public ngContentIndex: number, constructor(
public sourceSpan: ParseSourceSpan) {} public value: string, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); } visit(visitor: TemplateAstVisitor, context: any): any { return visitor.visitText(this, context); }
} }
@ -31,8 +31,8 @@ export class TextAst implements TemplateAst {
* A bound expression within the text of a template. * A bound expression within the text of a template.
*/ */
export class BoundTextAst implements TemplateAst { export class BoundTextAst implements TemplateAst {
constructor(public value: AST, public ngContentIndex: number, constructor(
public sourceSpan: ParseSourceSpan) {} public value: AST, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitBoundText(this, context); return visitor.visitBoundText(this, context);
} }
@ -50,8 +50,9 @@ export class AttrAst implements TemplateAst {
* A binding for an element property (e.g. `[property]="expression"`). * A binding for an element property (e.g. `[property]="expression"`).
*/ */
export class BoundElementPropertyAst implements TemplateAst { export class BoundElementPropertyAst implements TemplateAst {
constructor(public name: string, public type: PropertyBindingType, public value: AST, constructor(
public unit: string, public sourceSpan: ParseSourceSpan) {} public name: string, public type: PropertyBindingType, public value: AST, public unit: string,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElementProperty(this, context); return visitor.visitElementProperty(this, context);
} }
@ -61,8 +62,9 @@ export class BoundElementPropertyAst implements TemplateAst {
* A binding for an element event (e.g. `(event)="handler()"`). * A binding for an element event (e.g. `(event)="handler()"`).
*/ */
export class BoundEventAst implements TemplateAst { export class BoundEventAst implements TemplateAst {
constructor(public name: string, public target: string, public handler: AST, constructor(
public sourceSpan: ParseSourceSpan) {} public name: string, public target: string, public handler: AST,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitEvent(this, context); return visitor.visitEvent(this, context);
} }
@ -89,11 +91,11 @@ export class VariableAst implements TemplateAst {
* An element declaration in a template. * An element declaration in a template.
*/ */
export class ElementAst implements TemplateAst { export class ElementAst implements TemplateAst {
constructor(public name: string, public attrs: AttrAst[], constructor(
public inputs: BoundElementPropertyAst[], public outputs: BoundEventAst[], public name: string, public attrs: AttrAst[], public inputs: BoundElementPropertyAst[],
public exportAsVars: VariableAst[], public directives: DirectiveAst[], public outputs: BoundEventAst[], public exportAsVars: VariableAst[],
public children: TemplateAst[], public ngContentIndex: number, public directives: DirectiveAst[], public children: TemplateAst[],
public sourceSpan: ParseSourceSpan) {} public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitElement(this, context); return visitor.visitElement(this, context);
} }
@ -102,8 +104,9 @@ export class ElementAst implements TemplateAst {
* Whether the element has any active bindings (inputs, outputs, vars, or directives). * Whether the element has any active bindings (inputs, outputs, vars, or directives).
*/ */
isBound(): boolean { isBound(): boolean {
return (this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 || return (
this.directives.length > 0); this.inputs.length > 0 || this.outputs.length > 0 || this.exportAsVars.length > 0 ||
this.directives.length > 0);
} }
/** /**
@ -111,8 +114,8 @@ export class ElementAst implements TemplateAst {
*/ */
getComponent(): CompileDirectiveMetadata { getComponent(): CompileDirectiveMetadata {
return this.directives.length > 0 && this.directives[0].directive.isComponent ? return this.directives.length > 0 && this.directives[0].directive.isComponent ?
this.directives[0].directive : this.directives[0].directive :
null; null;
} }
} }
@ -120,9 +123,10 @@ export class ElementAst implements TemplateAst {
* A `<template>` element included in an Angular template. * A `<template>` element included in an Angular template.
*/ */
export class EmbeddedTemplateAst implements TemplateAst { export class EmbeddedTemplateAst implements TemplateAst {
constructor(public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[], constructor(
public directives: DirectiveAst[], public children: TemplateAst[], public attrs: AttrAst[], public outputs: BoundEventAst[], public vars: VariableAst[],
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {} public directives: DirectiveAst[], public children: TemplateAst[],
public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitEmbeddedTemplate(this, context); return visitor.visitEmbeddedTemplate(this, context);
} }
@ -132,8 +136,9 @@ export class EmbeddedTemplateAst implements TemplateAst {
* A directive property with a bound value (e.g. `*ngIf="condition"). * A directive property with a bound value (e.g. `*ngIf="condition").
*/ */
export class BoundDirectivePropertyAst implements TemplateAst { export class BoundDirectivePropertyAst implements TemplateAst {
constructor(public directiveName: string, public templateName: string, public value: AST, constructor(
public sourceSpan: ParseSourceSpan) {} public directiveName: string, public templateName: string, public value: AST,
public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitDirectiveProperty(this, context); return visitor.visitDirectiveProperty(this, context);
} }
@ -143,10 +148,10 @@ export class BoundDirectivePropertyAst implements TemplateAst {
* A directive declared on an element. * A directive declared on an element.
*/ */
export class DirectiveAst implements TemplateAst { export class DirectiveAst implements TemplateAst {
constructor(public directive: CompileDirectiveMetadata, constructor(
public inputs: BoundDirectivePropertyAst[], public directive: CompileDirectiveMetadata, public inputs: BoundDirectivePropertyAst[],
public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[], public hostProperties: BoundElementPropertyAst[], public hostEvents: BoundEventAst[],
public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {} public exportAsVars: VariableAst[], public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitDirective(this, context); return visitor.visitDirective(this, context);
} }
@ -156,8 +161,8 @@ export class DirectiveAst implements TemplateAst {
* Position where content is to be projected (instance of `<ng-content>` in a template). * Position where content is to be projected (instance of `<ng-content>` in a template).
*/ */
export class NgContentAst implements TemplateAst { export class NgContentAst implements TemplateAst {
constructor(public index: number, public ngContentIndex: number, constructor(
public sourceSpan: ParseSourceSpan) {} public index: number, public ngContentIndex: number, public sourceSpan: ParseSourceSpan) {}
visit(visitor: TemplateAstVisitor, context: any): any { visit(visitor: TemplateAstVisitor, context: any): any {
return visitor.visitNgContent(this, context); return visitor.visitNgContent(this, context);
} }
@ -209,8 +214,8 @@ export interface TemplateAstVisitor {
/** /**
* Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}. * Visit every node in a list of {@link TemplateAst}s with the given {@link TemplateAstVisitor}.
*/ */
export function templateVisitAll(visitor: TemplateAstVisitor, asts: TemplateAst[], export function templateVisitAll(
context: any = null): any[] { visitor: TemplateAstVisitor, asts: TemplateAst[], context: any = null): any[] {
var result = []; var result = [];
asts.forEach(ast => { asts.forEach(ast => {
var astResult = ast.visit(visitor, context); var astResult = ast.visit(visitor, context);

View File

@ -1,55 +1,15 @@
import { import {IS_DART, Type, Json, isBlank, isPresent, stringify, evalExpression} from 'angular2/src/facade/lang';
IS_DART,
Type,
Json,
isBlank,
isPresent,
stringify,
evalExpression
} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import { import {ListWrapper, SetWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
ListWrapper,
SetWrapper,
MapWrapper,
StringMapWrapper
} from 'angular2/src/facade/collection';
import {PromiseWrapper} from 'angular2/src/facade/async'; import {PromiseWrapper} from 'angular2/src/facade/async';
import { import {createHostComponentMeta, CompileDirectiveMetadata, CompileTypeMetadata, CompileTemplateMetadata, CompilePipeMetadata, CompileMetadataWithType} from './directive_metadata';
createHostComponentMeta, import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
CompileDirectiveMetadata,
CompileTypeMetadata,
CompileTemplateMetadata,
CompilePipeMetadata,
CompileMetadataWithType
} from './directive_metadata';
import {
TemplateAst,
TemplateAstVisitor,
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
BoundTextAst,
TextAst,
DirectiveAst,
BoundDirectivePropertyAst,
templateVisitAll
} from './template_ast';
import {Injectable} from 'angular2/src/core/di'; import {Injectable} from 'angular2/src/core/di';
import {SourceModule, moduleRef, SourceExpression} from './source_module'; import {SourceModule, moduleRef, SourceExpression} from './source_module';
import {ChangeDetectionCompiler, CHANGE_DETECTION_JIT_IMPORTS} from './change_detector_compiler'; import {ChangeDetectionCompiler, CHANGE_DETECTION_JIT_IMPORTS} from './change_detector_compiler';
import {StyleCompiler} from './style_compiler'; import {StyleCompiler} from './style_compiler';
import {ViewCompiler, VIEW_JIT_IMPORTS} from './view_compiler'; import {ViewCompiler, VIEW_JIT_IMPORTS} from './view_compiler';
import { import {ProtoViewCompiler, APP_VIEW_MODULE_REF, CompileProtoView, PROTO_VIEW_JIT_IMPORTS} from './proto_view_compiler';
ProtoViewCompiler,
APP_VIEW_MODULE_REF,
CompileProtoView,
PROTO_VIEW_JIT_IMPORTS
} from './proto_view_compiler';
import {TemplateParser, PipeCollector} from './template_parser'; import {TemplateParser, PipeCollector} from './template_parser';
import {TemplateNormalizer} from './template_normalizer'; import {TemplateNormalizer} from './template_normalizer';
import {RuntimeMetadataResolver} from './runtime_metadata'; import {RuntimeMetadataResolver} from './runtime_metadata';
@ -57,14 +17,7 @@ import {HostViewFactory} from 'angular2/src/core/linker/view';
import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection'; import {ChangeDetectorGenConfig} from 'angular2/src/core/change_detection/change_detection';
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache'; import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
import { import {codeGenExportVariable, escapeSingleQuoteString, codeGenValueFn, MODULE_SUFFIX, addAll, Expression} from './util';
codeGenExportVariable,
escapeSingleQuoteString,
codeGenValueFn,
MODULE_SUFFIX,
addAll,
Expression
} from './util';
export var METADATA_CACHE_MODULE_REF = export var METADATA_CACHE_MODULE_REF =
moduleRef('package:angular2/src/core/linker/resolved_metadata_cache' + MODULE_SUFFIX); moduleRef('package:angular2/src/core/linker/resolved_metadata_cache' + MODULE_SUFFIX);
@ -80,13 +33,13 @@ export class TemplateCompiler {
private _compiledTemplateCache = new Map<any, CompiledTemplate>(); private _compiledTemplateCache = new Map<any, CompiledTemplate>();
private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>(); private _compiledTemplateDone = new Map<any, Promise<CompiledTemplate>>();
constructor(private _runtimeMetadataResolver: RuntimeMetadataResolver, constructor(
private _templateNormalizer: TemplateNormalizer, private _runtimeMetadataResolver: RuntimeMetadataResolver,
private _templateParser: TemplateParser, private _styleCompiler: StyleCompiler, private _templateNormalizer: TemplateNormalizer, private _templateParser: TemplateParser,
private _cdCompiler: ChangeDetectionCompiler, private _styleCompiler: StyleCompiler, private _cdCompiler: ChangeDetectionCompiler,
private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler, private _protoViewCompiler: ProtoViewCompiler, private _viewCompiler: ViewCompiler,
private _resolvedMetadataCache: ResolvedMetadataCache, private _resolvedMetadataCache: ResolvedMetadataCache,
private _genConfig: ChangeDetectorGenConfig) {} private _genConfig: ChangeDetectorGenConfig) {}
normalizeDirectiveMetadata(directive: CompileDirectiveMetadata): normalizeDirectiveMetadata(directive: CompileDirectiveMetadata):
Promise<CompileDirectiveMetadata> { Promise<CompileDirectiveMetadata> {
@ -131,8 +84,9 @@ export class TemplateCompiler {
this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []); this._compileComponentRuntime(hostCacheKey, hostMeta, [compMeta], [], []);
} }
return this._compiledTemplateDone.get(hostCacheKey) return this._compiledTemplateDone.get(hostCacheKey)
.then((compiledTemplate: CompiledTemplate) => .then(
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory)); (compiledTemplate: CompiledTemplate) =>
new HostViewFactory(compMeta.selector, compiledTemplate.viewFactory));
} }
clearCache() { clearCache() {
@ -150,8 +104,8 @@ export class TemplateCompiler {
components.forEach(componentWithDirs => { components.forEach(componentWithDirs => {
var compMeta = <CompileDirectiveMetadata>componentWithDirs.component; var compMeta = <CompileDirectiveMetadata>componentWithDirs.component;
assertComponent(compMeta); assertComponent(compMeta);
this._compileComponentCodeGen(compMeta, componentWithDirs.directives, componentWithDirs.pipes, this._compileComponentCodeGen(
declarations); compMeta, componentWithDirs.directives, componentWithDirs.pipes, declarations);
if (compMeta.dynamicLoadable) { if (compMeta.dynamicLoadable) {
var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector); var hostMeta = createHostComponentMeta(compMeta.type, compMeta.selector);
var viewFactoryExpression = var viewFactoryExpression =
@ -173,10 +127,9 @@ export class TemplateCompiler {
private _compileComponentRuntime(cacheKey: any, compMeta: CompileDirectiveMetadata, private _compileComponentRuntime(
viewDirectives: CompileDirectiveMetadata[], cacheKey: any, compMeta: CompileDirectiveMetadata, viewDirectives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], pipes: CompilePipeMetadata[], compilingComponentsPath: any[]): CompiledTemplate {
compilingComponentsPath: any[]): CompiledTemplate {
let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives); let uniqViewDirectives = <CompileDirectiveMetadata[]>removeDuplicates(viewDirectives);
let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes); let uniqViewPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
var compiledTemplate = this._compiledTemplateCache.get(cacheKey); var compiledTemplate = this._compiledTemplateCache.get(cacheKey);
@ -184,38 +137,37 @@ export class TemplateCompiler {
if (isBlank(compiledTemplate)) { if (isBlank(compiledTemplate)) {
compiledTemplate = new CompiledTemplate(); compiledTemplate = new CompiledTemplate();
this._compiledTemplateCache.set(cacheKey, compiledTemplate); this._compiledTemplateCache.set(cacheKey, compiledTemplate);
done = PromiseWrapper done =
.all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat( PromiseWrapper
uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta)))) .all([<any>this._styleCompiler.compileComponentRuntime(compMeta.template)].concat(
.then((stylesAndNormalizedViewDirMetas: any[]) => { uniqViewDirectives.map(dirMeta => this.normalizeDirectiveMetadata(dirMeta))))
var normalizedViewDirMetas = stylesAndNormalizedViewDirMetas.slice(1); .then((stylesAndNormalizedViewDirMetas: any[]) => {
var styles = stylesAndNormalizedViewDirMetas[0]; var normalizedViewDirMetas = stylesAndNormalizedViewDirMetas.slice(1);
var parsedTemplate = this._templateParser.parse( var styles = stylesAndNormalizedViewDirMetas[0];
compMeta.template.template, normalizedViewDirMetas, uniqViewPipes, var parsedTemplate = this._templateParser.parse(
compMeta.type.name); compMeta.template.template, normalizedViewDirMetas, uniqViewPipes,
compMeta.type.name);
var childPromises = []; var childPromises = [];
var usedDirectives = DirectiveCollector.findUsedDirectives(parsedTemplate); var usedDirectives = DirectiveCollector.findUsedDirectives(parsedTemplate);
usedDirectives.components.forEach( usedDirectives.components.forEach(
component => this._compileNestedComponentRuntime( component => this._compileNestedComponentRuntime(
component, compilingComponentsPath, childPromises)); component, compilingComponentsPath, childPromises));
return PromiseWrapper.all(childPromises) return PromiseWrapper.all(childPromises).then((_) => {
.then((_) => { var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes);
var filteredPipes = filterPipes(parsedTemplate, uniqViewPipes); compiledTemplate.init(this._createViewFactoryRuntime(
compiledTemplate.init(this._createViewFactoryRuntime( compMeta, parsedTemplate, usedDirectives.directives, styles, filteredPipes));
compMeta, parsedTemplate, usedDirectives.directives, styles, return compiledTemplate;
filteredPipes)); });
return compiledTemplate; });
});
});
this._compiledTemplateDone.set(cacheKey, done); this._compiledTemplateDone.set(cacheKey, done);
} }
return compiledTemplate; return compiledTemplate;
} }
private _compileNestedComponentRuntime(childComponentDir: CompileDirectiveMetadata, private _compileNestedComponentRuntime(
parentCompilingComponentsPath: any[], childComponentDir: CompileDirectiveMetadata, parentCompilingComponentsPath: any[],
childPromises: Promise<any>[]) { childPromises: Promise<any>[]) {
var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath); var compilingComponentsPath = ListWrapper.clone(parentCompilingComponentsPath);
var childCacheKey = childComponentDir.type.runtime; var childCacheKey = childComponentDir.type.runtime;
@ -225,18 +177,19 @@ export class TemplateCompiler {
this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime); this._runtimeMetadataResolver.getViewPipesMetadata(childComponentDir.type.runtime);
var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey); var childIsRecursive = ListWrapper.contains(compilingComponentsPath, childCacheKey);
compilingComponentsPath.push(childCacheKey); compilingComponentsPath.push(childCacheKey);
this._compileComponentRuntime(childCacheKey, childComponentDir, childViewDirectives, this._compileComponentRuntime(
childViewPipes, compilingComponentsPath); childCacheKey, childComponentDir, childViewDirectives, childViewPipes,
compilingComponentsPath);
if (!childIsRecursive) { if (!childIsRecursive) {
// Only wait for a child if it is not a cycle // Only wait for a child if it is not a cycle
childPromises.push(this._compiledTemplateDone.get(childCacheKey)); childPromises.push(this._compiledTemplateDone.get(childCacheKey));
} }
} }
private _createViewFactoryRuntime(compMeta: CompileDirectiveMetadata, private _createViewFactoryRuntime(
parsedTemplate: TemplateAst[], compMeta: CompileDirectiveMetadata, parsedTemplate: TemplateAst[],
directives: CompileDirectiveMetadata[], styles: string[], directives: CompileDirectiveMetadata[], styles: string[],
pipes: CompilePipeMetadata[]): Function { pipes: CompilePipeMetadata[]): Function {
if (IS_DART || !this._genConfig.useJit) { if (IS_DART || !this._genConfig.useJit) {
var changeDetectorFactories = this._cdCompiler.compileComponentRuntime( var changeDetectorFactories = this._cdCompiler.compileComponentRuntime(
compMeta.type, compMeta.changeDetection, parsedTemplate); compMeta.type, compMeta.changeDetection, parsedTemplate);
@ -247,11 +200,14 @@ export class TemplateCompiler {
(compMeta) => this._getNestedComponentViewFactory(compMeta)); (compMeta) => this._getNestedComponentViewFactory(compMeta));
} else { } else {
var declarations = []; var declarations = [];
var viewFactoryExpr = this._createViewFactoryCodeGen('resolvedMetadataCache', compMeta, var viewFactoryExpr = this._createViewFactoryCodeGen(
new SourceExpression([], 'styles'), 'resolvedMetadataCache', compMeta, new SourceExpression([], 'styles'), parsedTemplate,
parsedTemplate, pipes, declarations); pipes, declarations);
var vars: {[key: string]: any} = var vars: {[key: string]: any} = {
{'exports': {}, 'styles': styles, 'resolvedMetadataCache': this._resolvedMetadataCache}; 'exports': {},
'styles': styles,
'resolvedMetadataCache': this._resolvedMetadataCache
};
directives.forEach(dirMeta => { directives.forEach(dirMeta => {
vars[dirMeta.type.name] = dirMeta.type.runtime; vars[dirMeta.type.name] = dirMeta.type.runtime;
if (dirMeta.isComponent && dirMeta.type.runtime !== compMeta.type.runtime) { if (dirMeta.isComponent && dirMeta.type.runtime !== compMeta.type.runtime) {
@ -272,25 +228,24 @@ export class TemplateCompiler {
return this._compiledTemplateCache.get(compMeta.type.runtime).viewFactory; return this._compiledTemplateCache.get(compMeta.type.runtime).viewFactory;
} }
private _compileComponentCodeGen(compMeta: CompileDirectiveMetadata, private _compileComponentCodeGen(
directives: CompileDirectiveMetadata[], compMeta: CompileDirectiveMetadata, directives: CompileDirectiveMetadata[],
pipes: CompilePipeMetadata[], pipes: CompilePipeMetadata[], targetDeclarations: string[]): string {
targetDeclarations: string[]): string {
let uniqueDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives); let uniqueDirectives = <CompileDirectiveMetadata[]>removeDuplicates(directives);
let uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes); let uniqPipes = <CompilePipeMetadata[]>removeDuplicates(pipes);
var styleExpr = this._styleCompiler.compileComponentCodeGen(compMeta.template); var styleExpr = this._styleCompiler.compileComponentCodeGen(compMeta.template);
var parsedTemplate = this._templateParser.parse(compMeta.template.template, uniqueDirectives, var parsedTemplate = this._templateParser.parse(
uniqPipes, compMeta.type.name); compMeta.template.template, uniqueDirectives, uniqPipes, compMeta.type.name);
var filteredPipes = filterPipes(parsedTemplate, uniqPipes); var filteredPipes = filterPipes(parsedTemplate, uniqPipes);
return this._createViewFactoryCodeGen( return this._createViewFactoryCodeGen(
`${METADATA_CACHE_MODULE_REF}CODEGEN_RESOLVED_METADATA_CACHE`, compMeta, styleExpr, `${METADATA_CACHE_MODULE_REF}CODEGEN_RESOLVED_METADATA_CACHE`, compMeta, styleExpr,
parsedTemplate, filteredPipes, targetDeclarations); parsedTemplate, filteredPipes, targetDeclarations);
} }
private _createViewFactoryCodeGen(resolvedMetadataCacheExpr: string, private _createViewFactoryCodeGen(
compMeta: CompileDirectiveMetadata, styleExpr: SourceExpression, resolvedMetadataCacheExpr: string, compMeta: CompileDirectiveMetadata,
parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[], styleExpr: SourceExpression, parsedTemplate: TemplateAst[], pipes: CompilePipeMetadata[],
targetDeclarations: string[]): string { targetDeclarations: string[]): string {
var changeDetectorsExprs = this._cdCompiler.compileComponentCodeGen( var changeDetectorsExprs = this._cdCompiler.compileComponentCodeGen(
compMeta.type, compMeta.changeDetection, parsedTemplate); compMeta.type, compMeta.changeDetection, parsedTemplate);
var protoViewExprs = this._protoViewCompiler.compileProtoViewCodeGen( var protoViewExprs = this._protoViewCompiler.compileProtoViewCodeGen(
@ -308,8 +263,9 @@ export class TemplateCompiler {
} }
export class NormalizedComponentWithViewDirectives { export class NormalizedComponentWithViewDirectives {
constructor(public component: CompileDirectiveMetadata, constructor(
public directives: CompileDirectiveMetadata[], public pipes: CompilePipeMetadata[]) {} public component: CompileDirectiveMetadata, public directives: CompileDirectiveMetadata[],
public pipes: CompilePipeMetadata[]) {}
} }
class CompiledTemplate { class CompiledTemplate {
@ -348,8 +304,9 @@ function removeDuplicates(items: CompileMetadataWithType[]): CompileMetadataWith
let res = []; let res = [];
items.forEach(item => { items.forEach(item => {
let hasMatch = let hasMatch =
res.filter(r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl && res.filter(
r.type.runtime == item.type.runtime) r => r.type.name == item.type.name && r.type.moduleUrl == item.type.moduleUrl &&
r.type.runtime == item.type.runtime)
.length > 0; .length > 0;
if (!hasMatch) { if (!hasMatch) {
res.push(item); res.push(item);
@ -401,8 +358,8 @@ class DirectiveCollector implements TemplateAstVisitor {
} }
function filterPipes(template: TemplateAst[], function filterPipes(
allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] { template: TemplateAst[], allPipes: CompilePipeMetadata[]): CompilePipeMetadata[] {
var visitor = new PipeVisitor(); var visitor = new PipeVisitor();
templateVisitAll(visitor, template); templateVisitAll(visitor, template);
return allPipes.filter((pipeMeta) => SetWrapper.has(visitor.collector.pipes, pipeMeta.name)); return allPipes.filter((pipeMeta) => SetWrapper.has(visitor.collector.pipes, pipeMeta.name));

View File

@ -1,8 +1,4 @@
import { import {CompileTypeMetadata, CompileDirectiveMetadata, CompileTemplateMetadata} from './directive_metadata';
CompileTypeMetadata,
CompileDirectiveMetadata,
CompileTemplateMetadata
} from './directive_metadata';
import {isPresent, isBlank} from 'angular2/src/facade/lang'; import {isPresent, isBlank} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {PromiseWrapper} from 'angular2/src/facade/async'; import {PromiseWrapper} from 'angular2/src/facade/async';
@ -14,41 +10,35 @@ import {Injectable} from 'angular2/src/core/di';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view'; import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import { import {HtmlAstVisitor, HtmlElementAst, HtmlTextAst, HtmlAttrAst, HtmlAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
HtmlAstVisitor,
HtmlElementAst,
HtmlTextAst,
HtmlAttrAst,
HtmlAst,
HtmlCommentAst,
htmlVisitAll
} from './html_ast';
import {HtmlParser} from './html_parser'; import {HtmlParser} from './html_parser';
import {preparseElement, PreparsedElement, PreparsedElementType} from './template_preparser'; import {preparseElement, PreparsedElement, PreparsedElementType} from './template_preparser';
@Injectable() @Injectable()
export class TemplateNormalizer { export class TemplateNormalizer {
constructor(private _xhr: XHR, private _urlResolver: UrlResolver, constructor(
private _htmlParser: HtmlParser) {} private _xhr: XHR, private _urlResolver: UrlResolver, private _htmlParser: HtmlParser) {}
normalizeTemplate(directiveType: CompileTypeMetadata, normalizeTemplate(directiveType: CompileTypeMetadata, template: CompileTemplateMetadata):
template: CompileTemplateMetadata): Promise<CompileTemplateMetadata> { Promise<CompileTemplateMetadata> {
if (isPresent(template.template)) { if (isPresent(template.template)) {
return PromiseWrapper.resolve(this.normalizeLoadedTemplate( return PromiseWrapper.resolve(this.normalizeLoadedTemplate(
directiveType, template, template.template, directiveType.moduleUrl)); directiveType, template, template.template, directiveType.moduleUrl));
} else if (isPresent(template.templateUrl)) { } else if (isPresent(template.templateUrl)) {
var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl); var sourceAbsUrl = this._urlResolver.resolve(directiveType.moduleUrl, template.templateUrl);
return this._xhr.get(sourceAbsUrl) return this._xhr.get(sourceAbsUrl)
.then(templateContent => this.normalizeLoadedTemplate(directiveType, template, .then(
templateContent, sourceAbsUrl)); templateContent => this.normalizeLoadedTemplate(
directiveType, template, templateContent, sourceAbsUrl));
} else { } else {
throw new BaseException(`No template specified for component ${directiveType.name}`); throw new BaseException(`No template specified for component ${directiveType.name}`);
} }
} }
normalizeLoadedTemplate(directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata, normalizeLoadedTemplate(
template: string, templateAbsUrl: string): CompileTemplateMetadata { directiveType: CompileTypeMetadata, templateMeta: CompileTemplateMetadata, template: string,
templateAbsUrl: string): CompileTemplateMetadata {
var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name); var rootNodesAndErrors = this._htmlParser.parse(template, directiveType.name);
if (rootNodesAndErrors.errors.length > 0) { if (rootNodesAndErrors.errors.length > 0) {
var errorString = rootNodesAndErrors.errors.join('\n'); var errorString = rootNodesAndErrors.errors.join('\n');

View File

@ -11,23 +11,7 @@ import {splitNsName, mergeNsAndName} from './html_tags';
import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util'; import {ParseSourceSpan, ParseError, ParseLocation} from './parse_util';
import {RecursiveAstVisitor, BindingPipe} from 'angular2/src/core/change_detection/parser/ast'; import {RecursiveAstVisitor, BindingPipe} from 'angular2/src/core/change_detection/parser/ast';
import { import {ElementAst, BoundElementPropertyAst, BoundEventAst, VariableAst, TemplateAst, TemplateAstVisitor, templateVisitAll, TextAst, BoundTextAst, EmbeddedTemplateAst, AttrAst, NgContentAst, PropertyBindingType, DirectiveAst, BoundDirectivePropertyAst} from './template_ast';
ElementAst,
BoundElementPropertyAst,
BoundEventAst,
VariableAst,
TemplateAst,
TemplateAstVisitor,
templateVisitAll,
TextAst,
BoundTextAst,
EmbeddedTemplateAst,
AttrAst,
NgContentAst,
PropertyBindingType,
DirectiveAst,
BoundDirectivePropertyAst
} from './template_ast';
import {CssSelector, SelectorMatcher} from 'angular2/src/compiler/selector'; import {CssSelector, SelectorMatcher} from 'angular2/src/compiler/selector';
import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry'; import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry';
@ -35,15 +19,7 @@ import {preparseElement, PreparsedElement, PreparsedElementType} from './templat
import {isStyleUrlResolvable} from './style_url_resolver'; import {isStyleUrlResolvable} from './style_url_resolver';
import { import {HtmlAstVisitor, HtmlAst, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from './html_ast';
HtmlAstVisitor,
HtmlAst,
HtmlElementAst,
HtmlAttrAst,
HtmlTextAst,
HtmlCommentAst,
htmlVisitAll
} from './html_ast';
import {splitAtColon} from './util'; import {splitAtColon} from './util';
@ -89,12 +65,14 @@ export class TemplateParseResult {
@Injectable() @Injectable()
export class TemplateParser { export class TemplateParser {
constructor(private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry, constructor(
private _htmlParser: HtmlParser, private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry,
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {} private _htmlParser: HtmlParser,
@Optional() @Inject(TEMPLATE_TRANSFORMS) public transforms: TemplateAstVisitor[]) {}
parse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[], parse(
templateUrl: string): TemplateAst[] { template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
templateUrl: string): TemplateAst[] {
var result = this.tryParse(template, directives, pipes, templateUrl); var result = this.tryParse(template, directives, pipes, templateUrl);
if (isPresent(result.errors)) { if (isPresent(result.errors)) {
var errorString = result.errors.join('\n'); var errorString = result.errors.join('\n');
@ -103,8 +81,9 @@ export class TemplateParser {
return result.templateAst; return result.templateAst;
} }
tryParse(template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[], tryParse(
templateUrl: string): TemplateParseResult { template: string, directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
templateUrl: string): TemplateParseResult {
var parseVisitor = var parseVisitor =
new TemplateParseVisitor(directives, pipes, this._exprParser, this._schemaRegistry); new TemplateParseVisitor(directives, pipes, this._exprParser, this._schemaRegistry);
var htmlAstWithErrors = this._htmlParser.parse(template, templateUrl); var htmlAstWithErrors = this._htmlParser.parse(template, templateUrl);
@ -128,15 +107,16 @@ class TemplateParseVisitor implements HtmlAstVisitor {
ngContentCount: number = 0; ngContentCount: number = 0;
pipesByName: Map<string, CompilePipeMetadata>; pipesByName: Map<string, CompilePipeMetadata>;
constructor(directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[], constructor(
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) { directives: CompileDirectiveMetadata[], pipes: CompilePipeMetadata[],
private _exprParser: Parser, private _schemaRegistry: ElementSchemaRegistry) {
this.selectorMatcher = new SelectorMatcher(); this.selectorMatcher = new SelectorMatcher();
ListWrapper.forEachWithIndex(directives, ListWrapper.forEachWithIndex(
(directive: CompileDirectiveMetadata, index: number) => { directives, (directive: CompileDirectiveMetadata, index: number) => {
var selector = CssSelector.parse(directive.selector); var selector = CssSelector.parse(directive.selector);
this.selectorMatcher.addSelectables(selector, directive); this.selectorMatcher.addSelectables(selector, directive);
this.directivesIndex.set(directive, index); this.directivesIndex.set(directive, index);
}); });
this.pipesByName = new Map<string, CompilePipeMetadata>(); this.pipesByName = new Map<string, CompilePipeMetadata>();
pipes.forEach(pipe => this.pipesByName.set(pipe.name, pipe)); pipes.forEach(pipe => this.pipesByName.set(pipe.name, pipe));
} }
@ -275,13 +255,14 @@ class TemplateParseVisitor implements HtmlAstVisitor {
elementOrDirectiveProps, isTemplateElement ? [] : vars, element.sourceSpan); elementOrDirectiveProps, isTemplateElement ? [] : vars, element.sourceSpan);
var elementProps: BoundElementPropertyAst[] = var elementProps: BoundElementPropertyAst[] =
this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directives); this._createElementPropertyAsts(element.name, elementOrDirectiveProps, directives);
var children = htmlVisitAll(preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, var children = htmlVisitAll(
element.children, Component.create(directives)); preparsedElement.nonBindable ? NON_BINDABLE_VISITOR : this, element.children,
Component.create(directives));
// Override the actual selector when the `ngProjectAs` attribute is provided // Override the actual selector when the `ngProjectAs` attribute is provided
var projectionSelector = isPresent(preparsedElement.projectAs) ? var projectionSelector = isPresent(preparsedElement.projectAs) ?
CssSelector.parse(preparsedElement.projectAs)[0] : CssSelector.parse(preparsedElement.projectAs)[0] :
elementCssSelector; elementCssSelector;
var ngContentIndex = component.findNgContentIndex(projectionSelector); var ngContentIndex = component.findNgContentIndex(projectionSelector);
var parsedElement; var parsedElement;
@ -296,21 +277,21 @@ class TemplateParseVisitor implements HtmlAstVisitor {
this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); this.ngContentCount++, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
} else if (isTemplateElement) { } else if (isTemplateElement) {
this._assertAllEventsPublishedByDirectives(directives, events); this._assertAllEventsPublishedByDirectives(directives, events);
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps, this._assertNoComponentsNorElementBindingsOnTemplate(
element.sourceSpan); directives, elementProps, element.sourceSpan);
parsedElement = parsedElement = new EmbeddedTemplateAst(
new EmbeddedTemplateAst(attrs, events, vars, directives, children, attrs, events, vars, directives, children, hasInlineTemplates ? null : ngContentIndex,
hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); element.sourceSpan);
} else { } else {
this._assertOnlyOneComponent(directives, element.sourceSpan); this._assertOnlyOneComponent(directives, element.sourceSpan);
var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0); var elementExportAsVars = vars.filter(varAst => varAst.value.length === 0);
let ngContentIndex = let ngContentIndex =
hasInlineTemplates ? null : component.findNgContentIndex(projectionSelector); hasInlineTemplates ? null : component.findNgContentIndex(projectionSelector);
parsedElement = parsedElement = new ElementAst(
new ElementAst(nodeName, attrs, elementProps, events, elementExportAsVars, directives, nodeName, attrs, elementProps, events, elementExportAsVars, directives, children,
children, hasInlineTemplates ? null : ngContentIndex, element.sourceSpan); hasInlineTemplates ? null : ngContentIndex, element.sourceSpan);
} }
if (hasInlineTemplates) { if (hasInlineTemplates) {
var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs); var templateCssSelector = createElementCssSelector(TEMPLATE_ELEMENT, templateMatchableAttrs);
@ -319,18 +300,19 @@ class TemplateParseVisitor implements HtmlAstVisitor {
templateElementOrDirectiveProps, [], element.sourceSpan); templateElementOrDirectiveProps, [], element.sourceSpan);
var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts( var templateElementProps: BoundElementPropertyAst[] = this._createElementPropertyAsts(
element.name, templateElementOrDirectiveProps, templateDirectives); element.name, templateElementOrDirectiveProps, templateDirectives);
this._assertNoComponentsNorElementBindingsOnTemplate(templateDirectives, templateElementProps, this._assertNoComponentsNorElementBindingsOnTemplate(
element.sourceSpan); templateDirectives, templateElementProps, element.sourceSpan);
parsedElement = new EmbeddedTemplateAst([], [], templateVars, templateDirectives, parsedElement = new EmbeddedTemplateAst(
[parsedElement], ngContentIndex, element.sourceSpan); [], [], templateVars, templateDirectives, [parsedElement], ngContentIndex,
element.sourceSpan);
} }
return parsedElement; return parsedElement;
} }
private _parseInlineTemplateBinding(attr: HtmlAttrAst, targetMatchableAttrs: string[][], private _parseInlineTemplateBinding(
targetProps: BoundElementOrDirectiveProperty[], attr: HtmlAttrAst, targetMatchableAttrs: string[][],
targetVars: VariableAst[]): boolean { targetProps: BoundElementOrDirectiveProperty[], targetVars: VariableAst[]): boolean {
var templateBindingsSource = null; var templateBindingsSource = null;
if (attr.name == TEMPLATE_ATTR) { if (attr.name == TEMPLATE_ATTR) {
templateBindingsSource = attr.value; templateBindingsSource = attr.value;
@ -346,8 +328,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan)); targetVars.push(new VariableAst(binding.key, binding.name, attr.sourceSpan));
targetMatchableAttrs.push([binding.key, binding.name]); targetMatchableAttrs.push([binding.key, binding.name]);
} else if (isPresent(binding.expression)) { } else if (isPresent(binding.expression)) {
this._parsePropertyAst(binding.key, binding.expression, attr.sourceSpan, this._parsePropertyAst(
targetMatchableAttrs, targetProps); binding.key, binding.expression, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else { } else {
targetMatchableAttrs.push([binding.key, '']); targetMatchableAttrs.push([binding.key, '']);
this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps); this._parseLiteralAttr(binding.key, null, attr.sourceSpan, targetProps);
@ -358,9 +340,10 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return false; return false;
} }
private _parseAttr(attr: HtmlAttrAst, targetMatchableAttrs: string[][], private _parseAttr(
targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[], attr: HtmlAttrAst, targetMatchableAttrs: string[][],
targetVars: VariableAst[]): boolean { targetProps: BoundElementOrDirectiveProperty[], targetEvents: BoundEventAst[],
targetVars: VariableAst[]): boolean {
var attrName = this._normalizeAttributeName(attr.name); var attrName = this._normalizeAttributeName(attr.name);
var attrValue = attr.value; var attrValue = attr.value;
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName); var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
@ -368,8 +351,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
if (isPresent(bindParts)) { if (isPresent(bindParts)) {
hasBinding = true; hasBinding = true;
if (isPresent(bindParts[1])) { // match: bind-prop if (isPresent(bindParts[1])) { // match: bind-prop
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseProperty(
targetProps); bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else if (isPresent( } else if (isPresent(
bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden" bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
@ -377,32 +360,32 @@ class TemplateParseVisitor implements HtmlAstVisitor {
this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars); this._parseVariable(identifier, attrValue, attr.sourceSpan, targetVars);
} else if (isPresent(bindParts[3])) { // match: on-event } else if (isPresent(bindParts[3])) { // match: on-event
this._parseEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseEvent(
targetEvents); bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[4])) { // match: bindon-prop } else if (isPresent(bindParts[4])) { // match: bindon-prop
this._parseProperty(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseProperty(
targetProps); bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
this._parseAssignmentEvent(bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseAssignmentEvent(
targetEvents); bindParts[5], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[6])) { // match: [(expr)] } else if (isPresent(bindParts[6])) { // match: [(expr)]
this._parseProperty(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseProperty(
targetProps); bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
this._parseAssignmentEvent(bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseAssignmentEvent(
targetEvents); bindParts[6], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} else if (isPresent(bindParts[7])) { // match: [expr] } else if (isPresent(bindParts[7])) { // match: [expr]
this._parseProperty(bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseProperty(
targetProps); bindParts[7], attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
} else if (isPresent(bindParts[8])) { // match: (event) } else if (isPresent(bindParts[8])) { // match: (event)
this._parseEvent(bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, this._parseEvent(
targetEvents); bindParts[8], attrValue, attr.sourceSpan, targetMatchableAttrs, targetEvents);
} }
} else { } else {
hasBinding = this._parsePropertyInterpolation(attrName, attrValue, attr.sourceSpan, hasBinding = this._parsePropertyInterpolation(
targetMatchableAttrs, targetProps); attrName, attrValue, attr.sourceSpan, targetMatchableAttrs, targetProps);
} }
if (!hasBinding) { if (!hasBinding) {
this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps); this._parseLiteralAttr(attrName, attrValue, attr.sourceSpan, targetProps);
@ -414,24 +397,25 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName; return attrName.toLowerCase().startsWith('data-') ? attrName.substring(5) : attrName;
} }
private _parseVariable(identifier: string, value: string, sourceSpan: ParseSourceSpan, private _parseVariable(
targetVars: VariableAst[]) { identifier: string, value: string, sourceSpan: ParseSourceSpan, targetVars: VariableAst[]) {
if (identifier.indexOf('-') > -1) { if (identifier.indexOf('-') > -1) {
this._reportError(`"-" is not allowed in variable names`, sourceSpan); this._reportError(`"-" is not allowed in variable names`, sourceSpan);
} }
targetVars.push(new VariableAst(identifier, value, sourceSpan)); targetVars.push(new VariableAst(identifier, value, sourceSpan));
} }
private _parseProperty(name: string, expression: string, sourceSpan: ParseSourceSpan, private _parseProperty(
targetMatchableAttrs: string[][], name: string, expression: string, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) { targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
this._parsePropertyAst(name, this._parseBinding(expression, sourceSpan), sourceSpan, this._parsePropertyAst(
targetMatchableAttrs, targetProps); name, this._parseBinding(expression, sourceSpan), sourceSpan, targetMatchableAttrs,
targetProps);
} }
private _parsePropertyInterpolation(name: string, value: string, sourceSpan: ParseSourceSpan, private _parsePropertyInterpolation(
targetMatchableAttrs: string[][], name: string, value: string, sourceSpan: ParseSourceSpan, targetMatchableAttrs: string[][],
targetProps: BoundElementOrDirectiveProperty[]): boolean { targetProps: BoundElementOrDirectiveProperty[]): boolean {
var expr = this._parseInterpolation(value, sourceSpan); var expr = this._parseInterpolation(value, sourceSpan);
if (isPresent(expr)) { if (isPresent(expr)) {
this._parsePropertyAst(name, expr, sourceSpan, targetMatchableAttrs, targetProps); this._parsePropertyAst(name, expr, sourceSpan, targetMatchableAttrs, targetProps);
@ -440,21 +424,23 @@ class TemplateParseVisitor implements HtmlAstVisitor {
return false; return false;
} }
private _parsePropertyAst(name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan, private _parsePropertyAst(
targetMatchableAttrs: string[][], name: string, ast: ASTWithSource, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) { targetMatchableAttrs: string[][], targetProps: BoundElementOrDirectiveProperty[]) {
targetMatchableAttrs.push([name, ast.source]); targetMatchableAttrs.push([name, ast.source]);
targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan)); targetProps.push(new BoundElementOrDirectiveProperty(name, ast, false, sourceSpan));
} }
private _parseAssignmentEvent(name: string, expression: string, sourceSpan: ParseSourceSpan, private _parseAssignmentEvent(
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) { name: string, expression: string, sourceSpan: ParseSourceSpan,
this._parseEvent(`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs, targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
targetEvents); this._parseEvent(
`${name}Change`, `${expression}=$event`, sourceSpan, targetMatchableAttrs, targetEvents);
} }
private _parseEvent(name: string, expression: string, sourceSpan: ParseSourceSpan, private _parseEvent(
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) { name: string, expression: string, sourceSpan: ParseSourceSpan,
targetMatchableAttrs: string[][], targetEvents: BoundEventAst[]) {
// long format: 'target: eventName' // long format: 'target: eventName'
var parts = splitAtColon(name, [null, name]); var parts = splitAtColon(name, [null, name]);
var target = parts[0]; var target = parts[0];
@ -466,46 +452,47 @@ class TemplateParseVisitor implements HtmlAstVisitor {
// so don't add the event name to the matchableAttrs // so don't add the event name to the matchableAttrs
} }
private _parseLiteralAttr(name: string, value: string, sourceSpan: ParseSourceSpan, private _parseLiteralAttr(
targetProps: BoundElementOrDirectiveProperty[]) { name: string, value: string, sourceSpan: ParseSourceSpan,
targetProps: BoundElementOrDirectiveProperty[]) {
targetProps.push(new BoundElementOrDirectiveProperty( targetProps.push(new BoundElementOrDirectiveProperty(
name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan)); name, this._exprParser.wrapLiteralPrimitive(value, ''), true, sourceSpan));
} }
private _parseDirectives(selectorMatcher: SelectorMatcher, private _parseDirectives(selectorMatcher: SelectorMatcher, elementCssSelector: CssSelector):
elementCssSelector: CssSelector): CompileDirectiveMetadata[] { CompileDirectiveMetadata[] {
var directives = []; var directives = [];
selectorMatcher.match(elementCssSelector, selectorMatcher.match(
(selector, directive) => { directives.push(directive); }); elementCssSelector, (selector, directive) => { directives.push(directive); });
// Need to sort the directives so that we get consistent results throughout, // Need to sort the directives so that we get consistent results throughout,
// as selectorMatcher uses Maps inside. // as selectorMatcher uses Maps inside.
// Also need to make components the first directive in the array // Also need to make components the first directive in the array
ListWrapper.sort(directives, ListWrapper.sort(
(dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => { directives, (dir1: CompileDirectiveMetadata, dir2: CompileDirectiveMetadata) => {
var dir1Comp = dir1.isComponent; var dir1Comp = dir1.isComponent;
var dir2Comp = dir2.isComponent; var dir2Comp = dir2.isComponent;
if (dir1Comp && !dir2Comp) { if (dir1Comp && !dir2Comp) {
return -1; return -1;
} else if (!dir1Comp && dir2Comp) { } else if (!dir1Comp && dir2Comp) {
return 1; return 1;
} else { } else {
return this.directivesIndex.get(dir1) - this.directivesIndex.get(dir2); return this.directivesIndex.get(dir1) - this.directivesIndex.get(dir2);
} }
}); });
return directives; return directives;
} }
private _createDirectiveAsts(elementName: string, directives: CompileDirectiveMetadata[], private _createDirectiveAsts(
props: BoundElementOrDirectiveProperty[], elementName: string, directives: CompileDirectiveMetadata[],
possibleExportAsVars: VariableAst[], props: BoundElementOrDirectiveProperty[], possibleExportAsVars: VariableAst[],
sourceSpan: ParseSourceSpan): DirectiveAst[] { sourceSpan: ParseSourceSpan): DirectiveAst[] {
var matchedVariables = new Set<string>(); var matchedVariables = new Set<string>();
var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => { var directiveAsts = directives.map((directive: CompileDirectiveMetadata) => {
var hostProperties: BoundElementPropertyAst[] = []; var hostProperties: BoundElementPropertyAst[] = [];
var hostEvents: BoundEventAst[] = []; var hostEvents: BoundEventAst[] = [];
var directiveProperties: BoundDirectivePropertyAst[] = []; var directiveProperties: BoundDirectivePropertyAst[] = [];
this._createDirectiveHostPropertyAsts(elementName, directive.hostProperties, sourceSpan, this._createDirectiveHostPropertyAsts(
hostProperties); elementName, directive.hostProperties, sourceSpan, hostProperties);
this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents); this._createDirectiveHostEventAsts(directive.hostListeners, sourceSpan, hostEvents);
this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties); this._createDirectivePropertyAsts(directive.inputs, props, directiveProperties);
var exportAsVars = []; var exportAsVars = [];
@ -516,21 +503,21 @@ class TemplateParseVisitor implements HtmlAstVisitor {
matchedVariables.add(varAst.name); matchedVariables.add(varAst.name);
} }
}); });
return new DirectiveAst(directive, directiveProperties, hostProperties, hostEvents, return new DirectiveAst(
exportAsVars, sourceSpan); directive, directiveProperties, hostProperties, hostEvents, exportAsVars, sourceSpan);
}); });
possibleExportAsVars.forEach((varAst) => { possibleExportAsVars.forEach((varAst) => {
if (varAst.value.length > 0 && !SetWrapper.has(matchedVariables, varAst.name)) { if (varAst.value.length > 0 && !SetWrapper.has(matchedVariables, varAst.name)) {
this._reportError(`There is no directive with "exportAs" set to "${varAst.value}"`, this._reportError(
varAst.sourceSpan); `There is no directive with "exportAs" set to "${varAst.value}"`, varAst.sourceSpan);
} }
}); });
return directiveAsts; return directiveAsts;
} }
private _createDirectiveHostPropertyAsts(elementName: string, hostProps: {[key: string]: string}, private _createDirectiveHostPropertyAsts(
sourceSpan: ParseSourceSpan, elementName: string, hostProps: {[key: string]: string}, sourceSpan: ParseSourceSpan,
targetPropertyAsts: BoundElementPropertyAst[]) { targetPropertyAsts: BoundElementPropertyAst[]) {
if (isPresent(hostProps)) { if (isPresent(hostProps)) {
StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => { StringMapWrapper.forEach(hostProps, (expression: string, propName: string) => {
var exprAst = this._parseBinding(expression, sourceSpan); var exprAst = this._parseBinding(expression, sourceSpan);
@ -540,9 +527,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
} }
} }
private _createDirectiveHostEventAsts(hostListeners: {[key: string]: string}, private _createDirectiveHostEventAsts(
sourceSpan: ParseSourceSpan, hostListeners: {[key: string]: string}, sourceSpan: ParseSourceSpan,
targetEventAsts: BoundEventAst[]) { targetEventAsts: BoundEventAst[]) {
if (isPresent(hostListeners)) { if (isPresent(hostListeners)) {
StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => { StringMapWrapper.forEach(hostListeners, (expression: string, propName: string) => {
this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts); this._parseEvent(propName, expression, sourceSpan, [], targetEventAsts);
@ -550,9 +537,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
} }
} }
private _createDirectivePropertyAsts(directiveProperties: {[key: string]: string}, private _createDirectivePropertyAsts(
boundProps: BoundElementOrDirectiveProperty[], directiveProperties: {[key: string]: string}, boundProps: BoundElementOrDirectiveProperty[],
targetBoundDirectiveProps: BoundDirectivePropertyAst[]) { targetBoundDirectiveProps: BoundDirectivePropertyAst[]) {
if (isPresent(directiveProperties)) { if (isPresent(directiveProperties)) {
var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>(); var boundPropsByName = new Map<string, BoundElementOrDirectiveProperty>();
boundProps.forEach(boundProp => { boundProps.forEach(boundProp => {
@ -575,8 +562,9 @@ class TemplateParseVisitor implements HtmlAstVisitor {
} }
} }
private _createElementPropertyAsts(elementName: string, props: BoundElementOrDirectiveProperty[], private _createElementPropertyAsts(
directives: DirectiveAst[]): BoundElementPropertyAst[] { elementName: string, props: BoundElementOrDirectiveProperty[],
directives: DirectiveAst[]): BoundElementPropertyAst[] {
var boundElementProps: BoundElementPropertyAst[] = []; var boundElementProps: BoundElementPropertyAst[] = [];
var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>(); var boundDirectivePropsIndex = new Map<string, BoundDirectivePropertyAst>();
directives.forEach((directive: DirectiveAst) => { directives.forEach((directive: DirectiveAst) => {
@ -586,15 +574,16 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}); });
props.forEach((prop: BoundElementOrDirectiveProperty) => { props.forEach((prop: BoundElementOrDirectiveProperty) => {
if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) { if (!prop.isLiteral && isBlank(boundDirectivePropsIndex.get(prop.name))) {
boundElementProps.push(this._createElementPropertyAst(elementName, prop.name, boundElementProps.push(this._createElementPropertyAst(
prop.expression, prop.sourceSpan)); elementName, prop.name, prop.expression, prop.sourceSpan));
} }
}); });
return boundElementProps; return boundElementProps;
} }
private _createElementPropertyAst(elementName: string, name: string, ast: AST, private _createElementPropertyAst(
sourceSpan: ParseSourceSpan): BoundElementPropertyAst { elementName: string, name: string, ast: AST,
sourceSpan: ParseSourceSpan): BoundElementPropertyAst {
var unit = null; var unit = null;
var bindingType; var bindingType;
var boundPropertyName; var boundPropertyName;
@ -652,13 +641,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
} }
} }
private _assertNoComponentsNorElementBindingsOnTemplate(directives: DirectiveAst[], private _assertNoComponentsNorElementBindingsOnTemplate(
elementProps: BoundElementPropertyAst[], directives: DirectiveAst[], elementProps: BoundElementPropertyAst[],
sourceSpan: ParseSourceSpan) { sourceSpan: ParseSourceSpan) {
var componentTypeNames: string[] = this._findComponentDirectiveNames(directives); var componentTypeNames: string[] = this._findComponentDirectiveNames(directives);
if (componentTypeNames.length > 0) { if (componentTypeNames.length > 0) {
this._reportError(`Components on an embedded template: ${componentTypeNames.join(',')}`, this._reportError(
sourceSpan); `Components on an embedded template: ${componentTypeNames.join(',')}`, sourceSpan);
} }
elementProps.forEach(prop => { elementProps.forEach(prop => {
this._reportError( this._reportError(
@ -667,12 +656,13 @@ class TemplateParseVisitor implements HtmlAstVisitor {
}); });
} }
private _assertAllEventsPublishedByDirectives(directives: DirectiveAst[], private _assertAllEventsPublishedByDirectives(
events: BoundEventAst[]) { directives: DirectiveAst[], events: BoundEventAst[]) {
var allDirectiveEvents = new Set<string>(); var allDirectiveEvents = new Set<string>();
directives.forEach(directive => { directives.forEach(directive => {
StringMapWrapper.forEach(directive.directive.outputs, StringMapWrapper.forEach(directive.directive.outputs, (eventName: string, _) => {
(eventName: string, _) => { allDirectiveEvents.add(eventName); }); allDirectiveEvents.add(eventName);
});
}); });
events.forEach(event => { events.forEach(event => {
if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) { if (isPresent(event.target) || !SetWrapper.has(allDirectiveEvents, event.name)) {
@ -700,8 +690,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
var selector = createElementCssSelector(ast.name, attrNameAndValues); var selector = createElementCssSelector(ast.name, attrNameAndValues);
var ngContentIndex = component.findNgContentIndex(selector); var ngContentIndex = component.findNgContentIndex(selector);
var children = htmlVisitAll(this, ast.children, EMPTY_COMPONENT); var children = htmlVisitAll(this, ast.children, EMPTY_COMPONENT);
return new ElementAst(ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children, return new ElementAst(
ngContentIndex, ast.sourceSpan); ast.name, htmlVisitAll(this, ast.attrs), [], [], [], [], children, ngContentIndex,
ast.sourceSpan);
} }
visitComment(ast: HtmlCommentAst, context: any): any { return null; } visitComment(ast: HtmlCommentAst, context: any): any { return null; }
visitAttr(ast: HtmlAttrAst, context: any): AttrAst { visitAttr(ast: HtmlAttrAst, context: any): AttrAst {
@ -714,8 +705,9 @@ class NonBindableVisitor implements HtmlAstVisitor {
} }
class BoundElementOrDirectiveProperty { class BoundElementOrDirectiveProperty {
constructor(public name: string, public expression: AST, public isLiteral: boolean, constructor(
public sourceSpan: ParseSourceSpan) {} public name: string, public expression: AST, public isLiteral: boolean,
public sourceSpan: ParseSourceSpan) {}
} }
export function splitClasses(classAttrValue: string): string[] { export function splitClasses(classAttrValue: string): string[] {
@ -740,8 +732,8 @@ class Component {
} }
return new Component(matcher, wildcardNgContentIndex); return new Component(matcher, wildcardNgContentIndex);
} }
constructor(public ngContentIndexMatcher: SelectorMatcher, constructor(
public wildcardNgContentIndex: number) {} public ngContentIndexMatcher: SelectorMatcher, public wildcardNgContentIndex: number) {}
findNgContentIndex(selector: CssSelector): number { findNgContentIndex(selector: CssSelector): number {
var ngContentIndices = []; var ngContentIndices = [];

View File

@ -59,8 +59,9 @@ export enum PreparsedElementType {
} }
export class PreparsedElement { export class PreparsedElement {
constructor(public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string, constructor(
public nonBindable: boolean, public projectAs: string) {} public type: PreparsedElementType, public selectAttr: string, public hrefAttr: string,
public nonBindable: boolean, public projectAs: string) {}
} }

View File

@ -1,11 +1,5 @@
import {Injectable, Inject} from 'angular2/src/core/di'; import {Injectable, Inject} from 'angular2/src/core/di';
import { import {StringWrapper, isPresent, isBlank, RegExpWrapper, normalizeBlank} from 'angular2/src/facade/lang';
StringWrapper,
isPresent,
isBlank,
RegExpWrapper,
normalizeBlank
} from 'angular2/src/facade/lang';
import {BaseException, WrappedException} from 'angular2/src/facade/exceptions'; import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
import {PACKAGE_ROOT_URL} from 'angular2/src/core/application_tokens'; import {PACKAGE_ROOT_URL} from 'angular2/src/core/application_tokens';
@ -21,7 +15,7 @@ export function createWithoutPackagePrefix(): UrlResolver {
/** /**
* A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'. * A default provider for {@link PACKAGE_ROOT_URL} that maps to '/'.
*/ */
export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: "/"}); export var DEFAULT_PACKAGE_URL_PROVIDER = new Provider(PACKAGE_ROOT_URL, {useValue: '/'});
/** /**
* Used by the {@link Compiler} when resolving HTML and CSS template URLs. * Used by the {@link Compiler} when resolving HTML and CSS template URLs.
@ -40,7 +34,7 @@ export class UrlResolver {
constructor(@Inject(PACKAGE_ROOT_URL) packagePrefix: string = null) { constructor(@Inject(PACKAGE_ROOT_URL) packagePrefix: string = null) {
if (isPresent(packagePrefix)) { if (isPresent(packagePrefix)) {
this._packagePrefix = StringWrapper.stripRight(packagePrefix, "/") + "/"; this._packagePrefix = StringWrapper.stripRight(packagePrefix, '/') + '/';
} }
} }
@ -61,8 +55,8 @@ export class UrlResolver {
if (isPresent(baseUrl) && baseUrl.length > 0) { if (isPresent(baseUrl) && baseUrl.length > 0) {
resolvedUrl = _resolveUrl(baseUrl, resolvedUrl); resolvedUrl = _resolveUrl(baseUrl, resolvedUrl);
} }
if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == "package") { if (isPresent(this._packagePrefix) && getUrlScheme(resolvedUrl) == 'package') {
resolvedUrl = resolvedUrl.replace("package:", this._packagePrefix); resolvedUrl = resolvedUrl.replace('package:', this._packagePrefix);
} }
return resolvedUrl; return resolvedUrl;
} }
@ -73,7 +67,7 @@ export class UrlResolver {
*/ */
export function getUrlScheme(url: string): string { export function getUrlScheme(url: string): string {
var match = _split(url); var match = _split(url);
return (match && match[_ComponentIndex.Scheme]) || ""; return (match && match[_ComponentIndex.Scheme]) || '';
} }
// The code below is adapted from Traceur: // The code below is adapted from Traceur:
@ -96,9 +90,9 @@ export function getUrlScheme(url: string): string {
* @param {?string=} opt_fragment The URI-encoded fragment identifier. * @param {?string=} opt_fragment The URI-encoded fragment identifier.
* @return {string} The fully combined URI. * @return {string} The fully combined URI.
*/ */
function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_domain?: string, function _buildFromEncodedParts(
opt_port?: string, opt_path?: string, opt_queryData?: string, opt_scheme?: string, opt_userInfo?: string, opt_domain?: string, opt_port?: string,
opt_fragment?: string): string { opt_path?: string, opt_queryData?: string, opt_fragment?: string): string {
var out = []; var out = [];
if (isPresent(opt_scheme)) { if (isPresent(opt_scheme)) {
@ -196,24 +190,24 @@ function _buildFromEncodedParts(opt_scheme?: string, opt_userInfo?: string, opt_
* @type {!RegExp} * @type {!RegExp}
* @internal * @internal
*/ */
var _splitRe = var _splitRe = RegExpWrapper.create(
RegExpWrapper.create('^' + '^' +
'(?:' + '(?:' +
'([^:/?#.]+)' + // scheme - ignore special characters '([^:/?#.]+)' + // scheme - ignore special characters
// used by other URL parts such as :, // used by other URL parts such as :,
// ?, /, #, and . // ?, /, #, and .
':)?' + ':)?' +
'(?://' + '(?://' +
'(?:([^/?#]*)@)?' + // userInfo '(?:([^/?#]*)@)?' + // userInfo
'([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters, '([\\w\\d\\-\\u0100-\\uffff.%]*)' + // domain - restrict to letters,
// digits, dashes, dots, percent // digits, dashes, dots, percent
// escapes, and unicode characters. // escapes, and unicode characters.
'(?::([0-9]+))?' + // port '(?::([0-9]+))?' + // port
')?' + ')?' +
'([^?#]+)?' + // path '([^?#]+)?' + // path
'(?:\\?([^#]*))?' + // query '(?:\\?([^#]*))?' + // query
'(?:#(.*))?' + // fragment '(?:#(.*))?' + // fragment
'$'); '$');
/** /**
* The index of each URI component in the return value of goog.uri.utils.split. * The index of each URI component in the return value of goog.uri.utils.split.
@ -244,7 +238,7 @@ enum _ComponentIndex {
* on the browser's regular expression implementation. Never null, since * on the browser's regular expression implementation. Never null, since
* arbitrary strings may still look like path names. * arbitrary strings may still look like path names.
*/ */
function _split(uri: string): Array<string | any> { function _split(uri: string): Array<string|any> {
return RegExpWrapper.firstMatch(_splitRe, uri); return RegExpWrapper.firstMatch(_splitRe, uri);
} }
@ -304,9 +298,10 @@ function _joinAndCanonicalizePath(parts: any[]): string {
path = isBlank(path) ? '' : _removeDotSegments(path); path = isBlank(path) ? '' : _removeDotSegments(path);
parts[_ComponentIndex.Path] = path; parts[_ComponentIndex.Path] = path;
return _buildFromEncodedParts(parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], return _buildFromEncodedParts(
parts[_ComponentIndex.Domain], parts[_ComponentIndex.Port], path, parts[_ComponentIndex.Scheme], parts[_ComponentIndex.UserInfo], parts[_ComponentIndex.Domain],
parts[_ComponentIndex.QueryData], parts[_ComponentIndex.Fragment]); parts[_ComponentIndex.Port], path, parts[_ComponentIndex.QueryData],
parts[_ComponentIndex.Fragment]);
} }
/** /**

View File

@ -1,11 +1,4 @@
import { import {IS_DART, StringWrapper, isBlank, isPresent, isString, isArray} from 'angular2/src/facade/lang';
IS_DART,
StringWrapper,
isBlank,
isPresent,
isString,
isArray
} from 'angular2/src/facade/lang';
var CAMEL_CASE_REGEXP = /([A-Z])/g; var CAMEL_CASE_REGEXP = /([A-Z])/g;
var DASH_CASE_REGEXP = /-([a-z])/g; var DASH_CASE_REGEXP = /-([a-z])/g;
@ -17,13 +10,13 @@ export var MODULE_SUFFIX = IS_DART ? '.dart' : '.js';
export var CONST_VAR = IS_DART ? 'const' : 'var'; export var CONST_VAR = IS_DART ? 'const' : 'var';
export function camelCaseToDashCase(input: string): string { export function camelCaseToDashCase(input: string): string {
return StringWrapper.replaceAllMapped(input, CAMEL_CASE_REGEXP, return StringWrapper.replaceAllMapped(
(m) => { return '-' + m[1].toLowerCase(); }); input, CAMEL_CASE_REGEXP, (m) => { return '-' + m[1].toLowerCase(); });
} }
export function dashCaseToCamelCase(input: string): string { export function dashCaseToCamelCase(input: string): string {
return StringWrapper.replaceAllMapped(input, DASH_CASE_REGEXP, return StringWrapper.replaceAllMapped(
(m) => { return m[1].toUpperCase(); }); input, DASH_CASE_REGEXP, (m) => { return m[1].toUpperCase(); });
} }
export function escapeSingleQuoteString(input: string): string { export function escapeSingleQuoteString(input: string): string {

View File

@ -1,65 +1,18 @@
import { import {isPresent, isBlank, Type, isString, StringWrapper, IS_DART, CONST_EXPR} from 'angular2/src/facade/lang';
isPresent,
isBlank,
Type,
isString,
StringWrapper,
IS_DART,
CONST_EXPR
} from 'angular2/src/facade/lang';
import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {SetWrapper, StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import { import {TemplateAst, TemplateAstVisitor, NgContentAst, EmbeddedTemplateAst, ElementAst, VariableAst, BoundEventAst, BoundElementPropertyAst, AttrAst, BoundTextAst, TextAst, DirectiveAst, BoundDirectivePropertyAst, templateVisitAll} from './template_ast';
TemplateAst,
TemplateAstVisitor,
NgContentAst,
EmbeddedTemplateAst,
ElementAst,
VariableAst,
BoundEventAst,
BoundElementPropertyAst,
AttrAst,
BoundTextAst,
TextAst,
DirectiveAst,
BoundDirectivePropertyAst,
templateVisitAll
} from './template_ast';
import {CompileTypeMetadata, CompileDirectiveMetadata} from './directive_metadata'; import {CompileTypeMetadata, CompileDirectiveMetadata} from './directive_metadata';
import {SourceExpressions, SourceExpression, moduleRef} from './source_module'; import {SourceExpressions, SourceExpression, moduleRef} from './source_module';
import { import {AppProtoView, AppView, flattenNestedViewRenderNodes, checkSlotCount} from 'angular2/src/core/linker/view';
AppProtoView,
AppView,
flattenNestedViewRenderNodes,
checkSlotCount
} from 'angular2/src/core/linker/view';
import {ViewType} from 'angular2/src/core/linker/view_type'; import {ViewType} from 'angular2/src/core/linker/view_type';
import {AppViewManager_} from 'angular2/src/core/linker/view_manager'; import {AppViewManager_} from 'angular2/src/core/linker/view_manager';
import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element'; import {AppProtoElement, AppElement} from 'angular2/src/core/linker/element';
import {Renderer, ParentRenderer} from 'angular2/src/core/render/api'; import {Renderer, ParentRenderer} from 'angular2/src/core/render/api';
import {ViewEncapsulation} from 'angular2/src/core/metadata/view'; import {ViewEncapsulation} from 'angular2/src/core/metadata/view';
import { import {escapeSingleQuoteString, codeGenConstConstructorCall, codeGenValueFn, codeGenFnHeader, MODULE_SUFFIX, Statement, escapeValue, codeGenArray, codeGenFlatArray, Expression, flattenArray, CONST_VAR} from './util';
escapeSingleQuoteString,
codeGenConstConstructorCall,
codeGenValueFn,
codeGenFnHeader,
MODULE_SUFFIX,
Statement,
escapeValue,
codeGenArray,
codeGenFlatArray,
Expression,
flattenArray,
CONST_VAR
} from './util';
import {ResolvedProvider, Injectable, Injector} from 'angular2/src/core/di'; import {ResolvedProvider, Injectable, Injector} from 'angular2/src/core/di';
import { import {APP_VIEW_MODULE_REF, APP_EL_MODULE_REF, METADATA_MODULE_REF, CompileProtoView, CompileProtoElement} from './proto_view_compiler';
APP_VIEW_MODULE_REF,
APP_EL_MODULE_REF,
METADATA_MODULE_REF,
CompileProtoView,
CompileProtoElement
} from './proto_view_compiler';
export const VIEW_JIT_IMPORTS = CONST_EXPR({ export const VIEW_JIT_IMPORTS = CONST_EXPR({
'AppView': AppView, 'AppView': AppView,
@ -73,74 +26,77 @@ export const VIEW_JIT_IMPORTS = CONST_EXPR({
export class ViewCompiler { export class ViewCompiler {
constructor() {} constructor() {}
compileComponentRuntime(component: CompileDirectiveMetadata, template: TemplateAst[], compileComponentRuntime(
styles: Array<string | any[]>, component: CompileDirectiveMetadata, template: TemplateAst[], styles: Array<string|any[]>,
protoViews: CompileProtoView<AppProtoView, AppProtoElement>[], protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
changeDetectorFactories: Function[], changeDetectorFactories: Function[], componentViewFactory: Function): Function {
componentViewFactory: Function): Function { var viewFactory = new RuntimeViewFactory(
var viewFactory = new RuntimeViewFactory(component, styles, protoViews, changeDetectorFactories, component, styles, protoViews, changeDetectorFactories, componentViewFactory);
componentViewFactory);
return viewFactory.createViewFactory(template, 0, []); return viewFactory.createViewFactory(template, 0, []);
} }
compileComponentCodeGen(component: CompileDirectiveMetadata, template: TemplateAst[], compileComponentCodeGen(
styles: SourceExpression, component: CompileDirectiveMetadata, template: TemplateAst[], styles: SourceExpression,
protoViews: CompileProtoView<Expression, Expression>[], protoViews: CompileProtoView<Expression, Expression>[],
changeDetectorFactoryExpressions: SourceExpressions, changeDetectorFactoryExpressions: SourceExpressions,
componentViewFactory: Function): SourceExpression { componentViewFactory: Function): SourceExpression {
var viewFactory = new CodeGenViewFactory( var viewFactory = new CodeGenViewFactory(
component, styles, protoViews, changeDetectorFactoryExpressions, componentViewFactory); component, styles, protoViews, changeDetectorFactoryExpressions, componentViewFactory);
var targetStatements: Statement[] = []; var targetStatements: Statement[] = [];
var viewFactoryExpression = viewFactory.createViewFactory(template, 0, targetStatements); var viewFactoryExpression = viewFactory.createViewFactory(template, 0, targetStatements);
return new SourceExpression(targetStatements.map(stmt => stmt.statement), return new SourceExpression(
viewFactoryExpression.expression); targetStatements.map(stmt => stmt.statement), viewFactoryExpression.expression);
} }
} }
interface ViewFactory<EXPRESSION, STATEMENT> { interface ViewFactory<EXPRESSION, STATEMENT> {
createText(renderer: EXPRESSION, parent: EXPRESSION, text: string, createText(renderer: EXPRESSION, parent: EXPRESSION, text: string, targetStatements: STATEMENT[]):
targetStatements: STATEMENT[]): EXPRESSION; EXPRESSION;
createElement(renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION, createElement(
targetStatements: STATEMENT[]): EXPRESSION; renderer: EXPRESSION, parent: EXPRESSION, name: string, rootSelector: EXPRESSION,
targetStatements: STATEMENT[]): EXPRESSION;
createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION, createTemplateAnchor(renderer: EXPRESSION, parent: EXPRESSION, targetStatements: STATEMENT[]):
targetStatements: STATEMENT[]): EXPRESSION; EXPRESSION;
createGlobalEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, createGlobalEventListener(
eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION; renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, eventAst: BoundEventAst,
targetStatements: STATEMENT[]): EXPRESSION;
createElementEventListener(renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, createElementEventListener(
renderNode: EXPRESSION, eventAst: BoundEventAst, renderer: EXPRESSION, view: EXPRESSION, boundElementIndex: number, renderNode: EXPRESSION,
targetStatements: STATEMENT[]): EXPRESSION; eventAst: BoundEventAst, targetStatements: STATEMENT[]): EXPRESSION;
setElementAttribute(renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string, setElementAttribute(
attrValue: string, targetStatements: STATEMENT[]); renderer: EXPRESSION, renderNode: EXPRESSION, attrName: string, attrValue: string,
targetStatements: STATEMENT[]);
createAppElement(appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION, createAppElement(
parentAppEl: EXPRESSION, embeddedViewFactory: EXPRESSION, appProtoEl: EXPRESSION, view: EXPRESSION, renderNode: EXPRESSION, parentAppEl: EXPRESSION,
targetStatements: STATEMENT[]): EXPRESSION; embeddedViewFactory: EXPRESSION, targetStatements: STATEMENT[]): EXPRESSION;
createAndSetComponentView(renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION, createAndSetComponentView(
appEl: EXPRESSION, component: CompileDirectiveMetadata, renderer: EXPRESSION, viewManager: EXPRESSION, view: EXPRESSION, appEl: EXPRESSION,
contentNodesByNgContentIndex: EXPRESSION[][], component: CompileDirectiveMetadata, contentNodesByNgContentIndex: EXPRESSION[][],
targetStatements: STATEMENT[]); targetStatements: STATEMENT[]);
getProjectedNodes(projectableNodes: EXPRESSION, ngContentIndex: number): EXPRESSION; getProjectedNodes(projectableNodes: EXPRESSION, ngContentIndex: number): EXPRESSION;
appendProjectedNodes(renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION, appendProjectedNodes(
targetStatements: STATEMENT[]); renderer: EXPRESSION, parent: EXPRESSION, nodes: EXPRESSION, targetStatements: STATEMENT[]);
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, createViewFactory(
targetStatements: STATEMENT[]): EXPRESSION; asts: TemplateAst[], embeddedTemplateIndex: number,
targetStatements: STATEMENT[]): EXPRESSION;
} }
class CodeGenViewFactory implements ViewFactory<Expression, Statement> { class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
private _nextVarId: number = 0; private _nextVarId: number = 0;
constructor(public component: CompileDirectiveMetadata, public styles: SourceExpression, constructor(
public protoViews: CompileProtoView<Expression, Expression>[], public component: CompileDirectiveMetadata, public styles: SourceExpression,
public changeDetectorExpressions: SourceExpressions, public protoViews: CompileProtoView<Expression, Expression>[],
public componentViewFactory: Function) {} public changeDetectorExpressions: SourceExpressions, public componentViewFactory: Function) {}
private _nextVar(prefix: string): string { private _nextVar(prefix: string): string {
return `${prefix}${this._nextVarId++}_${this.component.type.name}`; return `${prefix}${this._nextVarId++}_${this.component.type.name}`;
@ -154,8 +110,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return `disposable${this._nextVarId++}_${this.component.type.name}`; return `disposable${this._nextVarId++}_${this.component.type.name}`;
} }
createText(renderer: Expression, parent: Expression, text: string, createText(renderer: Expression, parent: Expression, text: string, targetStatements: Statement[]):
targetStatements: Statement[]): Expression { Expression {
var varName = this._nextRenderVar(); var varName = this._nextRenderVar();
var statement = var statement =
`var ${varName} = ${renderer.expression}.createText(${isPresent(parent) ? parent.expression : null}, ${escapeSingleQuoteString(text)});`; `var ${varName} = ${renderer.expression}.createText(${isPresent(parent) ? parent.expression : null}, ${escapeSingleQuoteString(text)});`;
@ -163,8 +119,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(varName); return new Expression(varName);
} }
createElement(renderer: Expression, parentRenderNode: Expression, name: string, createElement(
rootSelector: Expression, targetStatements: Statement[]): Expression { renderer: Expression, parentRenderNode: Expression, name: string, rootSelector: Expression,
targetStatements: Statement[]): Expression {
var varName = this._nextRenderVar(); var varName = this._nextRenderVar();
var valueExpr; var valueExpr;
if (isPresent(rootSelector)) { if (isPresent(rootSelector)) {
@ -180,8 +137,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(varName); return new Expression(varName);
} }
createTemplateAnchor(renderer: Expression, parentRenderNode: Expression, createTemplateAnchor(
targetStatements: Statement[]): Expression { renderer: Expression, parentRenderNode: Expression,
targetStatements: Statement[]): Expression {
var varName = this._nextRenderVar(); var varName = this._nextRenderVar();
var valueExpr = var valueExpr =
`${renderer.expression}.createTemplateAnchor(${isPresent(parentRenderNode) ? parentRenderNode.expression : null});`; `${renderer.expression}.createTemplateAnchor(${isPresent(parentRenderNode) ? parentRenderNode.expression : null});`;
@ -189,8 +147,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(varName); return new Expression(varName);
} }
createGlobalEventListener(renderer: Expression, appView: Expression, boundElementIndex: number, createGlobalEventListener(
eventAst: BoundEventAst, targetStatements: Statement[]): Expression { renderer: Expression, appView: Expression, boundElementIndex: number, eventAst: BoundEventAst,
targetStatements: Statement[]): Expression {
var disposableVar = this._nextDisposableVar(); var disposableVar = this._nextDisposableVar();
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName); var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
targetStatements.push(new Statement( targetStatements.push(new Statement(
@ -198,9 +157,9 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(disposableVar); return new Expression(disposableVar);
} }
createElementEventListener(renderer: Expression, appView: Expression, boundElementIndex: number, createElementEventListener(
renderNode: Expression, eventAst: BoundEventAst, renderer: Expression, appView: Expression, boundElementIndex: number, renderNode: Expression,
targetStatements: Statement[]): Expression { eventAst: BoundEventAst, targetStatements: Statement[]): Expression {
var disposableVar = this._nextDisposableVar(); var disposableVar = this._nextDisposableVar();
var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName); var eventHandlerExpr = codeGenEventHandler(appView, boundElementIndex, eventAst.fullName);
targetStatements.push(new Statement( targetStatements.push(new Statement(
@ -208,15 +167,16 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(disposableVar); return new Expression(disposableVar);
} }
setElementAttribute(renderer: Expression, renderNode: Expression, attrName: string, setElementAttribute(
attrValue: string, targetStatements: Statement[]) { renderer: Expression, renderNode: Expression, attrName: string, attrValue: string,
targetStatements: Statement[]) {
targetStatements.push(new Statement( targetStatements.push(new Statement(
`${renderer.expression}.setElementAttribute(${renderNode.expression}, ${escapeSingleQuoteString(attrName)}, ${escapeSingleQuoteString(attrValue)});`)); `${renderer.expression}.setElementAttribute(${renderNode.expression}, ${escapeSingleQuoteString(attrName)}, ${escapeSingleQuoteString(attrValue)});`));
} }
createAppElement(appProtoEl: Expression, appView: Expression, renderNode: Expression, createAppElement(
parentAppEl: Expression, embeddedViewFactory: Expression, appProtoEl: Expression, appView: Expression, renderNode: Expression, parentAppEl: Expression,
targetStatements: Statement[]): Expression { embeddedViewFactory: Expression, targetStatements: Statement[]): Expression {
var appVar = this._nextAppVar(); var appVar = this._nextAppVar();
var varValue = var varValue =
`new ${APP_EL_MODULE_REF}AppElement(${appProtoEl.expression}, ${appView.expression}, `new ${APP_EL_MODULE_REF}AppElement(${appProtoEl.expression}, ${appView.expression},
@ -225,10 +185,10 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(appVar); return new Expression(appVar);
} }
createAndSetComponentView(renderer: Expression, viewManager: Expression, view: Expression, createAndSetComponentView(
appEl: Expression, component: CompileDirectiveMetadata, renderer: Expression, viewManager: Expression, view: Expression, appEl: Expression,
contentNodesByNgContentIndex: Expression[][], component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Expression[][],
targetStatements: Statement[]) { targetStatements: Statement[]) {
var codeGenContentNodes; var codeGenContentNodes;
if (this.component.type.isHost) { if (this.component.type.isHost) {
codeGenContentNodes = `${view.expression}.projectableNodes`; codeGenContentNodes = `${view.expression}.projectableNodes`;
@ -244,14 +204,15 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
return new Expression(`${projectableNodes.expression}[${ngContentIndex}]`, true); return new Expression(`${projectableNodes.expression}[${ngContentIndex}]`, true);
} }
appendProjectedNodes(renderer: Expression, parent: Expression, nodes: Expression, appendProjectedNodes(
targetStatements: Statement[]) { renderer: Expression, parent: Expression, nodes: Expression, targetStatements: Statement[]) {
targetStatements.push(new Statement( targetStatements.push(new Statement(
`${renderer.expression}.projectNodes(${parent.expression}, ${APP_VIEW_MODULE_REF}flattenNestedViewRenderNodes(${nodes.expression}));`)); `${renderer.expression}.projectNodes(${parent.expression}, ${APP_VIEW_MODULE_REF}flattenNestedViewRenderNodes(${nodes.expression}));`));
} }
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, createViewFactory(
targetStatements: Statement[]): Expression { asts: TemplateAst[], embeddedTemplateIndex: number,
targetStatements: Statement[]): Expression {
var compileProtoView = this.protoViews[embeddedTemplateIndex]; var compileProtoView = this.protoViews[embeddedTemplateIndex];
var isHostView = this.component.type.isHost; var isHostView = this.component.type.isHost;
var isComponentView = embeddedTemplateIndex === 0 && !isHostView; var isComponentView = embeddedTemplateIndex === 0 && !isHostView;
@ -268,13 +229,8 @@ class CodeGenViewFactory implements ViewFactory<Expression, Statement> {
var viewFactoryName = codeGenViewFactoryName(this.component, embeddedTemplateIndex); var viewFactoryName = codeGenViewFactoryName(this.component, embeddedTemplateIndex);
var changeDetectorFactory = this.changeDetectorExpressions.expressions[embeddedTemplateIndex]; var changeDetectorFactory = this.changeDetectorExpressions.expressions[embeddedTemplateIndex];
var factoryArgs = [ var factoryArgs = [
'parentRenderer', 'parentRenderer', 'viewManager', 'containerEl', 'projectableNodes', 'rootSelector',
'viewManager', 'dynamicallyCreatedProviders', 'rootInjector'
'containerEl',
'projectableNodes',
'rootSelector',
'dynamicallyCreatedProviders',
'rootInjector'
]; ];
var initRendererStmts = []; var initRendererStmts = [];
var rendererExpr = `parentRenderer`; var rendererExpr = `parentRenderer`;
@ -316,16 +272,18 @@ ${codeGenFnHeader(factoryArgs, viewFactoryName)}{
} }
class RuntimeViewFactory implements ViewFactory<any, any> { class RuntimeViewFactory implements ViewFactory<any, any> {
constructor(public component: CompileDirectiveMetadata, public styles: Array<string | any[]>, constructor(
public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[], public component: CompileDirectiveMetadata, public styles: Array<string|any[]>,
public changeDetectorFactories: Function[], public componentViewFactory: Function) {} public protoViews: CompileProtoView<AppProtoView, AppProtoElement>[],
public changeDetectorFactories: Function[], public componentViewFactory: Function) {}
createText(renderer: Renderer, parent: any, text: string, targetStatements: any[]): any { createText(renderer: Renderer, parent: any, text: string, targetStatements: any[]): any {
return renderer.createText(parent, text); return renderer.createText(parent, text);
} }
createElement(renderer: Renderer, parent: any, name: string, rootSelector: string, createElement(
targetStatements: any[]): any { renderer: Renderer, parent: any, name: string, rootSelector: string,
targetStatements: any[]): any {
var el; var el;
if (isPresent(rootSelector)) { if (isPresent(rootSelector)) {
el = renderer.selectRootElement(rootSelector); el = renderer.selectRootElement(rootSelector);
@ -339,36 +297,38 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
return renderer.createTemplateAnchor(parent); return renderer.createTemplateAnchor(parent);
} }
createGlobalEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number, createGlobalEventListener(
eventAst: BoundEventAst, targetStatements: any[]): any { renderer: Renderer, appView: AppView, boundElementIndex: number, eventAst: BoundEventAst,
targetStatements: any[]): any {
return renderer.listenGlobal( return renderer.listenGlobal(
eventAst.target, eventAst.name, eventAst.target, eventAst.name,
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex)); (event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
} }
createElementEventListener(renderer: Renderer, appView: AppView, boundElementIndex: number, createElementEventListener(
renderNode: any, eventAst: BoundEventAst, renderer: Renderer, appView: AppView, boundElementIndex: number, renderNode: any,
targetStatements: any[]): any { eventAst: BoundEventAst, targetStatements: any[]): any {
return renderer.listen( return renderer.listen(
renderNode, eventAst.name, renderNode, eventAst.name,
(event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex)); (event) => appView.triggerEventHandlers(eventAst.fullName, event, boundElementIndex));
} }
setElementAttribute(renderer: Renderer, renderNode: any, attrName: string, attrValue: string, setElementAttribute(
targetStatements: any[]) { renderer: Renderer, renderNode: any, attrName: string, attrValue: string,
targetStatements: any[]) {
renderer.setElementAttribute(renderNode, attrName, attrValue); renderer.setElementAttribute(renderNode, attrName, attrValue);
} }
createAppElement(appProtoEl: AppProtoElement, appView: AppView, renderNode: any, createAppElement(
parentAppEl: AppElement, embeddedViewFactory: Function, appProtoEl: AppProtoElement, appView: AppView, renderNode: any, parentAppEl: AppElement,
targetStatements: any[]): any { embeddedViewFactory: Function, targetStatements: any[]): any {
return new AppElement(appProtoEl, appView, parentAppEl, renderNode, embeddedViewFactory); return new AppElement(appProtoEl, appView, parentAppEl, renderNode, embeddedViewFactory);
} }
createAndSetComponentView(renderer: Renderer, viewManager: AppViewManager_, appView: AppView, createAndSetComponentView(
appEl: AppElement, component: CompileDirectiveMetadata, renderer: Renderer, viewManager: AppViewManager_, appView: AppView, appEl: AppElement,
contentNodesByNgContentIndex: Array<Array<any | any[]>>, component: CompileDirectiveMetadata, contentNodesByNgContentIndex: Array<Array<any|any[]>>,
targetStatements: any[]) { targetStatements: any[]) {
var flattenedContentNodes; var flattenedContentNodes;
if (this.component.type.isHost) { if (this.component.type.isHost) {
flattenedContentNodes = appView.projectableNodes; flattenedContentNodes = appView.projectableNodes;
@ -389,8 +349,8 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
renderer.projectNodes(parent, flattenNestedViewRenderNodes(nodes)); renderer.projectNodes(parent, flattenNestedViewRenderNodes(nodes));
} }
createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, createViewFactory(asts: TemplateAst[], embeddedTemplateIndex: number, targetStatements: any[]):
targetStatements: any[]): Function { Function {
var compileProtoView = this.protoViews[embeddedTemplateIndex]; var compileProtoView = this.protoViews[embeddedTemplateIndex];
var isComponentView = compileProtoView.protoView.type === ViewType.COMPONENT; var isComponentView = compileProtoView.protoView.type === ViewType.COMPONENT;
var renderComponentType = null; var renderComponentType = null;
@ -398,8 +358,9 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
projectableNodes: any[][], rootSelector: string = null, projectableNodes: any[][], rootSelector: string = null,
dynamicallyCreatedProviders: ResolvedProvider[] = null, dynamicallyCreatedProviders: ResolvedProvider[] = null,
rootInjector: Injector = null) => { rootInjector: Injector = null) => {
checkSlotCount(this.component.type.name, this.component.template.ngContentSelectors.length, checkSlotCount(
projectableNodes); this.component.type.name, this.component.template.ngContentSelectors.length,
projectableNodes);
var renderer; var renderer;
if (embeddedTemplateIndex === 0) { if (embeddedTemplateIndex === 0) {
if (isBlank(renderComponentType)) { if (isBlank(renderComponentType)) {
@ -411,16 +372,17 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
renderer = <Renderer>parentRenderer; renderer = <Renderer>parentRenderer;
} }
var changeDetector = this.changeDetectorFactories[embeddedTemplateIndex](); var changeDetector = this.changeDetectorFactories[embeddedTemplateIndex]();
var view = var view = new AppView(
new AppView(compileProtoView.protoView, renderer, viewManager, projectableNodes, compileProtoView.protoView, renderer, viewManager, projectableNodes, containerEl,
containerEl, dynamicallyCreatedProviders, rootInjector, changeDetector); dynamicallyCreatedProviders, rootInjector, changeDetector);
var visitor = new ViewBuilderVisitor<any, any>( var visitor = new ViewBuilderVisitor<any, any>(
renderer, viewManager, projectableNodes, rootSelector, view, compileProtoView, [], this); renderer, viewManager, projectableNodes, rootSelector, view, compileProtoView, [], this);
var parentRenderNode = var parentRenderNode =
isComponentView ? renderer.createViewRoot(containerEl.nativeElement) : null; isComponentView ? renderer.createViewRoot(containerEl.nativeElement) : null;
templateVisitAll(visitor, asts, new ParentElement(parentRenderNode, null, null)); templateVisitAll(visitor, asts, new ParentElement(parentRenderNode, null, null));
view.init(flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes, view.init(
visitor.appDisposables, visitor.appElements); flattenArray(visitor.rootNodesOrAppElements, []), visitor.renderNodes,
visitor.appDisposables, visitor.appElements);
return view; return view;
}; };
} }
@ -429,8 +391,9 @@ class RuntimeViewFactory implements ViewFactory<any, any> {
class ParentElement<EXPRESSION> { class ParentElement<EXPRESSION> {
public contentNodesByNgContentIndex: Array<EXPRESSION>[]; public contentNodesByNgContentIndex: Array<EXPRESSION>[];
constructor(public renderNode: EXPRESSION, public appEl: EXPRESSION, constructor(
public component: CompileDirectiveMetadata) { public renderNode: EXPRESSION, public appEl: EXPRESSION,
public component: CompileDirectiveMetadata) {
if (isPresent(component)) { if (isPresent(component)) {
this.contentNodesByNgContentIndex = this.contentNodesByNgContentIndex =
ListWrapper.createFixedSize(component.template.ngContentSelectors.length); ListWrapper.createFixedSize(component.template.ngContentSelectors.length);
@ -458,14 +421,15 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
elementCount: number = 0; elementCount: number = 0;
constructor(public renderer: EXPRESSION, public viewManager: EXPRESSION, constructor(
public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION, public renderer: EXPRESSION, public viewManager: EXPRESSION,
public view: EXPRESSION, public protoView: CompileProtoView<EXPRESSION, EXPRESSION>, public projectableNodes: EXPRESSION, public rootSelector: EXPRESSION, public view: EXPRESSION,
public targetStatements: STATEMENT[], public protoView: CompileProtoView<EXPRESSION, EXPRESSION>,
public factory: ViewFactory<EXPRESSION, STATEMENT>) {} public targetStatements: STATEMENT[], public factory: ViewFactory<EXPRESSION, STATEMENT>) {}
private _addRenderNode(renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number, private _addRenderNode(
parent: ParentElement<EXPRESSION>) { renderNode: EXPRESSION, appEl: EXPRESSION, ngContentIndex: number,
parent: ParentElement<EXPRESSION>) {
this.renderNodes.push(renderNode); this.renderNodes.push(renderNode);
if (isPresent(parent.component)) { if (isPresent(parent.component)) {
if (isPresent(ngContentIndex)) { if (isPresent(ngContentIndex)) {
@ -476,12 +440,12 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
} }
} }
private _getParentRenderNode(ngContentIndex: number, private _getParentRenderNode(ngContentIndex: number, parent: ParentElement<EXPRESSION>):
parent: ParentElement<EXPRESSION>): EXPRESSION { EXPRESSION {
return isPresent(parent.component) && return isPresent(parent.component) &&
parent.component.template.encapsulation !== ViewEncapsulation.Native ? parent.component.template.encapsulation !== ViewEncapsulation.Native ?
null : null :
parent.renderNode; parent.renderNode;
} }
visitBoundText(ast: BoundTextAst, parent: ParentElement<EXPRESSION>): any { visitBoundText(ast: BoundTextAst, parent: ParentElement<EXPRESSION>): any {
@ -505,8 +469,8 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
} }
} else { } else {
if (isPresent(parent.renderNode)) { if (isPresent(parent.renderNode)) {
this.factory.appendProjectedNodes(this.renderer, parent.renderNode, nodesExpression, this.factory.appendProjectedNodes(
this.renderStmts); this.renderer, parent.renderNode, nodesExpression, this.renderStmts);
} else { } else {
this.rootNodesOrAppElements.push(nodesExpression); this.rootNodesOrAppElements.push(nodesExpression);
} }
@ -529,22 +493,22 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
disposable = this.factory.createGlobalEventListener( disposable = this.factory.createGlobalEventListener(
this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts); this.renderer, this.view, protoEl.boundElementIndex, eventAst, this.renderStmts);
} else { } else {
disposable = this.factory.createElementEventListener(this.renderer, this.view, disposable = this.factory.createElementEventListener(
protoEl.boundElementIndex, renderNode, this.renderer, this.view, protoEl.boundElementIndex, renderNode, eventAst,
eventAst, this.renderStmts); this.renderStmts);
} }
this.appDisposables.push(disposable); this.appDisposables.push(disposable);
}); });
for (var i = 0; i < protoEl.attrNameAndValues.length; i++) { for (var i = 0; i < protoEl.attrNameAndValues.length; i++) {
var attrName = protoEl.attrNameAndValues[i][0]; var attrName = protoEl.attrNameAndValues[i][0];
var attrValue = protoEl.attrNameAndValues[i][1]; var attrValue = protoEl.attrNameAndValues[i][1];
this.factory.setElementAttribute(this.renderer, renderNode, attrName, attrValue, this.factory.setElementAttribute(
this.renderStmts); this.renderer, renderNode, attrName, attrValue, this.renderStmts);
} }
var appEl = null; var appEl = null;
if (isPresent(protoEl.appProtoEl)) { if (isPresent(protoEl.appProtoEl)) {
appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode, parent.appEl, appEl = this.factory.createAppElement(
null, this.appStmts); protoEl.appProtoEl, this.view, renderNode, parent.appEl, null, this.appStmts);
this.appElements.push(appEl); this.appElements.push(appEl);
} }
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent); this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
@ -553,9 +517,9 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
renderNode, isPresent(appEl) ? appEl : parent.appEl, component); renderNode, isPresent(appEl) ? appEl : parent.appEl, component);
templateVisitAll(this, ast.children, newParent); templateVisitAll(this, ast.children, newParent);
if (isPresent(appEl) && isPresent(component)) { if (isPresent(appEl) && isPresent(component)) {
this.factory.createAndSetComponentView(this.renderer, this.viewManager, this.view, appEl, this.factory.createAndSetComponentView(
component, newParent.contentNodesByNgContentIndex, this.renderer, this.viewManager, this.view, appEl, component,
this.appStmts); newParent.contentNodesByNgContentIndex, this.appStmts);
} }
return null; return null;
} }
@ -569,8 +533,9 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
var embeddedViewFactory = this.factory.createViewFactory( var embeddedViewFactory = this.factory.createViewFactory(
ast.children, protoEl.embeddedTemplateIndex, this.targetStatements); ast.children, protoEl.embeddedTemplateIndex, this.targetStatements);
var appEl = this.factory.createAppElement(protoEl.appProtoEl, this.view, renderNode, var appEl = this.factory.createAppElement(
parent.appEl, embeddedViewFactory, this.appStmts); protoEl.appProtoEl, this.view, renderNode, parent.appEl, embeddedViewFactory,
this.appStmts);
this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent); this._addRenderNode(renderNode, appEl, ast.ngContentIndex, parent);
this.appElements.push(appEl); this.appElements.push(appEl);
return null; return null;
@ -585,15 +550,15 @@ class ViewBuilderVisitor<EXPRESSION, STATEMENT> implements TemplateAstVisitor {
} }
function codeGenEventHandler(view: Expression, boundElementIndex: number, function codeGenEventHandler(
eventName: string): string { view: Expression, boundElementIndex: number, eventName: string): string {
return codeGenValueFn( return codeGenValueFn(
['event'], ['event'],
`${view.expression}.triggerEventHandlers(${escapeValue(eventName)}, event, ${boundElementIndex})`); `${view.expression}.triggerEventHandlers(${escapeValue(eventName)}, event, ${boundElementIndex})`);
} }
function codeGenViewFactoryName(component: CompileDirectiveMetadata, function codeGenViewFactoryName(
embeddedTemplateIndex: number): string { component: CompileDirectiveMetadata, embeddedTemplateIndex: number): string {
return `viewFactory_${component.type.name}${embeddedTemplateIndex}`; return `viewFactory_${component.type.name}${embeddedTemplateIndex}`;
} }

View File

@ -1,40 +1,26 @@
import {Type, CONST_EXPR} from 'angular2/src/facade/lang'; import {Type, CONST_EXPR} from 'angular2/src/facade/lang';
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di'; import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
import { import {APP_COMPONENT_REF_PROMISE, APP_COMPONENT, APP_ID_RANDOM_PROVIDER} from './application_tokens';
APP_COMPONENT_REF_PROMISE, import {IterableDiffers, defaultIterableDiffers, KeyValueDiffers, defaultKeyValueDiffers} from './change_detection/change_detection';
APP_COMPONENT,
APP_ID_RANDOM_PROVIDER
} from './application_tokens';
import {
IterableDiffers,
defaultIterableDiffers,
KeyValueDiffers,
defaultKeyValueDiffers
} from './change_detection/change_detection';
import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache'; import {ResolvedMetadataCache} from 'angular2/src/core/linker/resolved_metadata_cache';
import {AppViewManager} from './linker/view_manager'; import {AppViewManager} from './linker/view_manager';
import {AppViewManager_} from "./linker/view_manager"; import {AppViewManager_} from './linker/view_manager';
import {ViewResolver} from './linker/view_resolver'; import {ViewResolver} from './linker/view_resolver';
import {DirectiveResolver} from './linker/directive_resolver'; import {DirectiveResolver} from './linker/directive_resolver';
import {PipeResolver} from './linker/pipe_resolver'; import {PipeResolver} from './linker/pipe_resolver';
import {Compiler} from './linker/compiler'; import {Compiler} from './linker/compiler';
import {Compiler_} from "./linker/compiler"; import {Compiler_} from './linker/compiler';
import {DynamicComponentLoader} from './linker/dynamic_component_loader'; import {DynamicComponentLoader} from './linker/dynamic_component_loader';
import {DynamicComponentLoader_} from "./linker/dynamic_component_loader"; import {DynamicComponentLoader_} from './linker/dynamic_component_loader';
/** /**
* A default set of providers which should be included in any Angular * A default set of providers which should be included in any Angular
* application, regardless of the platform it runs onto. * application, regardless of the platform it runs onto.
*/ */
export const APPLICATION_COMMON_PROVIDERS: Array<Type | Provider | any[]> = CONST_EXPR([ export const APPLICATION_COMMON_PROVIDERS: Array<Type|Provider|any[]> = CONST_EXPR([
new Provider(Compiler, {useClass: Compiler_}), new Provider(Compiler, {useClass: Compiler_}), APP_ID_RANDOM_PROVIDER, ResolvedMetadataCache,
APP_ID_RANDOM_PROVIDER, new Provider(AppViewManager, {useClass: AppViewManager_}), ViewResolver,
ResolvedMetadataCache,
new Provider(AppViewManager, {useClass: AppViewManager_}),
ViewResolver,
new Provider(IterableDiffers, {useValue: defaultIterableDiffers}), new Provider(IterableDiffers, {useValue: defaultIterableDiffers}),
new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}), new Provider(KeyValueDiffers, {useValue: defaultKeyValueDiffers}), DirectiveResolver,
DirectiveResolver, PipeResolver, new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
PipeResolver,
new Provider(DynamicComponentLoader, {useClass: DynamicComponentLoader_})
]); ]);

View File

@ -1,33 +1,12 @@
import {NgZone, NgZoneError} from 'angular2/src/core/zone/ng_zone'; import {NgZone, NgZoneError} from 'angular2/src/core/zone/ng_zone';
import { import {Type, isBlank, isPresent, assertionsEnabled, print, IS_DART} from 'angular2/src/facade/lang';
Type,
isBlank,
isPresent,
assertionsEnabled,
print,
IS_DART
} from 'angular2/src/facade/lang';
import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di'; import {provide, Provider, Injector, OpaqueToken} from 'angular2/src/core/di';
import { import {APP_COMPONENT_REF_PROMISE, APP_COMPONENT, APP_ID_RANDOM_PROVIDER, PLATFORM_INITIALIZER, APP_INITIALIZER} from './application_tokens';
APP_COMPONENT_REF_PROMISE,
APP_COMPONENT,
APP_ID_RANDOM_PROVIDER,
PLATFORM_INITIALIZER,
APP_INITIALIZER
} from './application_tokens';
import {PromiseWrapper, PromiseCompleter, ObservableWrapper} from 'angular2/src/facade/async'; import {PromiseWrapper, PromiseCompleter, ObservableWrapper} from 'angular2/src/facade/async';
import {ListWrapper} from 'angular2/src/facade/collection'; import {ListWrapper} from 'angular2/src/facade/collection';
import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability'; import {TestabilityRegistry, Testability} from 'angular2/src/core/testability/testability';
import { import {ComponentRef, DynamicComponentLoader} from 'angular2/src/core/linker/dynamic_component_loader';
ComponentRef, import {BaseException, WrappedException, ExceptionHandler, unimplemented} from 'angular2/src/facade/exceptions';
DynamicComponentLoader
} from 'angular2/src/core/linker/dynamic_component_loader';
import {
BaseException,
WrappedException,
ExceptionHandler,
unimplemented
} from 'angular2/src/facade/exceptions';
import {Console} from 'angular2/src/core/console'; import {Console} from 'angular2/src/core/console';
import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile'; import {wtfLeave, wtfCreateScope, WtfScopeFn} from './profile/profile';
import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref'; import {ChangeDetectorRef} from 'angular2/src/core/change_detection/change_detector_ref';
@ -37,35 +16,33 @@ import {ElementRef_} from 'angular2/src/core/linker/element_ref';
/** /**
* Construct providers specific to an individual root component. * Construct providers specific to an individual root component.
*/ */
function _componentProviders(appComponentType: Type): Array<Type | Provider | any[]> { function _componentProviders(appComponentType: Type): Array<Type|Provider|any[]> {
return [ return [
provide(APP_COMPONENT, {useValue: appComponentType}), provide(APP_COMPONENT, {useValue: appComponentType}),
provide(APP_COMPONENT_REF_PROMISE, provide(APP_COMPONENT_REF_PROMISE, {
{ useFactory: (dynamicComponentLoader: DynamicComponentLoader, appRef: ApplicationRef_,
useFactory: (dynamicComponentLoader: DynamicComponentLoader, appRef: ApplicationRef_, injector: Injector) => {
injector: Injector) => { // Save the ComponentRef for disposal later.
// Save the ComponentRef for disposal later. var ref: ComponentRef;
var ref: ComponentRef; // TODO(rado): investigate whether to support providers on root component.
// TODO(rado): investigate whether to support providers on root component. return dynamicComponentLoader
return dynamicComponentLoader.loadAsRoot(appComponentType, null, injector, .loadAsRoot(appComponentType, null, injector, () => { appRef._unloadComponent(ref); })
() => { appRef._unloadComponent(ref); }) .then((componentRef) => {
.then((componentRef) => { ref = componentRef;
ref = componentRef; var testability = injector.getOptional(Testability);
var testability = injector.getOptional(Testability); if (isPresent(testability)) {
if (isPresent(testability)) { injector.get(TestabilityRegistry)
injector.get(TestabilityRegistry) .registerApplication(componentRef.location.nativeElement, testability);
.registerApplication(componentRef.location.nativeElement, testability); }
} return componentRef;
return componentRef; });
}); },
}, deps: [DynamicComponentLoader, ApplicationRef, Injector]
deps: [DynamicComponentLoader, ApplicationRef, Injector] }),
}), provide(appComponentType, {
provide(appComponentType, useFactory: (p: Promise<any>) => p.then(ref => ref.instance),
{ deps: [APP_COMPONENT_REF_PROMISE]
useFactory: (p: Promise<any>) => p.then(ref => ref.instance), }),
deps: [APP_COMPONENT_REF_PROMISE]
}),
]; ];
} }
@ -93,13 +70,13 @@ var _platformProviders: any[];
* is passed into each call. If the platform function is called with a different set of * is passed into each call. If the platform function is called with a different set of
* provides, Angular will throw an exception. * provides, Angular will throw an exception.
*/ */
export function platform(providers?: Array<Type | Provider | any[]>): PlatformRef { export function platform(providers?: Array<Type|Provider|any[]>): PlatformRef {
lockMode(); lockMode();
if (isPresent(_platform)) { if (isPresent(_platform)) {
if (ListWrapper.equals(_platformProviders, providers)) { if (ListWrapper.equals(_platformProviders, providers)) {
return _platform; return _platform;
} else { } else {
throw new BaseException("platform cannot be initialized with different sets of providers."); throw new BaseException('platform cannot be initialized with different sets of providers.');
} }
} else { } else {
return _createPlatform(providers); return _createPlatform(providers);
@ -116,7 +93,7 @@ export function disposePlatform(): void {
} }
} }
function _createPlatform(providers?: Array<Type | Provider | any[]>): PlatformRef { function _createPlatform(providers?: Array<Type|Provider|any[]>): PlatformRef {
_platformProviders = providers; _platformProviders = providers;
let injector = Injector.resolveAndCreate(providers); let injector = Injector.resolveAndCreate(providers);
_platform = new PlatformRef_(injector, () => { _platform = new PlatformRef_(injector, () => {
@ -175,7 +152,7 @@ export abstract class PlatformRef {
* *
* See the {@link bootstrap} documentation for more details. * See the {@link bootstrap} documentation for more details.
*/ */
abstract application(providers: Array<Type | Provider | any[]>): ApplicationRef; abstract application(providers: Array<Type|Provider|any[]>): ApplicationRef;
/** /**
* Instantiate a new Angular application on the page, using providers which * Instantiate a new Angular application on the page, using providers which
@ -189,8 +166,9 @@ export abstract class PlatformRef {
* new application. Once this promise resolves, the application will be * new application. Once this promise resolves, the application will be
* constructed in the same manner as a normal `application()`. * constructed in the same manner as a normal `application()`.
*/ */
abstract asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>, abstract asyncApplication(
providers?: Array<Type | Provider | any[]>): Promise<ApplicationRef>; bindingFn: (zone: NgZone) => Promise<Array<Type|Provider|any[]>>,
providers?: Array<Type|Provider|any[]>): Promise<ApplicationRef>;
/** /**
* Destroy the Angular platform and all Angular applications on the page. * Destroy the Angular platform and all Angular applications on the page.
@ -210,24 +188,25 @@ export class PlatformRef_ extends PlatformRef {
get injector(): Injector { return this._injector; } get injector(): Injector { return this._injector; }
application(providers: Array<Type | Provider | any[]>): ApplicationRef { application(providers: Array<Type|Provider|any[]>): ApplicationRef {
var app = this._initApp(createNgZone(), providers); var app = this._initApp(createNgZone(), providers);
if (PromiseWrapper.isPromise(app)) { if (PromiseWrapper.isPromise(app)) {
throw new BaseException( throw new BaseException(
"Cannot use asyncronous app initializers with application. Use asyncApplication instead."); 'Cannot use asyncronous app initializers with application. Use asyncApplication instead.');
} }
return <ApplicationRef>app; return <ApplicationRef>app;
} }
asyncApplication(bindingFn: (zone: NgZone) => Promise<Array<Type | Provider | any[]>>, asyncApplication(
additionalProviders?: Array<Type | Provider | any[]>): Promise<ApplicationRef> { bindingFn: (zone: NgZone) => Promise<Array<Type|Provider|any[]>>,
additionalProviders?: Array<Type|Provider|any[]>): Promise<ApplicationRef> {
var zone = createNgZone(); var zone = createNgZone();
var completer = PromiseWrapper.completer<ApplicationRef>(); var completer = PromiseWrapper.completer<ApplicationRef>();
if (bindingFn === null) { if (bindingFn === null) {
completer.resolve(this._initApp(zone, additionalProviders)); completer.resolve(this._initApp(zone, additionalProviders));
} else { } else {
zone.run(() => { zone.run(() => {
PromiseWrapper.then(bindingFn(zone), (providers: Array<Type | Provider | any[]>) => { PromiseWrapper.then(bindingFn(zone), (providers: Array<Type|Provider|any[]>) => {
if (isPresent(additionalProviders)) { if (isPresent(additionalProviders)) {
providers = ListWrapper.concat(providers, additionalProviders); providers = ListWrapper.concat(providers, additionalProviders);
} }
@ -239,9 +218,8 @@ export class PlatformRef_ extends PlatformRef {
return completer.promise; return completer.promise;
} }
private _initApp(zone: NgZone, private _initApp(zone: NgZone, providers: Array<Type|Provider|any[]>):
providers: Array<Type | Provider | any[]>): Promise<ApplicationRef>| Promise<ApplicationRef>|ApplicationRef {
ApplicationRef {
var injector: Injector; var injector: Injector;
var app: ApplicationRef; var app: ApplicationRef;
zone.run(() => { zone.run(() => {
@ -338,8 +316,8 @@ export abstract class ApplicationRef {
* ### Example * ### Example
* {@example core/ts/platform/platform.ts region='longform'} * {@example core/ts/platform/platform.ts region='longform'}
*/ */
abstract bootstrap(componentType: Type, abstract bootstrap(componentType: Type, providers?: Array<Type|Provider|any[]>):
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef>; Promise<ComponentRef>;
/** /**
* Retrieve the application {@link Injector}. * Retrieve the application {@link Injector}.
@ -396,8 +374,8 @@ export class ApplicationRef_ extends ApplicationRef {
constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) { constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) {
super(); super();
if (isPresent(this._zone)) { if (isPresent(this._zone)) {
ObservableWrapper.subscribe(this._zone.onMicrotaskEmpty, ObservableWrapper.subscribe(
(_) => { this._zone.run(() => { this.tick(); }); }); this._zone.onMicrotaskEmpty, (_) => { this._zone.run(() => { this.tick(); }); });
} }
this._enforceNoNewChanges = assertionsEnabled(); this._enforceNoNewChanges = assertionsEnabled();
} }
@ -416,8 +394,7 @@ export class ApplicationRef_ extends ApplicationRef {
ListWrapper.remove(this._changeDetectorRefs, changeDetector); ListWrapper.remove(this._changeDetectorRefs, changeDetector);
} }
bootstrap(componentType: Type, bootstrap(componentType: Type, providers?: Array<Type|Provider|any[]>): Promise<ComponentRef> {
providers?: Array<Type | Provider | any[]>): Promise<ComponentRef> {
var completer = PromiseWrapper.completer(); var completer = PromiseWrapper.completer();
this._zone.run(() => { this._zone.run(() => {
var componentProviders = _componentProviders(componentType); var componentProviders = _componentProviders(componentType);
@ -449,7 +426,7 @@ export class ApplicationRef_ extends ApplicationRef {
let c = this._injector.get(Console); let c = this._injector.get(Console);
if (assertionsEnabled()) { if (assertionsEnabled()) {
c.log( c.log(
"Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode."); 'Angular 2 is running in the development mode. Call enableProdMode() to enable the production mode.');
} }
return ref; return ref;
}); });
@ -481,7 +458,7 @@ export class ApplicationRef_ extends ApplicationRef {
tick(): void { tick(): void {
if (this._runningTick) { if (this._runningTick) {
throw new BaseException("ApplicationRef.tick is called recursively"); throw new BaseException('ApplicationRef.tick is called recursively');
} }
var s = ApplicationRef_._tickScope(); var s = ApplicationRef_._tickScope();

View File

@ -53,15 +53,15 @@ function _randomChar(): string {
* A function that will be executed when a platform is initialized. * A function that will be executed when a platform is initialized.
*/ */
export const PLATFORM_INITIALIZER: OpaqueToken = export const PLATFORM_INITIALIZER: OpaqueToken =
CONST_EXPR(new OpaqueToken("Platform Initializer")); CONST_EXPR(new OpaqueToken('Platform Initializer'));
/** /**
* A function that will be executed when an application is initialized. * A function that will be executed when an application is initialized.
*/ */
export const APP_INITIALIZER: OpaqueToken = CONST_EXPR(new OpaqueToken("Application Initializer")); export const APP_INITIALIZER: OpaqueToken = CONST_EXPR(new OpaqueToken('Application Initializer'));
/** /**
* A token which indicates the root directory of the application * A token which indicates the root directory of the application
*/ */
export const PACKAGE_ROOT_URL: OpaqueToken = export const PACKAGE_ROOT_URL: OpaqueToken =
CONST_EXPR(new OpaqueToken("Application Packages Root URL")); CONST_EXPR(new OpaqueToken('Application Packages Root URL'));

View File

@ -4,24 +4,4 @@
* Change detection enables data binding in Angular. * Change detection enables data binding in Angular.
*/ */
export { export {ChangeDetectionStrategy, ExpressionChangedAfterItHasBeenCheckedException, ChangeDetectionError, ChangeDetectorRef, WrappedValue, SimpleChange, PipeTransform, IterableDiffers, IterableDiffer, IterableDifferFactory, KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory, CollectionChangeRecord, KeyValueChangeRecord, TrackByFn} from './change_detection/change_detection';
ChangeDetectionStrategy,
ExpressionChangedAfterItHasBeenCheckedException,
ChangeDetectionError,
ChangeDetectorRef,
WrappedValue,
SimpleChange,
PipeTransform,
IterableDiffers,
IterableDiffer,
IterableDifferFactory,
KeyValueDiffers,
KeyValueDiffer,
KeyValueDifferFactory,
CollectionChangeRecord,
KeyValueChangeRecord,
TrackByFn
} from './change_detection/change_detection';

View File

@ -5,13 +5,7 @@ import {ChangeDetectorRef, ChangeDetectorRef_} from './change_detector_ref';
import {DirectiveIndex} from './directive_record'; import {DirectiveIndex} from './directive_record';
import {ChangeDetector, ChangeDispatcher} from './interfaces'; import {ChangeDetector, ChangeDispatcher} from './interfaces';
import {Pipes} from './pipes'; import {Pipes} from './pipes';
import { import {ChangeDetectionError, ExpressionChangedAfterItHasBeenCheckedException, DehydratedException, EventEvaluationErrorContext, EventEvaluationError} from './exceptions';
ChangeDetectionError,
ExpressionChangedAfterItHasBeenCheckedException,
DehydratedException,
EventEvaluationErrorContext,
EventEvaluationError
} from './exceptions';
import {BindingTarget} from './binding_record'; import {BindingTarget} from './binding_record';
import {Locals} from './parser/locals'; import {Locals} from './parser/locals';
import {ChangeDetectionStrategy, ChangeDetectorState} from './constants'; import {ChangeDetectionStrategy, ChangeDetectorState} from './constants';
@ -21,8 +15,9 @@ import {ObservableWrapper} from 'angular2/src/facade/async';
var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`); var _scope_check: WtfScopeFn = wtfCreateScope(`ChangeDetector#check(ascii id, bool throwOnChange)`);
class _Context { class _Context {
constructor(public element: any, public componentElement: any, public context: any, constructor(
public locals: any, public injector: any, public expression: any) {} public element: any, public componentElement: any, public context: any, public locals: any,
public injector: any, public expression: any) {}
} }
export class AbstractChangeDetector<T> implements ChangeDetector { export class AbstractChangeDetector<T> implements ChangeDetector {
@ -44,9 +39,10 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
dispatcher: ChangeDispatcher; dispatcher: ChangeDispatcher;
constructor(public id: string, public numberOfPropertyProtoRecords: number, constructor(
public bindingTargets: BindingTarget[], public directiveIndices: DirectiveIndex[], public id: string, public numberOfPropertyProtoRecords: number,
public strategy: ChangeDetectionStrategy) { public bindingTargets: BindingTarget[], public directiveIndices: DirectiveIndex[],
public strategy: ChangeDetectionStrategy) {
this.ref = new ChangeDetectorRef_(this); this.ref = new ChangeDetectorRef_(this);
} }
@ -79,9 +75,9 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
} catch (e) { } catch (e) {
var c = this.dispatcher.getDebugContext(null, elIndex, null); var c = this.dispatcher.getDebugContext(null, elIndex, null);
var context = isPresent(c) ? var context = isPresent(c) ?
new EventEvaluationErrorContext(c.element, c.componentElement, c.context, new EventEvaluationErrorContext(
c.locals, c.injector) : c.element, c.componentElement, c.context, c.locals, c.injector) :
null; null;
throw new EventEvaluationError(eventName, e, e.stack, context); throw new EventEvaluationError(eventName, e, e.stack, context);
} }
} }
@ -271,8 +267,9 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
var error; var error;
try { try {
var c = this.dispatcher.getDebugContext(null, this._currentBinding().elementIndex, null); var c = this.dispatcher.getDebugContext(null, this._currentBinding().elementIndex, null);
var context = isPresent(c) ? new _Context(c.element, c.componentElement, c.context, c.locals, var context = isPresent(c) ? new _Context(
c.injector, this._currentBinding().debug) : c.element, c.componentElement, c.context, c.locals,
c.injector, this._currentBinding().debug) :
null; null;
error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context); error = new ChangeDetectionError(this._currentBinding().debug, exception, stack, context);
} catch (e) { } catch (e) {
@ -284,8 +281,8 @@ export class AbstractChangeDetector<T> implements ChangeDetector {
} }
throwOnChangeError(oldValue: any, newValue: any): void { throwOnChangeError(oldValue: any, newValue: any): void {
throw new ExpressionChangedAfterItHasBeenCheckedException(this._currentBinding().debug, throw new ExpressionChangedAfterItHasBeenCheckedException(
oldValue, newValue, null); this._currentBinding().debug, oldValue, newValue, null);
} }
throwDehydratedError(detail: string): void { throw new DehydratedException(detail); } throwDehydratedError(detail: string): void { throw new DehydratedException(detail); }

View File

@ -3,21 +3,22 @@ import {SetterFn} from 'angular2/src/core/reflection/types';
import {AST} from './parser/ast'; import {AST} from './parser/ast';
import {DirectiveIndex, DirectiveRecord} from './directive_record'; import {DirectiveIndex, DirectiveRecord} from './directive_record';
const DIRECTIVE_LIFECYCLE = "directiveLifecycle"; const DIRECTIVE_LIFECYCLE = 'directiveLifecycle';
const BINDING = "native"; const BINDING = 'native';
const DIRECTIVE = "directive"; const DIRECTIVE = 'directive';
const ELEMENT_PROPERTY = "elementProperty"; const ELEMENT_PROPERTY = 'elementProperty';
const ELEMENT_ATTRIBUTE = "elementAttribute"; const ELEMENT_ATTRIBUTE = 'elementAttribute';
const ELEMENT_CLASS = "elementClass"; const ELEMENT_CLASS = 'elementClass';
const ELEMENT_STYLE = "elementStyle"; const ELEMENT_STYLE = 'elementStyle';
const TEXT_NODE = "textNode"; const TEXT_NODE = 'textNode';
const EVENT = "event"; const EVENT = 'event';
const HOST_EVENT = "hostEvent"; const HOST_EVENT = 'hostEvent';
export class BindingTarget { export class BindingTarget {
constructor(public mode: string, public elementIndex: number, public name: string, constructor(
public unit: string, public debug: string) {} public mode: string, public elementIndex: number, public name: string, public unit: string,
public debug: string) {}
isDirective(): boolean { return this.mode === DIRECTIVE; } isDirective(): boolean { return this.mode === DIRECTIVE; }
@ -33,9 +34,10 @@ export class BindingTarget {
} }
export class BindingRecord { export class BindingRecord {
constructor(public mode: string, public target: BindingTarget, public implicitReceiver: any, constructor(
public ast: AST, public setter: SetterFn, public lifecycleEvent: string, public mode: string, public target: BindingTarget, public implicitReceiver: any,
public directiveRecord: DirectiveRecord) {} public ast: AST, public setter: SetterFn, public lifecycleEvent: string,
public directiveRecord: DirectiveRecord) {}
isDirectiveLifecycle(): boolean { return this.mode === DIRECTIVE_LIFECYCLE; } isDirectiveLifecycle(): boolean { return this.mode === DIRECTIVE_LIFECYCLE; }
@ -48,22 +50,23 @@ export class BindingRecord {
} }
static createDirectiveDoCheck(directiveRecord: DirectiveRecord): BindingRecord { static createDirectiveDoCheck(directiveRecord: DirectiveRecord): BindingRecord {
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "DoCheck", directiveRecord); return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, 'DoCheck', directiveRecord);
} }
static createDirectiveOnInit(directiveRecord: DirectiveRecord): BindingRecord { static createDirectiveOnInit(directiveRecord: DirectiveRecord): BindingRecord {
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "OnInit", directiveRecord); return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, 'OnInit', directiveRecord);
} }
static createDirectiveOnChanges(directiveRecord: DirectiveRecord): BindingRecord { static createDirectiveOnChanges(directiveRecord: DirectiveRecord): BindingRecord {
return new BindingRecord(DIRECTIVE_LIFECYCLE, null, 0, null, null, "OnChanges", return new BindingRecord(
directiveRecord); DIRECTIVE_LIFECYCLE, null, 0, null, null, 'OnChanges', directiveRecord);
} }
static createForDirective(ast: AST, propertyName: string, setter: SetterFn, static createForDirective(
directiveRecord: DirectiveRecord): BindingRecord { ast: AST, propertyName: string, setter: SetterFn,
directiveRecord: DirectiveRecord): BindingRecord {
var elementIndex = directiveRecord.directiveIndex.elementIndex; var elementIndex = directiveRecord.directiveIndex.elementIndex;
var t = new BindingTarget(DIRECTIVE, elementIndex, propertyName, null, ast.toString()); var t = new BindingTarget(DIRECTIVE, elementIndex, propertyName, null, ast.toString());
return new BindingRecord(DIRECTIVE, t, 0, ast, setter, null, directiveRecord); return new BindingRecord(DIRECTIVE, t, 0, ast, setter, null, directiveRecord);
@ -71,14 +74,14 @@ export class BindingRecord {
static createForElementProperty(ast: AST, elementIndex: number, static createForElementProperty(ast: AST, elementIndex: number, propertyName: string):
propertyName: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_PROPERTY, elementIndex, propertyName, null, ast.toString()); var t = new BindingTarget(ELEMENT_PROPERTY, elementIndex, propertyName, null, ast.toString());
return new BindingRecord(BINDING, t, 0, ast, null, null, null); return new BindingRecord(BINDING, t, 0, ast, null, null, null);
} }
static createForElementAttribute(ast: AST, elementIndex: number, static createForElementAttribute(ast: AST, elementIndex: number, attributeName: string):
attributeName: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_ATTRIBUTE, elementIndex, attributeName, null, ast.toString()); var t = new BindingTarget(ELEMENT_ATTRIBUTE, elementIndex, attributeName, null, ast.toString());
return new BindingRecord(BINDING, t, 0, ast, null, null, null); return new BindingRecord(BINDING, t, 0, ast, null, null, null);
} }
@ -88,39 +91,39 @@ export class BindingRecord {
return new BindingRecord(BINDING, t, 0, ast, null, null, null); return new BindingRecord(BINDING, t, 0, ast, null, null, null);
} }
static createForElementStyle(ast: AST, elementIndex: number, styleName: string, static createForElementStyle(ast: AST, elementIndex: number, styleName: string, unit: string):
unit: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_STYLE, elementIndex, styleName, unit, ast.toString()); var t = new BindingTarget(ELEMENT_STYLE, elementIndex, styleName, unit, ast.toString());
return new BindingRecord(BINDING, t, 0, ast, null, null, null); return new BindingRecord(BINDING, t, 0, ast, null, null, null);
} }
static createForHostProperty(directiveIndex: DirectiveIndex, ast: AST, static createForHostProperty(directiveIndex: DirectiveIndex, ast: AST, propertyName: string):
propertyName: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_PROPERTY, directiveIndex.elementIndex, propertyName, null, var t = new BindingTarget(
ast.toString()); ELEMENT_PROPERTY, directiveIndex.elementIndex, propertyName, null, ast.toString());
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null); return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
} }
static createForHostAttribute(directiveIndex: DirectiveIndex, ast: AST, static createForHostAttribute(directiveIndex: DirectiveIndex, ast: AST, attributeName: string):
attributeName: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_ATTRIBUTE, directiveIndex.elementIndex, attributeName, null, var t = new BindingTarget(
ast.toString()); ELEMENT_ATTRIBUTE, directiveIndex.elementIndex, attributeName, null, ast.toString());
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null); return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
} }
static createForHostClass(directiveIndex: DirectiveIndex, ast: AST, static createForHostClass(directiveIndex: DirectiveIndex, ast: AST, className: string):
className: string): BindingRecord { BindingRecord {
var t = new BindingTarget(ELEMENT_CLASS, directiveIndex.elementIndex, className, null, var t = new BindingTarget(
ast.toString()); ELEMENT_CLASS, directiveIndex.elementIndex, className, null, ast.toString());
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null); return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
} }
static createForHostStyle(directiveIndex: DirectiveIndex, ast: AST, styleName: string, static createForHostStyle(
unit: string): BindingRecord { directiveIndex: DirectiveIndex, ast: AST, styleName: string, unit: string): BindingRecord {
var t = new BindingTarget(ELEMENT_STYLE, directiveIndex.elementIndex, styleName, unit, var t = new BindingTarget(
ast.toString()); ELEMENT_STYLE, directiveIndex.elementIndex, styleName, unit, ast.toString());
return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null); return new BindingRecord(BINDING, t, directiveIndex, ast, null, null, null);
} }
@ -138,8 +141,8 @@ export class BindingRecord {
return new BindingRecord(EVENT, t, 0, ast, null, null, null); return new BindingRecord(EVENT, t, 0, ast, null, null, null);
} }
static createForHostEvent(ast: AST, eventName: string, static createForHostEvent(ast: AST, eventName: string, directiveRecord: DirectiveRecord):
directiveRecord: DirectiveRecord): BindingRecord { BindingRecord {
var directiveIndex = directiveRecord.directiveIndex; var directiveIndex = directiveRecord.directiveIndex;
var t = var t =
new BindingTarget(HOST_EVENT, directiveIndex.elementIndex, eventName, null, ast.toString()); new BindingTarget(HOST_EVENT, directiveIndex.elementIndex, eventName, null, ast.toString());

View File

@ -1,46 +1,19 @@
import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs'; import {IterableDiffers, IterableDifferFactory} from './differs/iterable_differs';
import {DefaultIterableDifferFactory} from './differs/default_iterable_differ'; import {DefaultIterableDifferFactory} from './differs/default_iterable_differ';
import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs'; import {KeyValueDiffers, KeyValueDifferFactory} from './differs/keyvalue_differs';
import { import {DefaultKeyValueDifferFactory, KeyValueChangeRecord} from './differs/default_keyvalue_differ';
DefaultKeyValueDifferFactory,
KeyValueChangeRecord
} from './differs/default_keyvalue_differ';
import {CONST_EXPR} from 'angular2/src/facade/lang'; import {CONST_EXPR} from 'angular2/src/facade/lang';
export { export {DefaultKeyValueDifferFactory, KeyValueChangeRecord} from './differs/default_keyvalue_differ';
DefaultKeyValueDifferFactory, export {DefaultIterableDifferFactory, CollectionChangeRecord} from './differs/default_iterable_differ';
KeyValueChangeRecord export {ASTWithSource, AST, AstTransformer, PropertyRead, LiteralArray, ImplicitReceiver} from './parser/ast';
} from './differs/default_keyvalue_differ';
export {
DefaultIterableDifferFactory,
CollectionChangeRecord
} from './differs/default_iterable_differ';
export {
ASTWithSource,
AST,
AstTransformer,
PropertyRead,
LiteralArray,
ImplicitReceiver
} from './parser/ast';
export {Lexer} from './parser/lexer'; export {Lexer} from './parser/lexer';
export {Parser} from './parser/parser'; export {Parser} from './parser/parser';
export {Locals} from './parser/locals'; export {Locals} from './parser/locals';
export { export {DehydratedException, ExpressionChangedAfterItHasBeenCheckedException, ChangeDetectionError} from './exceptions';
DehydratedException, export {ProtoChangeDetector, ChangeDetector, ChangeDispatcher, ChangeDetectorDefinition, DebugContext, ChangeDetectorGenConfig} from './interfaces';
ExpressionChangedAfterItHasBeenCheckedException,
ChangeDetectionError
} from './exceptions';
export {
ProtoChangeDetector,
ChangeDetector,
ChangeDispatcher,
ChangeDetectorDefinition,
DebugContext,
ChangeDetectorGenConfig
} from './interfaces';
export {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from './constants'; export {ChangeDetectionStrategy, CHANGE_DETECTION_STRATEGY_VALUES} from './constants';
export {DynamicProtoChangeDetector} from './proto_change_detector'; export {DynamicProtoChangeDetector} from './proto_change_detector';
export {JitProtoChangeDetector} from './jit_proto_change_detector'; export {JitProtoChangeDetector} from './jit_proto_change_detector';
@ -48,12 +21,7 @@ export {BindingRecord, BindingTarget} from './binding_record';
export {DirectiveIndex, DirectiveRecord} from './directive_record'; export {DirectiveIndex, DirectiveRecord} from './directive_record';
export {DynamicChangeDetector} from './dynamic_change_detector'; export {DynamicChangeDetector} from './dynamic_change_detector';
export {ChangeDetectorRef} from './change_detector_ref'; export {ChangeDetectorRef} from './change_detector_ref';
export { export {IterableDiffers, IterableDiffer, IterableDifferFactory, TrackByFn} from './differs/iterable_differs';
IterableDiffers,
IterableDiffer,
IterableDifferFactory,
TrackByFn
} from './differs/iterable_differs';
export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs'; export {KeyValueDiffers, KeyValueDiffer, KeyValueDifferFactory} from './differs/keyvalue_differs';
export {PipeTransform} from './pipe_transform'; export {PipeTransform} from './pipe_transform';
export {WrappedValue, SimpleChange} from './change_detection_util'; export {WrappedValue, SimpleChange} from './change_detection_util';

View File

@ -25,8 +25,8 @@ import {createPropertyRecords, createEventRecords} from './proto_change_detector
* `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates * `angular2.transform.template_compiler.change_detector_codegen` library. If you make updates
* here, please make equivalent changes there. * here, please make equivalent changes there.
*/ */
const IS_CHANGED_LOCAL = "isChanged"; const IS_CHANGED_LOCAL = 'isChanged';
const CHANGES_LOCAL = "changes"; const CHANGES_LOCAL = 'changes';
export class ChangeDetectorJITGenerator { export class ChangeDetectorJITGenerator {
private _logic: CodegenLogicUtil; private _logic: CodegenLogicUtil;
@ -41,9 +41,9 @@ export class ChangeDetectorJITGenerator {
private genConfig: ChangeDetectorGenConfig; private genConfig: ChangeDetectorGenConfig;
typeName: string; typeName: string;
constructor(definition: ChangeDetectorDefinition, private changeDetectionUtilVarName: string, constructor(
private abstractChangeDetectorVarName: string, definition: ChangeDetectorDefinition, private changeDetectionUtilVarName: string,
private changeDetectorStateVarName: string) { private abstractChangeDetectorVarName: string, private changeDetectorStateVarName: string) {
var propertyBindingRecords = createPropertyRecords(definition); var propertyBindingRecords = createPropertyRecords(definition);
var eventBindingRecords = createEventRecords(definition); var eventBindingRecords = createEventRecords(definition);
var propertyBindingTargets = definition.bindingRecords.map(b => b.target); var propertyBindingTargets = definition.bindingRecords.map(b => b.target);
@ -55,10 +55,10 @@ export class ChangeDetectorJITGenerator {
this.propertyBindingTargets = propertyBindingTargets; this.propertyBindingTargets = propertyBindingTargets;
this.eventBindings = eventBindingRecords; this.eventBindings = eventBindingRecords;
this.directiveRecords = definition.directiveRecords; this.directiveRecords = definition.directiveRecords;
this._names = new CodegenNameUtil(this.records, this.eventBindings, this.directiveRecords, this._names = new CodegenNameUtil(
this.changeDetectionUtilVarName); this.records, this.eventBindings, this.directiveRecords, this.changeDetectionUtilVarName);
this._logic = new CodegenLogicUtil(this._names, this.changeDetectionUtilVarName, this._logic = new CodegenLogicUtil(
this.changeDetectorStateVarName); this._names, this.changeDetectionUtilVarName, this.changeDetectorStateVarName);
this.typeName = sanitizeName(`ChangeDetector_${this.id}`); this.typeName = sanitizeName(`ChangeDetector_${this.id}`);
} }
@ -69,9 +69,10 @@ export class ChangeDetectorJITGenerator {
return new ${this.typeName}(); return new ${this.typeName}();
} }
`; `;
return new Function(this.abstractChangeDetectorVarName, this.changeDetectionUtilVarName, return new Function(
this.changeDetectorStateVarName, factorySource)( this.abstractChangeDetectorVarName, this.changeDetectionUtilVarName,
AbstractChangeDetector, ChangeDetectionUtil, ChangeDetectorState); this.changeDetectorStateVarName,
factorySource)(AbstractChangeDetector, ChangeDetectionUtil, ChangeDetectorState);
} }
generateSource(): string { generateSource(): string {
@ -112,8 +113,8 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_genPropertyBindingTargets(): string { _genPropertyBindingTargets(): string {
var targets = this._logic.genPropertyBindingTargets(this.propertyBindingTargets, var targets = this._logic.genPropertyBindingTargets(
this.genConfig.genDebugInfo); this.propertyBindingTargets, this.genConfig.genDebugInfo);
return `${this.typeName}.gen_propertyBindingTargets = ${targets};`; return `${this.typeName}.gen_propertyBindingTargets = ${targets};`;
} }
@ -126,7 +127,7 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_maybeGenHandleEventInternal(): string { _maybeGenHandleEventInternal(): string {
if (this.eventBindings.length > 0) { if (this.eventBindings.length > 0) {
var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join("\n"); var handlers = this.eventBindings.map(eb => this._genEventBinding(eb)).join('\n');
return ` return `
${this.typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) { ${this.typeName}.prototype.handleEventInternal = function(eventName, elIndex, locals) {
var ${this._names.getPreventDefaultAccesor()} = false; var ${this._names.getPreventDefaultAccesor()} = false;
@ -183,7 +184,7 @@ export class ChangeDetectorJITGenerator {
_genMarkPathToRootAsCheckOnce(r: ProtoRecord): string { _genMarkPathToRootAsCheckOnce(r: ProtoRecord): string {
var br = r.bindingRecord; var br = r.bindingRecord;
if (br.isDefaultChangeDetection()) { if (br.isDefaultChangeDetection()) {
return ""; return '';
} else { } else {
return `${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();`; return `${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markPathToRootAsCheckOnce();`;
} }
@ -225,7 +226,7 @@ export class ChangeDetectorJITGenerator {
_maybeGenAfterContentLifecycleCallbacks(): string { _maybeGenAfterContentLifecycleCallbacks(): string {
var notifications = this._logic.genContentLifecycleCallbacks(this.directiveRecords); var notifications = this._logic.genContentLifecycleCallbacks(this.directiveRecords);
if (notifications.length > 0) { if (notifications.length > 0) {
var directiveNotifications = notifications.join("\n"); var directiveNotifications = notifications.join('\n');
return ` return `
${this.typeName}.prototype.afterContentLifecycleCallbacksInternal = function() { ${this.typeName}.prototype.afterContentLifecycleCallbacksInternal = function() {
${directiveNotifications} ${directiveNotifications}
@ -240,7 +241,7 @@ export class ChangeDetectorJITGenerator {
_maybeGenAfterViewLifecycleCallbacks(): string { _maybeGenAfterViewLifecycleCallbacks(): string {
var notifications = this._logic.genViewLifecycleCallbacks(this.directiveRecords); var notifications = this._logic.genViewLifecycleCallbacks(this.directiveRecords);
if (notifications.length > 0) { if (notifications.length > 0) {
var directiveNotifications = notifications.join("\n"); var directiveNotifications = notifications.join('\n');
return ` return `
${this.typeName}.prototype.afterViewLifecycleCallbacksInternal = function() { ${this.typeName}.prototype.afterViewLifecycleCallbacksInternal = function() {
${directiveNotifications} ${directiveNotifications}
@ -282,7 +283,7 @@ export class ChangeDetectorJITGenerator {
codes.push(code); codes.push(code);
} }
return codes.join("\n"); return codes.join('\n');
} }
/** @internal */ /** @internal */
@ -315,11 +316,11 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_genDirectiveLifecycle(r: ProtoRecord): string { _genDirectiveLifecycle(r: ProtoRecord): string {
if (r.name === "DoCheck") { if (r.name === 'DoCheck') {
return this._genOnCheck(r); return this._genOnCheck(r);
} else if (r.name === "OnInit") { } else if (r.name === 'OnInit') {
return this._genOnInit(r); return this._genOnInit(r);
} else if (r.name === "OnChanges") { } else if (r.name === 'OnChanges') {
return this._genOnChange(r); return this._genOnChange(r);
} else { } else {
throw new BaseException(`Unknown lifecycle event '${r.name}'`); throw new BaseException(`Unknown lifecycle event '${r.name}'`);
@ -329,7 +330,7 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_genPipeCheck(r: ProtoRecord): string { _genPipeCheck(r: ProtoRecord): string {
var context = this._names.getLocalName(r.contextIndex); var context = this._names.getLocalName(r.contextIndex);
var argString = r.args.map((arg) => this._names.getLocalName(arg)).join(", "); var argString = r.args.map((arg) => this._names.getLocalName(arg)).join(', ');
var oldValue = this._names.getFieldName(r.selfIndex); var oldValue = this._names.getFieldName(r.selfIndex);
var newValue = this._names.getLocalName(r.selfIndex); var newValue = this._names.getLocalName(r.selfIndex);
@ -389,7 +390,7 @@ export class ChangeDetectorJITGenerator {
var genCode = r.shouldBeChecked() ? `${read}${check}` : read; var genCode = r.shouldBeChecked() ? `${read}${check}` : read;
if (r.isPureFunction()) { if (r.isPureFunction()) {
var condition = r.args.map((a) => this._names.getChangeName(a)).join(" || "); var condition = r.args.map((a) => this._names.getChangeName(a)).join(' || ');
if (r.isUsedByOtherRecord()) { if (r.isUsedByOtherRecord()) {
return `if (${condition}) { ${genCode} } else { ${newValue} = ${oldValue}; }`; return `if (${condition}) { ${genCode} } else { ${newValue} = ${oldValue}; }`;
} else { } else {
@ -407,10 +408,10 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_genUpdateDirectiveOrElement(r: ProtoRecord): string { _genUpdateDirectiveOrElement(r: ProtoRecord): string {
if (!r.lastInBinding) return ""; if (!r.lastInBinding) return '';
var newValue = this._names.getLocalName(r.selfIndex); var newValue = this._names.getLocalName(r.selfIndex);
var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : ""; var notifyDebug = this.genConfig.logBindingUpdate ? `this.logBindingUpdate(${newValue});` : '';
var br = r.bindingRecord; var br = r.bindingRecord;
if (br.target.isDirective()) { if (br.target.isDirective()) {
@ -446,7 +447,7 @@ export class ChangeDetectorJITGenerator {
_genAddToChanges(r: ProtoRecord): string { _genAddToChanges(r: ProtoRecord): string {
var newValue = this._names.getLocalName(r.selfIndex); var newValue = this._names.getLocalName(r.selfIndex);
var oldValue = this._names.getFieldName(r.selfIndex); var oldValue = this._names.getFieldName(r.selfIndex);
if (!r.bindingRecord.callOnChanges()) return ""; if (!r.bindingRecord.callOnChanges()) return '';
return `${CHANGES_LOCAL} = this.addChange(${CHANGES_LOCAL}, ${oldValue}, ${newValue});`; return `${CHANGES_LOCAL} = this.addChange(${CHANGES_LOCAL}, ${oldValue}, ${newValue});`;
} }
@ -455,13 +456,13 @@ export class ChangeDetectorJITGenerator {
var prev = ChangeDetectionUtil.protoByIndex(this.records, r.selfIndex - 1); var prev = ChangeDetectionUtil.protoByIndex(this.records, r.selfIndex - 1);
var firstInBinding = isBlank(prev) || prev.bindingRecord !== r.bindingRecord; var firstInBinding = isBlank(prev) || prev.bindingRecord !== r.bindingRecord;
return firstInBinding && !r.bindingRecord.isDirectiveLifecycle() ? return firstInBinding && !r.bindingRecord.isDirectiveLifecycle() ?
`${this._names.getPropertyBindingIndex()} = ${r.propertyBindingIndex};` : `${this._names.getPropertyBindingIndex()} = ${r.propertyBindingIndex};` :
''; '';
} }
/** @internal */ /** @internal */
_maybeGenLastInDirective(r: ProtoRecord): string { _maybeGenLastInDirective(r: ProtoRecord): string {
if (!r.lastInDirective) return ""; if (!r.lastInDirective) return '';
return ` return `
${CHANGES_LOCAL} = null; ${CHANGES_LOCAL} = null;
${this._genNotifyOnPushDetectors(r)} ${this._genNotifyOnPushDetectors(r)}
@ -490,7 +491,7 @@ export class ChangeDetectorJITGenerator {
/** @internal */ /** @internal */
_genNotifyOnPushDetectors(r: ProtoRecord): string { _genNotifyOnPushDetectors(r: ProtoRecord): string {
var br = r.bindingRecord; var br = r.bindingRecord;
if (!r.lastInDirective || br.isDefaultChangeDetection()) return ""; if (!r.lastInDirective || br.isDefaultChangeDetection()) return '';
var retVal = ` var retVal = `
if(${IS_CHANGED_LOCAL}) { if(${IS_CHANGED_LOCAL}) {
${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markAsCheckOnce(); ${this._names.getDetectorName(br.directiveRecord.directiveIndex)}.markAsCheckOnce();

View File

@ -1,20 +1,6 @@
import { import {CONST_EXPR, isPresent, isBlank, Type, StringWrapper, looseIdentical, isPrimitive} from 'angular2/src/facade/lang';
CONST_EXPR,
isPresent,
isBlank,
Type,
StringWrapper,
looseIdentical,
isPrimitive
} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import { import {ListWrapper, MapWrapper, StringMapWrapper, isListLikeIterable, areIterablesEqual} from 'angular2/src/facade/collection';
ListWrapper,
MapWrapper,
StringMapWrapper,
isListLikeIterable,
areIterablesEqual
} from 'angular2/src/facade/collection';
import {ProtoRecord} from './proto_record'; import {ProtoRecord} from './proto_record';
import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants'; import {ChangeDetectionStrategy, isDefaultChangeDetectionStrategy} from './constants';
import {implementsOnDestroy} from './pipe_lifecycle_reflector'; import {implementsOnDestroy} from './pipe_lifecycle_reflector';
@ -52,10 +38,7 @@ export class WrappedValue {
} }
var _wrappedValues = [ var _wrappedValues = [
new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null), new WrappedValue(null),
new WrappedValue(null),
new WrappedValue(null),
new WrappedValue(null),
new WrappedValue(null) new WrappedValue(null)
]; ];
@ -173,8 +156,8 @@ export class ChangeDetectionUtil {
static protoByIndex(protos: ProtoRecord[], selfIndex: number): ProtoRecord { static protoByIndex(protos: ProtoRecord[], selfIndex: number): ProtoRecord {
return selfIndex < 1 ? return selfIndex < 1 ?
null : null :
protos[selfIndex - 1]; // self index is shifted by one because of context protos[selfIndex - 1]; // self index is shifted by one because of context
} }
static callPipeOnDestroy(selectedPipe: SelectedPipe): void { static callPipeOnDestroy(selectedPipe: SelectedPipe): void {
@ -183,8 +166,9 @@ export class ChangeDetectionUtil {
} }
} }
static bindingTarget(mode: string, elementIndex: number, name: string, unit: string, static bindingTarget(
debug: string): BindingTarget { mode: string, elementIndex: number, name: string, unit: string,
debug: string): BindingTarget {
return new BindingTarget(mode, elementIndex, name, unit, debug); return new BindingTarget(mode, elementIndex, name, unit, debug);
} }
@ -198,8 +182,8 @@ export class ChangeDetectionUtil {
if (isListLikeIterable(a) && isListLikeIterable(b)) { if (isListLikeIterable(a) && isListLikeIterable(b)) {
return areIterablesEqual(a, b, ChangeDetectionUtil.devModeEqual); return areIterablesEqual(a, b, ChangeDetectionUtil.devModeEqual);
} else if (!isListLikeIterable(a) && !isPrimitive(a) && !isListLikeIterable(b) && } else if (
!isPrimitive(b)) { !isListLikeIterable(a) && !isPrimitive(a) && !isListLikeIterable(b) && !isPrimitive(b)) {
return true; return true;
} else { } else {

View File

@ -90,8 +90,9 @@ function _optimizeSkips(srcRecords: ProtoRecord[]): ProtoRecord[] {
/** /**
* Add a new record or re-use one of the existing records. * Add a new record or re-use one of the existing records.
*/ */
function _mayBeAddRecord(record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[], function _mayBeAddRecord(
excluded: boolean): ProtoRecord { record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[],
excluded: boolean): ProtoRecord {
let match = _findFirstMatch(record, dstRecords, excludedIdxs); let match = _findFirstMatch(record, dstRecords, excludedIdxs);
if (isPresent(match)) { if (isPresent(match)) {
@ -118,15 +119,15 @@ function _mayBeAddRecord(record: ProtoRecord, dstRecords: ProtoRecord[], exclude
/** /**
* Returns the first `ProtoRecord` that matches the record. * Returns the first `ProtoRecord` that matches the record.
*/ */
function _findFirstMatch(record: ProtoRecord, dstRecords: ProtoRecord[], function _findFirstMatch(
excludedIdxs: number[]): ProtoRecord { record: ProtoRecord, dstRecords: ProtoRecord[], excludedIdxs: number[]): ProtoRecord {
return dstRecords.find( return dstRecords.find(
// TODO(vicb): optimize excludedIdxs.indexOf (sorted array) // TODO(vicb): optimize excludedIdxs.indexOf (sorted array)
rr => excludedIdxs.indexOf(rr.selfIndex) == -1 && rr.mode !== RecordType.DirectiveLifecycle && rr => excludedIdxs.indexOf(rr.selfIndex) == -1 && rr.mode !== RecordType.DirectiveLifecycle &&
_haveSameDirIndex(rr, record) && rr.mode === record.mode && _haveSameDirIndex(rr, record) && rr.mode === record.mode &&
looseIdentical(rr.funcOrValue, record.funcOrValue) && looseIdentical(rr.funcOrValue, record.funcOrValue) &&
rr.contextIndex === record.contextIndex && looseIdentical(rr.name, record.name) && rr.contextIndex === record.contextIndex && looseIdentical(rr.name, record.name) &&
ListWrapper.equals(rr.args, record.args)); ListWrapper.equals(rr.args, record.args));
} }
/** /**
@ -135,17 +136,17 @@ function _findFirstMatch(record: ProtoRecord, dstRecords: ProtoRecord[],
* - the context, * - the context,
* - self * - self
*/ */
function _cloneAndUpdateIndexes(record: ProtoRecord, dstRecords: ProtoRecord[], function _cloneAndUpdateIndexes(
indexMap: Map<number, number>): ProtoRecord { record: ProtoRecord, dstRecords: ProtoRecord[], indexMap: Map<number, number>): ProtoRecord {
let args = record.args.map(src => _srcToDstSelfIndex(indexMap, src)); let args = record.args.map(src => _srcToDstSelfIndex(indexMap, src));
let contextIndex = _srcToDstSelfIndex(indexMap, record.contextIndex); let contextIndex = _srcToDstSelfIndex(indexMap, record.contextIndex);
let selfIndex = dstRecords.length + 1; let selfIndex = dstRecords.length + 1;
return new ProtoRecord(record.mode, record.name, record.funcOrValue, args, record.fixedArgs, return new ProtoRecord(
contextIndex, record.directiveIndex, selfIndex, record.bindingRecord, record.mode, record.name, record.funcOrValue, args, record.fixedArgs, contextIndex,
record.lastInBinding, record.lastInDirective, record.directiveIndex, selfIndex, record.bindingRecord, record.lastInBinding,
record.argumentToPureFunction, record.referencedBySelf, record.lastInDirective, record.argumentToPureFunction, record.referencedBySelf,
record.propertyBindingIndex); record.propertyBindingIndex);
} }
/** /**
@ -158,9 +159,9 @@ function _srcToDstSelfIndex(indexMap: Map<number, number>, srcIdx: number): numb
} }
function _createSelfRecord(r: ProtoRecord, contextIndex: number, selfIndex: number): ProtoRecord { function _createSelfRecord(r: ProtoRecord, contextIndex: number, selfIndex: number): ProtoRecord {
return new ProtoRecord(RecordType.Self, "self", null, [], r.fixedArgs, contextIndex, return new ProtoRecord(
r.directiveIndex, selfIndex, r.bindingRecord, r.lastInBinding, RecordType.Self, 'self', null, [], r.fixedArgs, contextIndex, r.directiveIndex, selfIndex,
r.lastInDirective, false, false, r.propertyBindingIndex); r.bindingRecord, r.lastInBinding, r.lastInDirective, false, false, r.propertyBindingIndex);
} }
function _haveSameDirIndex(a: ProtoRecord, b: ProtoRecord): boolean { function _haveSameDirIndex(a: ProtoRecord, b: ProtoRecord): boolean {

View File

@ -10,16 +10,17 @@ import {BaseException} from 'angular2/src/facade/exceptions';
* Class responsible for providing change detection logic for change detector classes. * Class responsible for providing change detection logic for change detector classes.
*/ */
export class CodegenLogicUtil { export class CodegenLogicUtil {
constructor(private _names: CodegenNameUtil, private _utilName: string, constructor(
private _changeDetectorStateName: string) {} private _names: CodegenNameUtil, private _utilName: string,
private _changeDetectorStateName: string) {}
/** /**
* Generates a statement which updates the local variable representing `protoRec` with the current * Generates a statement which updates the local variable representing `protoRec` with the current
* value of the record. Used by property bindings. * value of the record. Used by property bindings.
*/ */
genPropertyBindingEvalValue(protoRec: ProtoRecord): string { genPropertyBindingEvalValue(protoRec: ProtoRecord): string {
return this._genEvalValue(protoRec, idx => this._names.getLocalName(idx), return this._genEvalValue(
this._names.getLocalsAccessorName()); protoRec, idx => this._names.getLocalName(idx), this._names.getLocalsAccessorName());
} }
/** /**
@ -27,16 +28,16 @@ export class CodegenLogicUtil {
* value of the record. Used by event bindings. * value of the record. Used by event bindings.
*/ */
genEventBindingEvalValue(eventRecord: any, protoRec: ProtoRecord): string { genEventBindingEvalValue(eventRecord: any, protoRec: ProtoRecord): string {
return this._genEvalValue(protoRec, idx => this._names.getEventLocalName(eventRecord, idx), return this._genEvalValue(
"locals"); protoRec, idx => this._names.getEventLocalName(eventRecord, idx), 'locals');
} }
private _genEvalValue(protoRec: ProtoRecord, getLocalName: Function, private _genEvalValue(protoRec: ProtoRecord, getLocalName: Function, localsAccessor: string):
localsAccessor: string): string { string {
var context = (protoRec.contextIndex == -1) ? var context = (protoRec.contextIndex == -1) ?
this._names.getDirectiveName(protoRec.directiveIndex) : this._names.getDirectiveName(protoRec.directiveIndex) :
getLocalName(protoRec.contextIndex); getLocalName(protoRec.contextIndex);
var argString = protoRec.args.map(arg => getLocalName(arg)).join(", "); var argString = protoRec.args.map(arg => getLocalName(arg)).join(', ');
var rhs: string; var rhs: string;
switch (protoRec.mode) { switch (protoRec.mode) {
@ -108,12 +109,12 @@ export class CodegenLogicUtil {
return `${getLocalName(protoRec.selfIndex)} = ${rhs};`; return `${getLocalName(protoRec.selfIndex)} = ${rhs};`;
} }
genPropertyBindingTargets(propertyBindingTargets: BindingTarget[], genPropertyBindingTargets(propertyBindingTargets: BindingTarget[], genDebugInfo: boolean):
genDebugInfo: boolean): string { string {
var bs = propertyBindingTargets.map(b => { var bs = propertyBindingTargets.map(b => {
if (isBlank(b)) return "null"; if (isBlank(b)) return 'null';
var debug = genDebugInfo ? codify(b.debug) : "null"; var debug = genDebugInfo ? codify(b.debug) : 'null';
return `${this._utilName}.bindingTarget(${codify(b.mode)}, ${b.elementIndex}, ${codify(b.name)}, ${codify(b.unit)}, ${debug})`; return `${this._utilName}.bindingTarget(${codify(b.mode)}, ${b.elementIndex}, ${codify(b.name)}, ${codify(b.unit)}, ${debug})`;
}); });
return `[${bs.join(", ")}]`; return `[${bs.join(", ")}]`;
@ -165,7 +166,7 @@ export class CodegenLogicUtil {
res.unshift(`${statementStart} = new Array(${outputCount});`); res.unshift(`${statementStart} = new Array(${outputCount});`);
} }
} }
return res.join("\n"); return res.join('\n');
} }
genDirectivesOnDestroy(directiveRecords: DirectiveRecord[]): string { genDirectivesOnDestroy(directiveRecords: DirectiveRecord[]): string {
@ -177,7 +178,7 @@ export class CodegenLogicUtil {
res.push(`${dirVarName}.ngOnDestroy();`); res.push(`${dirVarName}.ngOnDestroy();`);
} }
} }
return res.join("\n"); return res.join('\n');
} }
private _genEventHandler(boundElementIndex: number, eventName: string): string { private _genEventHandler(boundElementIndex: number, eventName: string): string {
@ -199,7 +200,7 @@ export class CodegenLogicUtil {
`${this._names.getDetectorName(r.directiveIndex)} = this.getDetectorFor(directives, ${i});`); `${this._names.getDetectorName(r.directiveIndex)} = this.getDetectorFor(directives, ${i});`);
} }
} }
return res.join("\n"); return res.join('\n');
} }
genContentLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] { genContentLifecycleCallbacks(directiveRecords: DirectiveRecord[]): string[] {

View File

@ -8,16 +8,16 @@ import {EventBinding} from './event_binding';
// The names of these fields must be kept in sync with abstract_change_detector.ts or change // The names of these fields must be kept in sync with abstract_change_detector.ts or change
// detection will fail. // detection will fail.
const _STATE_ACCESSOR = "state"; const _STATE_ACCESSOR = 'state';
const _CONTEXT_ACCESSOR = "context"; const _CONTEXT_ACCESSOR = 'context';
const _PROP_BINDING_INDEX = "propertyBindingIndex"; const _PROP_BINDING_INDEX = 'propertyBindingIndex';
const _DIRECTIVES_ACCESSOR = "directiveIndices"; const _DIRECTIVES_ACCESSOR = 'directiveIndices';
const _DISPATCHER_ACCESSOR = "dispatcher"; const _DISPATCHER_ACCESSOR = 'dispatcher';
const _LOCALS_ACCESSOR = "locals"; const _LOCALS_ACCESSOR = 'locals';
const _MODE_ACCESSOR = "mode"; const _MODE_ACCESSOR = 'mode';
const _PIPES_ACCESSOR = "pipes"; const _PIPES_ACCESSOR = 'pipes';
const _PROTOS_ACCESSOR = "protos"; const _PROTOS_ACCESSOR = 'protos';
export const CONTEXT_ACCESSOR = "context"; export const CONTEXT_ACCESSOR = 'context';
// `context` is always first. // `context` is always first.
export const CONTEXT_INDEX = 0; export const CONTEXT_INDEX = 0;
@ -47,8 +47,9 @@ export class CodegenNameUtil {
/** @internal */ /** @internal */
_sanitizedEventNames = new Map<EventBinding, string[]>(); _sanitizedEventNames = new Map<EventBinding, string[]>();
constructor(private _records: ProtoRecord[], private _eventBindings: EventBinding[], constructor(
private _directiveRecords: any[], private _utilName: string) { private _records: ProtoRecord[], private _eventBindings: EventBinding[],
private _directiveRecords: any[], private _utilName: string) {
this._sanitizedNames = ListWrapper.createFixedSize(this._records.length + 1); this._sanitizedNames = ListWrapper.createFixedSize(this._records.length + 1);
this._sanitizedNames[CONTEXT_INDEX] = CONTEXT_ACCESSOR; this._sanitizedNames[CONTEXT_INDEX] = CONTEXT_ACCESSOR;
for (var i = 0, iLen = this._records.length; i < iLen; ++i) { for (var i = 0, iLen = this._records.length; i < iLen; ++i) {
@ -132,7 +133,7 @@ export class CodegenNameUtil {
return res.length > 1 ? `var ${res.join(',')};` : ''; return res.length > 1 ? `var ${res.join(',')};` : '';
} }
getPreventDefaultAccesor(): string { return "preventDefault"; } getPreventDefaultAccesor(): string { return 'preventDefault'; }
getFieldCount(): number { return this._sanitizedNames.length; } getFieldCount(): number { return this._sanitizedNames.length; }

View File

@ -68,25 +68,20 @@ export enum ChangeDetectionStrategy {
* List of possible {@link ChangeDetectionStrategy} values. * List of possible {@link ChangeDetectionStrategy} values.
*/ */
export var CHANGE_DETECTION_STRATEGY_VALUES = [ export var CHANGE_DETECTION_STRATEGY_VALUES = [
ChangeDetectionStrategy.CheckOnce, ChangeDetectionStrategy.CheckOnce, ChangeDetectionStrategy.Checked,
ChangeDetectionStrategy.Checked, ChangeDetectionStrategy.CheckAlways, ChangeDetectionStrategy.Detached,
ChangeDetectionStrategy.CheckAlways, ChangeDetectionStrategy.OnPush, ChangeDetectionStrategy.Default
ChangeDetectionStrategy.Detached,
ChangeDetectionStrategy.OnPush,
ChangeDetectionStrategy.Default
]; ];
/** /**
* List of possible {@link ChangeDetectorState} values. * List of possible {@link ChangeDetectorState} values.
*/ */
export var CHANGE_DETECTOR_STATE_VALUES = [ export var CHANGE_DETECTOR_STATE_VALUES = [
ChangeDetectorState.NeverChecked, ChangeDetectorState.NeverChecked, ChangeDetectorState.CheckedBefore, ChangeDetectorState.Errored
ChangeDetectorState.CheckedBefore,
ChangeDetectorState.Errored
]; ];
export function isDefaultChangeDetectionStrategy( export function isDefaultChangeDetectionStrategy(changeDetectionStrategy: ChangeDetectionStrategy):
changeDetectionStrategy: ChangeDetectionStrategy): boolean { boolean {
return isBlank(changeDetectionStrategy) || return isBlank(changeDetectionStrategy) ||
changeDetectionStrategy === ChangeDetectionStrategy.Default; changeDetectionStrategy === ChangeDetectionStrategy.Default;
} }

View File

@ -2,14 +2,7 @@ import {CONST} from 'angular2/src/facade/lang';
import {BaseException} from 'angular2/src/facade/exceptions'; import {BaseException} from 'angular2/src/facade/exceptions';
import {isListLikeIterable, iterateListLike, ListWrapper} from 'angular2/src/facade/collection'; import {isListLikeIterable, iterateListLike, ListWrapper} from 'angular2/src/facade/collection';
import { import {isBlank, isPresent, stringify, getMapKey, looseIdentical, isArray} from 'angular2/src/facade/lang';
isBlank,
isPresent,
stringify,
getMapKey,
looseIdentical,
isArray
} from 'angular2/src/facade/lang';
import {ChangeDetectorRef} from '../change_detector_ref'; import {ChangeDetectorRef} from '../change_detector_ref';
import {IterableDiffer, IterableDifferFactory, TrackByFn} from '../differs/iterable_differs'; import {IterableDiffer, IterableDifferFactory, TrackByFn} from '../differs/iterable_differs';
@ -170,7 +163,7 @@ export class DefaultIterableDiffer implements IterableDiffer {
*/ */
get isDirty(): boolean { get isDirty(): boolean {
return this._additionsHead !== null || this._movesHead !== null || return this._additionsHead !== null || this._movesHead !== null ||
this._removalsHead !== null || this._identityChangesHead !== null; this._removalsHead !== null || this._identityChangesHead !== null;
} }
/** /**
@ -218,8 +211,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
* *
* @internal * @internal
*/ */
_mismatch(record: CollectionChangeRecord, item: any, itemTrackBy: any, _mismatch(record: CollectionChangeRecord, item: any, itemTrackBy: any, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
// The previous record after which we will append the current one. // The previous record after which we will append the current one.
var previousRecord: CollectionChangeRecord; var previousRecord: CollectionChangeRecord;
@ -284,8 +277,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
* *
* @internal * @internal
*/ */
_verifyReinsertion(record: CollectionChangeRecord, item: any, itemTrackBy: any, _verifyReinsertion(record: CollectionChangeRecord, item: any, itemTrackBy: any, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
var reinsertRecord: CollectionChangeRecord = var reinsertRecord: CollectionChangeRecord =
this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy); this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy);
if (reinsertRecord !== null) { if (reinsertRecord !== null) {
@ -333,8 +326,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
} }
/** @internal */ /** @internal */
_reinsertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, _reinsertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
if (this._unlinkedRecords !== null) { if (this._unlinkedRecords !== null) {
this._unlinkedRecords.remove(record); this._unlinkedRecords.remove(record);
} }
@ -358,8 +351,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
} }
/** @internal */ /** @internal */
_moveAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, _moveAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
this._unlink(record); this._unlink(record);
this._insertAfter(record, prevRecord, index); this._insertAfter(record, prevRecord, index);
this._addToMoves(record, index); this._addToMoves(record, index);
@ -367,8 +360,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
} }
/** @internal */ /** @internal */
_addAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, _addAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
this._insertAfter(record, prevRecord, index); this._insertAfter(record, prevRecord, index);
if (this._additionsTail === null) { if (this._additionsTail === null) {
@ -385,8 +378,8 @@ export class DefaultIterableDiffer implements IterableDiffer {
} }
/** @internal */ /** @internal */
_insertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, _insertAfter(record: CollectionChangeRecord, prevRecord: CollectionChangeRecord, index: number):
index: number): CollectionChangeRecord { CollectionChangeRecord {
// todo(vicb) // todo(vicb)
// assert(record != prevRecord); // assert(record != prevRecord);
// assert(record._next === null); // assert(record._next === null);
@ -527,10 +520,12 @@ export class DefaultIterableDiffer implements IterableDiffer {
var identityChanges = []; var identityChanges = [];
this.forEachIdentityChange((record) => identityChanges.push(record)); this.forEachIdentityChange((record) => identityChanges.push(record));
return "collection: " + list.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" + return 'collection: ' + list.join(', ') + '\n' +
"additions: " + additions.join(', ') + "\n" + "moves: " + moves.join(', ') + "\n" + 'previous: ' + previous.join(', ') + '\n' +
"removals: " + removals.join(', ') + "\n" + "identityChanges: " + 'additions: ' + additions.join(', ') + '\n' +
identityChanges.join(', ') + "\n"; 'moves: ' + moves.join(', ') + '\n' +
'removals: ' + removals.join(', ') + '\n' +
'identityChanges: ' + identityChanges.join(', ') + '\n';
} }
} }
@ -563,10 +558,9 @@ export class CollectionChangeRecord {
constructor(public item: any, public trackById: any) {} constructor(public item: any, public trackById: any) {}
toString(): string { toString(): string {
return this.previousIndex === this.currentIndex ? return this.previousIndex === this.currentIndex ? stringify(this.item) :
stringify(this.item) : stringify(this.item) + '[' +
stringify(this.item) + '[' + stringify(this.previousIndex) + '->' + stringify(this.previousIndex) + '->' + stringify(this.currentIndex) + ']';
stringify(this.currentIndex) + ']';
} }
} }

View File

@ -24,7 +24,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
get isDirty(): boolean { get isDirty(): boolean {
return this._additionsHead !== null || this._changesHead !== null || return this._additionsHead !== null || this._changesHead !== null ||
this._removalsHead !== null; this._removalsHead !== null;
} }
forEachItem(fn: Function) { forEachItem(fn: Function) {
@ -206,7 +206,7 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
/** @internal */ /** @internal */
_isInRemovals(record: KeyValueChangeRecord) { _isInRemovals(record: KeyValueChangeRecord) {
return record === this._removalsHead || record._nextRemoved !== null || return record === this._removalsHead || record._nextRemoved !== null ||
record._prevRemoved !== null; record._prevRemoved !== null;
} }
/** @internal */ /** @internal */
@ -318,9 +318,11 @@ export class DefaultKeyValueDiffer implements KeyValueDiffer {
removals.push(stringify(record)); removals.push(stringify(record));
} }
return "map: " + items.join(', ') + "\n" + "previous: " + previous.join(', ') + "\n" + return 'map: ' + items.join(', ') + '\n' +
"additions: " + additions.join(', ') + "\n" + "changes: " + changes.join(', ') + "\n" + 'previous: ' + previous.join(', ') + '\n' +
"removals: " + removals.join(', ') + "\n"; 'additions: ' + additions.join(', ') + '\n' +
'changes: ' + changes.join(', ') + '\n' +
'removals: ' + removals.join(', ') + '\n';
} }
/** @internal */ /** @internal */
@ -355,8 +357,8 @@ export class KeyValueChangeRecord {
toString(): string { toString(): string {
return looseIdentical(this.previousValue, this.currentValue) ? return looseIdentical(this.previousValue, this.currentValue) ?
stringify(this.key) : stringify(this.key) :
(stringify(this.key) + '[' + stringify(this.previousValue) + '->' + (stringify(this.key) + '[' + stringify(this.previousValue) + '->' +
stringify(this.currentValue) + ']'); stringify(this.currentValue) + ']');
} }
} }

View File

@ -21,21 +21,22 @@ export class DirectiveRecord {
// array of [emitter property name, eventName] // array of [emitter property name, eventName]
outputs: string[][]; outputs: string[][];
constructor({directiveIndex, callAfterContentInit, callAfterContentChecked, callAfterViewInit, constructor(
callAfterViewChecked, callOnChanges, callDoCheck, callOnInit, callOnDestroy, {directiveIndex, callAfterContentInit, callAfterContentChecked, callAfterViewInit,
changeDetection, outputs}: { callAfterViewChecked, callOnChanges, callDoCheck, callOnInit, callOnDestroy, changeDetection,
directiveIndex?: DirectiveIndex, outputs}: {
callAfterContentInit?: boolean, directiveIndex?: DirectiveIndex,
callAfterContentChecked?: boolean, callAfterContentInit?: boolean,
callAfterViewInit?: boolean, callAfterContentChecked?: boolean,
callAfterViewChecked?: boolean, callAfterViewInit?: boolean,
callOnChanges?: boolean, callAfterViewChecked?: boolean,
callDoCheck?: boolean, callOnChanges?: boolean,
callOnInit?: boolean, callDoCheck?: boolean,
callOnDestroy?: boolean, callOnInit?: boolean,
changeDetection?: ChangeDetectionStrategy, callOnDestroy?: boolean,
outputs?: string[][] changeDetection?: ChangeDetectionStrategy,
} = {}) { outputs?: string[][]
} = {}) {
this.directiveIndex = directiveIndex; this.directiveIndex = directiveIndex;
this.callAfterContentInit = normalizeBool(callAfterContentInit); this.callAfterContentInit = normalizeBool(callAfterContentInit);
this.callAfterContentChecked = normalizeBool(callAfterContentChecked); this.callAfterContentChecked = normalizeBool(callAfterContentChecked);

View File

@ -20,11 +20,11 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
localPipes: any[]; localPipes: any[];
prevContexts: any[]; prevContexts: any[];
constructor(id: string, numberOfPropertyProtoRecords: number, constructor(
propertyBindingTargets: BindingTarget[], directiveIndices: DirectiveIndex[], id: string, numberOfPropertyProtoRecords: number, propertyBindingTargets: BindingTarget[],
strategy: ChangeDetectionStrategy, private _records: ProtoRecord[], directiveIndices: DirectiveIndex[], strategy: ChangeDetectionStrategy,
private _eventBindings: EventBinding[], private _directiveRecords: DirectiveRecord[], private _records: ProtoRecord[], private _eventBindings: EventBinding[],
private _genConfig: ChangeDetectorGenConfig) { private _directiveRecords: DirectiveRecord[], private _genConfig: ChangeDetectorGenConfig) {
super(id, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy); super(id, numberOfPropertyProtoRecords, propertyBindingTargets, directiveIndices, strategy);
var len = _records.length + 1; var len = _records.length + 1;
this.values = ListWrapper.createFixedSize(len); this.values = ListWrapper.createFixedSize(len);
@ -38,13 +38,12 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean { handleEventInternal(eventName: string, elIndex: number, locals: Locals): boolean {
var preventDefault = false; var preventDefault = false;
this._matchingEventBindings(eventName, elIndex) this._matchingEventBindings(eventName, elIndex).forEach(rec => {
.forEach(rec => { var res = this._processEventBinding(rec, locals);
var res = this._processEventBinding(rec, locals); if (res === false) {
if (res === false) { preventDefault = true;
preventDefault = true; }
} });
});
return preventDefault; return preventDefault;
} }
@ -72,7 +71,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
} }
} }
throw new BaseException("Cannot be reached"); throw new BaseException('Cannot be reached');
} }
private _computeSkipLength(protoIndex: number, proto: ProtoRecord, values: any[]): number { private _computeSkipLength(protoIndex: number, proto: ProtoRecord, values: any[]): number {
@ -90,7 +89,7 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
return condition ? 0 : proto.fixedArgs[0] - protoIndex - 1; return condition ? 0 : proto.fixedArgs[0] - protoIndex - 1;
} }
throw new BaseException("Cannot be reached"); throw new BaseException('Cannot be reached');
} }
/** @internal */ /** @internal */
@ -179,12 +178,13 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
} }
if (proto.isLifeCycleRecord()) { if (proto.isLifeCycleRecord()) {
if (proto.name === "DoCheck" && !throwOnChange) { if (proto.name === 'DoCheck' && !throwOnChange) {
this._getDirectiveFor(directiveRecord.directiveIndex).ngDoCheck(); this._getDirectiveFor(directiveRecord.directiveIndex).ngDoCheck();
} else if (proto.name === "OnInit" && !throwOnChange && } else if (
this.state == ChangeDetectorState.NeverChecked) { proto.name === 'OnInit' && !throwOnChange &&
this.state == ChangeDetectorState.NeverChecked) {
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnInit(); this._getDirectiveFor(directiveRecord.directiveIndex).ngOnInit();
} else if (proto.name === "OnChanges" && isPresent(changes) && !throwOnChange) { } else if (proto.name === 'OnChanges' && isPresent(changes) && !throwOnChange) {
this._getDirectiveFor(directiveRecord.directiveIndex).ngOnChanges(changes); this._getDirectiveFor(directiveRecord.directiveIndex).ngOnChanges(changes);
} }
} else if (proto.isSkipRecord()) { } else if (proto.isSkipRecord()) {
@ -276,8 +276,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
} }
/** @internal */ /** @internal */
private _check(proto: ProtoRecord, throwOnChange: boolean, values: any[], private _check(proto: ProtoRecord, throwOnChange: boolean, values: any[], locals: Locals):
locals: Locals): SimpleChange { SimpleChange {
if (proto.isPipeRecord()) { if (proto.isPipeRecord()) {
return this._pipeCheck(proto, throwOnChange, values); return this._pipeCheck(proto, throwOnChange, values);
} else { } else {
@ -286,8 +286,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
} }
/** @internal */ /** @internal */
private _referenceCheck(proto: ProtoRecord, throwOnChange: boolean, values: any[], private _referenceCheck(
locals: Locals) { proto: ProtoRecord, throwOnChange: boolean, values: any[], locals: Locals) {
if (this._pureFuncAndArgsDidNotChange(proto)) { if (this._pureFuncAndArgsDidNotChange(proto)) {
this._setChanged(proto, false); this._setChanged(proto, false);
return null; return null;
@ -298,8 +298,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
if (proto.shouldBeChecked()) { if (proto.shouldBeChecked()) {
var prevValue = this._readSelf(proto, values); var prevValue = this._readSelf(proto, values);
var detectedChange = throwOnChange ? var detectedChange = throwOnChange ?
!ChangeDetectionUtil.devModeEqual(prevValue, currValue) : !ChangeDetectionUtil.devModeEqual(prevValue, currValue) :
ChangeDetectionUtil.looseNotIdentical(prevValue, currValue); ChangeDetectionUtil.looseNotIdentical(prevValue, currValue);
if (detectedChange) { if (detectedChange) {
if (proto.lastInBinding) { if (proto.lastInBinding) {
var change = ChangeDetectionUtil.simpleChange(prevValue, currValue); var change = ChangeDetectionUtil.simpleChange(prevValue, currValue);
@ -379,8 +379,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
return args[args.length - 1]; return args[args.length - 1];
case RecordType.InvokeClosure: case RecordType.InvokeClosure:
return FunctionWrapper.apply(this._readContext(proto, values), return FunctionWrapper.apply(
this._readArgs(proto, values)); this._readContext(proto, values), this._readArgs(proto, values));
case RecordType.Interpolate: case RecordType.Interpolate:
case RecordType.PrimitiveOp: case RecordType.PrimitiveOp:
@ -402,8 +402,8 @@ export class DynamicChangeDetector extends AbstractChangeDetector<any> {
if (proto.shouldBeChecked()) { if (proto.shouldBeChecked()) {
var prevValue = this._readSelf(proto, values); var prevValue = this._readSelf(proto, values);
var detectedChange = throwOnChange ? var detectedChange = throwOnChange ?
!ChangeDetectionUtil.devModeEqual(prevValue, currValue) : !ChangeDetectionUtil.devModeEqual(prevValue, currValue) :
ChangeDetectionUtil.looseNotIdentical(prevValue, currValue); ChangeDetectionUtil.looseNotIdentical(prevValue, currValue);
if (detectedChange) { if (detectedChange) {
currValue = ChangeDetectionUtil.unwrapValue(currValue); currValue = ChangeDetectionUtil.unwrapValue(currValue);

View File

@ -2,6 +2,7 @@ import {DirectiveIndex} from './directive_record';
import {ProtoRecord} from './proto_record'; import {ProtoRecord} from './proto_record';
export class EventBinding { export class EventBinding {
constructor(public eventName: string, public elIndex: number, public dirIndex: DirectiveIndex, constructor(
public records: ProtoRecord[]) {} public eventName: string, public elIndex: number, public dirIndex: DirectiveIndex,
public records: ProtoRecord[]) {}
} }

View File

@ -1,4 +1,4 @@
import {BaseException, WrappedException} from "angular2/src/facade/exceptions"; import {BaseException, WrappedException} from 'angular2/src/facade/exceptions';
/** /**
* An error thrown if application changes model breaking the top-down data flow. * An error thrown if application changes model breaking the top-down data flow.
@ -35,8 +35,9 @@ import {BaseException, WrappedException} from "angular2/src/facade/exceptions";
*/ */
export class ExpressionChangedAfterItHasBeenCheckedException extends BaseException { export class ExpressionChangedAfterItHasBeenCheckedException extends BaseException {
constructor(exp: string, oldValue: any, currValue: any, context: any) { constructor(exp: string, oldValue: any, currValue: any, context: any) {
super(`Expression '${exp}' has changed after it was checked. ` + super(
`Previous value: '${oldValue}'. Current value: '${currValue}'`); `Expression '${exp}' has changed after it was checked. ` +
`Previous value: '${oldValue}'. Current value: '${currValue}'`);
} }
} }
@ -107,6 +108,7 @@ export class EventEvaluationError extends WrappedException {
* Error context included when an event handler throws an exception. * Error context included when an event handler throws an exception.
*/ */
export class EventEvaluationErrorContext { export class EventEvaluationErrorContext {
constructor(public element: any, public componentElement: any, public context: any, constructor(
public locals: any, public injector: any) {} public element: any, public componentElement: any, public context: any, public locals: any,
public injector: any) {}
} }

View File

@ -5,8 +5,9 @@ import {ChangeDetectionStrategy} from './constants';
import {ChangeDetectorRef} from './change_detector_ref'; import {ChangeDetectorRef} from './change_detector_ref';
export class DebugContext { export class DebugContext {
constructor(public element: any, public componentElement: any, public directive: any, constructor(
public context: any, public locals: any, public injector: any) {} public element: any, public componentElement: any, public directive: any, public context: any,
public locals: any, public injector: any) {}
} }
export interface ChangeDispatcher { export interface ChangeDispatcher {
@ -44,13 +45,13 @@ export interface ChangeDetector {
export interface ProtoChangeDetector { instantiate(): ChangeDetector; } export interface ProtoChangeDetector { instantiate(): ChangeDetector; }
export class ChangeDetectorGenConfig { export class ChangeDetectorGenConfig {
constructor(public genDebugInfo: boolean, public logBindingUpdate: boolean, constructor(
public useJit: boolean) {} public genDebugInfo: boolean, public logBindingUpdate: boolean, public useJit: boolean) {}
} }
export class ChangeDetectorDefinition { export class ChangeDetectorDefinition {
constructor(public id: string, public strategy: ChangeDetectionStrategy, constructor(
public variableNames: string[], public bindingRecords: BindingRecord[], public id: string, public strategy: ChangeDetectionStrategy, public variableNames: string[],
public eventRecords: BindingRecord[], public directiveRecords: DirectiveRecord[], public bindingRecords: BindingRecord[], public eventRecords: BindingRecord[],
public genConfig: ChangeDetectorGenConfig) {} public directiveRecords: DirectiveRecord[], public genConfig: ChangeDetectorGenConfig) {}
} }

View File

@ -18,8 +18,8 @@ export class JitProtoChangeDetector implements ProtoChangeDetector {
/** @internal */ /** @internal */
_createFactory(definition: ChangeDetectorDefinition) { _createFactory(definition: ChangeDetectorDefinition) {
return new ChangeDetectorJITGenerator(definition, 'util', 'AbstractChangeDetector', return new ChangeDetectorJITGenerator(
'ChangeDetectorStatus') definition, 'util', 'AbstractChangeDetector', 'ChangeDetectorStatus')
.generate(); .generate();
} }
} }

Some files were not shown because too many files have changed in this diff Show More