Hone logo
Hone
Problems

Build an Angular DevTools Extension: Component Inspector

This challenge asks you to build a basic Chrome DevTools extension using Angular that can inspect and display information about the currently selected Angular component in a web page. This is a fundamental step towards creating more advanced debugging tools for Angular applications.

Problem Description

You need to develop a Chrome DevTools extension that adds a custom panel to the DevTools. This panel should display information about the currently selected Angular component. Specifically, the extension should:

  1. Establish Communication: Implement the necessary messaging between the DevTools extension's background script, content script, and the custom DevTools panel UI.
  2. Detect Angular Components: The content script should be able to identify Angular components on the page.
  3. Inspect Component Data: When an Angular component is selected (this selection mechanism is simplified for this challenge, assume we're always inspecting the root component for now, or a component identified by a specific attribute), the extension should retrieve its properties (public properties).
  4. Display Component Information: The Angular-based DevTools panel should receive this component data and render it in a user-friendly format.

Key Requirements:

  • Manifest File (manifest.json): Correctly configured to define the DevTools page, content scripts, and background scripts.
  • Content Script (content-script.ts): Injected into the target web page to interact with Angular.
  • DevTools Page (devtools.html, devtools.ts): Creates the custom DevTools panel.
  • Panel Page (panel.html, panel.ts, panel.component.ts): The Angular application that forms the custom panel UI.
  • Messaging System: Use chrome.runtime.sendMessage and chrome.runtime.onMessage for cross-script communication.
  • Angular Component Inspection: The content script needs a way to access information about Angular components. For this challenge, assume Angular adds a global ng object with debugging capabilities or that components are marked with a specific data attribute. We'll simplify this by assuming we can access ng.getComponent(element) if we can identify a DOM element that is an Angular component root.
  • Display Public Properties: The panel should show the names and values of public properties of the inspected component.

Expected Behavior:

When the user navigates to a web page that has an Angular application and opens Chrome DevTools, a new tab/panel labeled "Angular Inspector" should appear. If an Angular component's root element is somehow highlighted or identifiable (for simplicity, let's assume the content script can find an Angular component and inspect it), the panel should display its public properties.

Edge Cases to Consider:

  • No Angular Application: The extension should gracefully handle pages without Angular.
  • Multiple Angular Applications: For simplicity, focus on inspecting one identifiable Angular component at a time.
  • Component Properties: Handle various data types for properties (strings, numbers, booleans, arrays, objects). For nested objects/arrays, display their string representation.

Examples

Example 1: Simple Component Inspection

Imagine an Angular component with the following template and class:

// In the target web page (not part of your solution)
@Component({
  selector: 'app-my-component',
  template: `<h1>{{ title }}</h1><p>{{ count }}</p>`
})
export class MyComponent {
  title: string = 'Hello DevTools';
  count: number = 42;
  private internalState: string = 'secret'; // Should not be displayed
}

Input (Conceptual): The content script identifies the root element of MyComponent.

Output (in the Angular Inspector Panel):

Property NameValue
titleHello DevTools
count42

Explanation: The DevTools extension successfully identified the MyComponent, retrieved its public properties (title and count), and displayed them in the panel. The private property internalState is ignored.

Example 2: Component with Object Property

Consider a component with an object:

// In the target web page
@Component({
  selector: 'app-data-display',
  template: `<div>{{ user.name }}</div>`
})
export class DataDisplayComponent {
  user = { name: 'Alice', age: 30, address: { street: '123 Main St' } };
}

Input (Conceptual): The content script identifies the root element of DataDisplayComponent.

Output (in the Angular Inspector Panel):

Property NameValue
user{"name":"Alice","age":30,"address":{"street":"123 Main St"}}

Explanation: The user object is displayed as its JSON string representation.

Example 3: Handling Non-Angular Pages

Input: User opens DevTools on a static HTML page without any Angular.

Output: The "Angular Inspector" panel shows a message like "No Angular application detected on this page."

Explanation: The extension gracefully handles the absence of an Angular application.

Constraints

  • Browser Support: Target Chrome browser.
  • Angular Version: Assume Angular v10 or later, which generally provides debugging information via ng.
  • Performance: The content script should be efficient and not significantly impact the performance of the inspected web page.
  • Security: Do not attempt to modify the web page's DOM or JavaScript in any way that could compromise the page's integrity or security.

Notes

  • Simplified Component Selection: For this challenge, you can simplify how you identify the component to inspect. A common approach in real DevTools is to allow users to click on an element in the DOM inspector to select it. Here, you can either:
    • Try to inspect the root Angular component of the page.
    • Look for a specific data attribute (e.g., data-ng-component-id) added to the component's root element for easier identification by the content script.
  • Accessing Angular Debug Info: You'll need to investigate how to access Angular's internal debugging information. In modern Angular versions, you might find the ng global object helpful, e.g., window.ng.getComponent(element). This is how you'll get the component instance.
  • Serialization: Be mindful of how you serialize and deserialize data between the content script and the panel. JSON is a good starting point.
  • Angular Project Setup: You'll need to set up a standard Angular project for your DevTools panel UI. The other parts (manifest, content script, background script) will be plain JavaScript/TypeScript files.
  • Building the Extension: You'll need to package these files into a Chrome extension. This involves placing them in a directory and loading them as an "unpacked extension" in Chrome's chrome://extensions/ page.
Loading editor...
typescript