feat(view): add support for components that use shadow dom emulation
This commit is contained in:
@ -66,7 +66,7 @@ export function main() {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null);
|
||||
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
||||
if (current.element === mainEl) {
|
||||
current.componentDirective = reader.annotatedType(NestedComponent);
|
||||
current.componentDirective = reader.read(NestedComponent);
|
||||
}
|
||||
});
|
||||
compiler.compile(MainComponent, mainEl).then( (protoView) => {
|
||||
@ -97,7 +97,7 @@ export function main() {
|
||||
var compiler = createCompiler( (parent, current, control) => {
|
||||
current.inheritedProtoView = new ProtoView(current.element, null);
|
||||
current.inheritedElementBinder = current.inheritedProtoView.bindElement(null);
|
||||
current.componentDirective = reader.annotatedType(RecursiveComponent);
|
||||
current.componentDirective = reader.read(RecursiveComponent);
|
||||
});
|
||||
compiler.compile(RecursiveComponent, null).then( (protoView) => {
|
||||
expect(protoView.elementBinders[0].nestedProtoView).toBe(protoView);
|
||||
|
@ -1,7 +1,8 @@
|
||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
||||
import {Decorator} from 'core/annotations/annotations';
|
||||
import {AnnotatedType} from 'core/compiler/annotated_type';
|
||||
import {Decorator, Component} from 'core/annotations/annotations';
|
||||
import {DirectiveMetadata} from 'core/compiler/directive_metadata';
|
||||
import {ShadowDomEmulated, ShadowDomNative} from 'core/compiler/shadow_dom';
|
||||
|
||||
@Decorator({
|
||||
selector: 'someSelector'
|
||||
@ -9,28 +10,50 @@ import {AnnotatedType} from 'core/compiler/annotated_type';
|
||||
class SomeDirective {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'someSelector'
|
||||
})
|
||||
class ComponentWithoutExplicitShadowDomStrategy {}
|
||||
|
||||
@Component({
|
||||
selector: 'someSelector',
|
||||
shadowDom: ShadowDomEmulated
|
||||
})
|
||||
class ComponentWithExplicitShadowDomStrategy {}
|
||||
|
||||
class SomeDirectiveWithoutAnnotation {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
describe("DirectiveMetadataReader", () => {
|
||||
var rader;
|
||||
var reader;
|
||||
|
||||
beforeEach( () => {
|
||||
rader = new DirectiveMetadataReader();
|
||||
reader = new DirectiveMetadataReader();
|
||||
});
|
||||
|
||||
it('should read out the annotation', () => {
|
||||
var annoatedDirective = rader.annotatedType(SomeDirective);
|
||||
expect(annoatedDirective).toEqual(
|
||||
new AnnotatedType(SomeDirective, new Decorator({selector: 'someSelector'})));
|
||||
var directiveMetadata = reader.read(SomeDirective);
|
||||
expect(directiveMetadata).toEqual(
|
||||
new DirectiveMetadata(SomeDirective, new Decorator({selector: 'someSelector'}), null));
|
||||
});
|
||||
|
||||
it('should throw if not matching annotation is found', () => {
|
||||
expect(() => {
|
||||
rader.annotatedType(SomeDirectiveWithoutAnnotation);
|
||||
reader.read(SomeDirectiveWithoutAnnotation);
|
||||
}).toThrowError('No Directive annotation found on SomeDirectiveWithoutAnnotation');
|
||||
});
|
||||
|
||||
describe("shadow dom strategy", () => {
|
||||
it('should return the provided shadow dom strategy when it is present', () => {
|
||||
var directiveMetadata = reader.read(ComponentWithExplicitShadowDomStrategy);
|
||||
expect(directiveMetadata.shadowDomStrategy).toEqual(ShadowDomEmulated);
|
||||
});
|
||||
|
||||
it('should return Native otherwise', () => {
|
||||
var directiveMetadata = reader.read(ComponentWithoutExplicitShadowDomStrategy);
|
||||
expect(directiveMetadata.shadowDomStrategy).toEqual(ShadowDomNative);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -28,7 +28,7 @@ export function main() {
|
||||
var parser = new Parser(new Lexer());
|
||||
var annotatedDirectives = ListWrapper.create();
|
||||
for (var i=0; i<directives.length; i++) {
|
||||
ListWrapper.push(annotatedDirectives, reader.annotatedType(directives[i]));
|
||||
ListWrapper.push(annotatedDirectives, reader.read(directives[i]));
|
||||
}
|
||||
|
||||
return new CompilePipeline([new MockStep((parent, current, control) => {
|
||||
@ -53,7 +53,7 @@ export function main() {
|
||||
describe('component directives', () => {
|
||||
it('should detect them in attributes', () => {
|
||||
var results = createPipeline().process(createElement('<div some-comp></div>'));
|
||||
expect(results[0].componentDirective).toEqual(reader.annotatedType(SomeComponent));
|
||||
expect(results[0].componentDirective).toEqual(reader.read(SomeComponent));
|
||||
});
|
||||
|
||||
it('should detect them in property bindings', () => {
|
||||
@ -61,7 +61,7 @@ export function main() {
|
||||
'some-comp': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<div></div>'));
|
||||
expect(results[0].componentDirective).toEqual(reader.annotatedType(SomeComponent));
|
||||
expect(results[0].componentDirective).toEqual(reader.read(SomeComponent));
|
||||
});
|
||||
|
||||
it('should detect them in variable bindings', () => {
|
||||
@ -69,7 +69,7 @@ export function main() {
|
||||
'some-comp': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<div></div>'));
|
||||
expect(results[0].componentDirective).toEqual(reader.annotatedType(SomeComponent));
|
||||
expect(results[0].componentDirective).toEqual(reader.read(SomeComponent));
|
||||
});
|
||||
|
||||
it('should not allow multiple component directives on the same element', () => {
|
||||
@ -92,7 +92,7 @@ export function main() {
|
||||
describe('template directives', () => {
|
||||
it('should detect them in attributes', () => {
|
||||
var results = createPipeline().process(createElement('<template some-templ></template>'));
|
||||
expect(results[0].templateDirective).toEqual(reader.annotatedType(SomeTemplate));
|
||||
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
|
||||
});
|
||||
|
||||
it('should detect them in property bindings', () => {
|
||||
@ -100,7 +100,7 @@ export function main() {
|
||||
'some-templ': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<template></template>'));
|
||||
expect(results[0].templateDirective).toEqual(reader.annotatedType(SomeTemplate));
|
||||
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
|
||||
});
|
||||
|
||||
it('should detect them in variable bindings', () => {
|
||||
@ -108,7 +108,7 @@ export function main() {
|
||||
'some-templ': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<template></template>'));
|
||||
expect(results[0].templateDirective).toEqual(reader.annotatedType(SomeTemplate));
|
||||
expect(results[0].templateDirective).toEqual(reader.read(SomeTemplate));
|
||||
});
|
||||
|
||||
it('should not allow multiple template directives on the same element', () => {
|
||||
@ -131,7 +131,7 @@ export function main() {
|
||||
describe('decorator directives', () => {
|
||||
it('should detect them in attributes', () => {
|
||||
var results = createPipeline().process(createElement('<div some-decor></div>'));
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.annotatedType(SomeDecorator)]);
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]);
|
||||
});
|
||||
|
||||
it('should detect them in property bindings', () => {
|
||||
@ -139,7 +139,7 @@ export function main() {
|
||||
'some-decor': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<div></div>'));
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.annotatedType(SomeDecorator)]);
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]);
|
||||
});
|
||||
|
||||
it('should detect them in variable bindings', () => {
|
||||
@ -147,7 +147,7 @@ export function main() {
|
||||
'some-decor': 'someExpr'
|
||||
}});
|
||||
var results = pipeline.process(createElement('<div></div>'));
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.annotatedType(SomeDecorator)]);
|
||||
expect(results[0].decoratorDirectives).toEqual([reader.read(SomeDecorator)]);
|
||||
});
|
||||
|
||||
it('should not allow decorator directives on <template> elements', () => {
|
||||
|
@ -59,7 +59,7 @@ export function main() {
|
||||
if (isPresent(current.element.getAttribute('directives'))) {
|
||||
hasBinding = true;
|
||||
for (var i=0; i<directives.length; i++) {
|
||||
current.addDirective(reflector.annotatedType(directives[i]));
|
||||
current.addDirective(reflector.read(directives[i]));
|
||||
}
|
||||
}
|
||||
if (hasBinding) {
|
||||
|
@ -32,7 +32,7 @@ export function main() {
|
||||
}
|
||||
if (isPresent(directives)) {
|
||||
for (var i=0; i<directives.length; i++) {
|
||||
current.addDirective(reader.annotatedType(directives[i]));
|
||||
current.addDirective(reader.read(directives[i]));
|
||||
}
|
||||
}
|
||||
}), new ElementBindingMarker()
|
||||
|
@ -32,7 +32,7 @@ export function main() {
|
||||
}
|
||||
if (isPresent(current.element.getAttribute('directives'))) {
|
||||
for (var i=0; i<directives.length; i++) {
|
||||
current.addDirective(reader.annotatedType(directives[i]));
|
||||
current.addDirective(reader.read(directives[i]));
|
||||
}
|
||||
}
|
||||
current.inheritedProtoView = protoView;
|
||||
|
@ -1,6 +1,7 @@
|
||||
import {describe, xit, it, expect, beforeEach, ddescribe, iit} from 'test_lib/test_lib';
|
||||
import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'core/compiler/view';
|
||||
import {ProtoElementInjector, ElementInjector} from 'core/compiler/element_injector';
|
||||
import {ShadowDomEmulated} from 'core/compiler/shadow_dom';
|
||||
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
||||
import {Component, Decorator, Template} from 'core/annotations/annotations';
|
||||
import {OnChange} from 'core/core';
|
||||
@ -29,8 +30,8 @@ export function main() {
|
||||
|
||||
beforeEach(() => {
|
||||
parser = new Parser(new Lexer());
|
||||
someComponentDirective = new DirectiveMetadataReader().annotatedType(SomeComponent);
|
||||
someTemplateDirective = new DirectiveMetadataReader().annotatedType(SomeTemplate);
|
||||
someComponentDirective = new DirectiveMetadataReader().read(SomeComponent);
|
||||
someTemplateDirective = new DirectiveMetadataReader().read(SomeTemplate);
|
||||
});
|
||||
|
||||
describe('instatiated from protoView', () => {
|
||||
@ -258,15 +259,6 @@ export function main() {
|
||||
return view;
|
||||
}
|
||||
|
||||
it('should create shadow dom', () => {
|
||||
var subpv = new ProtoView(createElement('<span>hello shadow dom</span>'), new ProtoRecordRange());
|
||||
var pv = createComponentWithSubPV(subpv);
|
||||
|
||||
var view = createNestedView(pv);
|
||||
|
||||
expect(view.nodes[0].shadowRoot.childNodes[0].childNodes[0].nodeValue).toEqual('hello shadow dom');
|
||||
});
|
||||
|
||||
it('should expose component services to the component', () => {
|
||||
var subpv = new ProtoView(createElement('<span></span>'), new ProtoRecordRange());
|
||||
var pv = createComponentWithSubPV(subpv);
|
||||
@ -316,6 +308,28 @@ export function main() {
|
||||
view.componentChildViews.forEach(
|
||||
(view) => expectViewHasNoDirectiveInstances(view));
|
||||
});
|
||||
|
||||
it('should create shadow dom', () => {
|
||||
var subpv = new ProtoView(createElement('<span>hello shadow dom</span>'), new ProtoRecordRange());
|
||||
var pv = createComponentWithSubPV(subpv);
|
||||
|
||||
var view = createNestedView(pv);
|
||||
|
||||
expect(view.nodes[0].shadowRoot.childNodes[0].childNodes[0].nodeValue).toEqual('hello shadow dom');
|
||||
});
|
||||
|
||||
it('should use the provided shadow DOM strategy', () => {
|
||||
var subpv = new ProtoView(createElement('<span>hello shadow dom</span>'), new ProtoRecordRange());
|
||||
|
||||
var pv = new ProtoView(createElement('<cmp class="ng-binding"></cmp>'), new ProtoRecordRange());
|
||||
var binder = pv.bindElement(new ProtoElementInjector(null, 0, [SomeComponentWithEmulatedShadowDom], true));
|
||||
binder.componentDirective = new DirectiveMetadataReader().read(SomeComponentWithEmulatedShadowDom);
|
||||
binder.nestedProtoView = subpv;
|
||||
|
||||
var view = createNestedView(pv);
|
||||
expect(view.nodes[0].childNodes[0].childNodes[0].nodeValue).toEqual('hello shadow dom');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('with template views', () => {
|
||||
@ -485,6 +499,12 @@ class SomeComponent {
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
shadowDom: ShadowDomEmulated
|
||||
})
|
||||
class SomeComponentWithEmulatedShadowDom {
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
selector: '[dec]'
|
||||
})
|
||||
|
Reference in New Issue
Block a user