chrome-devtools-frontend 1.0.1571007 → 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.
Files changed (65) hide show
  1. package/agents/prompts/README.md +18 -0
  2. package/agents/prompts/devtools-imports.md +47 -0
  3. package/agents/prompts/verification.md +27 -0
  4. package/front_end/core/host/UserMetrics.ts +1 -1
  5. package/front_end/core/root/Runtime.ts +48 -34
  6. package/front_end/core/sdk/CSSProperty.ts +1 -1
  7. package/front_end/core/sdk/CookieModel.ts +1 -1
  8. package/front_end/core/sdk/DOMModel.ts +1 -1
  9. package/front_end/core/sdk/OverlayModel.ts +3 -2
  10. package/front_end/entrypoints/main/MainImpl.ts +29 -18
  11. package/front_end/generated/SupportedCSSProperties.js +2 -6
  12. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +2 -2
  13. package/front_end/models/javascript_metadata/NativeFunctions.js +8 -0
  14. package/front_end/models/trace/ModelImpl.ts +0 -4
  15. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -1
  16. package/front_end/panels/ai_assistance/PatchWidget.ts +10 -15
  17. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +5 -4
  18. package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -2
  19. package/front_end/panels/application/FrameDetailsView.ts +2 -1
  20. package/front_end/panels/application/components/ReportsGrid.ts +2 -1
  21. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +3 -5
  22. package/front_end/panels/common/AiCodeCompletionTeaser.ts +5 -5
  23. package/front_end/panels/console/ConsoleInsightTeaser.ts +10 -11
  24. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
  25. package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
  26. package/front_end/panels/elements/ComputedStyleModel.ts +11 -13
  27. package/front_end/panels/elements/ComputedStyleWidget.ts +3 -3
  28. package/front_end/panels/elements/ElementsPanel.ts +5 -2
  29. package/front_end/panels/elements/ElementsSidebarPane.ts +1 -1
  30. package/front_end/panels/elements/PlatformFontsWidget.ts +1 -1
  31. package/front_end/panels/elements/StylePropertiesSection.ts +1 -1
  32. package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
  33. package/front_end/panels/emulation/DeviceModeWrapper.ts +101 -62
  34. package/front_end/panels/explain/components/ConsoleInsight.ts +27 -23
  35. package/front_end/panels/explain/components/consoleInsight.css +1 -1
  36. package/front_end/panels/network/RequestTimingView.ts +4 -3
  37. package/front_end/panels/network/components/RequestHeadersView.css +2 -2
  38. package/front_end/panels/network/components/RequestHeadersView.ts +7 -6
  39. package/front_end/panels/profiler/HeapProfileView.ts +3 -3
  40. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
  41. package/front_end/panels/recorder/RecorderController.ts +6 -7
  42. package/front_end/panels/recorder/recorderController.css +1 -1
  43. package/front_end/panels/security/CookieControlsView.ts +2 -2
  44. package/front_end/panels/security/CookieReportView.ts +7 -7
  45. package/front_end/panels/settings/AISettingsTab.ts +5 -5
  46. package/front_end/panels/settings/components/SyncSection.ts +4 -3
  47. package/front_end/panels/sources/CallStackSidebarPane.ts +4 -1
  48. package/front_end/panels/sources/NavigatorView.ts +1 -1
  49. package/front_end/panels/sources/SourcesPanel.ts +3 -1
  50. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +1 -1
  51. package/front_end/panels/timeline/ThreadAppender.ts +1 -1
  52. package/front_end/panels/timeline/TimelineController.ts +4 -3
  53. package/front_end/panels/timeline/TimelinePanel.ts +4 -3
  54. package/front_end/panels/whats_new/ReleaseNoteView.ts +4 -3
  55. package/front_end/third_party/chromium/README.chromium +1 -1
  56. package/front_end/ui/components/markdown_view/CodeBlock.ts +3 -6
  57. package/front_end/ui/components/markdown_view/MarkdownLink.ts +3 -4
  58. package/front_end/ui/components/panel_feedback/PanelFeedback.ts +3 -4
  59. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +9 -6
  60. package/front_end/ui/components/panel_feedback/panelFeedback.css +2 -2
  61. package/front_end/ui/kit/link/Link.ts +1 -14
  62. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -1
  63. package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +5 -4
  64. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -1
  65. 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.
