refactor(devtools): remove the standalone demo (#62455)

The default demo is already standalone

PR Close #62455
This commit is contained in:
Matthieu Riegler
2025-07-03 16:31:24 +02:00
committed by Jessica Janiuk
parent 720717eaed
commit 9ba59033b9
32 changed files with 1 additions and 1084 deletions
@@ -8,7 +8,7 @@ adev/shared-docs/package.json=450629456
adev/shared-docs/pipeline/api-gen/package.json=939673974
integration/package.json=-239561259
modules/package.json=-2081919225
package.json=1306517978
package.json=-1401411541
packages/animations/package.json=-678724831
packages/benchpress/package.json=-1908328724
packages/common/package.json=1729763064
-6
View File
@@ -46,12 +46,6 @@ To run the extension in development mode run:
yarn devtools:devserver
```
You can also run a standalone version of the demo app with:
```shell
yarn devtools:devserver:demo-standalone
```
This would start a development server that you can access on <http://localhost:4200>. In development, Angular DevTools
uses a "development shell." This is different from "chrome shell" in a way, that it runs the user's app in an iframe.
DevTools then communicate with the user's app via message passing.
@@ -1 +0,0 @@
package(default_visibility = ["//visibility:public"])
@@ -1,103 +0,0 @@
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild")
load("@build_bazel_rules_nodejs//:index.bzl", "pkg_web")
load("//devtools/tools:ng_project.bzl", "ng_project")
load("//tools:defaults.bzl", "http_server")
load("//tools:defaults2.bzl", "sass_binary")
package(default_visibility = ["//visibility:public"])
sass_binary(
name = "demo_styles",
src = "styles.scss",
include_paths = ["external/npm/node_modules"],
sourcemap = False,
deps = ["//devtools/projects/ng-devtools/src/styles:global"],
)
copy_to_directory(
name = "browser_specific_styles",
srcs = [
"//devtools/projects/ng-devtools/src/styles:chrome",
"//devtools/projects/ng-devtools/src/styles:firefox",
],
out = "styles",
replace_prefixes = {
"devtools/projects/ng-devtools/src/styles": "",
},
)
copy_to_directory(
name = "assets",
srcs = [
"//devtools/projects/ng-devtools/src/assets",
],
out = "assets",
replace_prefixes = {
"devtools/projects/ng-devtools/src/assets": "",
},
)
ng_project(
name = "demo",
srcs = ["main.ts"],
deps = [
"//:node_modules/@angular/common",
"//:node_modules/@angular/core",
"//:node_modules/@angular/platform-browser",
"//:node_modules/rxjs",
"//devtools/projects/demo-standalone/src/app:app_rjs",
"//devtools/src:demo_application_environment_rjs",
"//devtools/src:demo_application_operations_rjs",
],
)
esbuild(
name = "bundle",
srcs = [
"//:node_modules/@angular/build-tooling",
"//devtools/tools/esbuild:esbuild_base",
"//devtools/tools/esbuild:esbuild_config_esm",
],
config = "//devtools/tools/esbuild:esbuild_config_esm",
entry_points = [":main.ts"],
platform = "browser",
splitting = True,
target = "es2016",
deps = [
":demo_rjs",
"//:node_modules/@angular/cdk",
"//:node_modules/@angular/material",
],
)
exports_files(["index.html"])
filegroup(
name = "dev_app_static_files",
srcs = [
":assets",
":browser_specific_styles",
":demo_styles",
":index.html",
"//:node_modules/zone.js",
"//devtools/projects/demo-standalone/src/assets",
],
)
pkg_web(
name = "devapp",
srcs = [":dev_app_static_files"] + [
":bundle",
],
)
http_server(
name = "devserver",
srcs = [":dev_app_static_files"],
additional_root_paths = ["angular/devtools/projects/demo-standalone/src/devapp"],
tags = ["manual"],
deps = [
":devapp",
],
)
@@ -1,18 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
package(default_visibility = ["//visibility:public"])
ng_project(
name = "app",
srcs = [
"app.component.ts",
],
deps = [
"//:node_modules/@angular/core",
"//:node_modules/@angular/platform-browser",
"//:node_modules/@angular/router",
"//devtools/projects/demo-standalone/src/app/demo-app:demo-app_rjs",
"//devtools/projects/demo-standalone/src/app/devtools-app:devtools-app_rjs",
"//devtools/projects/ng-devtools:ng-devtools_rjs",
],
)
@@ -1,19 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component} from '@angular/core';
import {Router, RouterOutlet} from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`,
imports: [RouterOutlet],
})
export class AppComponent {
constructor(public router: Router) {}
}
@@ -1,41 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
load("//tools:defaults2.bzl", "npm_sass_library", "sass_binary")
package(default_visibility = ["//visibility:public"])
npm_sass_library(
name = "todo_mvc",
deps = [
"//:node_modules/todomvc-app-css",
"//:node_modules/todomvc-common",
],
)
sass_binary(
name = "demo_app_component_styles",
src = "demo-app.component.scss",
deps = [
":todo_mvc",
],
)
ng_project(
name = "demo-app",
srcs = [
"demo-app.component.ts",
"heavy.component.ts",
"zippy.component.ts",
],
angular_assets = [
"demo-app.component.html",
":demo_app_component_styles",
],
deps = [
"//:node_modules/@angular/core",
"//:node_modules/@angular/elements",
"//:node_modules/@angular/router",
"//devtools/projects/demo-standalone/src/app/demo-app/todo:todo_rjs",
"//devtools/projects/ng-devtools-backend:ng-devtools-backend_rjs",
"//devtools/src:zone-unaware-iframe_message_bus_rjs",
],
)
@@ -1,11 +0,0 @@
<router-outlet></router-outlet>
<app-zippy [title]="getTitle()">This is my content</app-zippy>
<app-heavy></app-heavy>
<div #elementReference>HTMLElement</div>
<hr />
<h2>Signals</h2>
<div>Object Signal: {{objectSignal()|json}}</div>
<div>Object Computed: {{objectComputed()|json}}</div>
<div>Editable Signal: {{primitiveSignal()}}</div>
<div>Primitive computed: {{primitiveComputed()}}</div>
@@ -1,2 +0,0 @@
@use 'todomvc-app-css/index.css';
@use 'todomvc-common/base.css';
@@ -1,103 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {JsonPipe} from '@angular/common';
import {
Component,
computed,
CUSTOM_ELEMENTS_SCHEMA,
ElementRef,
EventEmitter,
inject,
InjectionToken,
Injector,
Input,
Output,
signal,
ViewChild,
ViewEncapsulation,
} from '@angular/core';
import {createCustomElement} from '@angular/elements';
import {RouterOutlet} from '@angular/router';
import {initializeMessageBus} from '../../../../ng-devtools-backend';
import {ZoneUnawareIFrameMessageBus} from '../../../../../src/zone-unaware-iframe-message-bus';
import {HeavyComponent} from './heavy.component';
import {ZippyComponent} from './zippy.component';
const NUMBER_TOKEN = new InjectionToken<number>('number-token');
const SYMBOL_TOKEN = new InjectionToken<Symbol>('symbol-token');
@Component({
selector: 'app-demo-component',
templateUrl: './demo-app.component.html',
styleUrls: ['./demo-app.component.scss'],
encapsulation: ViewEncapsulation.None,
imports: [HeavyComponent, RouterOutlet, JsonPipe],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{provide: NUMBER_TOKEN, useValue: 42},
{provide: SYMBOL_TOKEN, useValue: Symbol('symbol_token')},
],
})
export class DemoAppComponent {
readonly myNumber = inject(NUMBER_TOKEN);
readonly mySymbol = inject(SYMBOL_TOKEN);
@ViewChild(ZippyComponent) zippy!: ZippyComponent;
@ViewChild('elementReference') elementRef!: ElementRef;
@Input('input_one') inputOne = 'input one';
@Input() inputTwo = 'input two';
@Output() outputOne = new EventEmitter();
@Output('output_two') outputTwo = new EventEmitter();
primitiveSignal = signal(123);
primitiveComputed = computed(() => this.primitiveSignal() ** 2);
objectSignal = signal({name: 'John', age: 40});
objectComputed = computed(() => {
const original = this.objectSignal();
return {...original, age: original.age + 1};
});
test = [signal(3)];
constructor() {
const el = createCustomElement(ZippyComponent, {injector: inject(Injector)});
customElements.define('app-zippy', el as any);
}
getTitle(): '► Click to expand' | '▼ Click to collapse' {
if (!this.zippy || !this.zippy.visible) {
return '► Click to expand';
}
return '▼ Click to collapse';
}
}
export const ROUTES = [
{
path: '',
component: DemoAppComponent,
children: [
{
path: '',
loadChildren: () => import('./todo/todo-app.component').then((m) => m.ROUTES),
},
],
},
];
initializeMessageBus(
new ZoneUnawareIFrameMessageBus(
'angular-devtools-backend',
'angular-devtools',
() => window.parent,
),
);
@@ -1,40 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Input} from '@angular/core';
const fib = (n: number): number => {
if (n === 1 || n === 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
};
@Component({selector: 'app-heavy', template: `<h1>{{ calculate() }}</h1>`})
export class HeavyComponent {
@Input()
set foo(_: any) {}
state = {
nested: {
props: {
foo: 1,
bar: 2,
},
[Symbol(3)](): number {
return 1.618;
},
get foo(): number {
return 42;
},
},
};
calculate(): number {
return fib(15);
}
}
@@ -1,20 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
package(default_visibility = ["//visibility:public"])
ng_project(
name = "todo",
srcs = [
"dialog.component.ts",
"todo-app.component.ts",
],
deps = [
"//:node_modules/@angular/common",
"//:node_modules/@angular/core",
"//:node_modules/@angular/forms",
"//:node_modules/@angular/material",
"//:node_modules/@angular/router",
"//devtools/projects/demo-standalone/src/app/demo-app/todo/about:about_rjs",
"//devtools/projects/demo-standalone/src/app/demo-app/todo/home:home_rjs",
],
)
@@ -1,12 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
package(default_visibility = ["//visibility:public"])
ng_project(
name = "about",
srcs = ["about.component.ts"],
deps = [
"//:node_modules/@angular/core",
"//:node_modules/@angular/router",
],
)
@@ -1,22 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component} from '@angular/core';
import {RouterLink} from '@angular/router';
@Component({
selector: 'app-about',
imports: [RouterLink],
template: `
About component
<a [routerLink]="">Home</a>
<a [routerLink]="">Home</a>
<a [routerLink]="">Home</a>
`,
})
export class AboutComponent {}
@@ -1,46 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Inject} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from '@angular/material/dialog';
import {MatFormField, MatLabel} from '@angular/material/form-field';
export interface DialogData {
animal: string;
name: string;
}
@Component({
selector: 'app-dialog',
imports: [MatDialogModule, MatFormField, MatLabel, FormsModule],
template: `
<h1 mat-dialog-title>Hi {{ data.name }}</h1>
<div mat-dialog-content>
<p>What's your favorite animal?</p>
<mat-form-field>
<mat-label>Favorite Animal</mat-label>
<input matInput [(ngModel)]="data.animal" />
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-button (click)="onNoClick()">No Thanks</button>
<button mat-button [mat-dialog-close]="data.animal" cdkFocusInitial>Ok</button>
</div>
`,
})
export class DialogComponent {
constructor(
public dialogRef: MatDialogRef<DialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: DialogData,
) {}
onNoClick(): void {
this.dialogRef.close();
}
}
@@ -1,18 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
package(default_visibility = ["//visibility:public"])
ng_project(
name = "home",
srcs = [
"sample.pipe.ts",
"todo.component.ts",
"todos.component.ts",
"tooltip.directive.ts",
],
deps = [
"//:node_modules/@angular/common",
"//:node_modules/@angular/core",
"//:node_modules/@angular/router",
],
)
@@ -1,21 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {OnDestroy, Pipe, PipeTransform} from '@angular/core';
@Pipe({name: 'sample', pure: false})
export class SamplePipe implements PipeTransform, OnDestroy {
transform(val: unknown) {
return val;
}
ngOnDestroy(): void {
// tslint:disable-next-line:no-console
console.log('Destroying');
}
}
@@ -1,70 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {ChangeDetectionStrategy, Component, EventEmitter, Input, Output} from '@angular/core';
import {TooltipDirective} from './tooltip.directive';
export interface Todo {
id: string;
completed: boolean;
label: string;
}
@Component({
selector: 'app-todo',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [TooltipDirective],
styles: [
`
.destroy {
cursor: pointer;
display: unset !important;
}
`,
],
template: `
<li [class.completed]="todo.completed">
<div class="view" appTooltip>
<input class="toggle" type="checkbox" [checked]="todo.completed" (change)="toggle()" />
<label (dblclick)="enableEditMode()" [style.display]="editMode ? 'none' : 'block'">{{
todo.label
}}</label>
<button class="destroy" (click)="delete.emit(todo)"></button>
</div>
<input
class="edit"
[value]="todo.label"
[style.display]="editMode ? 'block' : 'none'"
(keydown.enter)="completeEdit($any($event.target).value)"
/>
</li>
`,
})
export class TodoComponent {
@Input() todo!: Todo;
@Output() update = new EventEmitter();
@Output() delete = new EventEmitter();
editMode = false;
toggle(): void {
this.todo.completed = !this.todo.completed;
this.update.emit(this.todo);
}
completeEdit(label: string): void {
this.todo.label = label;
this.editMode = false;
this.update.emit(this.todo);
}
enableEditMode(): void {
this.editMode = true;
}
}
@@ -1,178 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {NgForOf} from '@angular/common';
import {
ChangeDetectorRef,
Component,
EventEmitter,
OnDestroy,
OnInit,
Output,
Pipe,
PipeTransform,
} from '@angular/core';
import {RouterLink} from '@angular/router';
import {SamplePipe} from './sample.pipe';
import {Todo, TodoComponent} from './todo.component';
import {TooltipDirective} from './tooltip.directive';
export const enum TodoFilter {
All = 'all',
Completed = 'completed',
Active = 'active',
}
@Pipe({pure: false, name: 'todosFilter'})
export class TodosFilter implements PipeTransform {
transform(todos: Todo[], filter: TodoFilter): Todo[] {
return (todos || []).filter((t) => {
if (filter === TodoFilter.All) {
return true;
}
if (filter === TodoFilter.Active && !t.completed) {
return true;
}
if (filter === TodoFilter.Completed && t.completed) {
return true;
}
return false;
});
}
}
const fib = (n: number): number => {
if (n === 1 || n === 2) {
return 1;
}
return fib(n - 1) + fib(n - 2);
};
@Component({
selector: 'app-todos',
imports: [RouterLink, TodoComponent, SamplePipe, TodosFilter, TooltipDirective],
template: `
<a [routerLink]="">Home</a>
<a [routerLink]="">Home</a>
<a [routerLink]="">Home</a>
<p>{{ 'Sample text processed by a pipe' | sample }}</p>
<section class="todoapp">
<header class="header">
<h1>todos</h1>
<input
(keydown.enter)="addTodo(input)"
#input
class="new-todo"
placeholder="What needs to be done?"
autofocus
/>
</header>
<section class="main">
<input id="toggle-all" class="toggle-all" type="checkbox" />
<label for="toggle-all">Mark all as complete</label>
<ul class="todo-list">
@for (todo of todos | todosFilter: filterValue; track todo) {
<app-todo
appTooltip
[todo]="todo"
(delete)="onDelete($event)"
(update)="onChange($event)"
/>
}
</ul>
</section>
<footer class="footer">
<span class="todo-count">
<strong>{{ itemsLeft }}</strong> item left
</span>
<button class="clear-completed" (click)="clearCompleted()">Clear completed</button>
</footer>
</section>
`,
})
export class TodosComponent implements OnInit, OnDestroy {
todos: Todo[] = [
{
label: 'Buy milk',
completed: false,
id: '42',
},
{
label: 'Build something fun!',
completed: false,
id: '43',
},
];
@Output() update = new EventEmitter();
@Output() delete = new EventEmitter();
@Output() add = new EventEmitter();
private hashListener!: EventListenerOrEventListenerObject;
constructor(private cdRef: ChangeDetectorRef) {}
ngOnInit(): void {
if (typeof window !== 'undefined') {
window.addEventListener('hashchange', (this.hashListener = () => this.cdRef.markForCheck()));
}
}
ngOnDestroy(): void {
fib(40);
if (typeof window !== 'undefined') {
window.removeEventListener('hashchange', this.hashListener);
}
}
get filterValue(): TodoFilter {
if (typeof window !== 'undefined') {
return (window.location.hash.replace(/^#\//, '') as TodoFilter) || TodoFilter.All;
}
return TodoFilter.All;
}
get itemsLeft(): number {
return (this.todos || []).filter((t) => !t.completed).length;
}
clearCompleted(): void {
(this.todos || []).filter((t) => t.completed).forEach((t) => this.delete.emit(t));
}
addTodo(input: HTMLInputElement): void {
const todo = {
completed: false,
label: input.value,
};
const result: Todo = {...todo, id: Math.random().toString()};
this.todos.push(result);
input.value = '';
}
onChange(todo: Todo): void {
if (!todo.id) {
return;
}
}
onDelete(todo: Todo): void {
if (!todo.id) {
return;
}
const idx = this.todos.findIndex((t) => t.id === todo.id);
if (idx < 0) {
return;
}
// tslint:disable-next-line:no-console
console.log('Deleting', idx);
this.todos.splice(idx, 1);
}
}
@@ -1,35 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Directive, HostListener} from '@angular/core';
@Directive({selector: '[appTooltip]'})
export class TooltipDirective {
visible = false;
nested = {
child: {
grandchild: {
prop: 1,
},
},
};
constructor() {
// setInterval(() => this.nested.child.grandchild.prop++, 500);
}
@HostListener('click')
handleClick(): void {
this.visible = !this.visible;
if (this.visible) {
(this as any).extraProp = true;
} else {
delete (this as any).extraProp;
}
}
}
@@ -1,93 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {MatDialog, MatDialogModule} from '@angular/material/dialog';
import {RouterLink, RouterOutlet} from '@angular/router';
import {DialogComponent} from './dialog.component';
@Component({
selector: 'app-todo-demo',
imports: [RouterLink, RouterOutlet, MatDialogModule, FormsModule],
styles: [
`
nav {
padding-top: 20px;
padding-bottom: 10px;
a {
margin-right: 15px;
text-decoration: none;
}
}
.dialog-open-button {
border: 1px solid #ccc;
padding: 10px;
margin-right: 20px;
}
`,
],
template: `
<nav>
<a routerLink="/demo-app/todos/app">Todos</a>
<a routerLink="/demo-app/todos/about">About</a>
</nav>
<button class="dialog-open-button" (click)="openDialog()">Open dialog</button>
<router-outlet></router-outlet>
`,
})
export class TodoAppComponent {
name!: string;
animal!: string;
constructor(public dialog: MatDialog) {}
openDialog(): void {
const dialogRef = this.dialog.open(DialogComponent, {
width: '250px',
data: {name: this.name, animal: this.animal},
});
dialogRef.afterClosed().subscribe((result) => {
// tslint:disable-next-line:no-console
console.log('The dialog was closed');
this.animal = result;
});
}
}
export const ROUTES = [
{
path: 'todos',
component: TodoAppComponent,
children: [
{
path: 'app',
loadComponent: () => import('./home/todos.component').then((m) => m.TodosComponent),
},
{
path: 'about',
loadComponent: () => import('./about/about.component').then((m) => m.AboutComponent),
},
{
path: '**',
redirectTo: 'app',
},
],
},
{
path: '**',
redirectTo: 'todos',
},
];
@@ -1,48 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, Input} from '@angular/core';
@Component({
selector: 'app-zippy',
styles: [
`
:host {
user-select: none;
}
header {
max-width: 120px;
border: 1px solid #ccc;
padding-left: 10px;
padding-right: 10px;
cursor: pointer;
}
div {
max-width: 120px;
border-left: 1px solid #ccc;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
padding: 10px;
}
`,
],
template: `
<section>
<header (click)="visible = !visible">{{ title }}</header>
<div [hidden]="!visible">
<ng-content></ng-content>
</div>
</section>
`,
})
export class ZippyComponent {
@Input() title!: string;
visible = false;
}
@@ -1,17 +0,0 @@
load("//devtools/tools:ng_project.bzl", "ng_project")
package(default_visibility = ["//visibility:public"])
ng_project(
name = "devtools-app",
srcs = ["devtools-app.component.ts"],
deps = [
"//:node_modules/@angular/common",
"//:node_modules/@angular/core",
"//:node_modules/@angular/router",
"//devtools/projects/ng-devtools:ng-devtools_rjs",
"//devtools/projects/ng-devtools/src/lib/application-services:frame_manager_rjs",
"//devtools/projects/protocol:protocol_rjs",
"//devtools/src:iframe_message_bus_rjs",
],
)
@@ -1,57 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {Component, ElementRef, ViewChild} from '@angular/core';
import {Events, MessageBus, PriorityAwareMessageBus} from '../../../../protocol';
import {IFrameMessageBus} from '../../../../../src/iframe-message-bus';
import {DevToolsComponent} from '../../../../ng-devtools';
import {FrameManager} from '../../../../../projects/ng-devtools/src/lib/application-services/frame_manager';
@Component({
imports: [DevToolsComponent],
providers: [
{provide: FrameManager, useFactory: () => FrameManager.initialize(null)},
{
provide: MessageBus,
useFactory(): MessageBus<Events> {
return new PriorityAwareMessageBus(
new IFrameMessageBus(
'angular-devtools',
'angular-devtools-backend',
() => (document.querySelector('#sample-app') as HTMLIFrameElement).contentWindow!,
),
);
},
},
],
styles: [
`
iframe {
height: 340px;
width: 100%;
border: 0;
}
.devtools-wrapper {
height: calc(100vh - 345px);
}
`,
],
template: `
<iframe #ref src="demo-app/todos/app" id="sample-app"></iframe>
<br />
<div class="devtools-wrapper">
<ng-devtools></ng-devtools>
</div>
`,
})
export class DemoDevToolsComponent {
messageBus: IFrameMessageBus | null = null;
@ViewChild('ref') iframe!: ElementRef;
}
@@ -1,9 +0,0 @@
package(default_visibility = ["//:__subpackages__"])
filegroup(
name = "assets",
srcs = [
"//third_party/fonts.google.com/material-symbols-outlined",
"//third_party/fonts.google.com/material-symbols-outlined:LICENSE",
],
)
@@ -1,13 +0,0 @@
load("//devtools/tools:typescript.bzl", "ts_project")
package(default_visibility = ["//visibility:public"])
ts_project(
name = "environments",
srcs = [
"environment.ts",
],
deps = [
"//:node_modules/@angular/platform-browser",
],
)
@@ -1,11 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
export const environment = {
production: false,
};
@@ -1,24 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>AngularDevtools</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="assets/icon16.png" />
<link
rel="stylesheet"
href="../third_party/fonts.google.com/material-symbols-outlined/outlined.css"
/>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<div>
<app-root></app-root>
</div>
<script src="./node_modules/zone.js/bundles/zone.umd.min.js"></script>
<script type="module" src="./bundle/main.js"></script>
</body>
</html>
@@ -1,43 +0,0 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {bootstrapApplication} from '@angular/platform-browser';
import {provideAnimations} from '@angular/platform-browser/animations';
import {provideRouter} from '@angular/router';
import {ApplicationEnvironment, ApplicationOperations} from '../../ng-devtools';
import {DemoApplicationEnvironment} from '../../../src/demo-application-environment';
import {DemoApplicationOperations} from '../../../src/demo-application-operations';
import {AppComponent} from './app/app.component';
bootstrapApplication(AppComponent, {
providers: [
provideAnimations(),
provideRouter([
{
path: '',
loadComponent: () =>
import('./app/devtools-app/devtools-app.component').then((m) => m.DemoDevToolsComponent),
pathMatch: 'full',
},
{
path: 'demo-app',
loadChildren: () => import('./app/demo-app/demo-app.component').then((m) => m.ROUTES),
},
]),
{
provide: ApplicationOperations,
useClass: DemoApplicationOperations,
},
{
provide: ApplicationEnvironment,
useClass: DemoApplicationEnvironment,
},
],
});
@@ -1 +0,0 @@
@use '../../../projects/ng-devtools/src/styles/global';
-1
View File
@@ -38,7 +38,6 @@
"ts-circular-deps:check": "yarn -s ng-dev ts-circular-deps check --config ./packages/circular-deps-test.conf.js",
"check-tooling-setup": "yarn tsc --project .ng-dev/tsconfig.json && yarn tsc --project scripts/tsconfig.json",
"devtools:devserver": "ibazel run //devtools/src:devserver",
"devtools:devserver:demo-standalone": "ibazel run //devtools/projects/demo-standalone/src:devserver",
"devtools:build:chrome": "bazelisk build --//devtools/projects/shell-browser/src:flag_browser=chrome //devtools/projects/shell-browser/src:prodapp",
"devtools:build:firefox": "bazelisk build --config snapshot-build-firefox --//devtools/projects/shell-browser/src:flag_browser=firefox //devtools/projects/shell-browser/src:prodapp",
"devtools:build:chrome:release": "yarn run -s devtools:build:chrome",