fix(projection): allow more bound render elements than app elements.
Fixes #3236 Closes #3247
This commit is contained in:
parent
b44b06c2c9
commit
46502e4d61
|
@ -37,8 +37,8 @@ export class AppProtoViewMergeMapping {
|
||||||
this.renderProtoViewRef = renderProtoViewMergeMapping.mergedProtoViewRef;
|
this.renderProtoViewRef = renderProtoViewMergeMapping.mergedProtoViewRef;
|
||||||
this.renderFragmentCount = renderProtoViewMergeMapping.fragmentCount;
|
this.renderFragmentCount = renderProtoViewMergeMapping.fragmentCount;
|
||||||
this.renderElementIndices = renderProtoViewMergeMapping.mappedElementIndices;
|
this.renderElementIndices = renderProtoViewMergeMapping.mappedElementIndices;
|
||||||
this.renderInverseElementIndices =
|
this.renderInverseElementIndices = inverseIndexMapping(
|
||||||
inverseIndexMapping(this.renderElementIndices, this.renderElementIndices.length);
|
this.renderElementIndices, renderProtoViewMergeMapping.mappedElementCount);
|
||||||
this.renderTextIndices = renderProtoViewMergeMapping.mappedTextIndices;
|
this.renderTextIndices = renderProtoViewMergeMapping.mappedTextIndices;
|
||||||
this.hostElementIndicesByViewIndex = renderProtoViewMergeMapping.hostElementIndicesByViewIndex;
|
this.hostElementIndicesByViewIndex = renderProtoViewMergeMapping.hostElementIndicesByViewIndex;
|
||||||
this.nestedViewIndicesByElementIndex =
|
this.nestedViewIndicesByElementIndex =
|
||||||
|
@ -48,7 +48,7 @@ export class AppProtoViewMergeMapping {
|
||||||
}
|
}
|
||||||
|
|
||||||
function inverseIndexMapping(input: number[], resultLength: number): number[] {
|
function inverseIndexMapping(input: number[], resultLength: number): number[] {
|
||||||
var result = ListWrapper.createFixedSize(resultLength);
|
var result = ListWrapper.createGrowableSize(resultLength);
|
||||||
for (var i = 0; i < input.length; i++) {
|
for (var i = 0; i < input.length; i++) {
|
||||||
var value = input[i];
|
var value = input[i];
|
||||||
if (isPresent(value)) {
|
if (isPresent(value)) {
|
||||||
|
|
|
@ -307,6 +307,10 @@ export class RenderProtoViewMergeMapping {
|
||||||
// Mappings of nested ProtoViews are in depth first order, with all
|
// Mappings of nested ProtoViews are in depth first order, with all
|
||||||
// indices for one ProtoView in a consecuitve block.
|
// indices for one ProtoView in a consecuitve block.
|
||||||
public mappedElementIndices: number[],
|
public mappedElementIndices: number[],
|
||||||
|
// Number of bound render element.
|
||||||
|
// Note: This could be more than the original ones
|
||||||
|
// as we might have bound a new element for projecting bound text nodes.
|
||||||
|
public mappedElementCount: number,
|
||||||
// Mapping from app text index to render text index.
|
// Mapping from app text index to render text index.
|
||||||
// Mappings of nested ProtoViews are in depth first order, with all
|
// Mappings of nested ProtoViews are in depth first order, with all
|
||||||
// indices for one ProtoView in a consecuitve block.
|
// indices for one ProtoView in a consecuitve block.
|
||||||
|
|
|
@ -56,9 +56,10 @@ export function mergeProtoViewsRecursively(protoViewRefs: List<RenderProtoViewRe
|
||||||
var mergedProtoView =
|
var mergedProtoView =
|
||||||
DomProtoView.create(mainProtoView.original.type, rootElement, fragmentsRootNodeCount,
|
DomProtoView.create(mainProtoView.original.type, rootElement, fragmentsRootNodeCount,
|
||||||
rootTextNodeIndices, mergedElementBinders);
|
rootTextNodeIndices, mergedElementBinders);
|
||||||
return new RenderProtoViewMergeMapping(
|
return new RenderProtoViewMergeMapping(new DomProtoViewRef(mergedProtoView),
|
||||||
new DomProtoViewRef(mergedProtoView), fragmentsRootNodeCount.length, mappedElementIndices,
|
fragmentsRootNodeCount.length, mappedElementIndices,
|
||||||
mappedTextIndices, hostElementIndicesByViewIndex, nestedViewCounts);
|
mergedBoundElements.length, mappedTextIndices,
|
||||||
|
hostElementIndicesByViewIndex, nestedViewCounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
function cloneProtoViews(protoViewRefs: List<RenderProtoViewRef | List<any>>,
|
function cloneProtoViews(protoViewRefs: List<RenderProtoViewRef | List<any>>,
|
||||||
|
|
|
@ -74,7 +74,7 @@ export function main() {
|
||||||
renderCompiler.spy('mergeProtoViewsRecursively')
|
renderCompiler.spy('mergeProtoViewsRecursively')
|
||||||
.andCallFake((protoViewRefs: List<renderApi.RenderProtoViewRef | List<any>>) => {
|
.andCallFake((protoViewRefs: List<renderApi.RenderProtoViewRef | List<any>>) => {
|
||||||
return PromiseWrapper.resolve(new renderApi.RenderProtoViewMergeMapping(
|
return PromiseWrapper.resolve(new renderApi.RenderProtoViewMergeMapping(
|
||||||
new MergedRenderProtoViewRef(protoViewRefs), 1, [], [], [], [null]));
|
new MergedRenderProtoViewRef(protoViewRefs), 1, [], 0, [], [], [null]));
|
||||||
});
|
});
|
||||||
// TODO spy on .compile and return RenderProtoViewRef, same for compileHost
|
// TODO spy on .compile and return RenderProtoViewRef, same for compileHost
|
||||||
rootProtoView = createRootProtoView(directiveResolver, MainComponent);
|
rootProtoView = createRootProtoView(directiveResolver, MainComponent);
|
||||||
|
|
|
@ -92,6 +92,26 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should support projecting text interpolation to a non bound element with other bound elements after it',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
tcb.overrideView(Simple, new viewAnn.View({
|
||||||
|
template: 'SIMPLE(<div><ng-content></ng-content></div><div [tab-index]="0">EL</div>)',
|
||||||
|
directives: []
|
||||||
|
}))
|
||||||
|
.overrideView(
|
||||||
|
MainComp,
|
||||||
|
new viewAnn.View({template: '<simple>{{text}}</simple>', directives: [Simple]}))
|
||||||
|
.createAsync(MainComp)
|
||||||
|
.then((main) => {
|
||||||
|
|
||||||
|
main.componentInstance.text = 'A';
|
||||||
|
main.detectChanges();
|
||||||
|
expect(main.nativeElement).toHaveText('SIMPLE(AEL)');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
it('should not show the light dom even if there is no content tag',
|
it('should not show the light dom even if there is no content tag',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
tcb.overrideView(MainComp,
|
tcb.overrideView(MainComp,
|
||||||
|
|
|
@ -324,9 +324,10 @@ function _createProtoView(type: ViewType, binders: ElementBinder[] = null) {
|
||||||
}
|
}
|
||||||
var hostElementIndicesByViewIndex = calcHostElementIndicesByViewIndex(res);
|
var hostElementIndicesByViewIndex = calcHostElementIndicesByViewIndex(res);
|
||||||
if (type === ViewType.EMBEDDED || type === ViewType.HOST) {
|
if (type === ViewType.EMBEDDED || type === ViewType.HOST) {
|
||||||
res.mergeMapping = new AppProtoViewMergeMapping(new RenderProtoViewMergeMapping(
|
res.mergeMapping = new AppProtoViewMergeMapping(
|
||||||
null, hostElementIndicesByViewIndex.length, mappedElementIndices, [],
|
new RenderProtoViewMergeMapping(null, hostElementIndicesByViewIndex.length,
|
||||||
hostElementIndicesByViewIndex, countNestedProtoViews(res)));
|
mappedElementIndices, mappedElementIndices.length, [],
|
||||||
|
hostElementIndicesByViewIndex, countNestedProtoViews(res)));
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue