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
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
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
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
`Object.getPrototypeOf(obj)` returns `null` if `obj` is an empty object. `Object.getOwnPropertyDescriptors` throws on `null`/`undefined`
PR Close#55061
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
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
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
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 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
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
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
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
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
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
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
.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