fix(compiler): changed the compiler to set up event listeners and host properties on host view elements

Closes #1584
This commit is contained in:
vsavkin 2015-04-27 15:14:30 -07:00 committed by Misko Hevery
parent 414e58edb5
commit e3c11045bf
14 changed files with 187 additions and 93 deletions

View File

@ -90,7 +90,9 @@ export class Compiler {
compileInHost(componentTypeOrBinding:any):Promise<AppProtoView> { compileInHost(componentTypeOrBinding:any):Promise<AppProtoView> {
var componentBinding = this._bindDirective(componentTypeOrBinding); var componentBinding = this._bindDirective(componentTypeOrBinding);
this._assertTypeIsComponent(componentBinding); this._assertTypeIsComponent(componentBinding);
return this._renderer.createHostProtoView('host').then( (hostRenderPv) => {
var directiveMetadata = Compiler.buildRenderDirective(componentBinding);
return this._renderer.createHostProtoView(directiveMetadata).then( (hostRenderPv) => {
return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true); return this._compileNestedProtoViews(null, hostRenderPv, [componentBinding], true);
}); });
} }

View File

@ -2,8 +2,9 @@ import {Injectable} from 'angular2/di';
import {PromiseWrapper, Promise} from 'angular2/src/facade/async'; import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
import {BaseException} from 'angular2/src/facade/lang'; import {BaseException} from 'angular2/src/facade/lang';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {ViewDefinition, ProtoViewDto} from '../../api'; import {ViewDefinition, ProtoViewDto, DirectiveMetadata} from '../../api';
import {CompilePipeline} from './compile_pipeline'; import {CompilePipeline} from './compile_pipeline';
import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader'; import {TemplateLoader} from 'angular2/src/render/dom/compiler/template_loader';
import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory'; import {CompileStepFactory, DefaultStepFactory} from './compile_step_factory';
@ -32,12 +33,21 @@ export class Compiler {
); );
} }
_compileTemplate(template: ViewDefinition, tplElement):Promise<ProtoViewDto> { compileHost(directiveMetadata: DirectiveMetadata):Promise<ProtoViewDto> {
var subTaskPromises = []; var hostViewDef = new ViewDefinition({
var pipeline = new CompilePipeline(this._stepFactory.createSteps(template, subTaskPromises)); componentId: directiveMetadata.id,
var compileElements; absUrl: null,
template: null,
directives: [directiveMetadata]
});
var element = DOM.createElement(directiveMetadata.selector);
return this._compileTemplate(hostViewDef, element);
}
compileElements = pipeline.process(tplElement, template.componentId); _compileTemplate(viewDef: ViewDefinition, tplElement):Promise<ProtoViewDto> {
var subTaskPromises = [];
var pipeline = new CompilePipeline(this._stepFactory.createSteps(viewDef, subTaskPromises));
var compileElements = pipeline.process(tplElement, viewDef.componentId);
var protoView = compileElements[0].inheritedProtoView.build(); var protoView = compileElements[0].inheritedProtoView.build();

View File

@ -27,11 +27,20 @@ export class DirectiveParser extends CompileStep {
this._selectorMatcher = new SelectorMatcher(); this._selectorMatcher = new SelectorMatcher();
this._directives = directives; this._directives = directives;
for (var i=0; i<directives.length; i++) { for (var i=0; i<directives.length; i++) {
var selector = CssSelector.parse(directives[i].selector); var directive = directives[i];
var selector = CssSelector.parse(directive.selector);
this._ensureComponentOnlyHasElementSelector(selector, directive);
this._selectorMatcher.addSelectables(selector, i); this._selectorMatcher.addSelectables(selector, i);
} }
} }
_ensureComponentOnlyHasElementSelector(selector, directive) {
var isElementSelector = selector.length === 1 && selector[0].isElementSelector();
if (! isElementSelector && directive.type === DirectiveMetadata.COMPONENT_TYPE) {
throw new BaseException(`Component '${directive.id}' can only have an element selector, but had '${directive.selector}'`);
}
}
process(parent:CompileElement, current:CompileElement, control:CompileControl) { process(parent:CompileElement, current:CompileElement, control:CompileControl) {
var attrs = current.attrs(); var attrs = current.attrs();
var classList = current.classList(); var classList = current.classList();

View File

@ -69,6 +69,13 @@ export class CssSelector {
this.notSelector = null; this.notSelector = null;
} }
isElementSelector():boolean {
return isPresent(this.element) &&
ListWrapper.isEmpty(this.classNames) &&
ListWrapper.isEmpty(this.attrs) &&
isBlank(this.notSelector);
}
setElement(element:string = null) { setElement(element:string = null) {
if (isPresent(element)) { if (isPresent(element)) {
element = element.toLowerCase(); element = element.toLowerCase();

View File

@ -11,7 +11,6 @@ import {RenderViewHydrator} from './view/view_hydrator';
import {Compiler} from './compiler/compiler'; import {Compiler} from './compiler/compiler';
import {ShadowDomStrategy} from './shadow_dom/shadow_dom_strategy'; import {ShadowDomStrategy} from './shadow_dom/shadow_dom_strategy';
import {ProtoViewBuilder} from './view/proto_view_builder'; import {ProtoViewBuilder} from './view/proto_view_builder';
import {DOM} from 'angular2/src/dom/dom_adapter';
import {ViewContainer} from './view/view_container'; import {ViewContainer} from './view/view_container';
function _resolveViewContainer(vc:api.RenderViewContainerRef) { function _resolveViewContainer(vc:api.RenderViewContainerRef) {
@ -80,15 +79,8 @@ export class DirectDomRenderer extends api.Renderer {
this._shadowDomStrategy = shadowDomStrategy; this._shadowDomStrategy = shadowDomStrategy;
} }
createHostProtoView(componentId):Promise<api.ProtoViewDto> { createHostProtoView(directiveMetadata:api.DirectiveMetadata):Promise<api.ProtoViewDto> {
var rootElement = DOM.createElement('div'); return this._compiler.compileHost(directiveMetadata);
var hostProtoViewBuilder = new ProtoViewBuilder(rootElement);
var elBinder = hostProtoViewBuilder.bindElement(rootElement, 'root element');
elBinder.setComponentId(componentId);
elBinder.bindDirective(0);
this._shadowDomStrategy.processElement(null, componentId, rootElement);
return PromiseWrapper.resolve(hostProtoViewBuilder.build());
} }
createImperativeComponentProtoView(rendererId):Promise<api.ProtoViewDto> { createImperativeComponentProtoView(rendererId):Promise<api.ProtoViewDto> {
@ -97,10 +89,10 @@ export class DirectDomRenderer extends api.Renderer {
return PromiseWrapper.resolve(protoViewBuilder.build()); return PromiseWrapper.resolve(protoViewBuilder.build());
} }
compile(template:api.ViewDefinition):Promise<api.ProtoViewDto> { compile(view:api.ViewDefinition):Promise<api.ProtoViewDto> {
// Note: compiler already uses a DirectDomProtoViewRef, so we don't // Note: compiler already uses a DirectDomProtoViewRef, so we don't
// need to do anything here // need to do anything here
return this._compiler.compile(template); return this._compiler.compile(view);
} }
mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List<api.ProtoViewRef>) { mergeChildComponentProtoViews(protoViewRef:api.ProtoViewRef, protoViewRefs:List<api.ProtoViewRef>) {

View File

@ -22,6 +22,8 @@ import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_compone
import {ElementRef} from 'angular2/src/core/compiler/element_injector'; import {ElementRef} from 'angular2/src/core/compiler/element_injector';
import {If} from 'angular2/src/directives/if'; import {If} from 'angular2/src/directives/if';
import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer'; import {DirectDomRenderer} from 'angular2/src/render/dom/direct_dom_renderer';
import {DOM} from 'angular2/src/dom/dom_adapter';
export function main() { export function main() {
describe('DynamicComponentLoader', function () { describe('DynamicComponentLoader', function () {
@ -134,6 +136,29 @@ export function main() {
}); });
}); });
})); }));
it('should update host properties', inject([DynamicComponentLoader, TestBed, AsyncTestCompleter],
(loader, tb, async) => {
tb.overrideView(MyComp, new View({
template: '<div><location #loc></location></div>',
directives: [Location]
}));
tb.createView(MyComp).then((view) => {
var location = view.rawView.locals.get("loc");
loader.loadNextToExistingLocation(DynamicallyLoadedWithHostProps, location.elementRef).then(ref => {
ref.instance.id = "new value";
view.detectChanges();
var newlyInsertedElement = DOM.childNodesAsList(view.rootNodes[0])[1];
expect(newlyInsertedElement.id).toEqual("new value")
async.done();
});
});
}));
}); });
describe('loading into a new location', () => { describe('loading into a new location', () => {
@ -242,6 +267,19 @@ class DynamicallyLoaded {
class DynamicallyLoaded2 { class DynamicallyLoaded2 {
} }
@Component({
selector: 'dummy',
hostProperties: {'id' : 'id'}
})
@View({template: "DynamicallyLoadedWithHostProps;"})
class DynamicallyLoadedWithHostProps {
id:string;
constructor() {
this.id = "default";
}
}
@Component({ @Component({
selector: 'location' selector: 'location'
}) })
@ -254,7 +292,9 @@ class Location {
} }
} }
@Component() @Component({
selector: 'my-comp'
})
@View({ @View({
directives: [] directives: []
}) })

View File

@ -255,20 +255,19 @@ export function main() {
tb.overrideView(MyComp, tb.overrideView(MyComp,
new View({ new View({
template: '<p [id]="ctxProp"></p>', template: '<p [id]="ctxProp"></p>',
directives: [IdComponent] directives: [IdDir]
})); }));
tb.createView(MyComp, {context: ctx}).then((view) => { tb.createView(MyComp, {context: ctx}).then((view) => {
var idDir = view.rawView.elementInjectors[0].get(IdDir);
ctx.ctxProp = 'some_id'; ctx.ctxProp = 'some_id';
view.detectChanges(); view.detectChanges();
expect(view.rootNodes[0].id).toEqual('some_id'); expect(idDir.id).toEqual('some_id');
expect(view.rootNodes).toHaveText('Matched on id with some_id');
ctx.ctxProp = 'other_id'; ctx.ctxProp = 'other_id';
view.detectChanges(); view.detectChanges();
expect(view.rootNodes[0].id).toEqual('other_id'); expect(idDir.id).toEqual('other_id');
expect(view.rootNodes).toHaveText('Matched on id with other_id');
async.done(); async.done();
}); });
@ -932,7 +931,9 @@ class PushCmpWithRef {
} }
} }
@Component() @Component({
selector: 'my-comp'
})
@View({directives: [ @View({directives: [
]}) ]})
class MyComp { class MyComp {
@ -1192,14 +1193,11 @@ class DecoratorListeningDomEventNoPrevent {
} }
} }
@Component({ @Decorator({
selector: '[id]', selector: '[id]',
properties: {'id': 'id'} properties: {'id': 'id'}
}) })
@View({ class IdDir {
template: '<div>Matched on id with {{id}}</div>'
})
class IdComponent {
id: string; id: string;
} }

