chrome-devtools-frontend 1.0.1666631 → 1.0.1668390
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/devtools-setting-migration/SKILL.md +290 -0
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +11 -4
- package/.agents/skills/ui-widgets/SKILL.md +25 -1
- package/docs/ui_engineering.md +44 -1
- package/front_end/core/common/Settings.ts +11 -4
- package/front_end/core/host/AidaClient.ts +6 -4
- package/front_end/core/host/InspectorFrontendHostAPI.ts +1 -0
- package/front_end/core/host/InspectorFrontendHostStub.ts +3 -3
- package/front_end/core/host/UserMetrics.ts +49 -1
- package/front_end/core/root/Runtime.ts +5 -0
- package/front_end/core/sdk/CSSMatchedStyles.ts +2 -5
- package/front_end/core/sdk/CSSModel.test.api.ts +102 -0
- package/front_end/core/sdk/CSSModel.ts +3 -2
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +12 -0
- package/front_end/core/sdk/Connections.ts +1 -1
- package/front_end/core/sdk/DOMModel.test.api.ts +104 -0
- package/front_end/core/sdk/DOMModel.ts +23 -11
- package/front_end/core/sdk/DebuggerModel.ts +12 -11
- package/front_end/core/sdk/IsolateManager.ts +1 -1
- package/front_end/core/sdk/NetworkManager.ts +105 -4
- package/front_end/core/sdk/OverlayModel.ts +15 -14
- package/front_end/core/sdk/RemoteObject.ts +1 -1
- package/front_end/core/sdk/SDKSettings.ts +19 -0
- package/front_end/core/sdk/sdk-meta.ts +0 -62
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/devtools_compatibility.js +1 -0
- package/front_end/entrypoints/main/MainImpl.ts +15 -5
- package/front_end/entrypoints/main/SimpleApp.ts +9 -3
- package/front_end/foundation/Universe.ts +13 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
- package/front_end/models/ai_assistance/BuiltInAi.ts +11 -6
- package/front_end/models/ai_assistance/ChangeManager.ts +17 -1
- package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +23 -10
- package/front_end/models/computed_style/ComputedStyleModel.ts +4 -7
- package/front_end/models/crux-manager/CrUXManager.ts +4 -0
- package/front_end/models/extensions/ExtensionAPI.ts +3 -3
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +2 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +22 -9
- package/front_end/models/live-metrics/LiveMetrics.ts +59 -19
- package/front_end/models/live-metrics/web-vitals-injected/README.md +1 -1
- package/front_end/models/live-metrics/web-vitals-injected/spec/spec.ts +6 -1
- package/front_end/models/live-metrics/web-vitals-injected/web-vitals-injected.ts +11 -3
- package/front_end/models/logs/LogManager.ts +1 -1
- package/front_end/models/persistence/FileSystemWorkspaceBinding.ts +1 -1
- package/front_end/models/source_map_scopes/FunctionCodeResolver.ts +6 -7
- package/front_end/models/source_map_scopes/NamesResolver.ts +23 -17
- package/front_end/models/workspace_diff/WorkspaceDiff.ts +13 -14
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +15 -7
- package/front_end/panels/application/BackgroundServiceView.ts +18 -20
- package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +78 -118
- package/front_end/panels/application/preloading/components/preloadingDetailsReportView.css +13 -13
- package/front_end/panels/autofill/AutofillView.ts +17 -17
- package/front_end/panels/autofill/autofillView.css +7 -8
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +31 -31
- package/front_end/panels/browser_debugger/DOMBreakpointsSidebarPane.ts +15 -15
- package/front_end/panels/browser_debugger/XHRBreakpointsSidebarPane.ts +12 -12
- package/front_end/panels/browser_debugger/browser_debugger-meta.ts +27 -27
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +14 -6
- package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +14 -6
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +13 -6
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +1 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +16 -8
- package/front_end/panels/console/ConsoleView.ts +6 -6
- package/front_end/panels/console_counters/WarningErrorCounter.ts +4 -4
- package/front_end/panels/coverage/CoverageModel.ts +11 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +50 -17
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +18 -7
- package/front_end/panels/emulation/AdvancedApp.ts +18 -8
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -2
- package/front_end/panels/emulation/DeviceModeView.ts +63 -104
- package/front_end/panels/event_listeners/EventListenersView.ts +8 -8
- package/front_end/panels/explain/components/ConsoleInsight.ts +15 -7
- package/front_end/panels/network/NetworkLogView.ts +13 -14
- package/front_end/panels/screencast/ScreencastApp.ts +12 -6
- package/front_end/panels/screencast/ScreencastView.ts +37 -11
- package/front_end/panels/sensors/LocationsSettingsTab.ts +244 -34
- package/front_end/panels/sensors/locationsSettingsTab.css +78 -0
- package/front_end/panels/settings/AISettingsTab.ts +13 -6
- package/front_end/panels/sources/DebuggerPlugin.ts +15 -4
- package/front_end/panels/sources/sources-meta.ts +55 -0
- package/front_end/panels/timeline/components/LiveMetricsView.ts +14 -1
- package/front_end/panels/timeline/components/cpuThrottlingSelector.css +4 -0
- package/front_end/panels/timeline/components/liveMetricsView.css +28 -0
- package/front_end/panels/timeline/timeline-meta.ts +13 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/menus/menu.css +4 -0
- package/front_end/ui/components/menus/menuItem.css +4 -0
- package/front_end/ui/components/menus/selectMenu.css +4 -0
- package/front_end/ui/components/menus/selectMenuButton.css +4 -0
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +21 -10
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -10
- package/front_end/ui/components/text_editor/config.ts +7 -0
- package/front_end/ui/legacy/AppProvider.ts +2 -1
- package/front_end/ui/legacy/Dialog.ts +93 -4
- package/front_end/ui/legacy/InspectorView.ts +1 -5
- package/front_end/ui/legacy/PopoverHelper.ts +5 -5
- package/front_end/ui/legacy/RootView.ts +8 -1
- package/front_end/ui/legacy/UniverseRequestEvent.ts +19 -0
- package/front_end/ui/legacy/Widget.ts +49 -6
- package/front_end/ui/legacy/inspectorCommon.css +1 -1
- package/front_end/ui/legacy/legacy.ts +2 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: devtools-setting-migration
|
|
3
|
+
description: "Workflow for splitting an existing SettingRegistration into a SettingDescriptor (placed in the lowest layer where used: core/, models/, or ui/settings/) and SettingUIDescriptor (registered in a higher-level -meta.ts file, outside of core/ and models/)."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DevTools Setting Migration Guide
|
|
7
|
+
|
|
8
|
+
This skill guide describes how to migrate an existing legacy `SettingRegistration` in DevTools by splitting it into a `SettingDescriptor` (non-UI descriptor) and a `SettingUIDescriptor` (UI descriptor).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Key Principles & Layer Boundaries
|
|
13
|
+
|
|
14
|
+
### 1. `SettingDescriptor` Location ("Lowest Layer")
|
|
15
|
+
* **Lowest Layer Rule:** A `SettingDescriptor` MUST be placed in the lowest architectural layer where the setting is used.
|
|
16
|
+
* **Core / Model Settings:** If a setting is used by `core/sdk` (or `models/`), its `SettingDescriptor` should be located in `core/sdk` (or `models/`).
|
|
17
|
+
* **Panel / UI Settings:** If a setting is only used by UI components or a specific panel (e.g. `panels/console/`), its `SettingDescriptor` **MUST GO INTO `ui/settings/FooSettings.ts`** (e.g. `ui/settings/ConsoleSettings.ts` where `Foo` is the panel name).
|
|
18
|
+
* **CRITICAL RULE — PANEL DESCRIPTORS MUST NOT BE PLACED IN `panels/`:**
|
|
19
|
+
* A `SettingDescriptor` **MUST NOT** be placed inside a `panels/` directory (e.g. `panels/console/ConsoleSettings.ts`).
|
|
20
|
+
* **Reason:** Panel `-meta.ts` files (e.g. `panels/console/console-meta.ts`) need to import the `SettingDescriptor` to call `SettingsUI.SettingUIRegistration.register(descriptor, uiDescriptor)`. `-meta.ts` files are loaded early and **MUST NOT import from `panels/`** (which would break lazy-loading of panel bundles). Since `ui/settings/` is in the `ui/` layer below `panels/`, `-meta.ts` files can safely import from `ui/settings/`.
|
|
21
|
+
* **CRITICAL RULE — MUST NOT BE IN A `-meta.ts` FILE:**
|
|
22
|
+
* A `SettingDescriptor` **MUST NOT** be placed in a `-meta.ts` file.
|
|
23
|
+
* **Reason:** Actual runtime code (e.g. models, panels, SDKs) needs to import the descriptor directly to call `Settings.instance().resolve(descriptor)`. Preload `-meta.ts` files are meant for lazy-loaded extension registrations and must not be imported by runtime code to avoid circular dependencies and module boundary violations.
|
|
24
|
+
|
|
25
|
+
### 2. `SettingUIDescriptor` Location (Higher-Level `-meta.ts` File)
|
|
26
|
+
* A `SettingUIDescriptor` defines UI-specific properties (category, title, tags, options, reload requirement, etc.).
|
|
27
|
+
* **Higher-Level Meta File Rule:** UI registrations **MUST BE PLACED IN A `-meta.ts` FILE ON A HIGHER LEVEL** (e.g., `entrypoints/main/main-meta.ts`, `entrypoints/inspector_main/inspector_main-meta.ts`, `panels/settings/settings-meta.ts`, or the specific panel's `-meta.ts` file).
|
|
28
|
+
* **CRITICAL RULE — MUST NOT REMAIN IN `core/` OR `models/`:**
|
|
29
|
+
* UI descriptors **MUST NOT** remain in or be added to `-meta.ts` files under `core/` or `models/` (such as `core/sdk/sdk-meta.ts` or `models/*/*-meta.ts`).
|
|
30
|
+
* **Goal:** A major goal of this migration is to completely eliminate `-meta.ts` files in `core/` and `models/`.
|
|
31
|
+
|
|
32
|
+
### 3. Resolving Settings vs `moduleSetting(name)`
|
|
33
|
+
* Legacy code retrieves settings using string identifiers: `Settings.instance().moduleSetting('setting-name')`.
|
|
34
|
+
* Refactored code should replace `moduleSetting('setting-name')` with `Settings.instance().resolve(settingDescriptor)`.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Step-by-Step Migration Workflow
|
|
39
|
+
|
|
40
|
+
Given a setting name (e.g., `'preserve-console-log'` or `'network-messages'`):
|
|
41
|
+
|
|
42
|
+
### Step 1: Locate Existing Registration & Analyze Use-Sites
|
|
43
|
+
1. Search for the setting name in `-meta.ts` files to find its `Common.Settings.registerSettingExtension` block.
|
|
44
|
+
2. Search for all occurrences of `'setting-name'` or `moduleSetting('setting-name')` across the codebase to identify all use-sites.
|
|
45
|
+
3. Determine the **lowest layer** among all use-sites:
|
|
46
|
+
* If used in `core/sdk` -> Target directory is `core/sdk/`.
|
|
47
|
+
* If used in `models/` -> Target directory is `models/<module>/`.
|
|
48
|
+
* If used in a panel (`panels/foo`) or UI -> Target directory is **`ui/settings/`** (file: `ui/settings/FooSettings.ts`). **NEVER place descriptors in `panels/`**.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
### Step 2: Extract & Define `SettingDescriptor` in the Lowest Layer
|
|
53
|
+
|
|
54
|
+
#### Decision Strategy: Create vs. Update File
|
|
55
|
+
When placing a `SettingDescriptor` in the target directory, decide whether to create or update a file using these rules:
|
|
56
|
+
|
|
57
|
+
1. **For Panel / UI Settings (Target is `ui/settings/`)**:
|
|
58
|
+
* **UPDATE**: Check if `ui/settings/FooSettings.ts` already exists (e.g., `ui/settings/ConsoleSettings.ts`). If so, add and export the `SettingDescriptor` there.
|
|
59
|
+
* **CREATE**: If `ui/settings/FooSettings.ts` does not exist:
|
|
60
|
+
* Create `ui/settings/FooSettings.ts`.
|
|
61
|
+
* Add `FooSettings.ts` to `sources` in `ui/settings/BUILD.gn`.
|
|
62
|
+
* Export `FooSettings.ts` from `ui/settings/settings.ts`.
|
|
63
|
+
|
|
64
|
+
2. **For Core / Model Settings (Target is `core/` or `models/`)**:
|
|
65
|
+
* **UPDATE**: Check if a module-wide settings file exists in that directory (e.g. `core/sdk/SDKSettings.ts`, `models/workspace/WorkspaceSettings.ts`). If so, add and export the `SettingDescriptor` there.
|
|
66
|
+
* **UPDATE**: If no module settings file exists and the setting is strictly used inside a single file (e.g., `ResourceTreeModel.ts`), update that `.ts` file by exporting the `SettingDescriptor` at the top.
|
|
67
|
+
* **CREATE**: Otherwise, create `<Module>Settings.ts` (e.g., `core/sdk/SDKSettings.ts`), add it to `sources` in `BUILD.gn`, and export it from the module's entrypoint (`sdk.ts`).
|
|
68
|
+
|
|
69
|
+
#### Code Definition Example:
|
|
70
|
+
Define and export the `SettingDescriptor` in the target file:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import type * as Common from '../core/common/common.js';
|
|
74
|
+
|
|
75
|
+
export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
|
|
76
|
+
name: 'preserve-console-log',
|
|
77
|
+
type: Common.Settings.SettingType.BOOLEAN,
|
|
78
|
+
defaultValue: false,
|
|
79
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
*Note: For conditional settings (dependent on `hostConfig`), use `Common.Settings.ConditionalSettingDescriptor<ValueT, ReasonT>` with an `isAvailable` function.*
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Step 3: Move UI Registration to a Higher-Level `-meta.ts` File
|
|
88
|
+
If the original registration was in a `core/` or `models/` `-meta.ts` file (e.g., `core/sdk/sdk-meta.ts`), **MOVE** the UI registration to a higher-level `-meta.ts` file (e.g., `entrypoints/main/main-meta.ts` or `panels/console/console-meta.ts`).
|
|
89
|
+
|
|
90
|
+
In the higher-level `-meta.ts` file:
|
|
91
|
+
1. Import `SettingsUI` from `ui/settings/settings.js` (e.g., `import * as SettingsUI from '../../ui/settings/settings.js';`).
|
|
92
|
+
2. Import the `SettingDescriptor` (from `core/sdk/`, `models/`, or `ui/settings/`).
|
|
93
|
+
3. Register using `SettingsUI.SettingUIRegistration.register(...)`:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
import * as SettingsUI from '../../ui/settings/settings.js';
|
|
97
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
98
|
+
|
|
99
|
+
SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, {
|
|
100
|
+
category: Common.Settings.SettingCategory.CONSOLE,
|
|
101
|
+
title: i18nLazyString(UIStrings.preserveLogUponNavigation),
|
|
102
|
+
options: [
|
|
103
|
+
{
|
|
104
|
+
value: true,
|
|
105
|
+
title: i18nLazyString(UIStrings.preserveLogUponNavigation),
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
value: false,
|
|
109
|
+
title: i18nLazyString(UIStrings.doNotPreserveLogUponNavigation),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
4. **Delete** the old `Common.Settings.registerSettingExtension` call from the `core/` or `models/` `-meta.ts` file. (If the `-meta.ts` file becomes empty, delete the file and clean up its build references).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
### Step 4: Update Call Sites (`moduleSetting` to `resolve`)
|
|
120
|
+
Find all call sites referencing the setting via `moduleSetting`:
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
// BEFORE:
|
|
124
|
+
const setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log');
|
|
125
|
+
|
|
126
|
+
// AFTER:
|
|
127
|
+
import { preserveConsoleLogSettingDescriptor } from './SDKSettings.js';
|
|
128
|
+
...
|
|
129
|
+
const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
*For conditional settings, use `Common.Settings.Settings.instance().maybeResolve(descriptor)` instead of `resolve(descriptor)`.*
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Step 5: Update `BUILD.gn` Files and Module Entrypoints
|
|
137
|
+
1. If a new `.ts` file was created (e.g., `SDKSettings.ts` or `ui/settings/ConsoleSettings.ts`):
|
|
138
|
+
* Add the file to `sources` in its module's `BUILD.gn`.
|
|
139
|
+
* Export the file from the module's entrypoint (`sdk.ts`, `settings.ts`, etc.).
|
|
140
|
+
2. If a `core/` or `models/` `-meta.ts` file was deleted, remove it from `BUILD.gn` and `devtools_grd_files.gni`.
|
|
141
|
+
3. Verify module imports strictly follow DevTools import rules (refer to `devtools-imports` skill).
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Step 6: Verify Changes
|
|
146
|
+
1. Run `autoninja -C out/Default` to check GN build.
|
|
147
|
+
2. Run `npm run lint` to check style and formatting rules.
|
|
148
|
+
3. Run relevant unit tests for the modified module.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Concrete Examples
|
|
153
|
+
|
|
154
|
+
### Example 1: Core/SDK Setting Migration (`preserve-console-log`)
|
|
155
|
+
|
|
156
|
+
#### Before Migration
|
|
157
|
+
Setting registered in **`front_end/core/sdk/sdk-meta.ts`** *(Legacy core meta file)*:
|
|
158
|
+
```typescript
|
|
159
|
+
Common.Settings.registerSettingExtension({
|
|
160
|
+
category: Common.Settings.SettingCategory.CONSOLE,
|
|
161
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
162
|
+
title: i18nLazyString(UIStrings.preserveLogUponNavigation),
|
|
163
|
+
settingName: 'preserve-console-log',
|
|
164
|
+
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
165
|
+
defaultValue: false,
|
|
166
|
+
options: [...],
|
|
167
|
+
});
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Setting used in **`front_end/core/sdk/ResourceTreeModel.ts`**:
|
|
171
|
+
```typescript
|
|
172
|
+
const setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log');
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
#### After Migration
|
|
178
|
+
|
|
179
|
+
1. **`front_end/core/sdk/SDKSettings.ts`** *(Lowest Layer in Core — NOT a `-meta.ts` file)*:
|
|
180
|
+
```typescript
|
|
181
|
+
import type * as Common from '../common/common.js';
|
|
182
|
+
|
|
183
|
+
export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
|
|
184
|
+
name: 'preserve-console-log',
|
|
185
|
+
type: Common.Settings.SettingType.BOOLEAN,
|
|
186
|
+
defaultValue: false,
|
|
187
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
188
|
+
};
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
2. **`front_end/entrypoints/main/main-meta.ts`** *(Higher-Level Meta File — NOT in `core/` or `models/`)*:
|
|
192
|
+
```typescript
|
|
193
|
+
import * as SDK from '../../core/sdk/sdk.js';
|
|
194
|
+
import * as SettingsUI from '../../ui/settings/settings.js';
|
|
195
|
+
|
|
196
|
+
SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, {
|
|
197
|
+
category: Common.Settings.SettingCategory.CONSOLE,
|
|
198
|
+
title: i18nLazyString(UIStrings.preserveLogUponNavigation),
|
|
199
|
+
options: [...],
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
3. **`front_end/core/sdk/ResourceTreeModel.ts`** *(Call Site in `core/sdk`)*:
|
|
204
|
+
```typescript
|
|
205
|
+
import { preserveConsoleLogSettingDescriptor } from './SDKSettings.js';
|
|
206
|
+
|
|
207
|
+
const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
4. **`front_end/core/sdk/sdk-meta.ts`**:
|
|
211
|
+
Registration for `'preserve-console-log'` removed.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Example 2: Panel UI Setting Migration (`network-messages`)
|
|
216
|
+
|
|
217
|
+
#### Before Migration
|
|
218
|
+
Setting registered in **`front_end/panels/console/console-meta.ts`**:
|
|
219
|
+
```typescript
|
|
220
|
+
Common.Settings.registerSettingExtension({
|
|
221
|
+
category: Common.Settings.SettingCategory.CONSOLE,
|
|
222
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
223
|
+
title: i18nLazyString(UIStrings.networkMessages),
|
|
224
|
+
settingName: 'network-messages',
|
|
225
|
+
settingType: Common.Settings.SettingType.BOOLEAN,
|
|
226
|
+
defaultValue: true,
|
|
227
|
+
options: [...],
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Setting used in **`front_end/panels/console/ConsoleView.ts`**:
|
|
232
|
+
```typescript
|
|
233
|
+
const setting = Common.Settings.Settings.instance().moduleSetting('network-messages');
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
#### After Migration
|
|
239
|
+
|
|
240
|
+
1. **`front_end/ui/settings/ConsoleSettings.ts`** *(Lowest Layer for UI/Panel Descriptor — NOT in `panels/console/`!)*:
|
|
241
|
+
```typescript
|
|
242
|
+
import type * as Common from '../../core/common/common.js';
|
|
243
|
+
|
|
244
|
+
export const networkMessagesSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
|
|
245
|
+
name: 'network-messages',
|
|
246
|
+
type: Common.Settings.SettingType.BOOLEAN,
|
|
247
|
+
defaultValue: true,
|
|
248
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
249
|
+
};
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
2. **`front_end/panels/console/console-meta.ts`** *(Panel Meta File — Imports Descriptor from `ui/settings/`)*:
|
|
253
|
+
```typescript
|
|
254
|
+
import * as SettingsUI from '../../ui/settings/settings.js';
|
|
255
|
+
|
|
256
|
+
SettingsUI.SettingUIRegistration.register(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor, {
|
|
257
|
+
category: Common.Settings.SettingCategory.CONSOLE,
|
|
258
|
+
title: i18nLazyString(UIStrings.networkMessages),
|
|
259
|
+
options: [...],
|
|
260
|
+
});
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
3. **`front_end/panels/console/ConsoleView.ts`** *(Call Site in `panels/console`)*:
|
|
264
|
+
```typescript
|
|
265
|
+
import * as SettingsUI from '../../ui/settings/settings.js';
|
|
266
|
+
|
|
267
|
+
const setting = Common.Settings.Settings.instance().resolve(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor);
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
## Interface Reference Summary
|
|
273
|
+
|
|
274
|
+
### `SettingDescriptor<T>`
|
|
275
|
+
Defined in `core/common/Settings.ts`:
|
|
276
|
+
* `name: string`: Unique setting name (kebab-case).
|
|
277
|
+
* `type: SettingType`: `BOOLEAN`, `ENUM`, `ARRAY`, or `REGEX`.
|
|
278
|
+
* `defaultValue: ValueT | ((hostConfig: HostConfig) => ValueT)`: Default setting value.
|
|
279
|
+
* `storageType?: SettingStorageType`: `SYNCED`, `LOCAL`, `GLOBAL`, or `SESSION`.
|
|
280
|
+
|
|
281
|
+
### `SettingUIDescriptor`
|
|
282
|
+
Defined in `ui/settings/SettingUIRegistration.ts`:
|
|
283
|
+
* `category?: SettingCategory`: Category under which setting is listed in Settings UI.
|
|
284
|
+
* `order?: number`: Sorting order.
|
|
285
|
+
* `title?: () => LocalizedString`: Title string displayed in Settings UI.
|
|
286
|
+
* `tags?: Array<() => LocalizedString>`: Search tags for Command Menu.
|
|
287
|
+
* `options?: SettingExtensionOption[]`: Enum / boolean option descriptions.
|
|
288
|
+
* `reloadRequired?: boolean`: Whether setting change requires DevTools reload.
|
|
289
|
+
* `deprecationNotice?: { disabled: boolean, warning: () => LocalizedString, experiment?: string }`: Deprecation notice.
|
|
290
|
+
* `learnMore?: LearnMore`: Help link or tooltip info.
|
|
@@ -36,13 +36,21 @@ clean `UI.Widget` classes that use native update rendering delegates.
|
|
|
36
36
|
};
|
|
37
37
|
```
|
|
38
38
|
|
|
39
|
-
* Make the view injectable in the constructor for testability (as per `docs/ui_engineering.md`)
|
|
39
|
+
* Make the view injectable in the constructor for testability (as per `docs/ui_engineering.md`), and use static `INJECT` if requesting dependencies from `Universe`:
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
42
|
class MyWidget extends UI.Widget.VBox {
|
|
43
|
+
static override readonly INJECT = [SDK.TargetManager.TargetManager] as const;
|
|
44
|
+
|
|
45
|
+
#targetManager: SDK.TargetManager.TargetManager;
|
|
43
46
|
#view: View;
|
|
44
|
-
constructor(
|
|
45
|
-
|
|
47
|
+
constructor(
|
|
48
|
+
element?: HTMLElement,
|
|
49
|
+
[targetManager]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
|
|
50
|
+
view: View = DEFAULT_VIEW,
|
|
51
|
+
) {
|
|
52
|
+
super(element);
|
|
53
|
+
this.#targetManager = targetManager;
|
|
46
54
|
this.#view = view;
|
|
47
55
|
}
|
|
48
56
|
```
|
|
@@ -84,4 +92,3 @@ clean `UI.Widget` classes that use native update rendering delegates.
|
|
|
84
92
|
2. ❓ **Inheritance**: Does the class now cleanly inherit from `UI.Widget` or its variants?
|
|
85
93
|
3. ❓ **Injectability**: Is the view injectable in the constructor?
|
|
86
94
|
4. ❓ **Build**: Does the code compile and do tests pass?
|
|
87
|
-
|
|
@@ -19,6 +19,7 @@ Adhere strictly to the Model-View-Presenter (MVP) architecture.
|
|
|
19
19
|
* MUST extend a base `UI.Widget` class (e.g., `UI.Widget.Widget`). Note that `UI.Widget.Widget` is not an `HTMLElement` and must be appended via `.show()` or `UI.Widget.widget`
|
|
20
20
|
* Constructor MUST assign the injected view function to a private `#view` field.
|
|
21
21
|
* Constructor MUST call `super()`. If taking `element?: HTMLElement`, pass it to `super(element)`. `super(true)` is forbidden.
|
|
22
|
+
* Dependencies from `Universe` SHOULD be requested via static `INJECT`: `static override readonly INJECT = [...] as const;` and received as constructor parameter #2 (`[dep1, dep2]: UI.Widget.WidgetDependencies<typeof MyWidget>`).
|
|
22
23
|
* Styling MUST be handled within the View. `this.registerCSSFiles()` is forbidden.
|
|
23
24
|
* Initial render MUST be triggered in `override wasShown(): void` by calling `this.requestUpdate()`.
|
|
24
25
|
* MUST hold all UI state as private class fields (e.g., `#counter`).
|
|
@@ -109,7 +110,30 @@ render(html`
|
|
|
109
110
|
* **Child Widgets:** Use `UI.Widget.widgetRef` to obtain the class instance of a child widget if you need to call methods on it directly (though declarative data flow is preferred).
|
|
110
111
|
|
|
111
112
|
### Dependencies
|
|
112
|
-
|
|
113
|
+
|
|
114
|
+
* **View Dependencies:** The `DEFAULT_VIEW` is typically a module-level function. Ensure all dependencies (enums, constants, other components) are imported at the top of the file so they are available in the function scope.
|
|
115
|
+
* **Presenter (`Universe`) Dependencies:** To access dependencies managed by `Universe` (e.g. `SDK.TargetManager.TargetManager`, `Common.Settings.Settings`), declare a static `INJECT` array on the `Widget` subclass:
|
|
116
|
+
```ts
|
|
117
|
+
export class MyWidget extends UI.Widget.Widget {
|
|
118
|
+
static override readonly INJECT = [SDK.TargetManager.TargetManager, Common.Settings.Settings] as const;
|
|
119
|
+
|
|
120
|
+
#targetManager: SDK.TargetManager.TargetManager;
|
|
121
|
+
#settings: Common.Settings.Settings;
|
|
122
|
+
#view: View;
|
|
123
|
+
|
|
124
|
+
constructor(
|
|
125
|
+
element?: HTMLElement,
|
|
126
|
+
[targetManager, settings]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
|
|
127
|
+
view: View = DEFAULT_VIEW,
|
|
128
|
+
) {
|
|
129
|
+
super(element);
|
|
130
|
+
this.#targetManager = targetManager;
|
|
131
|
+
this.#settings = settings;
|
|
132
|
+
this.#view = view;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
`instantiateWidget` automatically resolves dependencies from `Universe` and passes them as constructor parameter #2. In unit tests using `renderElementIntoDOM`, `TestUniverse` handles injection automatically (override via `setTestUniverseForWidgets`).
|
|
113
137
|
|
|
114
138
|
## Step-by-Step Implementation Example
|
|
115
139
|
|
package/docs/ui_engineering.md
CHANGED
|
@@ -38,13 +38,42 @@ Note that `VBox` and `HBox` inherit directly from `Widget`. They fully support v
|
|
|
38
38
|
|
|
39
39
|
To test the `DEFAULT_VIEW` function itself, we should use screenshot and e2e tests.
|
|
40
40
|
|
|
41
|
+
### Dependency Injection via `INJECT`
|
|
42
|
+
|
|
43
|
+
Subclasses of `UI.Widget.Widget` can declare dependencies from `Universe` to be automatically injected when instantiated (e.g. via `<devtools-widget>` or `UI.Widget.widget()`).
|
|
44
|
+
|
|
45
|
+
To opt into dependency injection, define a static `INJECT` array containing dependency constructors:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
class MyWidget extends UI.Widget.Widget {
|
|
49
|
+
static override readonly INJECT = [SDK.TargetManager.TargetManager, Common.Settings.Settings] as const;
|
|
50
|
+
|
|
51
|
+
#targetManager: SDK.TargetManager.TargetManager;
|
|
52
|
+
#settings: Common.Settings.Settings;
|
|
53
|
+
|
|
54
|
+
constructor(
|
|
55
|
+
element?: HTMLElement,
|
|
56
|
+
[targetManager, settings]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
|
|
57
|
+
view: View = DEFAULT_VIEW,
|
|
58
|
+
) {
|
|
59
|
+
super(element);
|
|
60
|
+
this.#targetManager = targetManager;
|
|
61
|
+
this.#settings = settings;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When `instantiateWidget` creates a widget with a non-empty `INJECT` array, it automatically resolves each requested constructor from the active `Universe` and passes the resolved instances array as parameter #2 to the constructor.
|
|
67
|
+
|
|
68
|
+
Use `UI.Widget.WidgetDependencies<typeof MyWidget>` to type the injected dependencies parameter.
|
|
69
|
+
|
|
41
70
|
## Declarative and orchestrated DOM updates
|
|
42
71
|
|
|
43
72
|
We should no longer use imperative API to update DOM. Instead we rely on orchestrated rendering of lit-html templates. The view function described above should be a call to lit-html `render`. The view function should be called from `UI.Widget`’s `performUpdate` method, which by default is scheduled using `requestAnimationFrame`.
|
|
44
73
|
|
|
45
74
|
To embed another presenter (`UI.Widget`) in the lit-html template, use `widget(<class>, {foo: 1, bar: 2})`
|
|
46
75
|
|
|
47
|
-
This will instantiate a `Widget` class with the web component as its `element` and, optionally, will set the properties provided in the second parameter. The widget won’t be re-instantiated on the subsequent template renders, but the properties would be updated. For this to work, the widget needs to accept `HTMLElement` as
|
|
76
|
+
This will instantiate a `Widget` class with the web component as its `element` and, optionally, will set the properties provided in the second parameter. The widget won’t be re-instantiated on the subsequent template renders, but the properties would be updated. For this to work, the widget needs to accept `HTMLElement` as its first constructor parameter, optional injected dependencies as parameter #2 (if `INJECT` is declared), and properties need to be public members or setters.
|
|
48
77
|
|
|
49
78
|
For backwards compatibility, the first argument to `widget` can also be a factory function: `widget(element => new MyWidget(foo, bar, element))`. Similar to the class constructor version, `element` is the actual `<devtools-widget>` so the following two invocations of `widget` are equivalent: `widget(MyWidget)` and `widget(element => new MyWidget(element))`.
|
|
50
79
|
|
|
@@ -218,6 +247,20 @@ const presenter = new Presenter();
|
|
|
218
247
|
presenter.doSomething();
|
|
219
248
|
```
|
|
220
249
|
|
|
250
|
+
#### Testing widgets with `INJECT` dependencies
|
|
251
|
+
|
|
252
|
+
When rendering widgets into DOM in unit tests (e.g. via `renderElementIntoDOM`), DOM test helpers automatically supply a default `TestUniverse` for resolving `INJECT` dependencies.
|
|
253
|
+
|
|
254
|
+
If a test requires a custom `TestUniverse` instance, pass it via `setTestUniverseForWidgets`:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import {setTestUniverseForWidgets} from '../../testing/DOMHelpers.js';
|
|
258
|
+
import {TestUniverse} from '../../testing/TestUniverse.js';
|
|
259
|
+
|
|
260
|
+
const customUniverse = new TestUniverse();
|
|
261
|
+
setTestUniverseForWidgets(customUniverse);
|
|
262
|
+
```
|
|
263
|
+
|
|
221
264
|
# Migrating Widgets and other "legacy" components
|
|
222
265
|
|
|
223
266
|
This section provides a series of examples for migrating from imperative DOM manipulation to a declarative approach using lit-html templates.
|
|
@@ -362,6 +362,8 @@ export class Settings {
|
|
|
362
362
|
this.createRegExpSetting(name, evaluatedDefaultValue, undefined, storageType) :
|
|
363
363
|
this.createSetting(name, evaluatedDefaultValue, storageType);
|
|
364
364
|
|
|
365
|
+
setting.setSettingType(type);
|
|
366
|
+
|
|
365
367
|
this.registerModuleSetting(setting);
|
|
366
368
|
return setting as Setting<T>;
|
|
367
369
|
}
|
|
@@ -511,6 +513,7 @@ export class Deprecation {
|
|
|
511
513
|
|
|
512
514
|
export class Setting<V> {
|
|
513
515
|
#registration: SettingRegistration|null = null;
|
|
516
|
+
#type: SettingType|null = null;
|
|
514
517
|
#requiresUserAction?: boolean;
|
|
515
518
|
#value?: V;
|
|
516
519
|
// TODO(crbug.com/1172300) Type cannot be inferred without changes to consumers. See above.
|
|
@@ -679,8 +682,15 @@ export class Setting<V> {
|
|
|
679
682
|
this.eventSupport.dispatchEventToListeners(this.name, value);
|
|
680
683
|
}
|
|
681
684
|
|
|
685
|
+
setSettingType(type: SettingType): void {
|
|
686
|
+
this.#type = type;
|
|
687
|
+
}
|
|
688
|
+
|
|
682
689
|
setRegistration(registration: SettingRegistration): void {
|
|
683
690
|
this.#registration = registration;
|
|
691
|
+
if (registration.settingType) {
|
|
692
|
+
this.#type = registration.settingType;
|
|
693
|
+
}
|
|
684
694
|
const {deprecationNotice} = registration;
|
|
685
695
|
if (deprecationNotice?.disabled) {
|
|
686
696
|
const experiment = deprecationNotice.experiment ?
|
|
@@ -694,10 +704,7 @@ export class Setting<V> {
|
|
|
694
704
|
}
|
|
695
705
|
|
|
696
706
|
type(): SettingType|null {
|
|
697
|
-
|
|
698
|
-
return this.#registration.settingType;
|
|
699
|
-
}
|
|
700
|
-
return null;
|
|
707
|
+
return this.#type ?? this.#registration?.settingType ?? null;
|
|
701
708
|
}
|
|
702
709
|
|
|
703
710
|
options(): SimpleSettingOption[] {
|
|
@@ -456,6 +456,10 @@ export class HostConfigTracker extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
|
456
456
|
#pollTimer?: ReturnType<typeof setTimeout>;
|
|
457
457
|
#aidaAvailability?: AidaAccessPreconditions;
|
|
458
458
|
|
|
459
|
+
get aidaAvailability(): AidaAccessPreconditions|undefined {
|
|
460
|
+
return this.#aidaAvailability;
|
|
461
|
+
}
|
|
462
|
+
|
|
459
463
|
static instance({forceNew}: {
|
|
460
464
|
forceNew: boolean,
|
|
461
465
|
} = {forceNew: false}): HostConfigTracker {
|
|
@@ -507,9 +511,7 @@ export class HostConfigTracker extends Common.ObjectWrapper.ObjectWrapper<EventT
|
|
|
507
511
|
const config =
|
|
508
512
|
await new Promise<Root.Runtime.HostConfig>(resolve => InspectorFrontendHostInstance.getHostConfig(resolve));
|
|
509
513
|
Object.assign(Root.Runtime.hostConfig, config);
|
|
510
|
-
|
|
511
|
-
// `await AidaClient.checkAccessPreconditions()` does not need to be called again in the event handlers.
|
|
512
|
-
this.dispatchEventToListeners(Events.AIDA_AVAILABILITY_CHANGED);
|
|
514
|
+
this.dispatchEventToListeners(Events.AIDA_AVAILABILITY_CHANGED, currentAidaAvailability);
|
|
513
515
|
}
|
|
514
516
|
}
|
|
515
517
|
}
|
|
@@ -519,7 +521,7 @@ export const enum Events {
|
|
|
519
521
|
}
|
|
520
522
|
|
|
521
523
|
export interface EventTypes {
|
|
522
|
-
[Events.AIDA_AVAILABILITY_CHANGED]:
|
|
524
|
+
[Events.AIDA_AVAILABILITY_CHANGED]: AidaAccessPreconditions;
|
|
523
525
|
}
|
|
524
526
|
|
|
525
527
|
export function isQuotaError(...inputs: Array<string|undefined>): boolean {
|
|
@@ -556,5 +556,6 @@ export const enum EnumeratedHistogram {
|
|
|
556
556
|
LighthouseCategoryUsed = 'DevTools.LighthouseCategoryUsed',
|
|
557
557
|
SwatchActivated = 'DevTools.SwatchActivated',
|
|
558
558
|
BuiltInAiAvailability = 'DevTools.BuiltInAiAvailability',
|
|
559
|
+
ResendRequest = 'DevTools.ResendRequest',
|
|
559
560
|
// LINT.ThenChange(/front_end/devtools_compatibility.js:EnumeratedHistogram)
|
|
560
561
|
}
|
|
@@ -118,15 +118,15 @@ export class InspectorFrontendHostStub implements InspectorFrontendHostAPI {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
setIsDocked(_isDocked: boolean, callback: () => void): void {
|
|
121
|
-
|
|
121
|
+
globalThis.setTimeout(callback, 0);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
showSurvey(_trigger: string, callback: (arg0: ShowSurveyResult) => void): void {
|
|
125
|
-
|
|
125
|
+
globalThis.setTimeout(() => callback({surveyShown: false}), 0);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
canShowSurvey(_trigger: string, callback: (arg0: CanShowSurveyResult) => void): void {
|
|
129
|
-
|
|
129
|
+
globalThis.setTimeout(() => callback({canShowSurvey: false}), 0);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
|
+
import * as Common from '../common/common.js';
|
|
6
|
+
|
|
5
7
|
import {InspectorFrontendHostInstance} from './InspectorFrontendHost.js';
|
|
6
8
|
import {EnumeratedHistogram} from './InspectorFrontendHostAPI.js';
|
|
7
9
|
|
|
@@ -29,6 +31,11 @@ export class UserMetrics {
|
|
|
29
31
|
InspectorFrontendHostInstance.recordEnumeratedHistogram(EnumeratedHistogram.ActionTaken, action, Action.MAX_VALUE);
|
|
30
32
|
}
|
|
31
33
|
|
|
34
|
+
resendRequest(resourceType: ResendRequestType): void {
|
|
35
|
+
InspectorFrontendHostInstance.recordEnumeratedHistogram(EnumeratedHistogram.ResendRequest, resourceType,
|
|
36
|
+
ResendRequestType.MAX_VALUE);
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
keybindSetSettingChanged(keybindSet: string): void {
|
|
33
40
|
const value = KeybindSetSettings[keybindSet as keyof typeof KeybindSetSettings] || 0;
|
|
34
41
|
InspectorFrontendHostInstance.recordEnumeratedHistogram(
|
|
@@ -253,7 +260,6 @@ export class UserMetrics {
|
|
|
253
260
|
InspectorFrontendHostInstance.recordPerformanceHistogram(
|
|
254
261
|
'DevTools.Insights.ShortTeaserGenerationTime', timeInMilliseconds);
|
|
255
262
|
}
|
|
256
|
-
|
|
257
263
|
}
|
|
258
264
|
|
|
259
265
|
/**
|
|
@@ -1182,3 +1188,45 @@ export const enum BuiltInAiAvailability {
|
|
|
1182
1188
|
DISABLED_NO_GPU = 9,
|
|
1183
1189
|
MAX_VALUE = 10,
|
|
1184
1190
|
}
|
|
1191
|
+
|
|
1192
|
+
export const enum ResendRequestType {
|
|
1193
|
+
XHR = 0,
|
|
1194
|
+
FETCH = 1,
|
|
1195
|
+
SCRIPT = 2,
|
|
1196
|
+
STYLESHEET = 3,
|
|
1197
|
+
IMAGE = 4,
|
|
1198
|
+
MEDIA = 5,
|
|
1199
|
+
FONT = 6,
|
|
1200
|
+
WASM = 7,
|
|
1201
|
+
MANIFEST = 8,
|
|
1202
|
+
TEXT_TRACK = 9,
|
|
1203
|
+
SOURCE_MAP_SCRIPT = 10,
|
|
1204
|
+
SOURCE_MAP_STYLE_SHEET = 11,
|
|
1205
|
+
DOCUMENT = 12,
|
|
1206
|
+
PREFETCH = 13,
|
|
1207
|
+
PING = 14,
|
|
1208
|
+
OTHER = 15,
|
|
1209
|
+
MAX_VALUE = 16,
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
const resendRequestTypeMap = new Map<Common.ResourceType.ResourceType, ResendRequestType>([
|
|
1213
|
+
[Common.ResourceType.resourceTypes.XHR, ResendRequestType.XHR],
|
|
1214
|
+
[Common.ResourceType.resourceTypes.Fetch, ResendRequestType.FETCH],
|
|
1215
|
+
[Common.ResourceType.resourceTypes.Script, ResendRequestType.SCRIPT],
|
|
1216
|
+
[Common.ResourceType.resourceTypes.Stylesheet, ResendRequestType.STYLESHEET],
|
|
1217
|
+
[Common.ResourceType.resourceTypes.Image, ResendRequestType.IMAGE],
|
|
1218
|
+
[Common.ResourceType.resourceTypes.Media, ResendRequestType.MEDIA],
|
|
1219
|
+
[Common.ResourceType.resourceTypes.Font, ResendRequestType.FONT],
|
|
1220
|
+
[Common.ResourceType.resourceTypes.Wasm, ResendRequestType.WASM],
|
|
1221
|
+
[Common.ResourceType.resourceTypes.Manifest, ResendRequestType.MANIFEST],
|
|
1222
|
+
[Common.ResourceType.resourceTypes.TextTrack, ResendRequestType.TEXT_TRACK],
|
|
1223
|
+
[Common.ResourceType.resourceTypes.SourceMapScript, ResendRequestType.SOURCE_MAP_SCRIPT],
|
|
1224
|
+
[Common.ResourceType.resourceTypes.SourceMapStyleSheet, ResendRequestType.SOURCE_MAP_STYLE_SHEET],
|
|
1225
|
+
[Common.ResourceType.resourceTypes.Document, ResendRequestType.DOCUMENT],
|
|
1226
|
+
[Common.ResourceType.resourceTypes.Prefetch, ResendRequestType.PREFETCH],
|
|
1227
|
+
[Common.ResourceType.resourceTypes.Ping, ResendRequestType.PING],
|
|
1228
|
+
]);
|
|
1229
|
+
|
|
1230
|
+
export function resendRequestType(resourceType: Common.ResourceType.ResourceType): ResendRequestType {
|
|
1231
|
+
return resendRequestTypeMap.get(resourceType) ?? ResendRequestType.OTHER;
|
|
1232
|
+
}
|
|
@@ -648,6 +648,10 @@ interface DevToolsPlusButton {
|
|
|
648
648
|
enabled: boolean;
|
|
649
649
|
}
|
|
650
650
|
|
|
651
|
+
interface DevToolsInstrumentationBreakpoints {
|
|
652
|
+
enabled: boolean;
|
|
653
|
+
}
|
|
654
|
+
|
|
651
655
|
/**
|
|
652
656
|
* The host configuration that we expect from the DevTools back-end.
|
|
653
657
|
*
|
|
@@ -705,6 +709,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
|
|
|
705
709
|
devToolsAdsPanel: DevToolsAdsPanel,
|
|
706
710
|
devToolsUseGcaApi: UseGcaApi,
|
|
707
711
|
devToolsPlusButton: DevToolsPlusButton,
|
|
712
|
+
devToolsInstrumentationBreakpoints: DevToolsInstrumentationBreakpoints,
|
|
708
713
|
extensionsOnChromeUrls: ExtensionsOnChromeUrls,
|
|
709
714
|
}>;
|
|
710
715
|
|
|
@@ -52,7 +52,7 @@ import {
|
|
|
52
52
|
CSSStyleRule,
|
|
53
53
|
} from './CSSRule.js';
|
|
54
54
|
import {CSSStyleDeclaration, Type} from './CSSStyleDeclaration.js';
|
|
55
|
-
import type
|
|
55
|
+
import {type DOMNode, NodeType} from './DOMModel.js';
|
|
56
56
|
|
|
57
57
|
function containsStyle(styles: CSSStyleDeclaration[]|Set<CSSStyleDeclaration>, query: CSSStyleDeclaration): boolean {
|
|
58
58
|
if (!query.styleSheetId || !query.range) {
|
|
@@ -456,7 +456,7 @@ export class CSSMatchedStyles {
|
|
|
456
456
|
}
|
|
457
457
|
|
|
458
458
|
// Inline style takes precedence over regular and inherited rules.
|
|
459
|
-
if (inlinePayload && this.#node.nodeType() ===
|
|
459
|
+
if (inlinePayload && this.#node.nodeType() === NodeType.ELEMENT_NODE) {
|
|
460
460
|
const style = new CSSStyleDeclaration(this.#cssModel, null, inlinePayload, Type.Inline);
|
|
461
461
|
this.#nodeForStyle.set(style, this.#node);
|
|
462
462
|
nodeStyles.push(style);
|
|
@@ -905,9 +905,6 @@ export class CSSMatchedStyles {
|
|
|
905
905
|
|
|
906
906
|
const matchCascade = (cascade: DOMInheritanceCascade): CSSStyleRule|null => {
|
|
907
907
|
for (const style of cascade.styles()) {
|
|
908
|
-
if (this.isInherited(style)) {
|
|
909
|
-
continue;
|
|
910
|
-
}
|
|
911
908
|
const parentRule = style.parentRule;
|
|
912
909
|
if (!(parentRule instanceof CSSStyleRule)) {
|
|
913
910
|
continue;
|