* Finds all the control flow blocks inside a specific node and view. * * @param node Node in which to search for blocks. * @param lView View within the node in which to search for blocks. * @param results (Optional) Array to which to add blocks once they're found. * @returns Found control flow
( node: Node, lView: LView, results: ControlFlowBlock[] = [], )
| 221 | * @returns Found control flow blocks results array. |
| 222 | */ |
| 223 | function findControlFlowBlocks( |
| 224 | node: Node, |
| 225 | lView: LView, |
| 226 | results: ControlFlowBlock[] = [], |
| 227 | ): ControlFlowBlock[] { |
| 228 | const tView = lView[TVIEW]; |
| 229 | |
| 230 | for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) { |
| 231 | const slot = lView[i]; |
| 232 | |
| 233 | for (const finder of CONTROL_FLOW_BLOCK_FINDERS) { |
| 234 | const block = finder({node, lView, tView, slotIdx: i}); |
| 235 | if (block) { |
| 236 | results.push(block); |
| 237 | break; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | if (isLContainer(slot)) { |
| 242 | const lContainer = slot; |
| 243 | |
| 244 | // The host can be an `LView` if this is the container |
| 245 | // for a component that injects `ViewContainerRef`. |
| 246 | if (isLView(lContainer[HOST])) { |
| 247 | findControlFlowBlocks(node, lContainer[HOST], results); |
| 248 | } |
| 249 | |
| 250 | for (let j = CONTAINER_HEADER_OFFSET; j < lContainer.length; j++) { |
| 251 | findControlFlowBlocks(node, lContainer[j], results); |
| 252 | } |
| 253 | } else if (isLView(slot)) { |
| 254 | // This is a component, enter the `findControlFlowBlocks` recursively. |
| 255 | findControlFlowBlocks(node, slot, results); |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | return results; |
| 260 | } |
| 261 | |
| 262 | /** |
| 263 | * Turns the `DeferBlockState` into a string which is more readable than the enum form. |
no test coverage detected
searching dependent graphs…