( tView: TView, tNode: TNode | null, lView: LView, )
| 530 | * @returns `null` if the `RElement` can't be determined at this time (no parent / projection) |
| 531 | */ |
| 532 | export function getClosestRElement( |
| 533 | tView: TView, |
| 534 | tNode: TNode | null, |
| 535 | lView: LView, |
| 536 | ): RElement | null { |
| 537 | let parentTNode: TNode | null = tNode; |
| 538 | // Skip over element and ICU containers as those are represented by a comment node and |
| 539 | // can't be used as a render parent. Also skip let declarations since they don't have a |
| 540 | // corresponding DOM node at all. |
| 541 | while ( |
| 542 | parentTNode !== null && |
| 543 | parentTNode.type & (TNodeType.ElementContainer | TNodeType.Icu | TNodeType.LetDeclaration) |
| 544 | ) { |
| 545 | tNode = parentTNode; |
| 546 | parentTNode = tNode.parent; |
| 547 | } |
| 548 | |
| 549 | // If the parent tNode is null, then we are inserting across views: either into an embedded view |
| 550 | // or a component view. |
| 551 | if (parentTNode === null) { |
| 552 | // We are inserting a root element of the component view into the component host element and |
| 553 | // it should always be eager. |
| 554 | return lView[HOST]; |
| 555 | } else { |
| 556 | ngDevMode && assertTNodeType(parentTNode, TNodeType.AnyRNode | TNodeType.Container); |
| 557 | if (isComponentHost(parentTNode)) { |
| 558 | ngDevMode && assertTNodeForLView(parentTNode, lView); |
| 559 | const {encapsulation} = tView.data[ |
| 560 | parentTNode.directiveStart + parentTNode.componentOffset |
| 561 | ] as ComponentDef<unknown>; |
| 562 | // We've got a parent which is an element in the current view. We just need to verify if the |
| 563 | // parent element is not a component. Component's content nodes are not inserted immediately |
| 564 | // because they will be projected, and so doing insert at this point would be wasteful. |
| 565 | // Since the projection would then move it to its final destination. Note that we can't |
| 566 | // make this assumption when using the Shadow DOM, because the native projection placeholders |
| 567 | // (<content> or <slot>) have to be in place as elements are being inserted. |
| 568 | if ( |
| 569 | encapsulation === ViewEncapsulation.None || |
| 570 | encapsulation === ViewEncapsulation.Emulated |
| 571 | ) { |
| 572 | return null; |
| 573 | } |
| 574 | } |
| 575 | |
| 576 | return getNativeByTNode(parentTNode, lView) as RElement; |
| 577 | } |
| 578 | } |
| 579 | |
| 580 | /** |
| 581 | * Find a node in front of which `currentTNode` should be inserted. |
no test coverage detected