( deferBlockId: string, injector: Injector, )
| 598 | * Note: This is utilizing serialized information to navigate up the tree |
| 599 | */ |
| 600 | export function getParentBlockHydrationQueue( |
| 601 | deferBlockId: string, |
| 602 | injector: Injector, |
| 603 | ): {parentBlockPromise: Promise<void> | null; hydrationQueue: string[]} { |
| 604 | const dehydratedBlockRegistry = injector.get(DEHYDRATED_BLOCK_REGISTRY); |
| 605 | const transferState = injector.get(TransferState); |
| 606 | const deferBlockParents = transferState.get(NGH_DEFER_BLOCKS_KEY, {}); |
| 607 | |
| 608 | let isTopMostDeferBlock = false; |
| 609 | let currentBlockId: string | undefined = deferBlockId; |
| 610 | let parentBlockPromise: Promise<void> | null = null; |
| 611 | const hydrationQueue: string[] = []; |
| 612 | |
| 613 | while (!isTopMostDeferBlock && currentBlockId) { |
| 614 | ngDevMode && |
| 615 | assertEqual( |
| 616 | hydrationQueue.indexOf(currentBlockId), |
| 617 | -1, |
| 618 | 'Internal error: defer block hierarchy has a cycle.', |
| 619 | ); |
| 620 | |
| 621 | isTopMostDeferBlock = dehydratedBlockRegistry.has(currentBlockId); |
| 622 | const hydratingParentBlock = dehydratedBlockRegistry.hydrating.get(currentBlockId); |
| 623 | if (parentBlockPromise === null && hydratingParentBlock != null) { |
| 624 | parentBlockPromise = hydratingParentBlock.promise; |
| 625 | break; |
| 626 | } |
| 627 | hydrationQueue.unshift(currentBlockId); |
| 628 | currentBlockId = deferBlockParents[currentBlockId][DEFER_PARENT_BLOCK_ID]; |
| 629 | } |
| 630 | return {parentBlockPromise, hydrationQueue}; |
| 631 | } |
| 632 | |
| 633 | function gatherDeferBlocksByJSActionAttribute(doc: Document): Set<HTMLElement> { |
| 634 | const jsactionNodes = doc.body.querySelectorAll('[jsaction]'); |
no test coverage detected
searching dependent graphs…