From dc345956ceef5652e127736f02febd085e6b07e8 Mon Sep 17 00:00:00 2001 From: Minko Gechev Date: Thu, 27 May 2021 22:54:52 -0700 Subject: [PATCH] fix(devtools): show properly dynamically inserted content with DOM APIs (rangle/angular-devtools#828) Fix rangle/angular-devtools#791 Build the render tree starting from the root node of the application. This fix is applicable only for v12+ apps that are using the latest debugging APIs. --- .../lib/directive-forest/render-tree.spec.ts | 24 +++++++++++++++++++ .../src/lib/directive-forest/render-tree.ts | 5 ++++ 2 files changed, 29 insertions(+) diff --git a/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.spec.ts b/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.spec.ts index 339634277f4..90191da352d 100644 --- a/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.spec.ts +++ b/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.spec.ts @@ -74,4 +74,28 @@ describe('render tree extraction', () => { expect(rtree[0].children.length).toBe(1); expect(rtree[0].children[0].children.length).toBe(0); }); + + it('should go all the way to the root element to look up for nodes', () => { + const rootNode = document.createElement('body'); + const siblingNode = document.createElement('section'); + const appNode = document.createElement('app'); + const childNode = document.createElement('div'); + const childComponentNode = document.createElement('child'); + rootNode.appendChild(appNode); + rootNode.appendChild(siblingNode); + appNode.appendChild(childNode); + childNode.appendChild(childComponentNode); + + const appComponent: any = {}; + const childComponent: any = {}; + const siblingComponent: any = {}; + componentMap.set(siblingNode, siblingComponent); + componentMap.set(appNode, appComponent); + componentMap.set(childComponentNode, childComponent); + + const rtree = treeStrategy.build(appNode); + expect(rtree[0].children.length).toBe(1); + expect(rtree[0].children[0].children.length).toBe(0); + expect(rtree[1].component?.instance).toBe(siblingComponent); + }); }); diff --git a/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts b/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts index 3d3310c78c4..9e639b47d0f 100644 --- a/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts +++ b/projects/ng-devtools-backend/src/lib/directive-forest/render-tree.ts @@ -56,6 +56,11 @@ export class RTreeStrategy { } build(element: Element): ComponentTreeNode[] { + // We want to start from the root element so that we can find components which are attached to the application ref + // and which host elements have been inserted with DOM APIs. + while (element.parentElement) { + element = element.parentElement; + } const getComponent = (window as any).ng.getComponent as (element: Element) => {}; const getDirectives = (window as any).ng.getDirectives as (node: Node) => {}[]; const result = extractViewTree(element, [], getComponent, getDirectives);