chrome-devtools-frontend 1.0.1570343 → 1.0.1571573
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/prompts/README.md +18 -0
- package/agents/prompts/devtools-imports.md +47 -0
- package/agents/prompts/verification.md +27 -0
- package/docs/contributing/infrastructure.md +22 -0
- package/front_end/core/host/AidaClient.ts +1 -1
- package/front_end/core/host/UserMetrics.ts +1 -1
- package/front_end/core/root/Runtime.ts +54 -34
- package/front_end/core/sdk/CSSProperty.ts +1 -1
- package/front_end/core/sdk/CookieModel.ts +1 -1
- package/front_end/core/sdk/DOMModel.ts +1 -1
- package/front_end/core/sdk/DebuggerModel.ts +2 -21
- package/front_end/core/sdk/OverlayModel.ts +3 -2
- package/front_end/core/sdk/SourceMap.ts +0 -9
- package/front_end/core/sdk/SourceMapScopesInfo.ts +0 -24
- package/front_end/entrypoints/main/MainImpl.ts +43 -18
- package/front_end/generated/SupportedCSSProperties.js +2 -6
- package/front_end/models/ai_assistance/BuiltInAi.ts +5 -4
- package/front_end/models/issues_manager/ContrastCheckTrigger.ts +2 -2
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
- package/front_end/models/trace/ModelImpl.ts +0 -4
- package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -1
- package/front_end/panels/ai_assistance/PatchWidget.ts +10 -15
- package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +5 -4
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -2
- package/front_end/panels/application/FrameDetailsView.ts +2 -1
- package/front_end/panels/application/components/ReportsGrid.ts +2 -1
- package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +3 -5
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +5 -5
- package/front_end/panels/console/ConsoleInsightTeaser.ts +10 -11
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
- package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
- package/front_end/panels/elements/ComputedStyleModel.ts +11 -13
- package/front_end/panels/elements/ComputedStyleWidget.ts +3 -3
- package/front_end/panels/elements/ElementsPanel.ts +5 -2
- package/front_end/panels/elements/ElementsSidebarPane.ts +1 -1
- package/front_end/panels/elements/PlatformFontsWidget.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/emulation/DeviceModeWrapper.ts +101 -62
- package/front_end/panels/explain/components/ConsoleInsight.ts +27 -23
- package/front_end/panels/explain/components/consoleInsight.css +1 -1
- package/front_end/panels/network/RequestConditionsDrawer.ts +0 -1
- package/front_end/panels/network/RequestTimingView.ts +4 -3
- package/front_end/panels/network/components/RequestHeadersView.css +2 -2
- package/front_end/panels/network/components/RequestHeadersView.ts +7 -6
- package/front_end/panels/profiler/HeapProfileView.ts +3 -3
- package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
- package/front_end/panels/recorder/RecorderController.ts +6 -7
- package/front_end/panels/recorder/recorderController.css +1 -1
- package/front_end/panels/security/CookieControlsView.ts +2 -2
- package/front_end/panels/security/CookieReportView.ts +7 -7
- package/front_end/panels/settings/AISettingsTab.ts +5 -5
- package/front_end/panels/settings/components/SyncSection.ts +4 -3
- package/front_end/panels/sources/CallStackSidebarPane.ts +4 -1
- package/front_end/panels/sources/NavigatorView.ts +1 -1
- package/front_end/panels/sources/SourcesPanel.ts +3 -1
- package/front_end/panels/timeline/CompatibilityTracksAppender.ts +1 -1
- package/front_end/panels/timeline/ThreadAppender.ts +1 -1
- package/front_end/panels/timeline/TimelineController.ts +4 -3
- package/front_end/panels/timeline/TimelinePanel.ts +4 -3
- package/front_end/panels/whats_new/ReleaseNoteView.ts +4 -3
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/components/markdown_view/CodeBlock.ts +3 -6
- package/front_end/ui/components/markdown_view/MarkdownLink.ts +3 -4
- package/front_end/ui/components/panel_feedback/PanelFeedback.ts +3 -4
- package/front_end/ui/components/panel_feedback/PreviewToggle.ts +9 -6
- package/front_end/ui/components/panel_feedback/panelFeedback.css +2 -2
- package/front_end/ui/kit/link/Link.ts +1 -14
- package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -1
- package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +5 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -1
- package/package.json +1 -1
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
This directory contains a series of prompts that can be added to your root `GEMINI.md` file, which is not committed to version control.
|
|
2
|
+
|
|
3
|
+
More context for Googlers: go/chrome-devtools:ai-agents-use
|
|
4
|
+
|
|
5
|
+
## Getting started
|
|
6
|
+
|
|
7
|
+
1. Create `//GEMINI.md` in the root of the `devtools-frontend` repository.
|
|
8
|
+
2. Include the relevant prompts with `@`:
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
@agents/prompts/verification.md
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
The `/memory show` command in Gemini CL can be used to verify that the files have been included correctly.
|
|
15
|
+
|
|
16
|
+
## Contributing
|
|
17
|
+
|
|
18
|
+
Contributions to existing prompts or to add new ones are encouraged; CLs are very welcome.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Imports
|
|
2
|
+
|
|
3
|
+
This codebase follows a special convention for importing code that must be followed to avoid build errors.
|
|
4
|
+
|
|
5
|
+
In DevTools each folder of code is considered a *module*:
|
|
6
|
+
|
|
7
|
+
- `front_end/models/trace` is the *trace module*.
|
|
8
|
+
- `front_end/panels/timeline` is the *timeline module*.
|
|
9
|
+
|
|
10
|
+
Within each module there are multiple TypeScript files. *The file that is named the same as the folder name is called the entrypoint*.
|
|
11
|
+
|
|
12
|
+
- `front_end/models/trace/trace.ts` is the *trace module's entrypoint*
|
|
13
|
+
- `front_end/models/trace/ModelImpl.ts` is part of the implementation of the trace module.
|
|
14
|
+
|
|
15
|
+
## Importing from another module
|
|
16
|
+
|
|
17
|
+
When you want to reuse code from other modules, *you must import that module via its entrypoint*. Imagine we are in `front_end/panels/timeline/TimelinePanel.ts`. This import is GOOD:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
import * as Trace from '../models/trace/trace.js'; // import the entrypoint
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This import is BAD because we import a file that is NOT the entrypoint:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
import * as ModelImpl from '../models/trace/ModelImpl.js' // NEVER ALLOWED
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Additionally, you **must import using the `import * as` syntax**.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
import {ModelImpl, X, Y} from '../models/trace/trace.js'; // BAD
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
import * as Trace from '../models/trace/trace.js'; // GOOD
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Importing from within the same module
|
|
40
|
+
|
|
41
|
+
If you are within the same module, it is OK to import from files directly rather than go via the entrypoint. You can also import specifically what you need.
|
|
42
|
+
|
|
43
|
+
For example, if you are editing `front_end/models/trace/ModelImpl.ts` this would be acceptable:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
import {Foo} from './Foo.js'; // allowed because Foo.ts is in the same directory.
|
|
47
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Instructions on how to verify your changes
|
|
2
|
+
|
|
3
|
+
## Testing
|
|
4
|
+
|
|
5
|
+
- To test a file, you can run `npm run test -- <FILEPATH>` where `FILEPATH` is a path to a `*.test.ts` file, relative to the working directory.
|
|
6
|
+
- Test files are usually defined alongside their implementation. So if you are working on `front_end/panels/timeline/TimelinePanel.ts`, you would expect the test file to be defined in `front_end/panels/timeline/TimelinePanel.test.ts`.
|
|
7
|
+
- You can also test an entire directory. For example, `npm run test -- front_end/models/trace` will run all tests in that directory.
|
|
8
|
+
|
|
9
|
+
## Building & compiling
|
|
10
|
+
|
|
11
|
+
- Check for TypeScript or dependency issues in the build system by running `autoninja -C out/Default`.
|
|
12
|
+
|
|
13
|
+
## Fast builds
|
|
14
|
+
|
|
15
|
+
- If the `out/Fast` or `out/fast-build` directory exists, this means that a build that does not execute TypeScript is available to you which greatly decreases build time.
|
|
16
|
+
- To use the fast build for tests, pass the `--target=Fast` (adjust the value based on the name of the directory) argument to `npm run test`.
|
|
17
|
+
|
|
18
|
+
## Linting
|
|
19
|
+
|
|
20
|
+
- `npm run lint` will execute ESLint and StyleLint and report any violations that must be fixed.
|
|
21
|
+
|
|
22
|
+
## Best practices
|
|
23
|
+
|
|
24
|
+
- Run tests often to verify your changes.
|
|
25
|
+
- Prefer using a fast build, if it exists, to keep the feedback loop shorter.
|
|
26
|
+
- Periodically compile with TypeScript to check for type errors.
|
|
27
|
+
- Run linting at the end of your code changes.
|
|
@@ -281,6 +281,28 @@ even if it consistently failed 4 times out of 5 runs for some time. Try to
|
|
|
281
281
|
correlate your failure with a luci-analysis report on this test and skip it
|
|
282
282
|
until the flakiness gets resolved.
|
|
283
283
|
|
|
284
|
+
### Clobber a builder's cache
|
|
285
|
+
|
|
286
|
+
Builder bots utilize caching for project checkouts to speed up updates. This
|
|
287
|
+
cache includes the build output directory (`/out`). Occasionally, stale files
|
|
288
|
+
within these directories can interfere with the build process or test execution.
|
|
289
|
+
|
|
290
|
+
If you suspect a cache issue, you can clear (clobber) the cache for a specific
|
|
291
|
+
builder. This requires a local Chromium checkout to access the necessary utility
|
|
292
|
+
script.
|
|
293
|
+
|
|
294
|
+
Run the following command from the root of your Chromium checkout:
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
./tools/infra/builder-cache-clobber.py -S https://chromium-swarm.appspot.com/ --builder "Stand-alone Mac-arm64" --bucket ci --project devtools-frontend
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### Note about caches on try bots:
|
|
301
|
+
|
|
302
|
+
Try bots (CQ) operate in tester/compilator pairs. When clearing caches, ensure
|
|
303
|
+
you target both builders in the pair. For example, if you clear the cache for
|
|
304
|
+
`dtf_mac_arm64_rel`, you must also clear it for `dtf_mac_arm64_compile_rel`.
|
|
305
|
+
|
|
284
306
|
## Luci Analysis configuration
|
|
285
307
|
|
|
286
308
|
[Luci Analysis](go/luci-analysis) is a tool that helps you understand the
|
|
@@ -79,7 +79,7 @@ export interface FunctionObjectParam<T extends string|number|symbol = string> ex
|
|
|
79
79
|
type: ParametersTypes.OBJECT;
|
|
80
80
|
// TODO: this can be also be ObjectParams
|
|
81
81
|
properties: Record<T, FunctionPrimitiveParams|FunctionArrayParam>;
|
|
82
|
-
required:
|
|
82
|
+
required: T[];
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
/**
|
|
@@ -825,7 +825,7 @@ export enum DevtoolsExperiments {
|
|
|
825
825
|
'live-heap-profile' = 11,
|
|
826
826
|
'protocol-monitor' = 13,
|
|
827
827
|
'sampling-heap-profiler-timeline' = 17,
|
|
828
|
-
'show-option-
|
|
828
|
+
'show-option-to-expose-internals-in-heap-snapshot' = 18,
|
|
829
829
|
'timeline-invalidation-tracking' = 26,
|
|
830
830
|
'timeline-show-all-events' = 27,
|
|
831
831
|
'timeline-v8-runtime-call-stats' = 28,
|
|
@@ -119,11 +119,17 @@ export class Runtime {
|
|
|
119
119
|
if (experiment === '*') {
|
|
120
120
|
return true;
|
|
121
121
|
}
|
|
122
|
-
if (experiment
|
|
123
|
-
|
|
122
|
+
if (experiment?.startsWith('!')) {
|
|
123
|
+
const experimentName = experiment.substring(1) as ExperimentName;
|
|
124
|
+
if (experiments.isEnabled(experimentName)) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
124
127
|
}
|
|
125
|
-
if (experiment && !experiment.startsWith('!')
|
|
126
|
-
|
|
128
|
+
if (experiment && !experiment.startsWith('!')) {
|
|
129
|
+
const experimentName = experiment as ExperimentName;
|
|
130
|
+
if (!experiments.isEnabled(experimentName)) {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
127
133
|
}
|
|
128
134
|
const {condition} = descriptor;
|
|
129
135
|
return condition ? condition(hostConfig) : true;
|
|
@@ -151,10 +157,10 @@ export interface Option {
|
|
|
151
157
|
|
|
152
158
|
export class ExperimentsSupport {
|
|
153
159
|
#experiments: Experiment[] = [];
|
|
154
|
-
readonly #experimentNames = new Set<
|
|
155
|
-
readonly #enabledTransiently = new Set<
|
|
156
|
-
readonly #enabledByDefault = new Set<
|
|
157
|
-
readonly #serverEnabled = new Set<
|
|
160
|
+
readonly #experimentNames = new Set<ExperimentName>();
|
|
161
|
+
readonly #enabledTransiently = new Set<ExperimentName>();
|
|
162
|
+
readonly #enabledByDefault = new Set<ExperimentName>();
|
|
163
|
+
readonly #serverEnabled = new Set<ExperimentName>();
|
|
158
164
|
readonly #storage = new ExperimentStorage();
|
|
159
165
|
|
|
160
166
|
allConfigurableExperiments(): Experiment[] {
|
|
@@ -167,7 +173,7 @@ export class ExperimentsSupport {
|
|
|
167
173
|
return result;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
|
-
register(experimentName:
|
|
176
|
+
register(experimentName: ExperimentName, experimentTitle: string, docLink?: string, feedbackLink?: string): void {
|
|
171
177
|
if (this.#experimentNames.has(experimentName)) {
|
|
172
178
|
throw new Error(`Duplicate registration of experiment '${experimentName}'`);
|
|
173
179
|
}
|
|
@@ -178,7 +184,7 @@ export class ExperimentsSupport {
|
|
|
178
184
|
feedbackLink as Platform.DevToolsPath.UrlString ?? Platform.DevToolsPath.EmptyUrlString));
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
isEnabled(experimentName:
|
|
187
|
+
isEnabled(experimentName: ExperimentName): boolean {
|
|
182
188
|
this.checkExperiment(experimentName);
|
|
183
189
|
// Check for explicitly disabled #experiments first - the code could call setEnable(false) on the experiment enabled
|
|
184
190
|
// by default and we should respect that.
|
|
@@ -195,38 +201,39 @@ export class ExperimentsSupport {
|
|
|
195
201
|
return Boolean(this.#storage.get(experimentName));
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
setEnabled(experimentName:
|
|
204
|
+
setEnabled(experimentName: ExperimentName, enabled: boolean): void {
|
|
199
205
|
this.checkExperiment(experimentName);
|
|
200
206
|
this.#storage.set(experimentName, enabled);
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
enableExperimentsTransiently(experimentNames:
|
|
209
|
+
enableExperimentsTransiently(experimentNames: ExperimentName[]): void {
|
|
204
210
|
for (const experimentName of experimentNames) {
|
|
205
211
|
this.checkExperiment(experimentName);
|
|
206
212
|
this.#enabledTransiently.add(experimentName);
|
|
207
213
|
}
|
|
208
214
|
}
|
|
209
215
|
|
|
210
|
-
enableExperimentsByDefault(experimentNames:
|
|
216
|
+
enableExperimentsByDefault(experimentNames: ExperimentName[]): void {
|
|
211
217
|
for (const experimentName of experimentNames) {
|
|
212
218
|
this.checkExperiment(experimentName);
|
|
213
219
|
this.#enabledByDefault.add(experimentName);
|
|
214
220
|
}
|
|
215
221
|
}
|
|
216
222
|
|
|
217
|
-
setServerEnabledExperiments(
|
|
218
|
-
for (const experiment of
|
|
219
|
-
|
|
220
|
-
this
|
|
223
|
+
setServerEnabledExperiments(experiments: string[]): void {
|
|
224
|
+
for (const experiment of experiments) {
|
|
225
|
+
const experimentName = experiment as ExperimentName;
|
|
226
|
+
this.checkExperiment(experimentName);
|
|
227
|
+
this.#serverEnabled.add(experimentName);
|
|
221
228
|
}
|
|
222
229
|
}
|
|
223
230
|
|
|
224
|
-
enableForTest(experimentName:
|
|
231
|
+
enableForTest(experimentName: ExperimentName): void {
|
|
225
232
|
this.checkExperiment(experimentName);
|
|
226
233
|
this.#enabledTransiently.add(experimentName);
|
|
227
234
|
}
|
|
228
235
|
|
|
229
|
-
disableForTest(experimentName:
|
|
236
|
+
disableForTest(experimentName: ExperimentName): void {
|
|
230
237
|
this.checkExperiment(experimentName);
|
|
231
238
|
this.#enabledTransiently.delete(experimentName);
|
|
232
239
|
}
|
|
@@ -243,7 +250,7 @@ export class ExperimentsSupport {
|
|
|
243
250
|
this.#storage.cleanUpStaleExperiments(this.#experimentNames);
|
|
244
251
|
}
|
|
245
252
|
|
|
246
|
-
private checkExperiment(experimentName:
|
|
253
|
+
private checkExperiment(experimentName: ExperimentName): void {
|
|
247
254
|
if (!this.#experimentNames.has(experimentName)) {
|
|
248
255
|
throw new Error(`Unknown experiment '${experimentName}'`);
|
|
249
256
|
}
|
|
@@ -271,11 +278,11 @@ class ExperimentStorage {
|
|
|
271
278
|
* - false: Explicitly disabled.
|
|
272
279
|
* - undefined: Disabled.
|
|
273
280
|
*/
|
|
274
|
-
get(experimentName:
|
|
281
|
+
get(experimentName: ExperimentName): boolean|undefined {
|
|
275
282
|
return this.#experiments[experimentName];
|
|
276
283
|
}
|
|
277
284
|
|
|
278
|
-
set(experimentName:
|
|
285
|
+
set(experimentName: ExperimentName, enabled: boolean): void {
|
|
279
286
|
this.#experiments[experimentName] = enabled;
|
|
280
287
|
this.#syncToLocalStorage();
|
|
281
288
|
}
|
|
@@ -294,14 +301,18 @@ class ExperimentStorage {
|
|
|
294
301
|
}
|
|
295
302
|
}
|
|
296
303
|
|
|
304
|
+
/**
|
|
305
|
+
* @deprecated Experiments should not be used anymore, instead use base::Feature.
|
|
306
|
+
* See docs/contributing/settings-experiments-features.md
|
|
307
|
+
*/
|
|
297
308
|
export class Experiment {
|
|
298
|
-
name:
|
|
309
|
+
name: ExperimentName;
|
|
299
310
|
title: string;
|
|
300
311
|
docLink?: Platform.DevToolsPath.UrlString;
|
|
301
312
|
readonly feedbackLink?: Platform.DevToolsPath.UrlString;
|
|
302
313
|
readonly #experiments: ExperimentsSupport;
|
|
303
314
|
constructor(
|
|
304
|
-
experiments: ExperimentsSupport, name:
|
|
315
|
+
experiments: ExperimentsSupport, name: ExperimentName, title: string, docLink: Platform.DevToolsPath.UrlString,
|
|
305
316
|
feedbackLink: Platform.DevToolsPath.UrlString) {
|
|
306
317
|
this.name = name;
|
|
307
318
|
this.title = title;
|
|
@@ -322,18 +333,21 @@ export class Experiment {
|
|
|
322
333
|
/** This must be constructed after the query parameters have been parsed. **/
|
|
323
334
|
export const experiments = new ExperimentsSupport();
|
|
324
335
|
|
|
325
|
-
|
|
326
|
-
*
|
|
327
|
-
* See docs/contributing/settings-experiments-features.md
|
|
328
|
-
*/
|
|
329
|
-
export const enum ExperimentName {
|
|
336
|
+
export enum ExperimentName {
|
|
337
|
+
ALL = '*',
|
|
330
338
|
CAPTURE_NODE_CREATION_STACKS = 'capture-node-creation-stacks',
|
|
331
|
-
CSS_OVERVIEW = 'css-overview',
|
|
332
339
|
LIVE_HEAP_PROFILE = 'live-heap-profile',
|
|
333
|
-
ALL = '*',
|
|
334
340
|
PROTOCOL_MONITOR = 'protocol-monitor',
|
|
341
|
+
SAMPLING_HEAP_PROFILER_TIMELINE = 'sampling-heap-profiler-timeline',
|
|
342
|
+
SHOW_OPTION_TO_EXPOSE_INTERNALS_IN_HEAP_SNAPSHOT = 'show-option-to-expose-internals-in-heap-snapshot',
|
|
343
|
+
TIMELINE_INVALIDATION_TRACKING = 'timeline-invalidation-tracking',
|
|
344
|
+
TIMELINE_SHOW_ALL_EVENTS = 'timeline-show-all-events',
|
|
345
|
+
TIMELINE_V8_RUNTIME_CALL_STATS = 'timeline-v8-runtime-call-stats',
|
|
346
|
+
APCA = 'apca',
|
|
347
|
+
FONT_EDITOR = 'font-editor',
|
|
335
348
|
FULL_ACCESSIBILITY_TREE = 'full-accessibility-tree',
|
|
336
|
-
|
|
349
|
+
CONTRAST_ISSUES = 'contrast-issues',
|
|
350
|
+
EXPERIMENTAL_COOKIE_FEATURES = 'experimental-cookie-features',
|
|
337
351
|
INSTRUMENTATION_BREAKPOINTS = 'instrumentation-breakpoints',
|
|
338
352
|
AUTHORED_DEPLOYED_GROUPING = 'authored-deployed-grouping',
|
|
339
353
|
JUST_MY_CODE = 'just-my-code',
|
|
@@ -342,8 +356,8 @@ export const enum ExperimentName {
|
|
|
342
356
|
TIMELINE_DEBUG_MODE = 'timeline-debug-mode',
|
|
343
357
|
// Adding or removing an entry from this enum?
|
|
344
358
|
// You will need to update:
|
|
345
|
-
// 1.
|
|
346
|
-
// 2.
|
|
359
|
+
// 1. DevToolsExperiments enum in host/UserMetrics.ts
|
|
360
|
+
// 2. Maybe REGISTERED_EXPERIMENTS in EnvironmentHelpers.ts (to create this experiment in the test env)
|
|
347
361
|
}
|
|
348
362
|
|
|
349
363
|
export enum GenAiEnterprisePolicyValue {
|
|
@@ -522,6 +536,11 @@ interface HostConfigAiAssistanceContextSelectionAgent {
|
|
|
522
536
|
enabled: boolean;
|
|
523
537
|
}
|
|
524
538
|
|
|
539
|
+
interface ConsoleInsightsTeasers {
|
|
540
|
+
enabled: boolean;
|
|
541
|
+
allowWithoutGpu: boolean;
|
|
542
|
+
}
|
|
543
|
+
|
|
525
544
|
/**
|
|
526
545
|
* The host configuration that we expect from the DevTools back-end.
|
|
527
546
|
*
|
|
@@ -570,6 +589,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
|
|
|
570
589
|
devToolsAiPromptApi: AiPromptApi,
|
|
571
590
|
devToolsEnableDurableMessages: DevToolsEnableDurableMessages,
|
|
572
591
|
devToolsAiAssistanceContextSelectionAgent: HostConfigAiAssistanceContextSelectionAgent,
|
|
592
|
+
devToolsConsoleInsightsTeasers: ConsoleInsightsTeasers,
|
|
573
593
|
}>;
|
|
574
594
|
|
|
575
595
|
/**
|
|
@@ -115,7 +115,7 @@ export class CSSProperty extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
115
115
|
const matchers = matchedStyles.propertyMatchers(this.ownerStyle, computedStyles);
|
|
116
116
|
|
|
117
117
|
matchers.push(new CSSWideKeywordMatcher(this, matchedStyles));
|
|
118
|
-
if (Root.Runtime.experiments.isEnabled(
|
|
118
|
+
if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.FONT_EDITOR)) {
|
|
119
119
|
matchers.push(new FontMatcher());
|
|
120
120
|
}
|
|
121
121
|
return matchers;
|
|
@@ -99,7 +99,7 @@ export class CookieModel extends SDKModel<EventTypes> {
|
|
|
99
99
|
if (cookie.expires()) {
|
|
100
100
|
expires = Math.floor(Date.parse(`${cookie.expires()}`) / 1000);
|
|
101
101
|
}
|
|
102
|
-
const enabled = Root.Runtime.experiments.isEnabled(
|
|
102
|
+
const enabled = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.EXPERIMENTAL_COOKIE_FEATURES);
|
|
103
103
|
const preserveUnset = (scheme: Protocol.Network.CookieSourceScheme): Protocol.Network.CookieSourceScheme.Unset|
|
|
104
104
|
undefined => scheme === Protocol.Network.CookieSourceScheme.Unset ? scheme : undefined;
|
|
105
105
|
const protocolCookie = {
|
|
@@ -1319,7 +1319,7 @@ export class DOMModel extends SDKModel<EventTypes> {
|
|
|
1319
1319
|
void this.agent.invoke_enable({});
|
|
1320
1320
|
}
|
|
1321
1321
|
|
|
1322
|
-
if (Root.Runtime.experiments.isEnabled(
|
|
1322
|
+
if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.CAPTURE_NODE_CREATION_STACKS)) {
|
|
1323
1323
|
void this.agent.invoke_setNodeStackTracesEnabled({enable: true});
|
|
1324
1324
|
}
|
|
1325
1325
|
}
|
|
@@ -653,26 +653,6 @@ export class DebuggerModel extends SDKModel<EventTypes> {
|
|
|
653
653
|
if (this.#expandCallFramesCallback) {
|
|
654
654
|
pausedDetails.callFrames = await this.#expandCallFramesCallback.call(null, pausedDetails.callFrames);
|
|
655
655
|
}
|
|
656
|
-
|
|
657
|
-
if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.USE_SOURCE_MAP_SCOPES)) {
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// TODO(crbug.com/40277685): Support attaching/detaching source maps after pausing.
|
|
662
|
-
// Expanding call frames via source maps here is only suitable for the experiment prototype because
|
|
663
|
-
// we block until all relevant source maps are loaded.
|
|
664
|
-
// We should change this so the "Debugger Plugin" and "Source Map" have a bottle neck where they expand
|
|
665
|
-
// call frames and that bottleneck should support attaching/detaching source maps while paused.
|
|
666
|
-
const finalFrames: CallFrame[] = [];
|
|
667
|
-
for (const frame of pausedDetails.callFrames) {
|
|
668
|
-
const sourceMap = await this.sourceMapManager().sourceMapForClientPromise(frame.script);
|
|
669
|
-
if (sourceMap?.hasScopeInfo()) {
|
|
670
|
-
finalFrames.push(...sourceMap.expandCallFrame(frame));
|
|
671
|
-
} else {
|
|
672
|
-
finalFrames.push(frame);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
pausedDetails.callFrames = finalFrames;
|
|
676
656
|
}
|
|
677
657
|
|
|
678
658
|
resumedScript(): void {
|
|
@@ -707,7 +687,8 @@ export class DebuggerModel extends SDKModel<EventTypes> {
|
|
|
707
687
|
this.registerScript(script);
|
|
708
688
|
this.dispatchEventToListeners(Events.ParsedScriptSource, script);
|
|
709
689
|
|
|
710
|
-
if (
|
|
690
|
+
if ((!selectedDebugSymbol || selectedDebugSymbol.type === Protocol.Debugger.DebugSymbolsType.SourceMap) &&
|
|
691
|
+
script.sourceMapURL && !hasSyntaxError) {
|
|
711
692
|
this.#sourceMapManager.attachSourceMap(script, script.sourceURL, script.sourceMapURL);
|
|
712
693
|
}
|
|
713
694
|
|
|
@@ -534,8 +534,9 @@ export class OverlayModel extends SDKModel<EventTypes> implements ProtocolProxyA
|
|
|
534
534
|
gridHighlightConfig: {},
|
|
535
535
|
flexContainerHighlightConfig: {},
|
|
536
536
|
flexItemHighlightConfig: {},
|
|
537
|
-
contrastAlgorithm: Root.Runtime.experiments.isEnabled(
|
|
538
|
-
|
|
537
|
+
contrastAlgorithm: Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.APCA) ?
|
|
538
|
+
Protocol.Overlay.ContrastAlgorithm.Apca :
|
|
539
|
+
Protocol.Overlay.ContrastAlgorithm.Aa,
|
|
539
540
|
};
|
|
540
541
|
|
|
541
542
|
if (mode === 'all' || mode === 'content') {
|
|
@@ -770,15 +770,6 @@ export class SourceMap {
|
|
|
770
770
|
this.hasIgnoreListHint(sourceURL) === other.hasIgnoreListHint(sourceURL);
|
|
771
771
|
}
|
|
772
772
|
|
|
773
|
-
expandCallFrame(frame: CallFrame): CallFrame[] {
|
|
774
|
-
this.#ensureSourceMapProcessed();
|
|
775
|
-
if (this.#scopesInfo === null) {
|
|
776
|
-
return [frame];
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
return this.#scopesInfo.expandCallFrame(frame);
|
|
780
|
-
}
|
|
781
|
-
|
|
782
773
|
resolveScopeChain(frame: CallFrame): ScopeChainEntry[]|null {
|
|
783
774
|
this.#ensureSourceMapProcessed();
|
|
784
775
|
if (this.#scopesInfo === null) {
|
|
@@ -276,30 +276,6 @@ export class SourceMapScopesInfo {
|
|
|
276
276
|
return result;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
|
-
/**
|
|
280
|
-
* Takes a V8 provided call frame and expands any inlined frames into virtual call frames.
|
|
281
|
-
*
|
|
282
|
-
* For call frames where nothing was inlined, the result contains only a single element,
|
|
283
|
-
* the provided frame but with the original name.
|
|
284
|
-
*
|
|
285
|
-
* For call frames where we are paused in inlined code, this function returns a list of
|
|
286
|
-
* call frames from "inner to outer". This is the call frame at index 0
|
|
287
|
-
* signifies the top of this stack trace fragment.
|
|
288
|
-
*
|
|
289
|
-
* The rest are "virtual" call frames and will have an "inlineFrameIndex" set in ascending
|
|
290
|
-
* order, so the condition `result[index] === result[index].inlineFrameIndex` always holds.
|
|
291
|
-
*/
|
|
292
|
-
expandCallFrame(callFrame: CallFrame): CallFrame[] {
|
|
293
|
-
const {originalFunctionName, inlinedFunctions} =
|
|
294
|
-
this.findInlinedFunctions(callFrame.location().lineNumber, callFrame.location().columnNumber);
|
|
295
|
-
const result: CallFrame[] = [];
|
|
296
|
-
for (const [index, fn] of inlinedFunctions.entries()) {
|
|
297
|
-
result.push(callFrame.createVirtualCallFrame(index, fn.name));
|
|
298
|
-
}
|
|
299
|
-
result.push(callFrame.createVirtualCallFrame(result.length, originalFunctionName));
|
|
300
|
-
return result;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
279
|
/**
|
|
304
280
|
* Given a generated position, this returns all the surrounding generated ranges from outer
|
|
305
281
|
* to inner.
|
|
@@ -58,6 +58,7 @@ import * as PanelCommon from '../../panels/common/common.js';
|
|
|
58
58
|
import * as Snippets from '../../panels/snippets/snippets.js';
|
|
59
59
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
60
60
|
import * as Snackbar from '../../ui/components/snackbars/snackbars.js';
|
|
61
|
+
import * as UIHelpers from '../../ui/helpers/helpers.js';
|
|
61
62
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
62
63
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
63
64
|
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
|
@@ -128,6 +129,10 @@ const UIStrings = {
|
|
|
128
129
|
* @description Notification shown to the user whenever DevTools has finished downloading a local AI model.
|
|
129
130
|
*/
|
|
130
131
|
aiModelDownloaded: 'AI model downloaded',
|
|
132
|
+
/**
|
|
133
|
+
* @description A title of the menu item in the main menu leading to https://github.com/ChromeDevTools/chrome-devtools-mcp.
|
|
134
|
+
*/
|
|
135
|
+
getDevToolsMcp: 'Get `DevTools MCP`'
|
|
131
136
|
} as const;
|
|
132
137
|
const str_ = i18n.i18n.registerUIStrings('entrypoints/main/MainImpl.ts', UIStrings);
|
|
133
138
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
@@ -324,49 +329,59 @@ export class MainImpl {
|
|
|
324
329
|
}
|
|
325
330
|
|
|
326
331
|
#initializeExperiments(): void {
|
|
327
|
-
Root.Runtime.experiments.register('capture-node-creation-stacks', 'Capture node creation stacks');
|
|
328
|
-
Root.Runtime.experiments.register('live-heap-profile', 'Live heap profile');
|
|
329
332
|
Root.Runtime.experiments.register(
|
|
330
|
-
|
|
333
|
+
Root.Runtime.ExperimentName.CAPTURE_NODE_CREATION_STACKS, 'Capture node creation stacks');
|
|
334
|
+
Root.Runtime.experiments.register(Root.Runtime.ExperimentName.LIVE_HEAP_PROFILE, 'Live heap profile');
|
|
335
|
+
Root.Runtime.experiments.register(
|
|
336
|
+
Root.Runtime.ExperimentName.PROTOCOL_MONITOR, 'Protocol Monitor',
|
|
331
337
|
'https://developer.chrome.com/blog/new-in-devtools-92/#protocol-monitor');
|
|
332
|
-
Root.Runtime.experiments.register('sampling-heap-profiler-timeline', 'Sampling heap profiler timeline');
|
|
333
338
|
Root.Runtime.experiments.register(
|
|
334
|
-
|
|
339
|
+
Root.Runtime.ExperimentName.SAMPLING_HEAP_PROFILER_TIMELINE, 'Sampling heap profiler timeline');
|
|
340
|
+
Root.Runtime.experiments.register(
|
|
341
|
+
Root.Runtime.ExperimentName.SHOW_OPTION_TO_EXPOSE_INTERNALS_IN_HEAP_SNAPSHOT,
|
|
342
|
+
'Show option to expose internals in heap snapshots');
|
|
335
343
|
|
|
336
344
|
// Timeline
|
|
337
|
-
Root.Runtime.experiments.register(
|
|
338
|
-
|
|
339
|
-
Root.Runtime.experiments.register(
|
|
345
|
+
Root.Runtime.experiments.register(
|
|
346
|
+
Root.Runtime.ExperimentName.TIMELINE_INVALIDATION_TRACKING, 'Performance panel: invalidation tracking');
|
|
347
|
+
Root.Runtime.experiments.register(
|
|
348
|
+
Root.Runtime.ExperimentName.TIMELINE_SHOW_ALL_EVENTS, 'Performance panel: show all events');
|
|
349
|
+
Root.Runtime.experiments.register(
|
|
350
|
+
Root.Runtime.ExperimentName.TIMELINE_V8_RUNTIME_CALL_STATS, 'Performance panel: V8 runtime call stats');
|
|
340
351
|
Root.Runtime.experiments.register(
|
|
341
352
|
Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE, 'Performance panel: debug mode (trace event details, etc)');
|
|
342
353
|
|
|
343
354
|
// Debugging
|
|
344
|
-
Root.Runtime.experiments.register(
|
|
345
|
-
|
|
355
|
+
Root.Runtime.experiments.register(
|
|
356
|
+
Root.Runtime.ExperimentName.INSTRUMENTATION_BREAKPOINTS, 'Instrumentation breakpoints');
|
|
357
|
+
Root.Runtime.experiments.register(
|
|
358
|
+
Root.Runtime.ExperimentName.USE_SOURCE_MAP_SCOPES, 'Use scope information from source maps');
|
|
346
359
|
|
|
347
360
|
// Advanced Perceptual Contrast Algorithm.
|
|
348
361
|
Root.Runtime.experiments.register(
|
|
349
|
-
|
|
362
|
+
Root.Runtime.ExperimentName.APCA,
|
|
363
|
+
'Advanced Perceptual Contrast Algorithm (APCA) replacing previous contrast ratio and AA/AAA guidelines',
|
|
350
364
|
'https://developer.chrome.com/blog/new-in-devtools-89/#apca');
|
|
351
365
|
|
|
352
366
|
// Full Accessibility Tree
|
|
353
367
|
Root.Runtime.experiments.register(
|
|
354
|
-
|
|
368
|
+
Root.Runtime.ExperimentName.FULL_ACCESSIBILITY_TREE, 'Full accessibility tree view in the Elements panel',
|
|
355
369
|
'https://developer.chrome.com/blog/new-in-devtools-90/#accessibility-tree',
|
|
356
370
|
'https://g.co/devtools/a11y-tree-feedback');
|
|
357
371
|
|
|
358
372
|
// Font Editor
|
|
359
373
|
Root.Runtime.experiments.register(
|
|
360
|
-
|
|
374
|
+
Root.Runtime.ExperimentName.FONT_EDITOR, 'New font editor in the Styles tab',
|
|
361
375
|
'https://developer.chrome.com/blog/new-in-devtools-89/#font');
|
|
362
376
|
|
|
363
377
|
// Contrast issues reported via the Issues panel.
|
|
364
378
|
Root.Runtime.experiments.register(
|
|
365
|
-
|
|
379
|
+
Root.Runtime.ExperimentName.CONTRAST_ISSUES, 'Automatic contrast issue reporting via the Issues panel',
|
|
366
380
|
'https://developer.chrome.com/blog/new-in-devtools-90/#low-contrast');
|
|
367
381
|
|
|
368
382
|
// New cookie features.
|
|
369
|
-
Root.Runtime.experiments.register(
|
|
383
|
+
Root.Runtime.experiments.register(
|
|
384
|
+
Root.Runtime.ExperimentName.EXPERIMENTAL_COOKIE_FEATURES, 'Experimental cookie features');
|
|
370
385
|
|
|
371
386
|
// Change grouping of sources panel to use Authored/Deployed trees
|
|
372
387
|
Root.Runtime.experiments.register(
|
|
@@ -384,7 +399,8 @@ export class MainImpl {
|
|
|
384
399
|
|
|
385
400
|
Root.Runtime.experiments.enableExperimentsByDefault([
|
|
386
401
|
Root.Runtime.ExperimentName.FULL_ACCESSIBILITY_TREE,
|
|
387
|
-
|
|
402
|
+
Root.Runtime.ExperimentName.USE_SOURCE_MAP_SCOPES,
|
|
403
|
+
...(Root.Runtime.Runtime.queryParam('isChromeForTesting') ? [Root.Runtime.ExperimentName.PROTOCOL_MONITOR] : []),
|
|
388
404
|
]);
|
|
389
405
|
|
|
390
406
|
Root.Runtime.experiments.cleanUpStaleExperiments();
|
|
@@ -397,7 +413,7 @@ export class MainImpl {
|
|
|
397
413
|
if (Host.InspectorFrontendHost.isUnderTest()) {
|
|
398
414
|
const testParam = Root.Runtime.Runtime.queryParam('test');
|
|
399
415
|
if (testParam?.includes('live-line-level-heap-profile.js')) {
|
|
400
|
-
Root.Runtime.experiments.enableForTest(
|
|
416
|
+
Root.Runtime.experiments.enableForTest(Root.Runtime.ExperimentName.LIVE_HEAP_PROFILE);
|
|
401
417
|
}
|
|
402
418
|
}
|
|
403
419
|
|
|
@@ -667,7 +683,7 @@ export class MainImpl {
|
|
|
667
683
|
const runnable = await lateInitializationLoader();
|
|
668
684
|
return await runnable.run();
|
|
669
685
|
});
|
|
670
|
-
if (Root.Runtime.experiments.isEnabled(
|
|
686
|
+
if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.LIVE_HEAP_PROFILE)) {
|
|
671
687
|
const PerfUI = await import('../../ui/legacy/components/perf_ui/perf_ui.js');
|
|
672
688
|
const setting = 'memory-live-heap-profile';
|
|
673
689
|
if (Common.Settings.Settings.instance().moduleSetting(setting).get()) {
|
|
@@ -942,6 +958,15 @@ export class MainMenuItem implements UI.Toolbar.Provider {
|
|
|
942
958
|
|
|
943
959
|
contextMenu.defaultSection().appendAction('freestyler.main-menu', undefined, /* optional */ true);
|
|
944
960
|
|
|
961
|
+
contextMenu.defaultSection().appendItem(i18nString(UIStrings.getDevToolsMcp), () => {
|
|
962
|
+
UIHelpers.openInNewTab('https://github.com/ChromeDevTools/chrome-devtools-mcp');
|
|
963
|
+
}, {
|
|
964
|
+
additionalElement: UI.UIUtils.maybeCreateNewBadge('get-devtools-mcp'),
|
|
965
|
+
jslogContext: 'get-devtools-mcp',
|
|
966
|
+
});
|
|
967
|
+
|
|
968
|
+
contextMenu.defaultSection().appendSeparator();
|
|
969
|
+
|
|
945
970
|
if (dockController.dockSide() === UI.DockController.DockState.UNDOCKED) {
|
|
946
971
|
const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
947
972
|
if (mainTarget && mainTarget.type() === SDK.Target.Type.FRAME) {
|
|
@@ -730,14 +730,13 @@ export const generatedProperties = [
|
|
|
730
730
|
"text-emphasis-color",
|
|
731
731
|
"text-emphasis-position",
|
|
732
732
|
"text-emphasis-style",
|
|
733
|
-
"text-
|
|
733
|
+
"text-fit",
|
|
734
734
|
"text-indent",
|
|
735
735
|
"text-justify",
|
|
736
736
|
"text-orientation",
|
|
737
737
|
"text-overflow",
|
|
738
738
|
"text-rendering",
|
|
739
739
|
"text-shadow",
|
|
740
|
-
"text-shrink",
|
|
741
740
|
"text-size-adjust",
|
|
742
741
|
"text-spacing-trim",
|
|
743
742
|
"text-transform",
|
|
@@ -4440,7 +4439,7 @@ export const generatedProperties = [
|
|
|
4440
4439
|
"name": "text-emphasis-style"
|
|
4441
4440
|
},
|
|
4442
4441
|
{
|
|
4443
|
-
"name": "text-
|
|
4442
|
+
"name": "text-fit"
|
|
4444
4443
|
},
|
|
4445
4444
|
{
|
|
4446
4445
|
"inherited": true,
|
|
@@ -4489,9 +4488,6 @@ export const generatedProperties = [
|
|
|
4489
4488
|
],
|
|
4490
4489
|
"name": "text-shadow"
|
|
4491
4490
|
},
|
|
4492
|
-
{
|
|
4493
|
-
"name": "text-shrink"
|
|
4494
|
-
},
|
|
4495
4491
|
{
|
|
4496
4492
|
"inherited": true,
|
|
4497
4493
|
"keywords": [
|