diff --git a/cypress/integration/comment-nodes.e2e.js b/cypress/integration/comment-nodes.e2e.js
new file mode 100644
index 00000000000..c379b0333df
--- /dev/null
+++ b/cypress/integration/comment-nodes.e2e.js
@@ -0,0 +1,22 @@
+function showComments() {
+ cy.get(
+ '#nav-buttons > button.mat-focus-indicator.mat-menu-trigger.mat-icon-button.mat-button-base.mat-primary'
+ ).click();
+ cy.get('#mat-slide-toggle-3 > label > div').click();
+}
+
+describe('Comment nodes', () => {
+ beforeEach(() => {
+ cy.visit('/');
+ });
+
+ it('should not find any comment nodes by default', () => {
+ const nodes = cy.$$('.tree-node:contains("#comment")');
+ expect(nodes.length).to.eql(0);
+ });
+
+ it('should find comment nodes when the setting is enabled', () => {
+ showComments();
+ cy.get('.tree-wrapper').find('.tree-node:contains("#comment")').its('length').should('not.eq', 0);
+ });
+});
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.html b/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.html
index 7a28438d8bc..d705b943c72 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.html
+++ b/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.html
@@ -25,6 +25,7 @@
@@ -46,4 +47,13 @@
>
Dark Mode
+
+
+
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.ts b/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.ts
index 97b6410281b..8d89e678de0 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.ts
+++ b/projects/ng-devtools/src/lib/devtools-tabs/devtools-tabs.component.ts
@@ -23,6 +23,7 @@ export class DevToolsTabsComponent implements OnInit, OnDestroy, AfterViewInit {
inspectorRunning = false;
routerTreeEnabled = false;
+ showCommentNodes = false;
private _currentThemeSubscription: Subscription;
currentTheme: Theme;
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.html b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.html
index 9dd39a91480..9c8ffdba6f8 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.html
+++ b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.html
@@ -11,6 +11,7 @@
(toggleInspector)="toggleInspector.emit()"
[forest]="forest"
[currentSelectedElement]="currentSelectedElement"
+ [showCommentNodes]="showCommentNodes"
>
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.ts b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.ts
index c7cf93849a8..d8da234c125 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.ts
+++ b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-explorer.component.ts
@@ -3,6 +3,7 @@ import {
Component,
ElementRef,
EventEmitter,
+ Input,
NgZone,
OnDestroy,
OnInit,
@@ -58,14 +59,18 @@ const sameDirectives = (a: IndexedNode, b: IndexedNode) => {
],
})
export class DirectiveExplorerComponent implements OnInit, OnDestroy {
+ @Input() showCommentNodes = false;
@Output() toggleInspector = new EventEmitter();
+ @ViewChild(DirectiveForestComponent) directiveForest: DirectiveForestComponent;
+ @ViewChild(BreadcrumbsComponent) breadcrumbs: BreadcrumbsComponent;
+ @ViewChild(SplitComponent, { static: true, read: ElementRef }) splitElementRef: ElementRef;
+ @ViewChild('directiveForestSplitArea', { static: true, read: ElementRef }) directiveForestSplitArea: ElementRef;
+
currentSelectedElement: IndexedNode | null = null;
forest: DevToolsNode[];
splitDirection: 'horizontal' | 'vertical' = 'horizontal';
-
- @ViewChild(SplitComponent, { static: true, read: ElementRef }) splitElementRef: ElementRef;
- @ViewChild('directiveForestSplitArea', { static: true, read: ElementRef }) directiveForestSplitArea: ElementRef;
+ parents: FlatNode[] | null = null;
private _resizeObserver = new ResizeObserver((entries) =>
this._ngZone.run(() => {
@@ -86,11 +91,6 @@ export class DirectiveExplorerComponent implements OnInit, OnDestroy {
private _clickedElement: IndexedNode | null = null;
private _refreshRetryTimeout: any = null;
- parents: FlatNode[] | null = null;
-
- @ViewChild(DirectiveForestComponent) directiveForest: DirectiveForestComponent;
- @ViewChild(BreadcrumbsComponent) breadcrumbs: BreadcrumbsComponent;
-
constructor(
private _appOperations: ApplicationOperations,
private _messageBus: MessageBus,
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.spec.ts b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.spec.ts
new file mode 100644
index 00000000000..ad3ee213b2b
--- /dev/null
+++ b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.spec.ts
@@ -0,0 +1,129 @@
+import { FlatTreeControl } from '@angular/cdk/tree';
+import { ComponentDataSource, FlatNode } from './component-data-source';
+import { DevToolsNode } from 'protocol';
+
+const tree1: DevToolsNode = {
+ element: 'app',
+ directives: [
+ {
+ id: 1,
+ name: 'foo',
+ },
+ ],
+ component: null,
+ children: [
+ {
+ children: [],
+ component: {
+ id: 2,
+ isElement: false,
+ name: 'bar',
+ },
+ directives: [],
+ element: 'bar',
+ nativeElement: document.createElement('bar'),
+ },
+ ],
+ nativeElement: document.createElement('foo'),
+};
+
+const tree2: DevToolsNode = {
+ element: 'app',
+ directives: [
+ {
+ id: 1,
+ name: 'foo',
+ },
+ ],
+ component: null,
+ children: [
+ {
+ children: [],
+ component: {
+ id: 2,
+ isElement: false,
+ name: 'bar',
+ },
+ directives: [],
+ element: 'bar',
+ nativeElement: document.createElement('bar'),
+ },
+ {
+ children: [],
+ component: {
+ id: 3,
+ isElement: false,
+ name: 'qux',
+ },
+ directives: [],
+ element: 'qux',
+ nativeElement: document.createElement('qux'),
+ },
+ ],
+ nativeElement: document.createElement('foo'),
+};
+
+const tree3: DevToolsNode = {
+ element: 'app',
+ directives: [
+ {
+ id: 1,
+ name: 'foo',
+ },
+ ],
+ component: null,
+ children: [
+ {
+ children: [],
+ component: {
+ id: 2,
+ isElement: false,
+ name: 'bar',
+ },
+ directives: [],
+ element: '#comment',
+ nativeElement: document.createComment('bar'),
+ },
+ {
+ children: [],
+ component: {
+ id: 3,
+ isElement: false,
+ name: 'qux',
+ },
+ directives: [],
+ element: '#comment',
+ nativeElement: document.createComment('bar'),
+ },
+ ],
+ nativeElement: document.createElement('foo'),
+};
+
+describe('ComponentDataSource', () => {
+ let dataSource: ComponentDataSource;
+ const treeControl = new FlatTreeControl(
+ (node) => node.level,
+ (node) => node.expandable
+ );
+
+ beforeEach(() => (dataSource = new ComponentDataSource(treeControl)));
+
+ it('should return new and old items', () => {
+ const result = dataSource.update([tree1], true);
+ expect(result.movedItems.length).toBe(0);
+ expect(result.newItems.length).toBe(2);
+
+ const updatedResult = dataSource.update([tree2], true);
+ expect(updatedResult.movedItems.length).toBe(0);
+ expect(updatedResult.removedItems.length).toBe(0);
+ expect(updatedResult.newItems.length).toBe(1);
+ expect(updatedResult.newItems[0].name).toBe('qux');
+ });
+
+ it('should not return comment nodes when not requested', () => {
+ const result = dataSource.update([tree3], false);
+ expect(result.movedItems.length).toBe(0);
+ expect(result.newItems.length).toBe(1);
+ expect(result.newItems[0].name).toBe('app');
+ });
+});
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.ts b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.ts
index 3ab9134db21..886ebae6b4d 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.ts
+++ b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/component-data-source.ts
@@ -84,13 +84,20 @@ export class ComponentDataSource extends DataSource {
return this._nodeToFlat.get(indexedNode);
}
- update(forest: DevToolsNode[]): { newItems: FlatNode[]; movedItems: FlatNode[]; removedItems: FlatNode[] } {
+ update(
+ forest: DevToolsNode[],
+ showCommentNodes: boolean
+ ): { newItems: FlatNode[]; movedItems: FlatNode[]; removedItems: FlatNode[] } {
if (!forest) {
return { newItems: [], movedItems: [], removedItems: [] };
}
const indexedForest = indexForest(forest);
- const flattenedCollection = this._treeFlattener.flattenNodes(indexedForest) as FlatNode[];
+ let flattenedCollection = this._treeFlattener.flattenNodes(indexedForest) as FlatNode[];
+
+ if (!showCommentNodes) {
+ flattenedCollection = flattenedCollection.filter((node) => node.original.element !== '#comment');
+ }
this.data.forEach((i) => (i.newItem = false));
diff --git a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts
index 44433f726ae..5990b2819dd 100644
--- a/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts
+++ b/projects/ng-devtools/src/lib/devtools-tabs/directive-explorer/directive-forest/directive-forest.component.ts
@@ -27,6 +27,7 @@ import { Subscription } from 'rxjs';
})
export class DirectiveForestComponent implements OnInit, OnDestroy {
@Input() set forest(forest: DevToolsNode[]) {
+ this._latestForest = forest;
const result = this._updateForest(forest);
const changed = result.movedItems.length || result.newItems.length || result.removedItems.length;
if (this.currentSelectedElement && changed) {
@@ -34,6 +35,10 @@ export class DirectiveForestComponent implements OnInit, OnDestroy {
}
}
@Input() currentSelectedElement: IndexedNode;
+ @Input() set showCommentNodes(show: boolean) {
+ this._showCommentNodes = show;
+ this.forest = this._latestForest;
+ }
@Output() selectNode = new EventEmitter();
@Output() selectDomElement = new EventEmitter();
@@ -52,6 +57,8 @@ export class DirectiveForestComponent implements OnInit, OnDestroy {
private _highlightIDinTreeFromElement: number | null = null;
private _tabUpdateSubscription: Subscription;
+ private _showCommentNodes = false;
+ private _latestForest: DevToolsNode[];
set highlightIDinTreeFromElement(id: number | null) {
this._highlightIDinTreeFromElement = id;
@@ -169,7 +176,7 @@ export class DirectiveForestComponent implements OnInit, OnDestroy {
private _updateForest(
forest: DevToolsNode[]
): { newItems: FlatNode[]; movedItems: FlatNode[]; removedItems: FlatNode[] } {
- const result = this.dataSource.update(forest);
+ const result = this.dataSource.update(forest, this._showCommentNodes);
if (!this._initialized && forest && forest.length) {
this.treeControl.expandAll();
this._initialized = true;