View File

@ -1,4 +1,4 @@
/* /*
* Runs compiler tests using in-browser DOM adapter. * Runs compiler tests using in-browser DOM adapter.
*/ */

View File

@ -17,7 +17,7 @@ import {Type, isBlank, stringify, isPresent} from 'angular2/src/facade/lang';
import {PromiseWrapper, Promise} from 'angular2/src/facade/async'; import {PromiseWrapper, Promise} from 'angular2/src/facade/async';
import {Compiler, CompilerCache} from 'angular2/src/render/dom/compiler/compiler'; import {Compiler, CompilerCache} from 'angular2/src/render/dom/compiler/compiler';
import {ProtoViewDto, ViewDefinition} from 'angular2/src/render/api'; import {ProtoViewDto, ViewDefinition, DirectiveMetadata} from 'angular2/src/render/api';
import {CompileElement} from 'angular2/src/render/dom/compiler/compile_element'; import {CompileElement} from 'angular2/src/render/dom/compiler/compile_element';
import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step' import {CompileStep} from 'angular2/src/render/dom/compiler/compile_step'
import {CompileStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory'; import {CompileStepFactory} from 'angular2/src/render/dom/compiler/compile_step_factory';
@ -54,6 +54,22 @@ export function runCompilerCommonTests() {
}); });
})); }));
it('should run the steps and build the proto view', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler((parent, current, control) => {
current.inheritedProtoView.bindVariable('b', 'a');
});
var dirMetadata = new DirectiveMetadata({id: 'id', selector: 'CUSTOM', type: DirectiveMetadata.COMPONENT_TYPE});
compiler.compileHost(dirMetadata).then( (protoView) => {
expect(DOM.tagName(protoView.render.delegate.element)).toEqual('CUSTOM')
expect(mockStepFactory.viewDef.directives).toEqual([dirMetadata]);
expect(protoView.variableBindings).toEqual(MapWrapper.createFromStringMap({
'a': 'b'
}));
async.done();
});
}));
it('should use the inline template and compile in sync', inject([AsyncTestCompleter], (async) => { it('should use the inline template and compile in sync', inject([AsyncTestCompleter], (async) => {
var compiler = createCompiler(EMPTY_STEP); var compiler = createCompiler(EMPTY_STEP);
compiler.compile(new ViewDefinition({ compiler.compile(new ViewDefinition({
@ -124,11 +140,14 @@ export function runCompilerCommonTests() {
class MockStepFactory extends CompileStepFactory { class MockStepFactory extends CompileStepFactory {
steps:List<CompileStep>; steps:List<CompileStep>;
subTaskPromises:List<Promise>; subTaskPromises:List<Promise>;
viewDef:ViewDefinition;
constructor(steps) { constructor(steps) {
super(); super();
this.steps = steps; this.steps = steps;
} }
createSteps(template, subTaskPromises) { createSteps(viewDef, subTaskPromises) {
this.viewDef = viewDef;
this.subTaskPromises = subTaskPromises; this.subTaskPromises = subTaskPromises;
ListWrapper.forEach(this.subTaskPromises, (p) => ListWrapper.push(subTaskPromises, p) ); ListWrapper.forEach(this.subTaskPromises, (p) => ListWrapper.push(subTaskPromises, p) );
return this.steps; return this.steps;

View File

@ -1,5 +1,5 @@
import {describe, beforeEach, it, xit, expect, iit, ddescribe, el} from 'angular2/test_lib'; import {describe, beforeEach, it, xit, expect, iit, ddescribe, el} from 'angular2/test_lib';
import {isPresent, assertionsEnabled} from 'angular2/src/facade/lang'; import {isPresent, isBlank, assertionsEnabled} from 'angular2/src/facade/lang';
import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {DirectiveParser} from 'angular2/src/render/dom/compiler/directive_parser'; import {DirectiveParser} from 'angular2/src/render/dom/compiler/directive_parser';
import {CompilePipeline} from 'angular2/src/render/dom/compiler/compile_pipeline'; import {CompilePipeline} from 'angular2/src/render/dom/compiler/compile_pipeline';
@ -17,11 +17,11 @@ export function main() {
annotatedDirectives = [ annotatedDirectives = [
someComponent, someComponent,
someComponent2, someComponent2,
someComponent3,
someViewport, someViewport,
someViewport2, someViewport2,
someDecorator, someDecorator,
someDecoratorIgnoringChildren, someDecoratorIgnoringChildren,
decoratorWithMultipleAttrs,
someDecoratorWithProps, someDecoratorWithProps,
someDecoratorWithHostProperties, someDecoratorWithHostProperties,
someDecoratorWithEvents, someDecoratorWithEvents,
@ -30,7 +30,9 @@ export function main() {
parser = new Parser(new Lexer()); parser = new Parser(new Lexer());
}); });
function createPipeline(propertyBindings = null) { function createPipeline(propertyBindings = null, directives = null) {
if (isBlank(directives)) directives = annotatedDirectives;
return new CompilePipeline([ return new CompilePipeline([
new MockStep( (parent, current, control) => { new MockStep( (parent, current, control) => {
if (isPresent(propertyBindings)) { if (isPresent(propertyBindings)) {
@ -39,12 +41,12 @@ export function main() {
}); });
} }
}), }),
new DirectiveParser(parser, annotatedDirectives) new DirectiveParser(parser, directives)
]); ]);
} }
function process(el, propertyBindings = null) { function process(el, propertyBindings = null, directives = null) {
var pipeline = createPipeline(propertyBindings); var pipeline = createPipeline(propertyBindings, directives);
return ListWrapper.map(pipeline.process(el), (ce) => ce.inheritedElementBinder ); return ListWrapper.map(pipeline.process(el), (ce) => ce.inheritedElementBinder );
} }
@ -63,7 +65,7 @@ export function main() {
it('should detect directives with multiple attributes', () => { it('should detect directives with multiple attributes', () => {
var results = process(el('<input type=text control=one></input>')); var results = process(el('<input type=text control=one></input>'));
expect(results[0].directives[0].directiveIndex).toBe( expect(results[0].directives[0].directiveIndex).toBe(
annotatedDirectives.indexOf(someComponent3) annotatedDirectives.indexOf(decoratorWithMultipleAttrs)
); );
}); });
@ -176,30 +178,27 @@ export function main() {
describe('component directives', () => { describe('component directives', () => {
it('should save the component id', () => { it('should save the component id', () => {
var results = process( var results = process(
el('<div some-comp></div>') el('<some-comp></some-comp>')
); );
expect(results[0].componentId).toEqual('someComponent'); expect(results[0].componentId).toEqual('someComponent');
}); });
it('should throw when the provided selector is not an element selector', () => {
expect( () => {
createPipeline(null, [componentWithNonElementSelector]);
}).toThrowError(`Component 'componentWithNonElementSelector' can only have an element selector, but had '[attr]'`);
});
it('should not allow multiple component directives on the same element', () => { it('should not allow multiple component directives on the same element', () => {
expect( () => { expect( () => {
process( process(
el('<div some-comp some-comp2></div>') el('<some-comp></some-comp>'),
null,
[someComponent, someComponentDup]
); );
}).toThrowError('Only one component directive is allowed per element - check ' }).toThrowError(new RegExp('Only one component directive is allowed per element' ));
+ (assertionsEnabled() ? '<div some-comp some-comp2>' : 'null'));
}); });
it('should not allow component directives on <template> elements', () => {
expect( () => {
process(
el('<template some-comp></template>')
);
}).toThrowError('Only template directives are allowed on template elements - check '
+ (assertionsEnabled() ? '<template some-comp>' : 'null'));
});
}); });
}); });
} }
@ -215,20 +214,20 @@ class MockStep extends CompileStep {
} }
var someComponent = new DirectiveMetadata({ var someComponent = new DirectiveMetadata({
selector: '[some-comp]', selector: 'some-comp',
id: 'someComponent', id: 'someComponent',
type: DirectiveMetadata.COMPONENT_TYPE type: DirectiveMetadata.COMPONENT_TYPE
}); });
var someComponent2 = new DirectiveMetadata({ var someComponentDup = new DirectiveMetadata({
selector: '[some-comp2]', selector: 'some-comp',
id: 'someComponent2', id: 'someComponentDup',
type: DirectiveMetadata.COMPONENT_TYPE type: DirectiveMetadata.COMPONENT_TYPE
}); });
var someComponent3 = new DirectiveMetadata({ var someComponent2 = new DirectiveMetadata({
selector: 'input[type=text][control]', selector: 'some-comp2',
id: 'someComponent3', id: 'someComponent2',
type: DirectiveMetadata.COMPONENT_TYPE type: DirectiveMetadata.COMPONENT_TYPE
}); });
@ -245,12 +244,21 @@ var someViewport2 = new DirectiveMetadata({
}); });
var someDecorator = new DirectiveMetadata({ var someDecorator = new DirectiveMetadata({
selector: '[some-decor]' selector: '[some-decor]',
type: DirectiveMetadata.DECORATOR_TYPE
}); });
var someDecoratorIgnoringChildren = new DirectiveMetadata({ var someDecoratorIgnoringChildren = new DirectiveMetadata({
selector: '[some-decor-ignoring-children]', selector: '[some-decor-ignoring-children]',
compileChildren: false compileChildren: false,
type: DirectiveMetadata.DECORATOR_TYPE
});
var decoratorWithMultipleAttrs = new DirectiveMetadata({
selector: 'input[type=text][control]',
id: 'decoratorWithMultipleAttrs',
type: DirectiveMetadata.DECORATOR_TYPE
}); });
var someDecoratorWithProps = new DirectiveMetadata({ var someDecoratorWithProps = new DirectiveMetadata({
@ -282,3 +290,9 @@ var someDecoratorWithGlobalEvents = new DirectiveMetadata({
'window:resize': 'doItGlobal()' 'window:resize': 'doItGlobal()'
}) })
}); });
var componentWithNonElementSelector = new DirectiveMetadata({
id: 'componentWithNonElementSelector',
selector: '[attr]',
type: DirectiveMetadata.COMPONENT_TYPE
});

View File

@ -41,7 +41,7 @@ export function main() {
it('should create host views while using the given elements in place', inject([AsyncTestCompleter], (async) => { it('should create host views while using the given elements in place', inject([AsyncTestCompleter], (async) => {
createRenderer(); createRenderer();
renderer.createHostProtoView('someComponentId').then( (rootProtoView) => { renderer.createHostProtoView(someComponent).then( (rootProtoView) => {
expect(rootProtoView.elementBinders[0].directives[0].directiveIndex).toBe(0); expect(rootProtoView.elementBinders[0].directives[0].directiveIndex).toBe(0);
var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render);
expect(viewRefs.length).toBe(1); expect(viewRefs.length).toBe(1);
@ -62,7 +62,7 @@ export function main() {
it('should add a static component', inject([AsyncTestCompleter], (async) => { it('should add a static component', inject([AsyncTestCompleter], (async) => {
createRenderer(); createRenderer();
renderer.createHostProtoView('someComponentId').then( (rootProtoView) => { renderer.createHostProtoView(someComponent).then( (rootProtoView) => {
var template = new ViewDefinition({ var template = new ViewDefinition({
componentId: 'someComponent', componentId: 'someComponent',
template: 'hello', template: 'hello',
@ -79,7 +79,7 @@ export function main() {
it('should add a a dynamic component', inject([AsyncTestCompleter], (async) => { it('should add a a dynamic component', inject([AsyncTestCompleter], (async) => {
createRenderer(); createRenderer();
renderer.createHostProtoView('someComponentId').then( (rootProtoView) => { renderer.createHostProtoView(someComponent).then( (rootProtoView) => {
var template = new ViewDefinition({ var template = new ViewDefinition({
componentId: 'someComponent', componentId: 'someComponent',
template: 'hello', template: 'hello',
@ -102,7 +102,7 @@ export function main() {
directives: [] directives: []
})] })]
}); });
compileRoot('someComponent').then( (rootProtoView) => { compileRoot(someComponent).then( (rootProtoView) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render);
renderer.setText(viewRefs[1], 0, 'hello'); renderer.setText(viewRefs[1], 0, 'hello');
expect(rootEl).toHaveText('hello'); expect(rootEl).toHaveText('hello');
@ -118,7 +118,7 @@ export function main() {
directives: [] directives: []
})] })]
}); });
compileRoot('someComponent').then( (rootProtoView) => { compileRoot(someComponent).then( (rootProtoView) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render);
renderer.setElementProperty(viewRefs[1], 0, 'value', 'hello'); renderer.setElementProperty(viewRefs[1], 0, 'value', 'hello');
expect(DOM.childNodes(rootEl)[0].value).toEqual('hello'); expect(DOM.childNodes(rootEl)[0].value).toEqual('hello');
@ -134,7 +134,7 @@ export function main() {
directives: [] directives: []
})] })]
}); });
compileRoot('someComponent').then( (rootProtoView) => { compileRoot(someComponent).then( (rootProtoView) => {
var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1]; var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1];
var vcProtoViewRef = rootProtoView.elementBinders[0] var vcProtoViewRef = rootProtoView.elementBinders[0]
.nestedProtoView.elementBinders[0].nestedProtoView.render; .nestedProtoView.elementBinders[0].nestedProtoView.render;
@ -162,7 +162,7 @@ export function main() {
})], })],
viewCacheCapacity: 2 viewCacheCapacity: 2
}); });
compileRoot('someComponent').then( (rootProtoView) => { compileRoot(someComponent).then( (rootProtoView) => {
var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1]; var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1];
var vcProtoViewRef = rootProtoView.elementBinders[0] var vcProtoViewRef = rootProtoView.elementBinders[0]
.nestedProtoView.elementBinders[0].nestedProtoView.render; .nestedProtoView.elementBinders[0].nestedProtoView.render;
@ -189,7 +189,7 @@ export function main() {
directives: [] directives: []
})] })]
}); });
compileRoot('someComponent').then( (rootProtoView) => { compileRoot(someComponent).then( (rootProtoView) => {
var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1]; var viewRef = renderer.createInPlaceHostView(null, rootEl, rootProtoView.render)[1];
var dispatcher = new LoggingEventDispatcher(); var dispatcher = new LoggingEventDispatcher();
renderer.setEventDispatcher(viewRef, dispatcher); renderer.setEventDispatcher(viewRef, dispatcher);

View File

@ -50,14 +50,9 @@ export class IntegrationTestbed {
this.renderer = new DirectDomRenderer(compiler, viewFactory, viewHydrator, shadowDomStrategy); this.renderer = new DirectDomRenderer(compiler, viewFactory, viewHydrator, shadowDomStrategy);
} }
compileRoot(componentId):Promise<ProtoViewDto> { compileRoot(componentMetadata):Promise<ProtoViewDto> {
return this.renderer.createHostProtoView(componentId).then( (rootProtoView) => { return this.renderer.createHostProtoView(componentMetadata).then( (rootProtoView) => {
return this._compileNestedProtoViews(rootProtoView, [ return this._compileNestedProtoViews(rootProtoView, [componentMetadata]);
new DirectiveMetadata({
type: DirectiveMetadata.COMPONENT_TYPE,
id: componentId
})
]);
}); });
} }

View File

@ -79,7 +79,7 @@ export function main() {
directives: [simple] directives: [simple]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
renderer.createInPlaceHostView(null, rootEl, pv.render); renderer.createInPlaceHostView(null, rootEl, pv.render);
expect(rootEl).toHaveText('SIMPLE(A)'); expect(rootEl).toHaveText('SIMPLE(A)');
@ -98,7 +98,7 @@ export function main() {
directives: [empty] directives: [empty]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
renderer.createInPlaceHostView(null, rootEl, pv.render); renderer.createInPlaceHostView(null, rootEl, pv.render);
expect(rootEl).toHaveText(''); expect(rootEl).toHaveText('');
@ -117,7 +117,7 @@ export function main() {
directives: [dynamicComponent] directives: [dynamicComponent]
})] })]
}); });
compileRoot('main').then( (rootPv) => { compileRoot(mainDir).then( (rootPv) => {
compile('simple').then( (simplePv) => { compile('simple').then( (simplePv) => {
var views = renderer.createInPlaceHostView(null, rootEl, rootPv.render); var views = renderer.createInPlaceHostView(null, rootEl, rootPv.render);
renderer.createDynamicComponentView(views[1], 0, simplePv.render); renderer.createDynamicComponentView(views[1], 0, simplePv.render);
@ -141,7 +141,7 @@ export function main() {
directives: [multipleContentTagsComponent] directives: [multipleContentTagsComponent]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
renderer.createInPlaceHostView(null, rootEl, pv.render); renderer.createInPlaceHostView(null, rootEl, pv.render);
expect(rootEl).toHaveText('(A, BC)'); expect(rootEl).toHaveText('(A, BC)');
@ -161,7 +161,7 @@ export function main() {
directives: [multipleContentTagsComponent] directives: [multipleContentTagsComponent]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
renderer.createInPlaceHostView(null, rootEl, pv.render); renderer.createInPlaceHostView(null, rootEl, pv.render);
expect(rootEl).toHaveText('(, BAC)'); expect(rootEl).toHaveText('(, BAC)');
@ -181,7 +181,7 @@ export function main() {
directives: [multipleContentTagsComponent, manualViewportDirective] directives: [multipleContentTagsComponent, manualViewportDirective]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render);
var vcRef = new RenderViewContainerRef(viewRefs[1], 1); var vcRef = new RenderViewContainerRef(viewRefs[1], 1);
var vcProtoViewRef = pv.elementBinders[0].nestedProtoView var vcProtoViewRef = pv.elementBinders[0].nestedProtoView
@ -211,7 +211,7 @@ export function main() {
directives: [multipleContentTagsComponent, manualViewportDirective] directives: [multipleContentTagsComponent, manualViewportDirective]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render);
var vcRef = new RenderViewContainerRef(viewRefs[1], 1); var vcRef = new RenderViewContainerRef(viewRefs[1], 1);
var vcProtoViewRef = pv.elementBinders[0].nestedProtoView var vcProtoViewRef = pv.elementBinders[0].nestedProtoView
@ -241,7 +241,7 @@ export function main() {
directives: [outerWithIndirectNestedComponent] directives: [outerWithIndirectNestedComponent]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
renderer.createInPlaceHostView(null, rootEl, pv.render); renderer.createInPlaceHostView(null, rootEl, pv.render);
expect(rootEl).toHaveText('OUTER(SIMPLE(AB))'); expect(rootEl).toHaveText('OUTER(SIMPLE(AB))');
@ -262,7 +262,7 @@ export function main() {
directives: [outerComponent, manualViewportDirective] directives: [outerComponent, manualViewportDirective]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render);
var vcRef = new RenderViewContainerRef(viewRefs[1], 1); var vcRef = new RenderViewContainerRef(viewRefs[1], 1);
var vcProtoViewRef = pv.elementBinders[0].nestedProtoView var vcProtoViewRef = pv.elementBinders[0].nestedProtoView
@ -288,7 +288,7 @@ export function main() {
directives: [conditionalContentComponent] directives: [conditionalContentComponent]
})] })]
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render);
var vcRef = new RenderViewContainerRef(viewRefs[2], 0); var vcRef = new RenderViewContainerRef(viewRefs[2], 0);
var vcProtoViewRef = pv.elementBinders[0].nestedProtoView var vcProtoViewRef = pv.elementBinders[0].nestedProtoView
@ -321,7 +321,7 @@ export function main() {
})], })],
viewCacheCapacity: 5 viewCacheCapacity: 5
}); });
compileRoot('main').then( (pv) => { compileRoot(mainDir).then( (pv) => {
var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render); var viewRefs = renderer.createInPlaceHostView(null, rootEl, pv.render);
var vcRef0 = new RenderViewContainerRef(viewRefs[2], 0); var vcRef0 = new RenderViewContainerRef(viewRefs[2], 0);
var vcRef1 = new RenderViewContainerRef(viewRefs[3], 0); var vcRef1 = new RenderViewContainerRef(viewRefs[3], 0);
@ -372,6 +372,12 @@ export function main() {
} }
var mainDir = new DirectiveMetadata({
selector: 'main',
id: 'main',
type: DirectiveMetadata.COMPONENT_TYPE
});
var simple = new DirectiveMetadata({ var simple = new DirectiveMetadata({
selector: 'simple', selector: 'simple',
id: 'simple', id: 'simple',

View File

@ -150,7 +150,9 @@ class ParentCmp {
constructor() {} constructor() {}
} }
@Component() @Component({
selector: 'my-comp'
})
class MyComp { class MyComp {
name; name;
} }