| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   xit, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   beforeEach, | 
					
						
							|  |  |  |   afterEach, | 
					
						
							|  |  |  |   inject, | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |   beforeEachProviders | 
					
						
							| 
									
										
										
										
											2015-10-13 00:29:13 -07:00
										 |  |  | } from 'angular2/testing_internal'; | 
					
						
							| 
									
										
										
										
											2015-10-10 22:11:13 -07:00
										 |  |  | import {provide} from 'angular2/src/core/di'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-10 22:11:13 -07:00
										 |  |  | import {TEST_PROVIDERS} from './test_bindings'; | 
					
						
							| 
									
										
										
										
											2015-11-06 17:34:07 -08:00
										 |  |  | import {isPresent} from 'angular2/src/facade/lang'; | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | import { | 
					
						
							|  |  |  |   TemplateParser, | 
					
						
							|  |  |  |   splitClasses, | 
					
						
							|  |  |  |   TEMPLATE_TRANSFORMS | 
					
						
							|  |  |  | } from 'angular2/src/compiler/template_parser'; | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |   CompileDirectiveMetadata, | 
					
						
							|  |  |  |   CompileTypeMetadata, | 
					
						
							|  |  |  |   CompileTemplateMetadata | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | } from 'angular2/src/compiler/directive_metadata'; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   templateVisitAll, | 
					
						
							|  |  |  |   TemplateAstVisitor, | 
					
						
							|  |  |  |   TemplateAst, | 
					
						
							|  |  |  |   NgContentAst, | 
					
						
							|  |  |  |   EmbeddedTemplateAst, | 
					
						
							|  |  |  |   ElementAst, | 
					
						
							|  |  |  |   VariableAst, | 
					
						
							|  |  |  |   BoundEventAst, | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |   BoundElementPropertyAst, | 
					
						
							|  |  |  |   BoundDirectivePropertyAst, | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |   AttrAst, | 
					
						
							|  |  |  |   BoundTextAst, | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |   TextAst, | 
					
						
							|  |  |  |   PropertyBindingType, | 
					
						
							|  |  |  |   DirectiveAst | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | } from 'angular2/src/compiler/template_ast'; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | import {ElementSchemaRegistry} from 'angular2/src/compiler/schema/element_schema_registry'; | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  | import {MockSchemaRegistry} from './schema_registry_mock'; | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-05 14:07:57 -08:00
										 |  |  | import {Unparser} from '../core/change_detection/parser/unparser'; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | var expressionUnparser = new Unparser(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   describe('TemplateParser', () => { | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |     beforeEachProviders(() => [ | 
					
						
							| 
									
										
										
										
											2015-10-10 22:11:13 -07:00
										 |  |  |       TEST_PROVIDERS, | 
					
						
							|  |  |  |       provide(ElementSchemaRegistry, | 
					
						
							|  |  |  |               { | 
					
						
							| 
									
										
										
										
											2015-10-12 11:30:34 -07:00
										 |  |  |                 useValue: new MockSchemaRegistry({'invalidProp': false}, | 
					
						
							|  |  |  |                                                  {'mappedAttr': 'mappedProp'}) | 
					
						
							| 
									
										
										
										
											2015-10-10 22:11:13 -07:00
										 |  |  |               }) | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |     ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     var parser: TemplateParser; | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     var ngIf; | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |     beforeEach(inject([TemplateParser], (_parser) => { | 
					
						
							|  |  |  |       parser = _parser; | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |       ngIf = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |           {selector: '[ng-if]', type: new CompileTypeMetadata({name: 'NgIf'}), inputs: ['ngIf']}); | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |     })); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |     function parse(template: string, directives: CompileDirectiveMetadata[]): TemplateAst[] { | 
					
						
							| 
									
										
										
										
											2015-09-14 15:59:09 -07:00
										 |  |  |       return parser.parse(template, directives, 'TestComp'); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  |     describe('template transform', () => { | 
					
						
							|  |  |  |       beforeEachProviders( | 
					
						
							|  |  |  |           () => [provide(TEMPLATE_TRANSFORMS, {useValue: new FooAstTransformer(), multi: true})]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should transform TemplateAST', | 
					
						
							|  |  |  |          () => { expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'foo']]); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('multiple', () => { | 
					
						
							|  |  |  |         beforeEachProviders( | 
					
						
							|  |  |  |             () => [provide(TEMPLATE_TRANSFORMS, {useValue: new BarAstTransformer(), multi: true})]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should compose transformers', | 
					
						
							|  |  |  |            () => { expect(humanizeTplAst(parse('<div>', []))).toEqual([[ElementAst, 'bar']]); }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     describe('parse', () => { | 
					
						
							|  |  |  |       describe('nodes without bindings', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |         it('should parse text nodes', | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |            () => { expect(humanizeTplAst(parse('a', []))).toEqual([[TextAst, 'a']]); }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should parse elements with attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a=b>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [AttrAst, 'a', 'b']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse ngContent', () => { | 
					
						
							|  |  |  |         var parsed = parse('<ng-content select="a">', []); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parsed)).toEqual([[NgContentAst]]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should parse bound text nodes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('{{a}}', []))).toEqual([[BoundTextAst, '{{ a }}']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       describe('bound properties', () => { | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         it('should parse mixed case bound properties', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div [someProp]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'someProp', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should parse and camel case bound properties', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [some-prop]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'someProp', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should normalize property names via the element schema', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [mapped-attr]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'mappedProp', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         it('should parse mixed case bound attributes', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div [attr.someAttr]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Attribute, 'someAttr', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should parse and camel case bound attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [attr.some-attr]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Attribute, 'someAttr', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [ATTR.some-attr]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Attribute, 'someAttr', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse and dash case bound classes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [class.some-class]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Class, 'some-class', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [CLASS.some-class]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Class, 'some-class', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse mixed case bound classes', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div [class.someClass]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Class, 'someClass', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse and camel case bound styles', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [style.some-style]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Style, 'someStyle', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div [STYLE.some-style]="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Style, 'someStyle', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse and mixed case bound styles', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div [style.someStyle]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Style, 'someStyle', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via [...] and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [prop]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via bind- and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div bind-prop="v">', []))) | 
					
						
							|  |  |  |               .toEqual([ | 
					
						
							|  |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null] | 
					
						
							|  |  |  |               ]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div BIND-prop="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties via {{...}} and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div prop="{{v}}">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', '{{ v }}', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('events', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events with a target', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div (window:event)="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', 'window', 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events via (...) and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div (event)="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         it('should parse and camel case event names', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div (some-event)="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'someEvent', null, 'v']]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse mixed case event names', () => { | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div (someEvent)="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'someEvent', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events via on- and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div on-event="v">', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div ON-event="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [BoundEventAst, 'event', null, 'v']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |         it('should allow events on explicit embedded templates that are emitted by a directive', | 
					
						
							|  |  |  |            () => { | 
					
						
							|  |  |  |              var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: 'template', | 
					
						
							|  |  |  |                outputs: ['e'], | 
					
						
							|  |  |  |                type: new CompileTypeMetadata({name: 'DirA'}) | 
					
						
							|  |  |  |              }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<template (e)="f"></template>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                    [BoundEventAst, 'e', null, 'f'], | 
					
						
							|  |  |  |                    [DirectiveAst, dirA], | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('bindon', () => { | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         it('should parse bound events and properties via [(...)] and not report them as attributes', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<div [(prop)]="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null], | 
					
						
							|  |  |  |                    [BoundEventAst, 'propChange', null, 'v = $event'] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound events and properties via bindon- and not report them as attributes', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<div bindon-prop="v">', []))) | 
					
						
							|  |  |  |                  .toEqual([ | 
					
						
							|  |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null], | 
					
						
							|  |  |  |                    [BoundEventAst, 'propChange', null, 'v = $event'] | 
					
						
							|  |  |  |                  ]); | 
					
						
							|  |  |  |              expect(humanizeTplAst(parse('<div BINDON-prop="v">', []))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [BoundElementPropertyAst, PropertyBindingType.Property, 'prop', 'v', null], | 
					
						
							|  |  |  |                    [BoundEventAst, 'propChange', null, 'v = $event'] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       describe('directives', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should locate directives components first and ordered by the directives array in the View', | 
					
						
							|  |  |  |            () => { | 
					
						
							|  |  |  |              var dirA = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-28 10:30:33 -07:00
										 |  |  |                  {selector: '[a]', type: new CompileTypeMetadata({name: 'DirA'})}); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              var dirB = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-28 10:30:33 -07:00
										 |  |  |                  {selector: '[b]', type: new CompileTypeMetadata({name: 'DirB'})}); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              var dirC = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-28 10:30:33 -07:00
										 |  |  |                  {selector: '[c]', type: new CompileTypeMetadata({name: 'DirC'})}); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              var comp = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |                selector: 'div', | 
					
						
							|  |  |  |                isComponent: true, | 
					
						
							|  |  |  |                type: new CompileTypeMetadata({name: 'ZComp'}), | 
					
						
							|  |  |  |                template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							|  |  |  |              }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<div a c b>', [dirA, dirB, dirC, comp]))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [ElementAst, 'div'], | 
					
						
							|  |  |  |                    [AttrAst, 'a', ''], | 
					
						
							|  |  |  |                    [AttrAst, 'c', ''], | 
					
						
							|  |  |  |                    [AttrAst, 'b', ''], | 
					
						
							|  |  |  |                    [DirectiveAst, comp], | 
					
						
							|  |  |  |                    [DirectiveAst, dirA], | 
					
						
							|  |  |  |                    [DirectiveAst, dirB], | 
					
						
							|  |  |  |                    [DirectiveAst, dirC] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should locate directives in property bindings', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |               {selector: '[a=b]', type: new CompileTypeMetadata({name: 'DirA'})}); | 
					
						
							|  |  |  |           var dirB = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |               {selector: '[b]', type: new CompileTypeMetadata({name: 'DirB'})}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [a]="b">', [dirA, dirB]))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'b', null], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should parse directive host properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |             selector: 'div', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							|  |  |  |             host: {'[a]': 'expr'} | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundElementPropertyAst, PropertyBindingType.Property, 'a', 'expr', null] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse directive host listeners', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |             selector: 'div', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							|  |  |  |             host: {'(a)': 'expr'} | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual( | 
					
						
							|  |  |  |                   [[ElementAst, 'div'], [DirectiveAst, dirA], [BoundEventAst, 'a', null, 'expr']]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse directive properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |               {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['aProp']}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [a-prop]="expr"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'aProp', 'expr'] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse renamed directive properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |               {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['b:a']}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div [a]="expr"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'b', 'expr'] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse literal directive properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |               {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['a']}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a="literal"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', 'literal'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'a', '"literal"'] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should favor explicit bound properties over literal properties', () => { | 
					
						
							|  |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |               {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['a']}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a="literal" [a]="\'literal2\'"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', 'literal'], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'a', '"literal2"'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         it('should support optional directive properties', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |               {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['a']}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [DirectiveAst, dirA]]); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       describe('variables', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via #... and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div #a>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [VariableAst, 'a', '']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via var-... and not report them as attributes', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div var-a>', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'div'], [VariableAst, 'a', '']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div VAR-a>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [VariableAst, 'a', '']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should camel case variables', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div var-some-a>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [VariableAst, 'someA', '']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         it('should assign variables with empty value to the element', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div #a></div>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'div'], [VariableAst, 'a', '']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should assign variables to directives via exportAs', () => { | 
					
						
							|  |  |  |           var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |               {selector: '[a]', type: new CompileTypeMetadata({name: 'DirA'}), exportAs: 'dirA'}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a #a="dirA"></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', ''], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [VariableAst, 'a', 'dirA'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should report variables with values that dont match a directive as errors', () => { | 
					
						
							|  |  |  |           expect(() => parse('<div #a="dirA"></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | There is no directive with "exportAs" set to "dirA" ("<div [ERROR ->]#a="dirA"></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should allow variables with values that dont match a directive on embedded template elements', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect(humanizeTplAst(parse('<template #a="b"></template>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                  .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should assign variables with empty value to components', () => { | 
					
						
							|  |  |  |           var dirA = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |             selector: '[a]', | 
					
						
							|  |  |  |             isComponent: true, | 
					
						
							|  |  |  |             type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |             exportAs: 'dirA', | 
					
						
							|  |  |  |             template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div a #a></div>', [dirA]))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [ElementAst, 'div'], | 
					
						
							|  |  |  |                 [AttrAst, 'a', ''], | 
					
						
							|  |  |  |                 [VariableAst, 'a', ''], | 
					
						
							|  |  |  |                 [DirectiveAst, dirA], | 
					
						
							|  |  |  |                 [VariableAst, 'a', ''] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       describe('explicit templates', () => { | 
					
						
							|  |  |  |         it('should create embedded templates for <template> elements', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<template></template>', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst]]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<TEMPLATE></TEMPLATE>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst]]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('inline templates', () => { | 
					
						
							|  |  |  |         it('should wrap the element into an EmbeddedTemplateAST', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div template>', []))) | 
					
						
							|  |  |  |               .toEqual([[EmbeddedTemplateAst], [ElementAst, 'div']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<div TEMPLATE>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse bound properties', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div template="ngIf test">', [ngIf]))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'test'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via #...', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div template="ngIf #a=b">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should parse variables via var ...', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div template="ngIf var a=b">', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[EmbeddedTemplateAst], [VariableAst, 'a', 'b'], [ElementAst, 'div']]); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         describe('directives', () => { | 
					
						
							|  |  |  |           it('should locate directives in property bindings', () => { | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |             var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |                 {selector: '[a=b]', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['a']}); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             var dirB = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |                 {selector: '[b]', type: new CompileTypeMetadata({name: 'DirB'})}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |             expect(humanizeTplAst(parse('<div template="a b" b>', [dirA, dirB]))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                 .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                   [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                   [DirectiveAst, dirA], | 
					
						
							|  |  |  |                   [BoundDirectivePropertyAst, 'a', 'b'], | 
					
						
							|  |  |  |                   [ElementAst, 'div'], | 
					
						
							|  |  |  |                   [AttrAst, 'b', ''], | 
					
						
							|  |  |  |                   [DirectiveAst, dirB] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                 ]); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it('should locate directives in variable bindings', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |                 {selector: '[a=b]', type: new CompileTypeMetadata({name: 'DirA'})}); | 
					
						
							|  |  |  |             var dirB = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |                 {selector: '[b]', type: new CompileTypeMetadata({name: 'DirB'})}); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |             expect(humanizeTplAst(parse('<div template="#a=b" b>', [dirA, dirB]))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                 .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                   [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                   [VariableAst, 'a', 'b'], | 
					
						
							|  |  |  |                   [DirectiveAst, dirA], | 
					
						
							|  |  |  |                   [ElementAst, 'div'], | 
					
						
							|  |  |  |                   [AttrAst, 'b', ''], | 
					
						
							|  |  |  |                   [DirectiveAst, dirB] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |                 ]); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should work with *... and use the attribute name as property binding name', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div *ng-if="test">', [ngIf]))) | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'test'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-10-26 13:22:45 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         it('should work with *... and empty value', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<div *ng-if>', [ngIf]))) | 
					
						
							| 
									
										
										
										
											2015-10-26 13:22:45 -07:00
										 |  |  |               .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                 [EmbeddedTemplateAst], | 
					
						
							|  |  |  |                 [DirectiveAst, ngIf], | 
					
						
							|  |  |  |                 [BoundDirectivePropertyAst, 'ngIf', 'null'], | 
					
						
							|  |  |  |                 [ElementAst, 'div'] | 
					
						
							| 
									
										
										
										
											2015-10-26 13:22:45 -07:00
										 |  |  |               ]); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |     describe('content projection', () => { | 
					
						
							| 
									
										
										
										
											2015-10-28 08:59:19 +01:00
										 |  |  |       function createComp(selector: string, | 
					
						
							|  |  |  |                           ngContentSelectors: string[]): CompileDirectiveMetadata { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         return CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: selector, | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           type: new CompileTypeMetadata({name: 'SomeComp'}), | 
					
						
							|  |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: ngContentSelectors}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }) | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('project text nodes', () => { | 
					
						
							|  |  |  |         it('should project text nodes with wildcard selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection(parse('<div>hello</div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['#text(hello)', 0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('project elements', () => { | 
					
						
							|  |  |  |         it('should project elements with wildcard selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><span></span></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['span', 0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project elements with css selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><a x></a><b></b></div>', [createComp('div', ['a[x]'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['a', 0], ['b', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('embedded templates', () => { | 
					
						
							|  |  |  |         it('should project embedded templates with wildcard selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><template></template></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['template', 0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project embedded templates with css selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><template x></template><template></template></div>', | 
					
						
							|  |  |  |                            [createComp('div', ['template[x]'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['template', 0], ['template', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('ng-content', () => { | 
					
						
							|  |  |  |         it('should project ng-content with wildcard selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><ng-content></ng-content></div>', [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['ng-content', 0]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should project ng-content with css selector', () => { | 
					
						
							|  |  |  |           expect(humanizeContentProjection( | 
					
						
							|  |  |  |                      parse('<div><ng-content x></ng-content><ng-content></ng-content></div>', | 
					
						
							|  |  |  |                            [createComp('div', ['ng-content[x]'])]))) | 
					
						
							|  |  |  |               .toEqual([['div', null], ['ng-content', 0], ['ng-content', null]]); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should project into the first matching ng-content', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div>hello<b></b><a></a></div>', [createComp('div', ['a', 'b', '*'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text(hello)', 2], ['b', 1], ['a', 0]]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-29 16:23:13 -07:00
										 |  |  |       it('should project into wildcard ng-content last', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div>hello<a></a></div>', [createComp('div', ['*', 'a'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text(hello)', 0], ['a', 1]]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |       it('should only project direct child nodes', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<div><span><a></a></span><a></a></div>', [createComp('div', ['a'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['span', null], ['a', null], ['a', 0]]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should project nodes of nested components', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection( | 
					
						
							|  |  |  |                    parse('<a><b>hello</b></a>', [createComp('a', ['*']), createComp('b', ['*'])]))) | 
					
						
							|  |  |  |             .toEqual([['a', null], ['b', 0], ['#text(hello)', 0]]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       it('should project children of components with ng-non-bindable', () => { | 
					
						
							|  |  |  |         expect(humanizeContentProjection(parse('<div ng-non-bindable>{{hello}}<span></span></div>', | 
					
						
							|  |  |  |                                                [createComp('div', ['*'])]))) | 
					
						
							|  |  |  |             .toEqual([['div', null], ['#text({{hello}})', 0], ['span', 0]]); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     describe('splitClasses', () => { | 
					
						
							|  |  |  |       it('should keep an empty class', () => { expect(splitClasses('a')).toEqual(['a']); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should split 2 classes', () => { expect(splitClasses('a b')).toEqual(['a', 'b']); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should trim classes', () => { expect(splitClasses(' a  b ')).toEqual(['a', 'b']); }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('error cases', () => { | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should report invalid property names', () => { | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |         expect(() => parse('<div [invalid-prop]></div>', [])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Can't bind to 'invalidProp' since it isn't a known native property ("<div [ERROR ->][invalid-prop]></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should report errors in expressions', () => { | 
					
						
							| 
									
										
										
										
											2015-09-10 15:25:36 -07:00
										 |  |  |         expect(() => parse('<div [prop]="a b"></div>', [])).toThrowErrorWith(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Parser Error: Unexpected token 'b' at column 3 in [a b] in TestComp@0:5 ("<div [ERROR ->][prop]="a b"></div>"): TestComp@0:5`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not throw on invalid property names if the property is used by a directive', | 
					
						
							|  |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |              selector: 'div', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |              inputs: ['invalidProp'] | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |            }); | 
					
						
							|  |  |  |            expect(() => parse('<div [invalid-prop]></div>', [dirA])).not.toThrow(); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not allow more than 1 component per element', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							|  |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirB = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           type: new CompileTypeMetadata({name: 'DirB'}), | 
					
						
							|  |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |         expect(() => parse('<div/>', [dirB, dirA])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | More than one component: DirB,DirA ("[ERROR ->]<div/>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-13 17:43:15 -07:00
										 |  |  |       it('should not allow components or element bindings nor dom events on explicit embedded templates', | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |            var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |              selector: '[a]', | 
					
						
							|  |  |  |              isComponent: true, | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |              type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							|  |  |  |              template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |            }); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |            expect(() => parse('<template [a]="b" (e)="f"></template>', [dirA])) | 
					
						
							|  |  |  |                .toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Event binding e not emitted by any directive on an embedded template ("<template [a]="b" [ERROR ->](e)="f"></template>"): TestComp@0:18 | 
					
						
							|  |  |  | Components on an embedded template: DirA ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0 | 
					
						
							|  |  |  | Property binding a not used by any directive on an embedded template ("[ERROR ->]<template [a]="b" (e)="f"></template>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should not allow components or element bindings on inline embedded templates', () => { | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |         var dirA = CompileDirectiveMetadata.create({ | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |           selector: '[a]', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |           type: new CompileTypeMetadata({name: 'DirA'}), | 
					
						
							|  |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |         expect(() => parse('<div *a="b"></div>', [dirA])).toThrowError(`Template parse errors:
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | Components on an embedded template: DirA ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0 | 
					
						
							|  |  |  | Property binding a not used by any directive on an embedded template ("[ERROR ->]<div *a="b"></div>"): TestComp@0:0`);
 | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('ignore elements', () => { | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <script> elements', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<script></script>a', []))).toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <style> elements', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<style></style>a', []))).toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |       describe('<link rel="stylesheet">', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should keep <link rel="stylesheet"> elements if they have an absolute non package: url', | 
					
						
							|  |  |  |            () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |              expect( | 
					
						
							|  |  |  |                  humanizeTplAst(parse('<link rel="stylesheet" href="http://someurl"></link>a', []))) | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |                  .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [ElementAst, 'link'], | 
					
						
							|  |  |  |                    [AttrAst, 'rel', 'stylesheet'], | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |                    [AttrAst, 'href', 'http://someurl'], | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                    [TextAst, 'a'] | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |                  ]); | 
					
						
							|  |  |  |            }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should keep <link rel="stylesheet"> elements if they have no uri', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet"></link>a', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[ElementAst, 'link'], [AttrAst, 'rel', 'stylesheet'], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<link REL="stylesheet"></link>a', []))) | 
					
						
							|  |  |  |               .toEqual([[ElementAst, 'link'], [AttrAst, 'REL', 'stylesheet'], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should ignore <link rel="stylesheet"> elements if they have a relative uri', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet" href="./other.css"></link>a', []))) | 
					
						
							|  |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							|  |  |  |           expect(humanizeTplAst(parse('<link rel="stylesheet" HREF="./other.css"></link>a', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should ignore <link rel="stylesheet"> elements if they have a package: uri', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |           expect(humanizeTplAst( | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |                      parse('<link rel="stylesheet" href="package:somePackage"></link>a', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               .toEqual([[TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-10-14 09:39:40 -07:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       it('should ignore bindings on children of elements with ng-non-bindable', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<div ng-non-bindable>{{b}}</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ng-non-bindable', ''], [TextAst, '{{b}}']]); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<div NG-NON-BINDABLE>{{b}}</div>', []))) | 
					
						
							|  |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'NG-NON-BINDABLE', ''], [TextAst, '{{b}}']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should keep nested children of elements with ng-non-bindable', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<div ng-non-bindable><span>{{b}}</span></div>', []))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |               [ElementAst, 'div'], | 
					
						
							|  |  |  |               [AttrAst, 'ng-non-bindable', ''], | 
					
						
							|  |  |  |               [ElementAst, 'span'], | 
					
						
							|  |  |  |               [TextAst, '{{b}}'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <script> elements inside of elements with ng-non-bindable', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<div ng-non-bindable><script></script>a</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ng-non-bindable', ''], [TextAst, 'a']]); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <style> elements inside of elements with ng-non-bindable', () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |         expect(humanizeTplAst(parse('<div ng-non-bindable><style></style>a</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |             .toEqual([[ElementAst, 'div'], [AttrAst, 'ng-non-bindable', ''], [TextAst, 'a']]); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should ignore <link rel="stylesheet"> elements inside of elements with ng-non-bindable', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |            expect(humanizeTplAst( | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                       parse('<div ng-non-bindable><link rel="stylesheet"></link>a</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                .toEqual([[ElementAst, 'div'], [AttrAst, 'ng-non-bindable', ''], [TextAst, 'a']]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       it('should convert <ng-content> elements into regular elements inside of elements with ng-non-bindable', | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          () => { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |            expect( | 
					
						
							|  |  |  |                humanizeTplAst(parse('<div ng-non-bindable><ng-content></ng-content>a</div>', []))) | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                .toEqual([ | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |                  [ElementAst, 'div'], | 
					
						
							|  |  |  |                  [AttrAst, 'ng-non-bindable', ''], | 
					
						
							|  |  |  |                  [ElementAst, 'ng-content'], | 
					
						
							|  |  |  |                  [TextAst, 'a'] | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |                ]); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('source spans', () => { | 
					
						
							|  |  |  |       it('should support ng-content', () => { | 
					
						
							|  |  |  |         var parsed = parse('<ng-content select="a">', []); | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parsed)) | 
					
						
							|  |  |  |             .toEqual([[NgContentAst, '<ng-content select="a">']]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support embedded template', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<template></template>', []))) | 
					
						
							|  |  |  |             .toEqual([[EmbeddedTemplateAst, '<template>']]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support element and attributes', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div key=value>', []))) | 
					
						
							|  |  |  |             .toEqual( | 
					
						
							|  |  |  |                 [[ElementAst, 'div', '<div key=value>'], [AttrAst, 'key', 'value', 'key=value']]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support variables', () => { | 
					
						
							|  |  |  |         var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |             {selector: '[a]', type: new CompileTypeMetadata({name: 'DirA'}), exportAs: 'dirA'}); | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div a #a="dirA"></div>', [dirA]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div a #a="dirA">'], | 
					
						
							|  |  |  |               [AttrAst, 'a', '', 'a'], | 
					
						
							|  |  |  |               [DirectiveAst, dirA, '<div a #a="dirA">'], | 
					
						
							|  |  |  |               [VariableAst, 'a', 'dirA', '#a="dirA"'] | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support event', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div (window:event)="v">', []))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div (window:event)="v">'], | 
					
						
							|  |  |  |               [BoundEventAst, 'event', 'window', 'v', '(window:event)="v"'] | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support element property', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div [someProp]="v">', []))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div [someProp]="v">'], | 
					
						
							|  |  |  |               [ | 
					
						
							|  |  |  |                 BoundElementPropertyAst, | 
					
						
							|  |  |  |                 PropertyBindingType.Property, | 
					
						
							|  |  |  |                 'someProp', | 
					
						
							|  |  |  |                 'v', | 
					
						
							|  |  |  |                 null, | 
					
						
							|  |  |  |                 '[someProp]="v"' | 
					
						
							|  |  |  |               ] | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support bound text', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('{{a}}', []))) | 
					
						
							|  |  |  |             .toEqual([[BoundTextAst, '{{ a }}', '{{a}}']]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support text nodes', () => { | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('a', []))).toEqual([[TextAst, 'a', 'a']]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support directive', () => { | 
					
						
							|  |  |  |         var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |             {selector: '[a]', type: new CompileTypeMetadata({name: 'DirA'})}); | 
					
						
							|  |  |  |         var comp = CompileDirectiveMetadata.create({ | 
					
						
							|  |  |  |           selector: 'div', | 
					
						
							|  |  |  |           isComponent: true, | 
					
						
							|  |  |  |           type: new CompileTypeMetadata({name: 'ZComp'}), | 
					
						
							|  |  |  |           template: new CompileTemplateMetadata({ngContentSelectors: []}) | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div a>', [dirA, comp]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div a>'], | 
					
						
							|  |  |  |               [AttrAst, 'a', '', 'a'], | 
					
						
							|  |  |  |               [DirectiveAst, comp, '<div a>'], | 
					
						
							|  |  |  |               [DirectiveAst, dirA, '<div a>'], | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should support directive property', () => { | 
					
						
							|  |  |  |         var dirA = CompileDirectiveMetadata.create( | 
					
						
							|  |  |  |             {selector: 'div', type: new CompileTypeMetadata({name: 'DirA'}), inputs: ['aProp']}); | 
					
						
							|  |  |  |         expect(humanizeTplAstSourceSpans(parse('<div [a-prop]="foo | bar"></div>', [dirA]))) | 
					
						
							|  |  |  |             .toEqual([ | 
					
						
							|  |  |  |               [ElementAst, 'div', '<div [a-prop]="foo | bar">'], | 
					
						
							|  |  |  |               [DirectiveAst, dirA, '<div [a-prop]="foo | bar">'], | 
					
						
							|  |  |  |               [BoundDirectivePropertyAst, 'aProp', '(foo | bar)', '[a-prop]="foo | bar"'] | 
					
						
							|  |  |  |             ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | function humanizeTplAst(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateHumanizer(false); | 
					
						
							|  |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function humanizeTplAstSourceSpans(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateHumanizer(true); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TemplateHumanizer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   result: any[] = []; | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor(private includeSourceSpan: boolean){}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitNgContent(ast: NgContentAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [NgContentAst]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [EmbeddedTemplateAst]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.attrs); | 
					
						
							| 
									
										
										
										
											2015-10-23 16:08:46 -07:00
										 |  |  |     templateVisitAll(this, ast.outputs); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.vars); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.directives); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [ElementAst, ast.name]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.attrs); | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |     templateVisitAll(this, ast.inputs); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.outputs); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |     templateVisitAll(this, ast.exportAsVars); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.directives); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitVariable(ast: VariableAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [VariableAst, ast.name, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitEvent(ast: BoundEventAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundEventAst, ast.name, ast.target, expressionUnparser.unparse(ast.handler)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [ | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |       BoundElementPropertyAst, | 
					
						
							|  |  |  |       ast.type, | 
					
						
							|  |  |  |       ast.name, | 
					
						
							|  |  |  |       expressionUnparser.unparse(ast.value), | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  |       ast.unit | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     ]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitAttr(ast: AttrAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [AttrAst, ast.name, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundTextAst, expressionUnparser.unparse(ast.value)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitText(ast: TextAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [TextAst, ast.value]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-25 15:36:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitDirective(ast: DirectiveAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [DirectiveAst, ast.directive]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-09-30 20:59:23 -07:00
										 |  |  |     templateVisitAll(this, ast.inputs); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     templateVisitAll(this, ast.hostProperties); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.hostEvents); | 
					
						
							| 
									
										
										
										
											2015-09-18 10:33:23 -07:00
										 |  |  |     templateVisitAll(this, ast.exportAsVars); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-09-01 16:24:23 -07:00
										 |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  |     var res = [BoundDirectivePropertyAst, ast.directiveName, expressionUnparser.unparse(ast.value)]; | 
					
						
							|  |  |  |     this.result.push(this._appendContext(ast, res)); | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-11-10 15:56:25 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   private _appendContext(ast: TemplateAst, input: any[]): any[] { | 
					
						
							|  |  |  |     if (!this.includeSourceSpan) return input; | 
					
						
							|  |  |  |     input.push(ast.sourceSpan.toString()); | 
					
						
							|  |  |  |     return input; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-08-27 16:29:02 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-07 09:34:21 -07:00
										 |  |  | function sourceInfo(ast: TemplateAst): string { | 
					
						
							|  |  |  |   return `${ast.sourceSpan}: ${ast.sourceSpan.start}`; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-09-11 13:37:05 -07:00
										 |  |  | function humanizeContentProjection(templateAsts: TemplateAst[]): any[] { | 
					
						
							|  |  |  |   var humanizer = new TemplateContentProjectionHumanizer(); | 
					
						
							|  |  |  |   templateVisitAll(humanizer, templateAsts); | 
					
						
							|  |  |  |   return humanizer.result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TemplateContentProjectionHumanizer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   result: any[] = []; | 
					
						
							|  |  |  |   visitNgContent(ast: NgContentAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push(['ng-content', ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push(['template', ast.ngContentIndex]); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([ast.name, ast.ngContentIndex]); | 
					
						
							|  |  |  |     templateVisitAll(this, ast.children); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitVariable(ast: VariableAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitEvent(ast: BoundEventAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitAttr(ast: AttrAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([`#text(${expressionUnparser.unparse(ast.value)})`, ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitText(ast: TextAst, context: any): any { | 
					
						
							|  |  |  |     this.result.push([`#text(${ast.value})`, ast.ngContentIndex]); | 
					
						
							|  |  |  |     return null; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitDirective(ast: DirectiveAst, context: any): any { return null; } | 
					
						
							|  |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { return null; } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-11-19 10:51:16 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class FooAstTransformer implements TemplateAstVisitor { | 
					
						
							|  |  |  |   visitNgContent(ast: NgContentAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     if (ast.name != 'div') return ast; | 
					
						
							|  |  |  |     return new ElementAst('foo', [], [], [], [], [], [], ast.ngContentIndex, ast.sourceSpan); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   visitVariable(ast: VariableAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitEvent(ast: BoundEventAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitElementProperty(ast: BoundElementPropertyAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitAttr(ast: AttrAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitBoundText(ast: BoundTextAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitText(ast: TextAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitDirective(ast: DirectiveAst, context: any): any { throw 'not implemented'; } | 
					
						
							|  |  |  |   visitDirectiveProperty(ast: BoundDirectivePropertyAst, context: any): any { | 
					
						
							|  |  |  |     throw 'not implemented'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BarAstTransformer extends FooAstTransformer { | 
					
						
							|  |  |  |   visitElement(ast: ElementAst, context: any): any { | 
					
						
							|  |  |  |     if (ast.name != 'foo') return ast; | 
					
						
							|  |  |  |     return new ElementAst('bar', [], [], [], [], [], [], ast.ngContentIndex, ast.sourceSpan); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |