Previously, if `ng.getDirectives` was not implemented, Angular DevTools won't throw when attempting to load the component tree. Now it safely ignores the function and assumes no directives exist on the page.
PR Close#60209
In general, we can't assume all applications implement the full `ng` contract as many are older Angular application which pre-date the current interface. As a result, it is safer to type this as a `Partial`.
For now, I just added non-null assertions at all current usage locations, as we do generally feature detect before using these fields. However, hopefully this `Partial` type will make it harder to accidentally call a function which might not be supported.
PR Close#60209
Previously Angular DevTools would throw when run on an application which does not support `getInjector`, now it safely ignores it and assumes dependency injection is not supported.
PR Close#60206
Previously this was throwing errors in applications with no Router token.
Now it skips emitting events for the router tree when it is unable to find the Router token.
Note: If these events don't emit, DevTools treats the RouterTree feature as disabled.
PR Close#60221
Previously Angular DevTools would throw if `ng.applyChanges` was not defined. Now DevTools silently ignores the issue, assuming `mutateComponentOrDirective` was sufficient to update the application.
PR Close#60207
Previously, the profiler would only emit the specific template event and context when a template is created/updated, but not the template function related to the event.
This commit emits this function by using the third argument of the profiler function, which previously was only used for lifecycle hooks and output listeners. This commit also renames this arg to eventFn to express that it varies depending on the event type emitting from the profiler.
Note: this change is fully backwards compatible, since previously these template events did not use the third arg of the profiler function.
PR Close#60174
- The token rendered in the first col of the table is now being truncated in favor of the horizontal scroll of the panel which should make the log button accessible/visible all the time
- Introduced a "No such providers" label when a filter is applied
- The icon of the logProvider button has been substituted with `code` (as per the doc)
- The font size and width of the provider type filter have been slightly improved
PR Close#59531
The purpose of this component is purely to encapsulate and offload the styles from `devtools.component.scss` since it wasn't very clear what their scope is.
PR Close#59916
Use the new UI and drop the `InjectorTreeVisualizer` dependency. Additionally, use concrete values for `SerializedInjector.type` type instead of `string`.
PR Close#60011
- Move all styles to ng-devtools/src/styles.
- Create a BrowserService that detects the browsers and adds it as a class to the body. Move global browser styles.
- Create theme mixins that incorporate the browser type into them.
- Refactor some of the affected code along with the introduced changes.
PR Close#59589
This commit solves two cases
Bug: When a directive of the same name is selected, the property view tab would not update properly. This was caused by a signals refactor that changed the behaviour of a string input property to not re-render because the underlying signal did not change (string equality). This is fixed by converting this input into an object.
Bug: When a selected element is removed from the component tree, DevTools would not rerender the component tree properly and deselect that component. Now if DevTools detects that a component is removed, it re-renders the tree and deselects the component.
PR Close#59873
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.
PR Close#59233
It looks like this height property was redundant prior to upgrading to angular/material 19.1.0-rc.0. An interaction between this property and that update caused elements inside of material expansion panels to be hidden.
This PR removes this unnecessary height assignment entirely.
PR Close#59493
Several profiler calls don't have any meaningful instance when
producing a profiling event. This commit changes the default
instance value to null to sreamline profiler invocations.
PR Close#59233
This commit extends the set of events understood by the
profiler integrated with the Angular time. The set got
extended to account for the recently added functionality
and mark entry point to the code execution points.
The new set of events can be visualised by the Angular
DevTools or other profiler integrations.
PR Close#59183
When setting `"useDefineForClassFields": false`, static fields are compiled within a block that relies on the `this` context. This output makes it more difficult for bundlers to treeshake and eliminate unused code.
PR Close#58297
with latest signal apis there are duplicates dependencies are shown in injected services, this PR filters the depdencies by token and value
PR Close#57564
We've been seeing some reports about Angular DevTools being unable to detect applications running in dev mode.
This commit adds more context to the error message displayed when development mode is not detected and offers some possible resolutions.
Displays 3 common reasons why DevTools fails to detect an application running in dev mode. Links directly to angular.dev for relevant configurations.
Links to the Angular DevTools issue template if none of the suggestions work.
PR Close#57861
Previously, when "Hide injectors with no providers" was toggled, it is possible for the injector tree visualizer to have no Element injectors to visualize. This caused a bug in the slicing logic that splits apart the environment and element injectors from DI resolution paths within the injector tree component in Angular DevTools.
Now, this logic is correctly handled when there are no element injectors to visualize.
PR Close#57442
Previously, if an application had DOM Nodes injected into it from other frames, DevTools would fail to parse component trees with the render tree strategy properly because of an instanceof Node check that the framework performs.
Now we check for instanceof Node before even calling framework debug APIs on DOM nodes so that we can skip nodes that come from other frames entirely.
PR Close#57518
When a browser extension is updated it becomes invalidated on currently open pages. If that extension then tries to send a message to those pages through `chrome.runtime.sendMessage(..)` then an error is thrown in the console
For Angular DevTools, this results in spamming the console with "Uncaught Error: Extension context invalidated." errors.
This commit catches that error and removes the event listener that triggers the `chrome.runtime.sendMessage(...)` call.
PR Close#55697
This change is a proof of concept of how the new Chrome DevTools
Performance extension API (https://bit.ly/rpp-e11y) can be used to
surface Angular runtime data directly in the Chrome DevTools Performance
panel.
Specifically, it implements the following changes:
1. Use the profiling status notification API to toggle the Timing API:
The notification API is implemented under the
chrome.devtools.performance extension namespace and consits of two
events: ProfilingStarted and ProfilingStopped, dispatched when the
Performance panel has started and stopped recording, respectively. This
API is used to enable the Timings API when the recording has started in
the Performance panel and disable it when recording has stopped.
2. Use the User Timings `detail` field format specification of the
Performance extension API
(https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/User_timing)
to inject data collected by the Angular Profiler into the
Performance panel timeline. Angular Profiler uses several hooks to
measure framework tasks like change detection. With this change, this
measurements are visible in the same context as the runtime data
collected by the browser in the Performance Panel timeline.
Note: to enable the user timings to be collected in the first place, one
needs to open the Angular DevTools panel so that the related artifacts
are loaded in the page. This shortcoming can be fixed in a follow up so
that the extra step isn't necessary.
PR Close#55805
This PR replaces all links available within the devtools to point
to the new docs.
The links to Input/Output (decorators) have been replaced with
their function (signal) counterparts: input, output.
PR Close#56138
This stamping is interfering with publishing to the Firefox addons store by brining in the entirety of the `.git` directory as part of the source code necessary for a reproducible build, which Firefox requires as part of it's approval process.
In it's place, we are now using the extension version pulled from the manifest.
PR Close#55694
This key comes from the release build of the Chrome extension. Setting it here configures the extension ID of a local build to match the extension ID of the public release. This makes Chrome recognize that local builds are the same extension leading to more intuitive behavior. It's also useful for allowlists of extension IDs to keep the local ID consistent.
PR Close#55639
In some cases the height of the viewport wasn't calculated correctly because of extension tabs quirks. This commit fixes this issue.
Fixes#53704
PR Close#54912
Angular DevTools depends on many modern Angular features in order to function. As a result, at present the last officially supported version is v12. Angular DevTools may function for some Angular 9, 10 and 11 applications, but they are not officially supported.
This commit fixes an issue where DevTools would not inject a backend script into an Angular application if it detected it was below version 12. This backend script is important because it's used to inform the DevTools panel that the inspected application is in fact Angular, but that it is not on a supported version.
Angular 9, 10 and 11 applications that successfully have Angular DevTools initialize will now have a red highlight and tooltip on their version number, informing the user that they are using Angular DevTools on a version of Angular that is no longer supported.
Angular DevTools for applications that are below version 9 will continue to display the "Angular Devtools supports Angular versions 12 and above" message.
PR Close#55233
`Object.getPrototypeOf(obj)` returns `null` if `obj` is an empty object. `Object.getOwnPropertyDescriptors` throws on `null`/`undefined`
PR Close#55061
Previously, a race condition could cause DevTools to enter a state where it can't detect an application on reload. This was caused by a sequencing issue between the content script connection, the devtools panel connection and an event "backendReady" that lets DevTools know when a particular frame is ready to be inspected.
This commit replaces the previously stored backendReady boolean with a promise, so that the devtools panel can eventually run a callback to connect to a content script when that content script emits it's backendReady message.
PR Close#54805
In the Angular DevTools Chrome DevTools page:
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
- Implements detection of non unique urls on the inspected page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
Modifies the messaging layer of devtools to allow for switching communication between frames on a page. When served as a browser extension.
Design:
- When a page renders, DevTools installs a content script onto it through it's manifest file. The all_frames option is used here to install this script onto every frame in a page.
- When Angular is detected, the content script will install a backend script into it's frame.
- Each content script / backend script pairing is kept track of in the background script. This pairing represents an angular devtools context in a particular frame.
- Angular DevTools is able to ask the background script to list each frame that has been registered on a page.
- Angular Devtools is able to ask the background script to "enable" the connection on a particular frame. This enables the messaging between the content script <-> background script <-> devtools page
Limitations:
- The `inspectedWindow.eval` API is only able to target frames by frameURL. This means some features that integrate with Chrome DevTools like inspect element and open source will not be available when inspecting frames that do not have a unique url on the page.
PR Close#53934
This commit adds hydration informations to the devtools.
* List of hydrated/hydrated components
* Shows hydration overlays
* Shows hydration errors for NG0500, 501 & 502
PR Close#53910
The devtools now support signals.
Writable signals of primitives are editable.
Object Signal and other non-writable signals (like computed) are not editable.
Co-authored-by: Tomasz Ducin <tomasz.ducin@gmail.com>
PR Close#53269
This PR provides strict type definition for the window.ng object used
for both console debugging and devtools. `GlobalDevModeUtils` now
gathers all type information about all methods exposed on window.ng.
PR Close#53439
The version of rxjs used to build the repository has been updated to v7.
This required only minimal changes to the code. Most of which were type
related only due to more strict types in v7. The behavior in those cases
was left intact. The most common type related change was to handle the
possibility of `undefined` with `toPromise` which was always possible with
v6 but the types did not reflect the runtime behavior. The one change that
was not type related was to provide a parameter value to the `defaultIfEmpty`
operator. It no longer defaults to a value of `null` if no default is provided.
To provide the same behavior the value of `null` is now passed to the operator.
PR Close#53500
Enabling `strict` is part of an effort to improve the quality of the devtools code base.
One of the direct side effect is to enable `noImplicitAny`, `strictPropertyInitialization` and `strictBindCallApply`.
This commit also replaces `fullTemplateTypeCheck` with `stringTemplates`.
PR Close#53340
In some injectors, there are LOTS of providers, making it slightly inconvenient to search for a certain one. This commit introduces a search-by-token for providers of a specific injector.
PR Close#53313
Added 2 tiny improvements:
- instead of "Symbol()", "Symbol(DESCRIPTION)" is displayed
- ECMAScript Maps are distinguished
Additionally:
- PropTypes has been moved to a separate file
- Simple unit tests covering each PropType except for PropType.Unknown
PR Close#53167
Previously, some versions of Angular 16.1.x that had 3/4 of the new DI debug APIs would enter a code path that required them to have access to the 4th.
Now DevTools checks for the existence of all 4 explicitly before going down this code path.
PR Close#52791
Previously transformInjectorResolutionPathsIntoTree returned an array, now it returns a tree node so we update the test cases to reflect that.
PR Close#52489
Previously only the trackpad could be used to navigate this view.
Now we can zoom and pan around using our mouse wheel and scroll.
Additionally, this commit fixes many issues related to the visualization of the injector graph visualization, allowing it to be more compact without impacting legibility and minimizing edge collisions in larger graphs.
PR Close#52489
Our algorithm for discovering the injector graph of an application involves calculating resolution paths for each angular node on a page, and then using those paths to construct the underlying tree.
Along the we way we perform many expensive computations that are candidates for optimization through caching. This commit implements this caching, resulting in a substantial increase in performance for large applications.
PR Close#52489
Implements a feature allowing users to visualize multiproviders as one row in the providers table.
Also enables the user to log to console any provider in the table. This log includes information about the provider selected, the injector it was configured in, and also calls `Injector.get(Token)` to determine the value the provider evaluates to in it's injector.
PR Close#52489
Previously this was the only page that used the inspector, so we automatically changed the tab out of convenience.
Now, the injector tree tab also does uses the inspector for some functionality, so we disable this behaviour.
PR Close#52489
While `performance.mark` is available on all supported browsers and node.js version this API is not available in JSDOM which is used by Jest and Cloudflare worker.
PR Close#52505
Creates set of unit tests for each function in the data transformation pipeline that enables injector metadata to be visualized as d3 graphs.
PR Close#51719
This commit introduces 2 new features into DevTools.
Directive level dependency inspection: Users can now view which dependencies their directives have injected in the property viewer tab. This view displays not only the dependency but also the resolution path that was used to service the injection.
Injector graph inspection: Users can now view a visualization of the element and environment hierarchies in their application. These trees are displayed separately but on the same page in the Injector Tree tab. User can click on individual injectors to view a list of all the providers configured in that injector, as well as highlight the resolution path from that injector to the root (with the corresponding environment injector connection highlighted as well).
PR Close#51719
In Devtools bar chart we can see the total time for all the directive instances in one change detection run.
This PR changes the bar chart to display the total count and time for all directive instances instead of showing the time for each directive instance separately in one change detection run.
PR Close#50866
Currently internally Angular has some customized tsconfig files, because we don't align with the tsconfig of the rest of g3. These changes enable `noImplicitReturns` and `noPropertyAccessFromIndexSignature` to align better with the internal config.
PR Close#51728
Currently the label showing the component name is always positioned from the bottom/right edge of the element which may be outside of the viewport. These changes add some logic to fall back to a different position so that the label is always visible.
I've also cleaned the `highlighter.ts` file up a bit.
Fixes#48479.
PR Close#50656
The existing DevTools demo app that is used for developing on DevTools is exclusively an NgModule application. This commit creates a copy of the old demo app but with no NgModules and only standalone APIs/Components/Directives/Pipes
PR Close#48533
We do this because of a bug caused by https://github.com/evanw/esbuild/issues/2950 and a recent change to how angular static properties are attached to class constructors. Targeting esnext or es2022 will cause the static initializer blocks that attach these static properties on class constructors to reference a class constructor variable that they do not have access to.
Because of this we explicitly target es2020 in our Angular DevTools builds.
PR Close#50086
DevMode is when the ng debug object is available. `Optimization:true` is responsible for treeshaking everything behind `ngDevMode`.
Fixes#48968
PR Close#48970
`RouterTestingModule` is not needed as of v16. Instead, TestBed
automatically provides `MockPlatformLocation` in order to help test
navigations in the application. The location mocks in the
RouterTestingModule aren't necessary anymore.
There doesn't appear to be any real documentation around
`RouterTestingModule` other than the API docs.
PR Close#49427
With this commit, Sets are displayed with the label Set(#) where # is the size of the set. They are not expandable/editable though.
Partial fix for #49312
PR Close#49316
`entryComponents` have been deprecated since version 9, because with Ivy they weren't necessary. These changes remove any remaining references.
BREAKING CHANGE:
* `entryComponents` has been deleted from the `@NgModule` and `@Component` public APIs. Any usages can be removed since they weren't doing anyting.
* `ANALYZE_FOR_ENTRY_COMPONENTS` injection token has been deleted. Any references can be removed.
PR Close#49484
Previously the DevTools demo app and browser app had duplicated styles in their respective styles.scss files.
This commit creates a global styles.scss that is imported with sass @use into the demo and browser app styles.scss files. This will prevent any issues where css changes to one are missed in the other. Also reduces duplication of material css theme definitions by consolidating it inone place. The respective styles.scss files for the demo app and browser app continue to exist incase those need environment specific css. For example the browser app requires that height: 100% is set on a document in order to render properly in a browsers devtools tab.
PR Close#49001
In the #48216 Material deps were updated to v15,
but the components and modules in DevTools were not
updated to MDC nor replaced with the legacy definitions.
PR Close#48420
On Firefox, Angular DevTools was breaking the XML display because of the script injected
Based on contentType, we won't inject that script anymore
Fixes#48017
PR Close#48021
Previously we built DevTools for all browsers with version 2 of the manifest file format.
This commit includes a number of refactors and API additions that will enable us to build DevTools with version 3 of the manifest file format.
The manifest v3 build of Angular DevTools has been tested on Chrome, Edge, and Safari.
Notably, the Firefox version of Angular DevTools remains as a manifest v2 build. Firefox does not yet support manifest v3 in it's latest stable release. When Firefox makes this transition, a follow up PR will update the Firefox manifest file to version 3.
Because Firefox still needs v2, we need to keep some old v2 APIs around in our background page (service worker in v3) that will execute conditionally based on if the extension was built for v2 or v3. This is determined with the chrome.runtime.getManifest().manifest_version API.
PR Close#47575
Previously, you could inspect the source code of a component but not a directive. This commit adds functionality to inspect source code for directives as well. Now you will see the inspect icon on the header component of each directive on a selected element.
PR Close#47334
With the introduction of standalone components, it is no longer guaranteed that getAllAngularRootElements will be available on the global object. This PR removes the dependency on this function so that DevTools can continue to work for Angular applications that use `bootstrapApplication`.
PR Close#45983
Add support to material design icons in offline mode for Angular Devtools. Self hosting the web font so icons are loaded regardless of network connection.
Bring the font file as well as its corresponding css file from third_party repo through bazel into shell-browser directory while building.
PR Close#45743
Uses `createEsbuildAngularOptimizePlugin` from dev-infra-private and passes in `GLOBAL_DEFS_FOR_TERSER_WITH_AOT` into a new esbuild prod configuration. Notably, this removes references to `ngDevMode` from the final build and enables minification.
PR Close#45886
In Angular v12 we introduced debugging APIs sufficient for DevTools.
Prior to that Angular DevTools accesses the logical data structures of
Ivy directly, which sometimes produces suboptimal results and skips
dynamically inserted content.
With the end of v11's LTS, we'll support only Angular v12 and up.
PR Close#45883
Adds support for TypeScript 4.7. Changes include:
* Bumping the TS version as well as some Bazel dependencies to include https://github.com/bazelbuild/rules_nodejs/pull/3420.
* Adding a backwards-compatibility layer for calls to `updateTypeParameterDeclaration`.
* Making `LView` generic in order to make it easier to type the context based on the usage. Currently the context can be 4 different types which coupled with stricter type checking would required a lot of extra casting all over `core`.
* Fixing a bunch of miscellaneous type errors.
* Removing assertions of `ReferenceEntry.isDefinition` in a few of the language service tests. The field isn't returned by TS anymore and we weren't using it for anything.
* Resolving in error in the language service that was caused by TS attempting to parse HTML files when we try to open them. Previous TS was silently setting them as `ScriptKind.Unknown` and ignoring the errors, but now it throws. I've worked around it by setting them as `ScriptKind.JSX`.
PR Close#45749
The menus weren't using the `mat-menu` component correctly which had led to some inconsistent spacing and the need for style overrides. These changes correctly wrap the menu content in `mat-menu-item` which has the added benefit of having keyboard support. I had to keep some of the overrides in order to preserve the dense layout of the menus.
I've also cleaned up the component by:
* Removing some unnecessary styles.
* Switching single-class usages of `ngClass` to `class.` bindings.
* Not using `br` tags for spacing.
PR Close#45665
* Added `flag_browser` to toggle between different browser builds chrome and firefox
* Updated build command to support new flag configuration
PR Close#44952
* Updating build to support both browsers firefox & chrome.
* Added new `config_setting` to support build.
* Added new genrule `copy_manifest` to `prodapp` pkg_web.
PR Close#44952
As part of the devtools migration, we copied the custom http server/
dev-server from the `angular/components` repo. This server implementation
has now moved to the shared dev-infra code, and we can clean up the
copy in this repository now.
PR Close#45452
.substr() is deprecated so we replace it with functions which work similarily but aren't deprecated
Signed-off-by: Tobias Speicher <rootcommander@gmail.com>
PR Close#45397
The used children property on a HTMLCollection does not contain text elements. Because of this, the highlighter overlay text never got fully cleared.
PR Close#44863
Values of Date properties were not shown in the preview. It was formatted to a simple string thus not giving valuable info to the developer.
PR Close#44864
Fixes an error in the satte-serializer spec:
```
devtools/projects/ng-devtools-backend/src/lib/state-serializer/state-serializer.spec.ts:103:60 - error TS2345: Argument of type '{ name: string; children: { name: string; children: { name: number; children: { name: number; children: { name: string; }[]; }[]; }[]; }[]; }[]' is not assignable to parameter of type 'NestedProp[]'.
Type '{ name: string; children: { name: string; children: { name: number; children: { name: number; children: { name: string; }[]; }[]; }[]; }[]; }' is not assignable to type 'NestedProp'.
Types of property 'children' are incompatible.
Type '{ name: string; children: { name: number; children: { name: number; children: { name: string; }[]; }[]; }[]; }[]' is not assignable to type 'NestedProp[]'.
Type '{ name: string; children: { name: number; children: { name: number; children: { name: string; }[]; }[]; }[]; }' is not assignable to type 'NestedProp'.
Types of property 'children' are incompatible.
Type '{ name: number; children: { name: number; children: { name: string; }[]; }[]; }[]' is not assignable to type 'NestedProp[]'.
Type '{ name: number; children: { name: number; children: { name: string; }[]; }[]; }' is not assignable to type 'NestedProp'.
Types of property 'children' are incompatible.
Type '{ name: number; children: { name: string; }[]; }[]' is not assignable to type 'NestedProp[]'.
Type '{ name: number; children: { name: string; }[]; }' is not assignable to type 'NestedProp'.
Types of property 'children' are incompatible.
Type '{ name: string; }[]' is not assignable to type 'NestedProp[]'.
Property 'children' is missing in type '{ name: string; }' but required in type 'NestedProp'.
103 const result = deeplySerializeSelectedProperties(dir1, QUERY_1_2);
```
PR Close#44735
Previously devtools used a nested workspace for its bazel configurations. This meant framework dependencies were consumed via npm.
Now devtools is part of the root bazel directory that all other files in this codebase fall under. This allows us to build devtools using local angular packages, removing the need to consume these dependencies with npn. This is useful because we no longer have to update these dependencies with an automated tool like renovate, and our CI tests will always run against the most up to date framework packages.
Previously the typescript override keyword was not on these methods. Now that devtools uses the tslint config in angular/angular (because of the no-implicit-override-abstract rule) we need to add these key words explicitly to method overrides. That is what this commit does.
This commit runs tslint --fix with the angular/angular tslint configuration on the files inside the devtools codebase.
Notably, the file-header rule in `tslint.json` was missing a default attribute. This commit adds that default attribute and sets it to the
license header that is present in all files in this repo. After running tslint --fix with this default added, this commit added the license header to all files in the devtools directory. Note for the reviewer: the automatically added license headers were added as comments with the "/*!" prefix. Since we want these comments removed in builds, and the rest of the codebase uses "/**", a simple find and replace was performed on the devtools directory to change these prefixes to "/**".
Previously, camel case was used for bazel labels in the devtools directory. This commit changes these labels to snake case except in the case where the label is identical to the directory name that the BUILD file is in.
Formats the entire devtools directory with the ng-dev formatting tool. Previously we relied on prettier, so this commit also remove prettier from devtools' dependencies.
Uses `cy.contains` as one command to optimize cypress' retry-ability mechanism
Affected tests are in:
`property-update.e2e.js` and `view-component-metadata.e2e.js`
Previously, we were using ngx-build-plus with a custom webpack config to determine the git SHA at runtime.
Now, after migrating to bazel and transfering to angular/angular, this commit uses ng-dev to stamp the latest git SHA directly in angular devtools' application environment.
This commit also removes the old webpack configs.
Previously we were running Cypress with bazel in an effort to save on CI time when devtools dependencies did not change. This commit reverts to running Cypress manually, until we can revisit building devtools with local Angular packages to save CI time.