feat(components): initial implementation of emulated content tag
This commit is contained in:
@ -1,8 +1,20 @@
|
||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'test_lib/test_lib';
|
||||
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
||||
import {Decorator, Component} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
import {DirectiveMetadata} from 'core/compiler/directive_metadata';
|
||||
import {ShadowDomEmulated, ShadowDomNative} from 'core/compiler/shadow_dom';
|
||||
import {ShadowDomStrategy, ShadowDomNative} from 'core/compiler/shadow_dom';
|
||||
import {CONST} from 'facade/lang';
|
||||
|
||||
|
||||
class FakeShadowDomStrategy extends ShadowDomStrategy {
|
||||
@CONST()
|
||||
constructor() {}
|
||||
|
||||
polyfillDirectives() {
|
||||
return [SomeDirective];
|
||||
}
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
selector: 'someSelector'
|
||||
@ -17,13 +29,28 @@ class ComponentWithoutExplicitShadowDomStrategy {}
|
||||
|
||||
@Component({
|
||||
selector: 'someSelector',
|
||||
shadowDom: ShadowDomEmulated
|
||||
shadowDom: new FakeShadowDomStrategy()
|
||||
})
|
||||
class ComponentWithExplicitShadowDomStrategy {}
|
||||
|
||||
class SomeDirectiveWithoutAnnotation {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'withoutDirectives'
|
||||
})
|
||||
class ComponentWithoutDirectives {}
|
||||
|
||||
@Component({
|
||||
selector: 'withDirectives',
|
||||
template: new TemplateConfig({
|
||||
directives: [ComponentWithoutDirectives]
|
||||
})
|
||||
})
|
||||
class ComponentWithDirectives {}
|
||||
|
||||
|
||||
|
||||
export function main() {
|
||||
describe("DirectiveMetadataReader", () => {
|
||||
var reader;
|
||||
@ -35,7 +62,7 @@ export function main() {
|
||||
it('should read out the annotation', () => {
|
||||
var directiveMetadata = reader.read(SomeDirective);
|
||||
expect(directiveMetadata).toEqual(
|
||||
new DirectiveMetadata(SomeDirective, new Decorator({selector: 'someSelector'}), null));
|
||||
new DirectiveMetadata(SomeDirective, new Decorator({selector: 'someSelector'}), null, null));
|
||||
});
|
||||
|
||||
it('should throw if not matching annotation is found', () => {
|
||||
@ -47,7 +74,7 @@ export function main() {
|
||||
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);
|
||||
expect(directiveMetadata.shadowDomStrategy).toBeAnInstanceOf(FakeShadowDomStrategy);
|
||||
});
|
||||
|
||||
it('should return Native otherwise', () => {
|
||||
@ -55,5 +82,22 @@ export function main() {
|
||||
expect(directiveMetadata.shadowDomStrategy).toEqual(ShadowDomNative);
|
||||
});
|
||||
});
|
||||
|
||||
describe("componentDirectives", () => {
|
||||
it("should return an empty list when no directives specified", () => {
|
||||
var cmp = reader.read(ComponentWithoutDirectives);
|
||||
expect(cmp.componentDirectives).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return a list of directives specified in the template config", () => {
|
||||
var cmp = reader.read(ComponentWithDirectives);
|
||||
expect(cmp.componentDirectives).toEqual([ComponentWithoutDirectives]);
|
||||
});
|
||||
|
||||
it("should include directives required by the shadow DOM strategy", () => {
|
||||
var cmp = reader.read(ComponentWithExplicitShadowDomStrategy);
|
||||
expect(cmp.componentDirectives).toEqual([SomeDirective]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
@ -8,11 +8,16 @@ import {View} from 'core/compiler/view';
|
||||
import {ProtoRecordRange} from 'change_detection/change_detection';
|
||||
import {ViewPort} from 'core/compiler/viewport';
|
||||
import {NgElement} from 'core/dom/element';
|
||||
import {LightDom, SourceLightDom, DestinationLightDom} from 'core/compiler/shadow_dom_emulation/light_dom';
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(View)
|
||||
class DummyView extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(LightDom)
|
||||
class DummyLightDom extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
|
||||
|
||||
|
||||
class Directive {
|
||||
}
|
||||
@ -65,7 +70,7 @@ class NeedsView {
|
||||
}
|
||||
|
||||
export function main() {
|
||||
var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null);
|
||||
var defaultPreBuiltObjects = new PreBuiltObjects(null, null, null, null);
|
||||
|
||||
function humanize(tree, names:List) {
|
||||
var lookupName = (item) =>
|
||||
@ -88,12 +93,15 @@ export function main() {
|
||||
return inj;
|
||||
}
|
||||
|
||||
function parentChildInjectors(parentBindings, childBindings) {
|
||||
function parentChildInjectors(parentBindings, childBindings, parentPreBuildObjects = null) {
|
||||
if (isBlank(parentPreBuildObjects)) parentPreBuildObjects = defaultPreBuiltObjects;
|
||||
|
||||
var inj = new Injector([]);
|
||||
|
||||
var protoParent = new ProtoElementInjector(null, 0, parentBindings);
|
||||
var parent = protoParent.instantiate(null, null);
|
||||
parent.instantiateDirectives(inj, null, defaultPreBuiltObjects);
|
||||
|
||||
parent.instantiateDirectives(inj, null, parentPreBuildObjects);
|
||||
|
||||
var protoChild = new ProtoElementInjector(protoParent, 1, childBindings);
|
||||
var child = protoChild.instantiate(parent, null);
|
||||
@ -102,13 +110,15 @@ export function main() {
|
||||
return child;
|
||||
}
|
||||
|
||||
function hostShadowInjectors(hostBindings, shadowBindings) {
|
||||
function hostShadowInjectors(hostBindings, shadowBindings, hostPreBuildObjects = null) {
|
||||
if (isBlank(hostPreBuildObjects)) hostPreBuildObjects = defaultPreBuiltObjects;
|
||||
|
||||
var inj = new Injector([]);
|
||||
var shadowInj = inj.createChild([]);
|
||||
|
||||
var protoParent = new ProtoElementInjector(null, 0, hostBindings, true);
|
||||
var host = protoParent.instantiate(null, null);
|
||||
host.instantiateDirectives(inj, shadowInj, null);
|
||||
host.instantiateDirectives(inj, shadowInj, hostPreBuildObjects);
|
||||
|
||||
var protoChild = new ProtoElementInjector(protoParent, 0, shadowBindings, false);
|
||||
var shadow = protoChild.instantiate(null, host);
|
||||
@ -186,7 +196,7 @@ export function main() {
|
||||
|
||||
it("should instantiate directives that depend on pre built objects", function () {
|
||||
var view = new DummyView();
|
||||
var inj = injector([NeedsView], null, null, new PreBuiltObjects(view, null, null));
|
||||
var inj = injector([NeedsView], null, null, new PreBuiltObjects(view, null, null, null));
|
||||
|
||||
expect(inj.get(NeedsView).view).toBe(view);
|
||||
});
|
||||
@ -291,24 +301,51 @@ export function main() {
|
||||
describe("pre built objects", function () {
|
||||
it("should return view", function () {
|
||||
var view = new DummyView();
|
||||
var inj = injector([], null, null, new PreBuiltObjects(view, null, null));
|
||||
var inj = injector([], null, null, new PreBuiltObjects(view, null, null, null));
|
||||
|
||||
expect(inj.get(View)).toEqual(view);
|
||||
});
|
||||
|
||||
it("should return element", function () {
|
||||
var element = new NgElement(null);
|
||||
var inj = injector([], null, null, new PreBuiltObjects(null, element, null));
|
||||
var inj = injector([], null, null, new PreBuiltObjects(null, element, null, null));
|
||||
|
||||
expect(inj.get(NgElement)).toEqual(element);
|
||||
});
|
||||
|
||||
it('should return viewPort', function () {
|
||||
var viewPort = new ViewPort(null, null, null, null);
|
||||
var inj = injector([], null, null, new PreBuiltObjects(null, null, viewPort));
|
||||
var inj = injector([], null, null, new PreBuiltObjects(null, null, viewPort, null));
|
||||
|
||||
expect(inj.get(ViewPort)).toEqual(viewPort);
|
||||
});
|
||||
|
||||
describe("light DOM", () => {
|
||||
var lightDom, parentPreBuiltObjects;
|
||||
|
||||
beforeEach(() => {
|
||||
lightDom = new DummyLightDom();
|
||||
parentPreBuiltObjects = new PreBuiltObjects(null, null, null, lightDom);
|
||||
});
|
||||
|
||||
it("should return destination light DOM from the parent's injector", function () {
|
||||
var child = parentChildInjectors([], [], parentPreBuiltObjects);
|
||||
|
||||
expect(child.get(DestinationLightDom)).toEqual(lightDom);
|
||||
});
|
||||
|
||||
it("should return null when parent's injector is a component boundary", function () {
|
||||
var child = hostShadowInjectors([], [], parentPreBuiltObjects);
|
||||
|
||||
expect(child.get(DestinationLightDom)).toBeNull();
|
||||
});
|
||||
|
||||
it("should return source light DOM from the closest component boundary", function () {
|
||||
var child = hostShadowInjectors([], [], parentPreBuiltObjects);
|
||||
|
||||
expect(child.get(SourceLightDom)).toEqual(lightDom);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import {Lexer, Parser, ChangeDetector} from 'change_detection/change_detection';
|
||||
|
||||
import {Compiler, CompilerCache} from 'core/compiler/compiler';
|
||||
import {DirectiveMetadataReader} from 'core/compiler/directive_metadata_reader';
|
||||
import {ShadowDomEmulated} from 'core/compiler/shadow_dom';
|
||||
|
||||
import {Decorator, Component, Template} from 'core/annotations/annotations';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
@ -108,9 +109,51 @@ export function main() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should emulate content tag', (done) => {
|
||||
var el = `<emulated-shadow-dom-component>` +
|
||||
`<div>Light</div>` +
|
||||
`<div template="trivial-template">DOM</div>` +
|
||||
`</emulated-shadow-dom-component>`;
|
||||
|
||||
function createView(pv) {
|
||||
var view = pv.instantiate(null);
|
||||
view.hydrate(new Injector([]), null, {});
|
||||
return view;
|
||||
}
|
||||
|
||||
compiler.compile(MyComp, createElement(el)).
|
||||
then(createView).
|
||||
then((view) => {
|
||||
expect(DOM.getText(view.nodes[0])).toEqual('Before LightDOM After');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@Template({
|
||||
selector: '[trivial-template]'
|
||||
})
|
||||
class TrivialTemplateDirective {
|
||||
constructor(viewPort:ViewPort) {
|
||||
viewPort.create();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'emulated-shadow-dom-component',
|
||||
template: new TemplateConfig({
|
||||
inline: 'Before <content></content> After',
|
||||
directives: []
|
||||
}),
|
||||
shadowDom: ShadowDomEmulated
|
||||
})
|
||||
class EmulatedShadowDomCmp {
|
||||
|
||||
}
|
||||
|
||||
@Decorator({
|
||||
selector: '[my-dir]',
|
||||
bind: {'elprop':'dirProp'}
|
||||
@ -124,7 +167,7 @@ class MyDir {
|
||||
|
||||
@Component({
|
||||
template: new TemplateConfig({
|
||||
directives: [MyDir, ChildComp, SomeTemplate]
|
||||
directives: [MyDir, ChildComp, SomeTemplate, EmulatedShadowDomCmp, TrivialTemplateDirective]
|
||||
})
|
||||
})
|
||||
class MyComp {
|
||||
|
55
modules/core/test/compiler/shadow_dom/content_tag_spec.js
Normal file
55
modules/core/test/compiler/shadow_dom/content_tag_spec.js
Normal file
@ -0,0 +1,55 @@
|
||||
import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject} from 'test_lib/test_lib';
|
||||
import {proxy, IMPLEMENTS} from 'facade/lang';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {Content} from 'core/compiler/shadow_dom_emulation/content_tag';
|
||||
import {NgElement} from 'core/dom/element';
|
||||
import {LightDom} from 'core/compiler/shadow_dom_emulation/light_dom';
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(LightDom)
|
||||
class DummyLightDom extends SpyObject {noSuchMethod(m){super.noSuchMethod(m)}}
|
||||
|
||||
var _script = `<script type="ng/content"></script>`;
|
||||
|
||||
export function main() {
|
||||
describe('Content', function() {
|
||||
it("should insert the nodes", () => {
|
||||
var lightDom = new DummyLightDom();
|
||||
var parent = createElement("<div><content></content></div>");
|
||||
var content = DOM.firstChild(parent);
|
||||
|
||||
var c = new Content(lightDom, new NgElement(content));
|
||||
c.insert([createElement("<a></a>"), createElement("<b></b>")])
|
||||
|
||||
expect(DOM.getInnerHTML(parent)).toEqual(`${_script}<a></a><b></b>${_script}`);
|
||||
});
|
||||
|
||||
it("should remove the nodes from the previous insertion", () => {
|
||||
var lightDom = new DummyLightDom();
|
||||
var parent = createElement("<div><content></content></div>");
|
||||
var content = DOM.firstChild(parent);
|
||||
|
||||
var c = new Content(lightDom, new NgElement(content));
|
||||
c.insert([createElement("<a></a>")]);
|
||||
c.insert([createElement("<b></b>")]);
|
||||
|
||||
expect(DOM.getInnerHTML(parent)).toEqual(`${_script}<b></b>${_script}`);
|
||||
});
|
||||
|
||||
it("should insert empty list", () => {
|
||||
var lightDom = new DummyLightDom();
|
||||
var parent = createElement("<div><content></content></div>");
|
||||
var content = DOM.firstChild(parent);
|
||||
|
||||
var c = new Content(lightDom, new NgElement(content));
|
||||
c.insert([createElement("<a></a>")]);
|
||||
c.insert([]);
|
||||
|
||||
expect(DOM.getInnerHTML(parent)).toEqual(`${_script}${_script}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createElement(html) {
|
||||
return DOM.createTemplate(html).content.firstChild;
|
||||
}
|
209
modules/core/test/compiler/shadow_dom/light_dom_spec.js
Normal file
209
modules/core/test/compiler/shadow_dom/light_dom_spec.js
Normal file
@ -0,0 +1,209 @@
|
||||
import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject} from 'test_lib/test_lib';
|
||||
import {proxy, IMPLEMENTS, isBlank} from 'facade/lang';
|
||||
import {ListWrapper, MapWrapper} from 'facade/collection';
|
||||
import {DOM} from 'facade/dom';
|
||||
import {Content} from 'core/compiler/shadow_dom_emulation/content_tag';
|
||||
import {NgElement} from 'core/dom/element';
|
||||
import {LightDom} from 'core/compiler/shadow_dom_emulation/light_dom';
|
||||
import {View} from 'core/compiler/view';
|
||||
import {ViewPort} from 'core/compiler/viewport';
|
||||
import {ElementInjector} from 'core/compiler/element_injector';
|
||||
import {ProtoRecordRange} from 'change_detection/change_detection';
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(ElementInjector)
|
||||
class FakeElementInjector {
|
||||
content;
|
||||
viewPort;
|
||||
|
||||
constructor(content, viewPort) {
|
||||
this.content = content;
|
||||
this.viewPort = viewPort;
|
||||
}
|
||||
|
||||
hasDirective(type) {
|
||||
return this.content != null;
|
||||
}
|
||||
|
||||
hasPreBuiltObject(type) {
|
||||
return this.viewPort != null;
|
||||
}
|
||||
|
||||
get(t) {
|
||||
if (t === Content) return this.content;
|
||||
if (t === ViewPort) return this.viewPort;
|
||||
return null;
|
||||
}
|
||||
|
||||
noSuchMethod(i) {
|
||||
super.noSuchMethod(i);
|
||||
}
|
||||
}
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(View)
|
||||
class FakeView {
|
||||
elementInjectors;
|
||||
ports;
|
||||
|
||||
constructor(elementInjectors = null, ports = null) {
|
||||
this.elementInjectors = elementInjectors;
|
||||
this.ports = ports;
|
||||
}
|
||||
|
||||
getViewPortByTemplateElement(el) {
|
||||
if (isBlank(this.ports)) return null;
|
||||
return MapWrapper.get(this.ports, el);
|
||||
}
|
||||
|
||||
noSuchMethod(i) {
|
||||
super.noSuchMethod(i);
|
||||
}
|
||||
}
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(ViewPort)
|
||||
class FakeViewPort {
|
||||
_nodes;
|
||||
_contentTagContainers;
|
||||
|
||||
constructor(nodes, views) {
|
||||
this._nodes = nodes;
|
||||
this._contentTagContainers = views;
|
||||
}
|
||||
|
||||
nodes(){
|
||||
return this._nodes;
|
||||
}
|
||||
|
||||
contentTagContainers(){
|
||||
return this._contentTagContainers;
|
||||
}
|
||||
|
||||
noSuchMethod(i) {
|
||||
super.noSuchMethod(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(Content)
|
||||
class FakeContentTag {
|
||||
select;
|
||||
nodes;
|
||||
|
||||
constructor(select = null) {
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
insert(nodes){
|
||||
this.nodes = ListWrapper.clone(nodes);
|
||||
}
|
||||
|
||||
noSuchMethod(i) {
|
||||
super.noSuchMethod(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
describe('LightDom', function() {
|
||||
var lightDomView;
|
||||
|
||||
beforeEach(() => {
|
||||
lightDomView = new FakeView([], MapWrapper.create());
|
||||
});
|
||||
|
||||
describe("contentTags", () => {
|
||||
it("should collect content tags from element injectors", () => {
|
||||
var tag = new FakeContentTag();
|
||||
var shadowDomView = new FakeView([new FakeElementInjector(tag, null)]);
|
||||
|
||||
var lightDom = new LightDom(lightDomView, shadowDomView, createElement("<div></div>"));
|
||||
|
||||
expect(lightDom.contentTags()).toEqual([tag]);
|
||||
});
|
||||
|
||||
it("should collect content tags from view ports", () => {
|
||||
var tag = new FakeContentTag();
|
||||
var vp = new FakeViewPort(null, [
|
||||
new FakeView([new FakeElementInjector(tag, null)])
|
||||
]);
|
||||
|
||||
var shadowDomView = new FakeView([new FakeElementInjector(null, vp)]);
|
||||
|
||||
var lightDom = new LightDom(lightDomView, shadowDomView, createElement("<div></div>"));
|
||||
|
||||
expect(lightDom.contentTags()).toEqual([tag]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("expanded roots", () => {
|
||||
it("should contain root nodes", () => {
|
||||
var lightDomEl = createElement("<div><a></a></div>")
|
||||
var lightDom = new LightDom(lightDomView, new FakeView(), lightDomEl);
|
||||
expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
|
||||
});
|
||||
|
||||
it("should include view port nodes", () => {
|
||||
var lightDomEl = createElement("<div><template></template></div>")
|
||||
var template = lightDomEl.childNodes[0];
|
||||
|
||||
var lightDomView = new FakeView([],
|
||||
MapWrapper.createFromPairs([
|
||||
[template, new FakeViewPort([createElement("<a></a>")], null)]
|
||||
])
|
||||
);
|
||||
|
||||
var lightDom = new LightDom(lightDomView, new FakeView(), lightDomEl);
|
||||
|
||||
expect(toHtml(lightDom.expandedDomNodes())).toEqual(["<a></a>"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("redistribute", () => {
|
||||
it("should redistribute nodes between content tags with select property set", () => {
|
||||
var contentA = new FakeContentTag("a");
|
||||
var contentB = new FakeContentTag("b");
|
||||
|
||||
var lightDomEl = createElement("<div><a>1</a><b>2</b><a>3</a></div>")
|
||||
|
||||
var lightDom = new LightDom(lightDomView, new FakeView([
|
||||
new FakeElementInjector(contentA, null),
|
||||
new FakeElementInjector(contentB, null)
|
||||
]), lightDomEl);
|
||||
|
||||
lightDom.redistribute();
|
||||
|
||||
expect(toHtml(contentA.nodes)).toEqual(["<a>1</a>", "<a>3</a>"]);
|
||||
expect(toHtml(contentB.nodes)).toEqual(["<b>2</b>"]);
|
||||
});
|
||||
|
||||
it("should support wildcard content tags", () => {
|
||||
var wildcard = new FakeContentTag(null);
|
||||
var contentB = new FakeContentTag("b");
|
||||
|
||||
var lightDomEl = createElement("<div><a>1</a><b>2</b><a>3</a></div>")
|
||||
|
||||
var lightDom = new LightDom(lightDomView, new FakeView([
|
||||
new FakeElementInjector(wildcard, null),
|
||||
new FakeElementInjector(contentB, null)
|
||||
]), lightDomEl);
|
||||
|
||||
lightDom.redistribute();
|
||||
|
||||
expect(toHtml(wildcard.nodes)).toEqual(["<a>1</a>", "<b>2</b>", "<a>3</a>"]);
|
||||
expect(toHtml(contentB.nodes)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function toHtml(nodes) {
|
||||
if (isBlank(nodes)) return [];
|
||||
return ListWrapper.map(nodes, DOM.getOuterHTML);
|
||||
}
|
||||
|
||||
function createElement(html) {
|
||||
return DOM.createTemplate(html).content.firstChild;
|
||||
}
|
@ -7,14 +7,30 @@ import {Component, Decorator, Template} from 'core/annotations/annotations';
|
||||
import {OnChange} from 'core/core';
|
||||
import {Lexer, Parser, ProtoRecordRange, ChangeDetector} from 'change_detection/change_detection';
|
||||
import {TemplateConfig} from 'core/annotations/template_config';
|
||||
import {List} from 'facade/collection';
|
||||
import {List, MapWrapper} from 'facade/collection';
|
||||
import {DOM, Element} from 'facade/dom';
|
||||
import {int} from 'facade/lang';
|
||||
import {int, proxy, IMPLEMENTS} from 'facade/lang';
|
||||
import {Injector} from 'di/di';
|
||||
import {View} from 'core/compiler/view';
|
||||
import {ViewPort} from 'core/compiler/viewport';
|
||||
import {reflector} from 'reflection/reflection';
|
||||
|
||||
|
||||
@proxy
|
||||
@IMPLEMENTS(ViewPort)
|
||||
class FakeViewPort {
|
||||
templateElement;
|
||||
|
||||
constructor(templateElement) {
|
||||
this.templateElement = templateElement;
|
||||
}
|
||||
|
||||
noSuchMethod(i) {
|
||||
super.noSuchMethod(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function main() {
|
||||
describe('view', function() {
|
||||
var parser, someComponentDirective, someTemplateDirective;
|
||||
@ -53,6 +69,25 @@ export function main() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("getViewPortByTemplateElement", () => {
|
||||
var view, viewPort, templateElement;
|
||||
|
||||
beforeEach(() => {
|
||||
templateElement = createElement("<template></template>");
|
||||
view = new View(null, null, new ProtoRecordRange(), MapWrapper.create());
|
||||
viewPort = new FakeViewPort(templateElement);
|
||||
view.viewPorts = [viewPort];
|
||||
});
|
||||
|
||||
it("should return null when the given element is not an element", () => {
|
||||
expect(view.getViewPortByTemplateElement("not an element")).toBeNull();
|
||||
});
|
||||
|
||||
it("should return a view port with the matching template element", () => {
|
||||
expect(view.getViewPortByTemplateElement(templateElement)).toBe(viewPort);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with locals', function() {
|
||||
var view;
|
||||
beforeEach(() => {
|
||||
|
Reference in New Issue
Block a user