| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | import {isBlank, isPresent, BaseException} from 'angular2/src/facade/lang'; | 
					
						
							| 
									
										
										
										
											2015-04-07 20:54:20 -07:00
										 |  |  | import {MapWrapper, ListWrapper, List, Map} from 'angular2/src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | import {PromiseWrapper, Promise} from 'angular2/src/facade/async'; | 
					
						
							|  |  |  | import {DOM} from 'angular2/src/dom/dom_adapter'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {Parser, Lexer} from 'angular2/change_detection'; | 
					
						
							|  |  |  | import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  | import {DefaultDomCompiler} from 'angular2/src/render/dom/compiler/compiler'; | 
					
						
							| 
									
										
										
										
											2015-04-28 11:20:01 -07:00
										 |  |  | import {RenderProtoViewRef, ProtoViewDto, ViewDefinition, RenderViewContainerRef, EventDispatcher, DirectiveMetadata} from 'angular2/src/render/api'; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader'; | 
					
						
							|  |  |  | import {UrlResolver} from 'angular2/src/services/url_resolver'; | 
					
						
							|  |  |  | import {EmulatedUnscopedShadowDomStrategy} from 'angular2/src/render/dom/shadow_dom/emulated_unscoped_shadow_dom_strategy'; | 
					
						
							|  |  |  | import {EventManager, EventManagerPlugin} from 'angular2/src/render/dom/events/event_manager'; | 
					
						
							|  |  |  | import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone'; | 
					
						
							|  |  |  | import {StyleUrlResolver} from 'angular2/src/render/dom/shadow_dom/style_url_resolver'; | 
					
						
							|  |  |  | import {ViewFactory} from 'angular2/src/render/dom/view/view_factory'; | 
					
						
							| 
									
										
										
										
											2015-04-15 21:51:30 -07:00
										 |  |  | import {RenderViewHydrator} from 'angular2/src/render/dom/view/view_hydrator'; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export class IntegrationTestbed { | 
					
						
							|  |  |  |   renderer; | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |   renderCompiler; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |   parser; | 
					
						
							|  |  |  |   eventPlugin; | 
					
						
							| 
									
										
										
										
											2015-04-09 21:20:11 +02:00
										 |  |  |   _templates:Map<string, ViewDefinition>; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   constructor({urlData, viewCacheCapacity, shadowDomStrategy, templates}) { | 
					
						
							|  |  |  |     this._templates = MapWrapper.create(); | 
					
						
							|  |  |  |     if (isPresent(templates)) { | 
					
						
							|  |  |  |       ListWrapper.forEach(templates, (template) => { | 
					
						
							|  |  |  |         MapWrapper.set(this._templates, template.componentId, template); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     var parser = new Parser(new Lexer()); | 
					
						
							|  |  |  |     var urlResolver = new UrlResolver(); | 
					
						
							|  |  |  |     if (isBlank(shadowDomStrategy)) { | 
					
						
							|  |  |  |       shadowDomStrategy = new EmulatedUnscopedShadowDomStrategy(new StyleUrlResolver(urlResolver), null); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |     this.renderCompiler = new DefaultDomCompiler(parser, shadowDomStrategy, new FakeTemplateLoader(urlResolver, urlData)); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (isBlank(viewCacheCapacity)) { | 
					
						
							| 
									
										
										
										
											2015-04-17 14:37:57 -07:00
										 |  |  |       viewCacheCapacity = 0; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (isBlank(urlData)) { | 
					
						
							|  |  |  |       urlData = MapWrapper.create(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     this.eventPlugin = new FakeEventManagerPlugin(); | 
					
						
							|  |  |  |     var eventManager = new EventManager([this.eventPlugin], new FakeVmTurnZone()); | 
					
						
							|  |  |  |     var viewFactory = new ViewFactory(viewCacheCapacity, eventManager, shadowDomStrategy); | 
					
						
							| 
									
										
										
										
											2015-04-20 11:34:53 -07:00
										 |  |  |     var viewHydrator = new RenderViewHydrator(eventManager, viewFactory, shadowDomStrategy); | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |     this.renderer = new DirectDomRenderer(viewFactory, viewHydrator, shadowDomStrategy); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-27 15:14:30 -07:00
										 |  |  |   compileRoot(componentMetadata):Promise<ProtoViewDto> { | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |     return this.renderCompiler.compileHost(componentMetadata).then( (rootProtoView) => { | 
					
						
							| 
									
										
										
										
											2015-04-27 15:14:30 -07:00
										 |  |  |       return this._compileNestedProtoViews(rootProtoView, [componentMetadata]); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-10 16:57:26 -07:00
										 |  |  |   compile(componentId):Promise<ProtoViewDto> { | 
					
						
							|  |  |  |     var childTemplate = MapWrapper.get(this._templates, componentId); | 
					
						
							|  |  |  |     if (isBlank(childTemplate)) { | 
					
						
							|  |  |  |       throw new BaseException(`No template for component ${componentId}`); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |     return this.renderCompiler.compile(childTemplate).then( (protoView) => { | 
					
						
							| 
									
										
										
										
											2015-04-10 16:57:26 -07:00
										 |  |  |       return this._compileNestedProtoViews(protoView, childTemplate.directives); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 21:20:11 +02:00
										 |  |  |   _compileNestedProtoViews(protoView, directives):Promise<ProtoViewDto> { | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |     var childComponentRenderPvRefs = []; | 
					
						
							|  |  |  |     var nestedPVPromises = []; | 
					
						
							|  |  |  |     ListWrapper.forEach(protoView.elementBinders, (elementBinder) => { | 
					
						
							|  |  |  |       var nestedComponentId = null; | 
					
						
							|  |  |  |       ListWrapper.forEach(elementBinder.directives, (db) => { | 
					
						
							|  |  |  |         var directiveMeta = directives[db.directiveIndex]; | 
					
						
							|  |  |  |         if (directiveMeta.type === DirectiveMetadata.COMPONENT_TYPE) { | 
					
						
							|  |  |  |           nestedComponentId = directiveMeta.id; | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |       var nestedCall; | 
					
						
							|  |  |  |       if (isPresent(nestedComponentId)) { | 
					
						
							|  |  |  |         var childTemplate = MapWrapper.get(this._templates, nestedComponentId); | 
					
						
							|  |  |  |         if (isBlank(childTemplate)) { | 
					
						
							| 
									
										
										
										
											2015-04-10 16:57:26 -07:00
										 |  |  |           // dynamic component
 | 
					
						
							|  |  |  |           ListWrapper.push(childComponentRenderPvRefs, null); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           nestedCall = this.compile(nestedComponentId); | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |         } | 
					
						
							|  |  |  |       } else if (isPresent(elementBinder.nestedProtoView)) { | 
					
						
							|  |  |  |         nestedCall = this._compileNestedProtoViews(elementBinder.nestedProtoView, directives); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |       if (isPresent(nestedCall)) { | 
					
						
							|  |  |  |         ListWrapper.push( | 
					
						
							|  |  |  |           nestedPVPromises, | 
					
						
							|  |  |  |           nestedCall.then( (nestedPv) => { | 
					
						
							|  |  |  |             elementBinder.nestedProtoView = nestedPv; | 
					
						
							|  |  |  |             if (isPresent(nestedComponentId)) { | 
					
						
							|  |  |  |               ListWrapper.push(childComponentRenderPvRefs, nestedPv.render); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           }) | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |     if (nestedPVPromises.length > 0) { | 
					
						
							|  |  |  |       return PromiseWrapper.all(nestedPVPromises).then((_) => { | 
					
						
							| 
									
										
										
										
											2015-05-06 10:17:38 -07:00
										 |  |  |         this.renderCompiler.mergeChildComponentProtoViews(protoView.render, childComponentRenderPvRefs); | 
					
						
							| 
									
										
										
										
											2015-04-07 17:24:09 -07:00
										 |  |  |         return protoView; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       return PromiseWrapper.resolve(protoView); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FakeTemplateLoader extends TemplateLoader { | 
					
						
							|  |  |  |   _urlData: Map<string, string>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor(urlResolver, urlData) { | 
					
						
							|  |  |  |     super(null, urlResolver); | 
					
						
							|  |  |  |     this._urlData = urlData; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-04-09 21:20:11 +02:00
										 |  |  |   load(template: ViewDefinition) { | 
					
						
							|  |  |  |     if (isPresent(template.template)) { | 
					
						
							|  |  |  |       return PromiseWrapper.resolve(DOM.createTemplate(template.template)); | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (isPresent(template.absUrl)) { | 
					
						
							|  |  |  |       var content = this._urlData[template.absUrl]; | 
					
						
							|  |  |  |       if (isPresent(content)) { | 
					
						
							|  |  |  |         return PromiseWrapper.resolve(DOM.createTemplate(content)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return PromiseWrapper.reject('Load failed'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FakeVmTurnZone extends VmTurnZone { | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     super({enableLongStackTrace: false}); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   run(fn) { | 
					
						
							|  |  |  |     fn(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   runOutsideAngular(fn) { | 
					
						
							|  |  |  |     fn(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FakeEventManagerPlugin extends EventManagerPlugin { | 
					
						
							|  |  |  |   _eventHandlers: Map; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     super(); | 
					
						
							|  |  |  |     this._eventHandlers = MapWrapper.create(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   dispatchEvent(eventName, event) { | 
					
						
							|  |  |  |     MapWrapper.get(this._eventHandlers, eventName)(event); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   supports(eventName: string): boolean { | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) { | 
					
						
							|  |  |  |     MapWrapper.set(this._eventHandlers, eventName, handler); | 
					
						
							| 
									
										
										
										
											2015-04-02 15:56:58 +02:00
										 |  |  |     return () => {MapWrapper.delete(this._eventHandlers, eventName);} | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class LoggingEventDispatcher extends EventDispatcher { | 
					
						
							|  |  |  |   log:List; | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     super(); | 
					
						
							|  |  |  |     this.log = []; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   dispatchEvent( | 
					
						
							| 
									
										
										
										
											2015-04-07 20:54:20 -07:00
										 |  |  |     elementIndex:number, eventName:string, locals:Map<string, any> | 
					
						
							| 
									
										
										
										
											2015-03-23 14:10:55 -07:00
										 |  |  |   ) { | 
					
						
							|  |  |  |     ListWrapper.push(this.log, [elementIndex, eventName, locals]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export class FakeEvent { | 
					
						
							|  |  |  |   target; | 
					
						
							|  |  |  |   constructor(target) { | 
					
						
							|  |  |  |     this.target = target; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-04-09 21:20:11 +02:00
										 |  |  | } |