@@ -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-tp-expose-internals-in-heap-snapshot' = 18,
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 && experiment.startsWith('!') && experiments.isEnabled(experiment.substring(1))) {
123
- return false;
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('!') && !experiments.isEnabled(experiment)) {
126
- return false;
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<string>();
155
- readonly #enabledTransiently = new Set<string>();
156
- readonly #enabledByDefault = new Set<string>();
157
- readonly #serverEnabled = new Set<string>();
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: string, experimentTitle: string, docLink?: string, feedbackLink?: string): void {
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: string): boolean {
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: string, enabled: boolean): void {
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: string[]): void {
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: string[]): void {
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(experimentNames: string[]): void {
218
- for (const experiment of experimentNames) {
219
- this.checkExperiment(experiment);
220
- this.#serverEnabled.add(experiment);
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: string): void {
231
+ enableForTest(experimentName: ExperimentName): void {
225
232
  this.checkExperiment(experimentName);
226
233
  this.#enabledTransiently.add(experimentName);
227
234
  }
228
235
 
229
- disableForTest(experimentName: string): void {
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: string): void {
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: string): boolean|undefined {
281
+ get(experimentName: ExperimentName): boolean|undefined {
275
282
  return this.#experiments[experimentName];
276
283
  }
277
284
 
278
- set(experimentName: string, enabled: boolean): void {
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: string;
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: string, title: string, docLink: Platform.DevToolsPath.UrlString,
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
- * @deprecated Experiments should not be used anymore, instead use base::Feature.
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
- HEADER_OVERRIDES = 'header-overrides',
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. REGISTERED_EXPERIMENTS in EnvironmentHelpers.ts (to create this experiment in the test env)
346
- // 2. DevToolsExperiments enum in host/UserMetrics.ts
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 {
@@ -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('font-editor')) {
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('experimental-cookie-features');
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('capture-node-creation-stacks')) {
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
  }
@@ -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('apca') ? Protocol.Overlay.ContrastAlgorithm.Apca :
538
- Protocol.Overlay.ContrastAlgorithm.Aa,
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') {
@@ -329,49 +329,59 @@ export class MainImpl {
329
329
  }
330
330
 
331
331
  #initializeExperiments(): void {
332
- Root.Runtime.experiments.register('capture-node-creation-stacks', 'Capture node creation stacks');
333
- Root.Runtime.experiments.register('live-heap-profile', 'Live heap profile');
334
332
  Root.Runtime.experiments.register(
335
- 'protocol-monitor', 'Protocol Monitor',
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',
336
337
  'https://developer.chrome.com/blog/new-in-devtools-92/#protocol-monitor');
337
- Root.Runtime.experiments.register('sampling-heap-profiler-timeline', 'Sampling heap profiler timeline');
338
338
  Root.Runtime.experiments.register(
339
- 'show-option-tp-expose-internals-in-heap-snapshot', 'Show option to expose internals in heap snapshots');
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');
340
343
 
341
344
  // Timeline
342
- Root.Runtime.experiments.register('timeline-invalidation-tracking', 'Performance panel: invalidation tracking');
343
- Root.Runtime.experiments.register('timeline-show-all-events', 'Performance panel: show all events');
344
- Root.Runtime.experiments.register('timeline-v8-runtime-call-stats', 'Performance panel: V8 runtime call stats');
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');
345
351
  Root.Runtime.experiments.register(
346
352
  Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE, 'Performance panel: debug mode (trace event details, etc)');
347
353
 
348
354
  // Debugging
349
- Root.Runtime.experiments.register('instrumentation-breakpoints', 'Instrumentation breakpoints');
350
- Root.Runtime.experiments.register('use-source-map-scopes', 'Use scope information from source maps');
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');
351
359
 
352
360
  // Advanced Perceptual Contrast Algorithm.
353
361
  Root.Runtime.experiments.register(
354
- 'apca', 'Advanced Perceptual Contrast Algorithm (APCA) replacing previous contrast ratio and AA/AAA guidelines',
362
+ Root.Runtime.ExperimentName.APCA,
363
+ 'Advanced Perceptual Contrast Algorithm (APCA) replacing previous contrast ratio and AA/AAA guidelines',
355
364
  'https://developer.chrome.com/blog/new-in-devtools-89/#apca');
356
365
 
357
366
  // Full Accessibility Tree
358
367
  Root.Runtime.experiments.register(
359
- 'full-accessibility-tree', 'Full accessibility tree view in the Elements panel',
368
+ Root.Runtime.ExperimentName.FULL_ACCESSIBILITY_TREE, 'Full accessibility tree view in the Elements panel',
360
369
  'https://developer.chrome.com/blog/new-in-devtools-90/#accessibility-tree',
361
370
  'https://g.co/devtools/a11y-tree-feedback');
362
371
 
363
372
  // Font Editor
364
373
  Root.Runtime.experiments.register(
365
- 'font-editor', 'New font editor in the Styles tab',
374
+ Root.Runtime.ExperimentName.FONT_EDITOR, 'New font editor in the Styles tab',
366
375
  'https://developer.chrome.com/blog/new-in-devtools-89/#font');
367
376
 
368
377
  // Contrast issues reported via the Issues panel.
369
378
  Root.Runtime.experiments.register(
370
- 'contrast-issues', 'Automatic contrast issue reporting via the Issues panel',
379
+ Root.Runtime.ExperimentName.CONTRAST_ISSUES, 'Automatic contrast issue reporting via the Issues panel',
371
380
  'https://developer.chrome.com/blog/new-in-devtools-90/#low-contrast');
372
381
 
373
382
  // New cookie features.
374
- Root.Runtime.experiments.register('experimental-cookie-features', 'Experimental cookie features');
383
+ Root.Runtime.experiments.register(
384
+ Root.Runtime.ExperimentName.EXPERIMENTAL_COOKIE_FEATURES, 'Experimental cookie features');
375
385
 
376
386
  // Change grouping of sources panel to use Authored/Deployed trees
377
387
  Root.Runtime.experiments.register(
@@ -389,7 +399,8 @@ export class MainImpl {
389
399
 
390
400
  Root.Runtime.experiments.enableExperimentsByDefault([
391
401
  Root.Runtime.ExperimentName.FULL_ACCESSIBILITY_TREE,
392
- ...(Root.Runtime.Runtime.queryParam('isChromeForTesting') ? ['protocol-monitor'] : []),
402
+ Root.Runtime.ExperimentName.USE_SOURCE_MAP_SCOPES,
403
+ ...(Root.Runtime.Runtime.queryParam('isChromeForTesting') ? [Root.Runtime.ExperimentName.PROTOCOL_MONITOR] : []),
393
404
  ]);
394
405
 
395
406
  Root.Runtime.experiments.cleanUpStaleExperiments();
@@ -402,7 +413,7 @@ export class MainImpl {
402
413
  if (Host.InspectorFrontendHost.isUnderTest()) {
403
414
  const testParam = Root.Runtime.Runtime.queryParam('test');
404
415
  if (testParam?.includes('live-line-level-heap-profile.js')) {
405
- Root.Runtime.experiments.enableForTest('live-heap-profile');
416
+ Root.Runtime.experiments.enableForTest(Root.Runtime.ExperimentName.LIVE_HEAP_PROFILE);
406
417
  }
407
418
  }
408
419
 
@@ -672,7 +683,7 @@ export class MainImpl {
672
683
  const runnable = await lateInitializationLoader();
673
684
  return await runnable.run();
674
685
  });
675
- if (Root.Runtime.experiments.isEnabled('live-heap-profile')) {
686
+ if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.LIVE_HEAP_PROFILE)) {
676
687
  const PerfUI = await import('../../ui/legacy/components/perf_ui/perf_ui.js');
677
688
  const setting = 'memory-live-heap-profile';
678
689
  if (Common.Settings.Settings.instance().moduleSetting(setting).get()) {
@@ -730,14 +730,13 @@ export const generatedProperties = [
730
730
  "text-emphasis-color",
731
731
  "text-emphasis-position",
732
732
  "text-emphasis-style",
733
- "text-grow",
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-grow"
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": [
@@ -45,7 +45,7 @@ export class ContrastCheckTrigger {
45
45
  }
46
46
 
47
47
  #checkContrast(resourceTreeModel: SDK.ResourceTreeModel.ResourceTreeModel): void {
48
- if (!Root.Runtime.experiments.isEnabled('contrast-issues')) {
48
+ if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.CONTRAST_ISSUES)) {
49
49
  return;
50
50
  }
51
51
  void resourceTreeModel.target().auditsAgent().invoke_checkContrast({});
@@ -60,7 +60,7 @@ export class ContrastCheckTrigger {
60
60
 
61
61
  async #frameAdded(event: Common.EventTarget.EventTargetEvent<SDK.ResourceTreeModel.ResourceTreeFrame>):
62
62
  Promise<void> {
63
- if (!Root.Runtime.experiments.isEnabled('contrast-issues')) {
63
+ if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.CONTRAST_ISSUES)) {
64
64
  return;
65
65
  }
66
66
  const frame = event.data;
@@ -6594,6 +6594,14 @@ export const NativeFunctions = [
6594
6594
  name: "setHTML",
6595
6595
  signatures: [["html","?options"]]
6596
6596
  },
6597
+ {
6598
+ name: "streamAppendHTMLUnsafe",
6599
+ signatures: [["?options"]]
6600
+ },
6601
+ {
6602
+ name: "streamHTMLUnsafe",
6603
+ signatures: [["?options"]]
6604
+ },
6597
6605
  {
6598
6606
  name: "scrollIntoViewIfNeeded",
6599
6607
  signatures: [["?centerIfNeeded"]]
@@ -10,10 +10,6 @@ import type * as Insights from './insights/insights.js';
10
10
  import {TraceParseProgressEvent, TraceProcessor} from './Processor.js';
11
11
  import * as Types from './types/types.js';
12
12
 
13
- // Note: this model is implemented in a way that can support multiple trace
14
- // processors. Currently there is only one implemented, but you will see
15
- // references to "processors" plural because it can easily be extended in the future.
16
-
17
13
  /**
18
14
  * The Model is responsible for parsing arrays of raw trace events and storing the
19
15
  * resulting data. It can store multiple traces at once, and can return the data for
@@ -95,7 +95,7 @@ export class AccessibilitySidebarView extends UI.Widget.VBox {
95
95
  if (!accessibilityModel) {
96
96
  return;
97
97
  }
98
- if (!Root.Runtime.experiments.isEnabled('full-accessibility-tree')) {
98
+ if (!Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.FULL_ACCESSIBILITY_TREE)) {
99
99
  accessibilityModel.clear();
100
100
  }
101
101
  await accessibilityModel.requestPartialAXTree(node);
@@ -5,6 +5,7 @@
5
5
  import '../../ui/legacy/legacy.js';
6
6
  import '../../ui/components/markdown_view/markdown_view.js';
7
7
  import '../../ui/components/spinners/spinners.js';
8
+ import '../../ui/kit/kit.js';
8
9
 
9
10
  import * as Common from '../../core/common/common.js';
10
11
  import * as Host from '../../core/host/host.js';
@@ -200,15 +201,13 @@ const DEFAULT_VIEW: View = (input, output, target) => {
200
201
  return nothing;
201
202
  }
202
203
 
203
- return html`<x-link
204
+ return html`<devtools-link
204
205
  class="link"
205
206
  title="${UIStringsNotTranslate.viewUploadedFiles} ${UIStringsNotTranslate.opensInNewTab}"
206
207
  href="data:text/plain;charset=utf-8,${encodeURIComponent(input.sources)}"
207
- jslog=${VisualLogging.link('files-used-in-patching').track({
208
- click: true
209
- })}>
208
+ .jslogContext=${'files-used-in-patching'}>
210
209
  ${UIStringsNotTranslate.viewUploadedFiles}
211
- </x-link>`;
210
+ </devtools-link>`;
212
211
  }
213
212
 
214
213
  function renderHeader(): LitTemplate {
@@ -297,12 +296,10 @@ const DEFAULT_VIEW: View = (input, output, target) => {
297
296
  return html`
298
297
  <div class="footer">
299
298
  <div class="left-side">
300
- <x-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" jslog=${
301
- VisualLogging.link('code-disclaimer').track({
302
- click: true,
303
- })}>
299
+ <devtools-link class="link disclaimer-link" href="https://support.google.com/legal/answer/13505487" .jslogContext=${
300
+ 'code-disclaimer'}>
304
301
  ${lockedString(UIStringsNotTranslate.codeDisclaimer)}
305
- </x-link>
302
+ </devtools-link>
306
303
  ${renderSourcesLink()}
307
304
  </div>
308
305
  <div class="save-or-discard-buttons">
@@ -575,13 +572,11 @@ export class PatchWidget extends UI.Widget.Widget {
575
572
  {
576
573
  iconName: 'warning',
577
574
  // clang-format off
578
- content: html`<x-link
575
+ content: html`<devtools-link
579
576
  href=${CODE_SNIPPET_WARNING_URL}
580
577
  class="link devtools-link"
581
- jslog=${VisualLogging.link('code-snippets-explainer.patch-widget').track({
582
- click: true
583
- })}
584
- >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</x-link>`,
578
+ .jslogContext=${'code-snippets-explainer.patch-widget'}
579
+ >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
585
580
  // clang-format on
586
581
  }
587
582
  ],
@@ -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 '../../ui/kit/kit.js';
6
+
5
7
  import * as Common from '../../core/common/common.js';
6
8
  import * as Host from '../../core/host/host.js';
7
9
  import * as i18n from '../../core/i18n/i18n.js';
@@ -13,7 +15,6 @@ import * as Workspace from '../../models/workspace/workspace.js';
13
15
  import * as Buttons from '../../ui/components/buttons/buttons.js';
14
16
  import * as UI from '../../ui/legacy/legacy.js';
15
17
  import {html, nothing, render} from '../../ui/lit/lit.js';
16
- import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
17
18
 
18
19
  import selectWorkspaceDialogStyles from './selectWorkspaceDialog.css.js';
19
20
 
@@ -89,11 +90,11 @@ export const SELECT_WORKSPACE_DIALOG_DEFAULT_VIEW: View = (input, _output, targe
89
90
  <!-- Hardcoding, because there is no 'getFormatLocalizedString' equivalent for 'lockedString' -->
90
91
  <div>
91
92
  Tip: provide a
92
- <x-link
93
+ <devtools-link
93
94
  class="devtools-link"
94
95
  href="https://goo.gle/devtools-automatic-workspace-folders"
95
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('automatic-workspaces-documentation')}
96
- >com.chrome.devtools.json</x-link>
96
+ .jslogContext=${'automatic-workspaces-documentation'}
97
+ >com.chrome.devtools.json</devtools-link>
97
98
  file to automatically connect your project to DevTools.
98
99
  </div>
99
100
  ` : nothing}
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import '../../../ui/components/markdown_view/markdown_view.js';
6
+ import '../../../ui/kit/kit.js';
6
7
 
7
8
  import * as Common from '../../../core/common/common.js';
8
9
  import * as Host from '../../../core/host/host.js';
@@ -576,12 +577,12 @@ function renderImageChatMessage(inlineData: Host.AidaClient.MediaBlob): Lit.LitT
576
577
  }
577
578
  const imageUrl = `data:${inlineData.mimeType};base64,${inlineData.data}`;
578
579
  // clang-format off
579
- return html`<x-link
580
+ return html`<devtools-link
580
581
  class="image-link" title=${UIStringsNotTranslate.openImageInNewTab}
581
582
  href=${imageUrl}
582
583
  >
583
584
  <img src=${imageUrl} alt=${UIStringsNotTranslate.imageInputSentToTheModel} />
584
- </x-link>`;
585
+ </devtools-link>`;
585
586
  // clang-format on
586
587
  }
587
588