test(ivy): get ViewRef.rootNodes should get all root nodes from projectable nodes (#33647)

PR Close #33647
This commit is contained in:
Pawel Kozlowski 2019-11-07 12:23:17 +01:00 committed by Kara Erickson
parent 9d99c7244f
commit 39712bcdb2
2 changed files with 13 additions and 12 deletions

View File

@ -19,7 +19,7 @@ import {CONTEXT, FLAGS, HOST, LView, LViewFlags, TVIEW, T_HOST} from './interfac
import {assertNodeOfPossibleTypes} from './node_assert'; import {assertNodeOfPossibleTypes} from './node_assert';
import {destroyLView, renderDetachView} from './node_manipulation'; import {destroyLView, renderDetachView} from './node_manipulation';
import {findComponentView, getLViewParent} from './util/view_traversal_utils'; import {findComponentView, getLViewParent} from './util/view_traversal_utils';
import {getNativeByTNode, unwrapRNode} from './util/view_utils'; import {unwrapRNode} from './util/view_utils';
@ -302,7 +302,8 @@ export class RootViewRef<T> extends ViewRef<T> {
get context(): T { return null !; } get context(): T { return null !; }
} }
function collectNativeNodes(lView: LView, tNode: TNode | null, result: any[]): any[] { function collectNativeNodes(
lView: LView, tNode: TNode | null, result: any[], isProjection: boolean = false): any[] {
while (tNode !== null) { while (tNode !== null) {
ngDevMode && assertNodeOfPossibleTypes( ngDevMode && assertNodeOfPossibleTypes(
tNode, TNodeType.Element, TNodeType.Container, TNodeType.Projection, tNode, TNodeType.Element, TNodeType.Container, TNodeType.Projection,
@ -333,15 +334,13 @@ function collectNativeNodes(lView: LView, tNode: TNode | null, result: any[]): a
const componentView = findComponentView(lView); const componentView = findComponentView(lView);
const componentHost = componentView[T_HOST] as TElementNode; const componentHost = componentView[T_HOST] as TElementNode;
const parentView = getLViewParent(componentView); const parentView = getLViewParent(componentView);
let currentProjectedNode: TNode|null = let firstProjectedNode: TNode|null =
(componentHost.projection as(TNode | null)[])[tNode.projection as number]; (componentHost.projection as(TNode | null)[])[tNode.projection as number];
if (firstProjectedNode !== null && parentView !== null) {
while (currentProjectedNode !== null && parentView !== null) { collectNativeNodes(parentView, firstProjectedNode, result, true);
result.push(getNativeByTNode(currentProjectedNode, parentView));
currentProjectedNode = currentProjectedNode.next;
} }
} }
tNode = tNode.next; tNode = isProjection ? tNode.projectionNext : tNode.next;
} }
return result; return result;

View File

@ -55,7 +55,7 @@ describe('TemplateRef', () => {
expect(rootNodes.length).toBe(0); expect(rootNodes.length).toBe(0);
}); });
it('should include projected nodes', () => { it('should include projected nodes and their children', () => {
@Component({ @Component({
selector: 'menu-content', selector: 'menu-content',
template: ` template: `
@ -75,6 +75,7 @@ describe('TemplateRef', () => {
<menu-content #menu="menuContent"> <menu-content #menu="menuContent">
<button>Item one</button> <button>Item one</button>
<button>Item two</button> <button>Item two</button>
<ng-template [ngIf]="true"><button>Item three</button></ng-template>
</menu-content> </menu-content>
` `
}) })
@ -90,10 +91,11 @@ describe('TemplateRef', () => {
const instance = fixture.componentInstance; const instance = fixture.componentInstance;
const viewRef = instance.viewContainerRef.createEmbeddedView(instance.content.template); const viewRef = instance.viewContainerRef.createEmbeddedView(instance.content.template);
const rootNodeTextContent = viewRef.rootNodes.map(node => node && node.textContent.trim()) const rootNodeTextContent =
.filter(text => text !== ''); viewRef.rootNodes.map(node => node && node.textContent.trim())
.filter(text => text !== '' && text.indexOf('ng-reflect-ng-if') === -1);
expect(rootNodeTextContent).toEqual(['Header', 'Item one', 'Item two']); expect(rootNodeTextContent).toEqual(['Header', 'Item one', 'Item two', 'Item three']);
}); });
it('should descend into view containers on ng-template', () => { it('should descend into view containers on ng-template', () => {