* `applyProjectionRecursive` performs operation on the projection specified by `action` (insert, * detach, destroy) * * Inserting a projection requires us to locate the projected nodes from the parent component. The * complication is that those nodes themselves could be re-projected from their p
( renderer: Renderer, action: WalkTNodeTreeAction, lView: LView, tProjectionNode: TProjectionNode, parentRElement: RElement | null, beforeNode: RNode | null, )
| 1015 | * @param beforeNode Before which node the insertions should happen. |
| 1016 | */ |
| 1017 | function applyProjectionRecursive( |
| 1018 | renderer: Renderer, |
| 1019 | action: WalkTNodeTreeAction, |
| 1020 | lView: LView, |
| 1021 | tProjectionNode: TProjectionNode, |
| 1022 | parentRElement: RElement | null, |
| 1023 | beforeNode: RNode | null, |
| 1024 | ) { |
| 1025 | const componentLView = lView[DECLARATION_COMPONENT_VIEW]; |
| 1026 | const componentNode = componentLView[T_HOST] as TElementNode; |
| 1027 | ngDevMode && |
| 1028 | assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index'); |
| 1029 | const nodeToProjectOrRNodes = componentNode.projection![tProjectionNode.projection]!; |
| 1030 | if (Array.isArray(nodeToProjectOrRNodes)) { |
| 1031 | // This should not exist, it is a bit of a hack. When we bootstrap a top level node and we |
| 1032 | // need to support passing projectable nodes, so we cheat and put them in the TNode |
| 1033 | // of the Host TView. (Yes we put instance info at the T Level). We can get away with it |
| 1034 | // because we know that TView is not shared and therefore it will not be a problem. |
| 1035 | // This should be refactored and cleaned up. |
| 1036 | for (let i = 0; i < nodeToProjectOrRNodes.length; i++) { |
| 1037 | const rNode = nodeToProjectOrRNodes[i]; |
| 1038 | applyToElementOrContainer( |
| 1039 | action, |
| 1040 | renderer, |
| 1041 | lView[INJECTOR], |
| 1042 | parentRElement, |
| 1043 | rNode, |
| 1044 | tProjectionNode, |
| 1045 | beforeNode, |
| 1046 | lView, |
| 1047 | ); |
| 1048 | } |
| 1049 | } else { |
| 1050 | let nodeToProject: TNode | null = nodeToProjectOrRNodes; |
| 1051 | const projectedComponentLView = componentLView[PARENT] as LView; |
| 1052 | // If a parent <ng-content> is located within a skip hydration block, |
| 1053 | // annotate an actual node that is being projected with the same flag too. |
| 1054 | if (hasInSkipHydrationBlockFlag(tProjectionNode)) { |
| 1055 | nodeToProject.flags |= TNodeFlags.inSkipHydrationBlock; |
| 1056 | } |
| 1057 | applyNodes( |
| 1058 | renderer, |
| 1059 | action, |
| 1060 | nodeToProject, |
| 1061 | projectedComponentLView, |
| 1062 | parentRElement, |
| 1063 | beforeNode, |
| 1064 | true, |
| 1065 | ); |
| 1066 | } |
| 1067 | } |
| 1068 | |
| 1069 | /** |
| 1070 | * `applyContainer` performs an operation on the container and its views as specified by |
no test coverage detected