( tView: TView, tNode: TNode | null, lView: LView, )
| 500 | * @returns `null` if the `RElement` can't be determined at this time (no parent / projection) |
| 501 | */ |
| 502 | export function getClosestRElement( |
| 503 | tView: TView, |
| 504 | tNode: TNode | null, |
| 505 | lView: LView, |
| 506 | ): RElement | null { |
| 507 | let parentTNode: TNode | null = tNode; |
| 508 | // Skip over element and ICU containers as those are represented by a comment node and |
| 509 | // can't be used as a render parent. Also skip let declarations since they don't have a |
| 510 | // corresponding DOM node at all. |
| 511 | while ( |
| 512 | parentTNode !== null && |
| 513 | parentTNode.type & (TNodeType.ElementContainer | TNodeType.Icu | TNodeType.LetDeclaration) |
| 514 | ) { |
| 515 | tNode = parentTNode; |
| 516 | parentTNode = tNode.parent; |
| 517 | } |
| 518 | |
| 519 | // If the parent tNode is null, then we are inserting across views: either into an embedded view |
| 520 | // or a component view. |
| 521 | if (parentTNode === null) { |
| 522 | // We are inserting a root element of the component view into the component host element and |
| 523 | // it should always be eager. |
| 524 | return lView[HOST]; |
| 525 | } else { |
| 526 | ngDevMode && assertTNodeType(parentTNode, TNodeType.AnyRNode | TNodeType.Container); |
| 527 | if (isComponentHost(parentTNode)) { |
| 528 | ngDevMode && assertTNodeForLView(parentTNode, lView); |
| 529 | const {encapsulation} = tView.data[ |
| 530 | parentTNode.directiveStart + parentTNode.componentOffset |
| 531 | ] as ComponentDef<unknown>; |
| 532 | // We've got a parent which is an element in the current view. We just need to verify if the |
| 533 | // parent element is not a component. Component's content nodes are not inserted immediately |
| 534 | // because they will be projected, and so doing insert at this point would be wasteful. |
| 535 | // Since the projection would then move it to its final destination. Note that we can't |
| 536 | // make this assumption when using the Shadow DOM, because the native projection placeholders |
| 537 | // (<content> or <slot>) have to be in place as elements are being inserted. |
| 538 | if ( |
| 539 | encapsulation === ViewEncapsulation.None || |
| 540 | encapsulation === ViewEncapsulation.Emulated |
| 541 | ) { |
| 542 | return null; |
| 543 | } |
| 544 | } |
| 545 | |
| 546 | return getNativeByTNode(parentTNode, lView) as RElement; |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | /** |
| 551 | * Find a node in front of which `currentTNode` should be inserted. |
no test coverage detected
searching dependent graphs…