chrome-devtools-frontend 1.0.1571573 → 1.0.1573331

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 (158) hide show
  1. package/front_end/Images/geminiInDevTools.png +0 -0
  2. package/front_end/Images/geminiInDevTools_2x.png +0 -0
  3. package/front_end/Images/src/database-off.svg +1 -0
  4. package/front_end/Images/src/lock-person.svg +1 -1
  5. package/front_end/core/common/Debouncer.ts +10 -1
  6. package/front_end/core/common/SettingRegistration.ts +1 -1
  7. package/front_end/core/host/AidaClient.ts +8 -0
  8. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -6
  9. package/front_end/core/host/UserMetrics.ts +0 -30
  10. package/front_end/core/root/ExperimentNames.ts +30 -0
  11. package/front_end/core/root/Runtime.ts +12 -27
  12. package/front_end/core/root/root.ts +2 -0
  13. package/front_end/core/sdk/CSSModel.ts +36 -13
  14. package/front_end/core/sdk/CSSProperty.ts +1 -1
  15. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +9 -0
  16. package/front_end/core/sdk/CookieModel.ts +2 -1
  17. package/front_end/core/sdk/DOMModel.ts +1 -1
  18. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  19. package/front_end/core/sdk/IsolateManager.ts +0 -7
  20. package/front_end/core/sdk/OverlayModel.ts +1 -1
  21. package/front_end/core/sdk/SourceMap.ts +1 -1
  22. package/front_end/devtools_compatibility.js +0 -6
  23. package/front_end/entrypoints/main/MainImpl.ts +34 -25
  24. package/front_end/entrypoints/main/main-meta.ts +1 -1
  25. package/front_end/generated/SupportedCSSProperties.js +4 -8
  26. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +0 -180
  27. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +7 -7
  28. package/front_end/models/ai_assistance/agents/StylingAgent.ts +4 -4
  29. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  30. package/front_end/models/breakpoints/BreakpointManager.ts +3 -3
  31. package/front_end/models/issues_manager/ContrastCheckTrigger.ts +2 -2
  32. package/front_end/models/source_map_scopes/NamesResolver.ts +1 -1
  33. package/front_end/models/trace/EventsSerializer.ts +5 -1
  34. package/front_end/models/trace/types/TraceEvents.ts +4 -0
  35. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +1 -1
  36. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -1
  37. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -63
  38. package/front_end/panels/ai_assistance/PatchWidget.ts +3 -4
  39. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +1 -1
  40. package/front_end/panels/ai_assistance/aiAssistancePanel.css +0 -16
  41. package/front_end/panels/ai_assistance/ai_assistance.ts +0 -1
  42. package/front_end/panels/ai_assistance/components/ChatView.ts +123 -108
  43. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +1 -145
  44. package/front_end/panels/application/AppManifestView.ts +5 -5
  45. package/front_end/panels/application/DeviceBoundSessionsModel.ts +55 -4
  46. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +46 -1
  47. package/front_end/panels/application/FrameDetailsView.ts +10 -10
  48. package/front_end/panels/application/components/BackForwardCacheView.ts +6 -8
  49. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +4 -3
  50. package/front_end/panels/application/components/ProtocolHandlersView.ts +5 -6
  51. package/front_end/panels/application/components/ReportsGrid.ts +8 -9
  52. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +5 -4
  53. package/front_end/panels/application/components/TrustTokensView.ts +4 -6
  54. package/front_end/panels/application/preloading/PreloadingView.ts +9 -8
  55. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +237 -230
  56. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +3 -2
  57. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +6 -10
  58. package/front_end/panels/application/resourcesSidebar.css +8 -0
  59. package/front_end/panels/autofill/AutofillView.ts +4 -3
  60. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +1 -1
  61. package/front_end/panels/common/AiCodeCompletionTeaser.ts +1 -1
  62. package/front_end/panels/common/AiCodeGenerationTeaser.ts +35 -4
  63. package/front_end/panels/common/AiCodeGenerationUpgradeDialog.ts +2 -2
  64. package/front_end/panels/common/BadgeNotification.ts +18 -14
  65. package/front_end/panels/common/GdpSignUpDialog.ts +5 -6
  66. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +192 -0
  67. package/front_end/panels/common/aiCodeGenerationTeaser.css +16 -1
  68. package/front_end/panels/common/common.ts +1 -0
  69. package/front_end/panels/common/geminiRebrandPromoDialog.css +47 -0
  70. package/front_end/panels/console/ConsoleInsightTeaser.ts +3 -3
  71. package/front_end/panels/console/ErrorStackParser.ts +11 -16
  72. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
  73. package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
  74. package/front_end/panels/elements/ComputedStyleModel.ts +7 -54
  75. package/front_end/panels/elements/ElementsPanel.ts +33 -6
  76. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  77. package/front_end/panels/elements/StylePropertiesSection.ts +16 -8
  78. package/front_end/panels/elements/StylePropertyTreeElement.ts +67 -32
  79. package/front_end/panels/elements/StylesSidebarPane.ts +28 -11
  80. package/front_end/panels/elements/components/CSSHintDetailsView.ts +3 -2
  81. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +3 -2
  82. package/front_end/panels/elements/elements-meta.ts +1 -1
  83. package/front_end/panels/explain/components/ConsoleInsight.ts +7 -7
  84. package/front_end/panels/issues/IssueView.ts +6 -6
  85. package/front_end/panels/network/RequestConditionsDrawer.ts +8 -7
  86. package/front_end/panels/network/RequestCookiesView.ts +3 -4
  87. package/front_end/panels/network/RequestTimingView.ts +3 -8
  88. package/front_end/panels/network/components/HeaderSectionRow.ts +3 -2
  89. package/front_end/panels/network/components/RequestHeaderSection.ts +3 -1
  90. package/front_end/panels/network/components/RequestHeadersView.ts +2 -2
  91. package/front_end/panels/profiler/HeapProfileView.ts +3 -3
  92. package/front_end/panels/profiler/HeapSnapshotView.ts +1 -1
  93. package/front_end/panels/profiler/IsolateSelector.ts +1 -2
  94. package/front_end/panels/profiler/profiler-meta.ts +3 -3
  95. package/front_end/panels/protocol_monitor/protocol_monitor-meta.ts +1 -1
  96. package/front_end/panels/recorder/RecorderController.ts +4 -9
  97. package/front_end/panels/recorder/components/CreateRecordingView.ts +6 -6
  98. package/front_end/panels/recorder/components/RecordingView.ts +0 -38
  99. package/front_end/panels/recorder/components/ReplaySection.ts +0 -14
  100. package/front_end/panels/recorder/components/StepEditor.ts +2 -40
  101. package/front_end/panels/recorder/recorderController.css +3 -3
  102. package/front_end/panels/security/CookieReportView.ts +17 -17
  103. package/front_end/panels/security/cookieControlsView.css +1 -1
  104. package/front_end/panels/security/cookieReportView.css +1 -1
  105. package/front_end/panels/settings/AISettingsTab.ts +8 -10
  106. package/front_end/panels/settings/components/SyncSection.ts +1 -1
  107. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +4 -12
  108. package/front_end/panels/settings/settings-meta.ts +1 -1
  109. package/front_end/panels/sources/BreakpointEditDialog.ts +4 -3
  110. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +1 -1
  111. package/front_end/panels/sources/NavigatorView.ts +4 -4
  112. package/front_end/panels/sources/SourcesPanel.ts +5 -4
  113. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  114. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +3 -2
  115. package/front_end/panels/timeline/ThreadAppender.ts +2 -1
  116. package/front_end/panels/timeline/TimelineController.ts +3 -3
  117. package/front_end/panels/timeline/TimelinePanel.ts +6 -4
  118. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -2
  119. package/front_end/panels/timeline/components/ExportTraceOptions.ts +4 -4
  120. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +13 -6
  121. package/front_end/panels/timeline/components/LiveMetricsView.ts +13 -9
  122. package/front_end/panels/timeline/components/exportTraceOptions.css +1 -1
  123. package/front_end/panels/timeline/components/fieldSettingsDialog.css +1 -1
  124. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -19
  125. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +3 -4
  126. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +0 -5
  127. package/front_end/panels/timeline/components/liveMetricsView.css +1 -1
  128. package/front_end/panels/whats_new/ReleaseNoteView.ts +1 -1
  129. package/front_end/third_party/chromium/README.chromium +1 -1
  130. package/front_end/ui/components/buttons/button.css +4 -0
  131. package/front_end/ui/components/markdown_view/CodeBlock.ts +1 -1
  132. package/front_end/ui/components/panel_feedback/PanelFeedback.ts +1 -1
  133. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +5 -5
  134. package/front_end/ui/components/panel_feedback/previewToggle.css +2 -2
  135. package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +27 -8
  136. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +36 -6
  137. package/front_end/ui/components/text_editor/AutocompleteHistory.ts +33 -1
  138. package/front_end/ui/legacy/ActionRegistration.ts +1 -1
  139. package/front_end/ui/legacy/ContextMenu.ts +2 -2
  140. package/front_end/ui/legacy/EmptyWidget.ts +3 -3
  141. package/front_end/ui/legacy/LinkContextMenuProvider.ts +42 -0
  142. package/front_end/ui/legacy/ViewRegistration.ts +1 -1
  143. package/front_end/ui/legacy/XLink.ts +0 -27
  144. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -1
  145. package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +4 -4
  146. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -2
  147. package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +1 -1
  148. package/front_end/ui/legacy/inspectorCommon.css +2 -1
  149. package/front_end/ui/legacy/legacy.ts +3 -1
  150. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  151. package/front_end/ui/visual_logging/LoggingDriver.ts +3 -0
  152. package/package.json +1 -1
  153. package/front_end/models/ai_assistance/ArtifactsManager.ts +0 -67
  154. package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +0 -183
  155. package/front_end/panels/ai_assistance/components/CollapsibleAssistanceContentWidget.ts +0 -89
  156. package/front_end/panels/ai_assistance/components/PerformanceAgentFlameChart.ts +0 -133
  157. package/front_end/panels/ai_assistance/components/artifactsViewer.css +0 -15
  158. package/front_end/panels/ai_assistance/components/collapsibleAssistanceContentWidget.css +0 -32
@@ -505,7 +505,7 @@ export class TimelineUIUtils {
505
505
  static getGetDebugModeEnabled(): boolean {
506
506
  if (TimelineUIUtils.debugModeEnabled === undefined) {
507
507
  TimelineUIUtils.debugModeEnabled =
508
- Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE);
508
+ Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.TIMELINE_DEBUG_MODE);
509
509
  }
510
510
  return TimelineUIUtils.debugModeEnabled;
511
511
  }
@@ -1527,7 +1527,7 @@ export class TimelineUIUtils {
1527
1527
  await TimelineUIUtils.generateCauses(event, contentHelper, parsedTrace);
1528
1528
  }
1529
1529
 
1530
- if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.TIMELINE_DEBUG_MODE)) {
1530
+ if (Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.TIMELINE_DEBUG_MODE)) {
1531
1531
  TimelineUIUtils.renderEventJson(event, contentHelper);
1532
1532
  }
1533
1533
 
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
+ import '../../../ui/kit/kit.js';
6
7
  import '../../../ui/components/tooltips/tooltips.js';
7
8
  import '../../../ui/components/buttons/buttons.js';
8
9
 
@@ -14,7 +15,6 @@ import * as Dialogs from '../../../ui/components/dialogs/dialogs.js';
14
15
  import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
15
16
  import * as UI from '../../../ui/legacy/legacy.js';
16
17
  import * as Lit from '../../../ui/lit/lit.js';
17
- import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
18
18
 
19
19
  import exportTraceOptionsStyles from './exportTraceOptions.css.js';
20
20
 
@@ -299,12 +299,12 @@ export class ExportTraceOptions extends HTMLElement {
299
299
  ${this.#renderCheckbox('compress-with-gzip', this.#shouldCompressCheckbox, i18nString(UIStrings.shouldCompress), this.#state.shouldCompress)}
300
300
  <div class='export-trace-options-row export-trace-options-row-last'>
301
301
  <div class="export-trace-explanation">
302
- <x-link
302
+ <devtools-link
303
303
  href="https://developer.chrome.com/docs/devtools/performance/save-trace"
304
304
  class=devtools-link
305
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('save-trace-explanation')}>
305
+ .jslogContext=${'save-trace-explanation'}>
306
306
  ${i18nString(UIStrings.explanation)}
307
- </x-link>
307
+ </devtools-link>
308
308
  </div>
309
309
  <devtools-button
310
310
  class="setup-button"
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
+ import '../../../ui/kit/kit.js';
6
7
  import './OriginMap.js';
7
8
 
8
9
  import * as i18n from '../../../core/i18n/i18n.js';
@@ -12,7 +13,6 @@ import * as Dialogs from '../../../ui/components/dialogs/dialogs.js';
12
13
  import * as ComponentHelpers from '../../../ui/components/helpers/helpers.js';
13
14
  import * as Input from '../../../ui/components/input/input.js';
14
15
  import * as uiI18n from '../../../ui/i18n/i18n.js';
15
- import * as UI from '../../../ui/legacy/legacy.js';
16
16
  import * as Lit from '../../../ui/lit/lit.js';
17
17
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
18
18
 
@@ -332,10 +332,6 @@ export class FieldSettingsDialog extends HTMLElement {
332
332
  }
333
333
 
334
334
  #render = (): void => {
335
- const linkEl =
336
- UI.XLink.XLink.create('https://developer.chrome.com/docs/crux', i18n.i18n.lockedString('Chrome UX Report'));
337
- const descriptionEl = uiI18n.getFormatLocalizedString(str_, UIStrings.fetchAggregated, {PH1: linkEl});
338
-
339
335
  // clang-format off
340
336
  const output = html`
341
337
  <style>${fieldSettingsDialogStyles}</style>
@@ -356,7 +352,18 @@ export class FieldSettingsDialog extends HTMLElement {
356
352
  })}
357
353
  >
358
354
  <div class="content">
359
- <div>${descriptionEl}</div>
355
+ <div>
356
+ ${uiI18n.getFormatLocalizedStringTemplate(
357
+ str_,
358
+ UIStrings.fetchAggregated,
359
+ {
360
+ PH1: html`<devtools-link
361
+ href="https://developer.chrome.com/docs/crux"
362
+ >${i18n.i18n.lockedString('Chrome UX Report')}</devtools-link
363
+ >`,
364
+ },
365
+ )}
366
+ </div>
360
367
  <div class="privacy-disclosure">
361
368
  <h3 class="section-title">${i18nString(UIStrings.privacyDisclosure)}</h3>
362
369
  <div>${i18nString(UIStrings.whenPerformanceIsShown)}</div>
@@ -867,10 +867,10 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
867
867
  tmp.searchParams.set('device', device);
868
868
  const cruxVis = `${tmp.origin}/#/${tmp.search}`;
869
869
  return html`
870
- (<x-link href=${cruxVis}
870
+ (<devtools-link href=${cruxVis}
871
871
  class="local-field-link"
872
872
  title=${i18nString(UIStrings.fieldDataHistoryTooltip)}
873
- >${i18nString(UIStrings.fieldDataHistoryLink)}</x-link>)
873
+ >${i18nString(UIStrings.fieldDataHistoryLink)}</devtools-link>)
874
874
  `;
875
875
  }
876
876
 
@@ -904,13 +904,17 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
904
904
  return this.#renderCollectionPeriod();
905
905
  }
906
906
 
907
- const linkEl =
908
- UI.XLink.XLink.create('https://developer.chrome.com/docs/crux', i18n.i18n.lockedString('Chrome UX Report'));
909
- const messageEl = uiI18n.getFormatLocalizedString(str_, UIStrings.seeHowYourLocalMetricsCompare, {PH1: linkEl});
910
-
907
+ // clang-format off
911
908
  return html`
912
- <div class="field-data-message">${messageEl}</div>
909
+ <div class="field-data-message">
910
+ ${uiI18n.getFormatLocalizedStringTemplate(
911
+ str_,
912
+ UIStrings.seeHowYourLocalMetricsCompare,
913
+ { PH1: html`<devtools-link href="https://developer.chrome.com/docs/crux">${i18n.i18n.lockedString('Chrome UX Report')}</devtools-link>` },
914
+ )}
915
+ </div>
913
916
  `;
917
+ // clang-format on
914
918
  }
915
919
 
916
920
  #renderLogSection(): Lit.LitTemplate {
@@ -1174,11 +1178,11 @@ export class LiveMetricsView extends LegacyWrapper.LegacyWrapper.WrappableCompon
1174
1178
  ${this.#renderInpCard()}
1175
1179
  </div>
1176
1180
  </div>
1177
- <x-link
1181
+ <devtools-link
1178
1182
  href=${helpLink}
1179
1183
  class="local-field-link"
1180
1184
  title=${i18nString(UIStrings.localFieldLearnMoreTooltip)}
1181
- >${i18nString(UIStrings.localFieldLearnMoreLink)}</x-link>
1185
+ >${i18nString(UIStrings.localFieldLearnMoreLink)}</devtools-link>
1182
1186
  ${this.#renderLogSection()}
1183
1187
  </main>
1184
1188
  <aside class="next-steps" aria-labelledby="next-steps-section-title">
@@ -34,7 +34,7 @@
34
34
  white-space: normal;
35
35
  }
36
36
 
37
- x-link {
37
+ devtools-link {
38
38
  color: var(--sys-color-primary);
39
39
  text-decoration-line: underline;
40
40
  }
@@ -104,7 +104,7 @@ input[type="text"][disabled] {
104
104
  color: var(--color-error-text);
105
105
  }
106
106
 
107
- x-link {
107
+ devtools-link {
108
108
  color: var(--sys-color-primary);
109
109
  text-decoration-line: underline;
110
110
  }
@@ -69,7 +69,6 @@ interface ViewInput {
69
69
  internalName: string;
70
70
  model: InsightModel;
71
71
  selected: boolean;
72
- isAIAssistanceContext: boolean;
73
72
  showAskAI: boolean;
74
73
  estimatedSavingsString: string|null;
75
74
  estimatedSavingsAriaLabel: string|null;
@@ -88,7 +87,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
88
87
  selected,
89
88
  estimatedSavingsString,
90
89
  estimatedSavingsAriaLabel,
91
- isAIAssistanceContext,
92
90
  showAskAI,
93
91
  dispatchInsightToggle,
94
92
  renderContent,
@@ -98,8 +96,7 @@ const DEFAULT_VIEW: View = (input, output, target) => {
98
96
 
99
97
  const containerClasses = Lit.Directives.classMap({
100
98
  insight: true,
101
- closed: !selected || isAIAssistanceContext,
102
- 'ai-assistance-context': isAIAssistanceContext,
99
+ closed: !selected,
103
100
  });
104
101
 
105
102
  let ariaLabel = `${i18nString(UIStrings.viewDetails, {PH1: model.title})}`;
@@ -139,10 +136,6 @@ const DEFAULT_VIEW: View = (input, output, target) => {
139
136
  }
140
137
 
141
138
  function renderHoverIcon(): Lit.LitTemplate {
142
- if (isAIAssistanceContext) {
143
- return Lit.nothing;
144
- }
145
-
146
139
  const containerClasses = Lit.Directives.classMap({
147
140
  'insight-hover-icon': true,
148
141
  active: selected,
@@ -205,10 +198,6 @@ export interface BaseInsightData {
205
198
  export abstract class BaseInsightComponent<T extends InsightModel> extends UI.Widget.Widget {
206
199
  #view: View;
207
200
  abstract internalName: string;
208
-
209
- // Tracks if this component is rendered withing the AI assistance panel.
210
- // Currently only relevant to GreenDev.
211
- #isAIAssistanceContext = false;
212
201
  #selected = false;
213
202
  #model: T|null = null;
214
203
  #agentFocus: AIAssistance.AIContext.AgentFocus|null = null;
@@ -243,11 +232,6 @@ export abstract class BaseInsightComponent<T extends InsightModel> extends UI.Wi
243
232
  return false;
244
233
  }
245
234
 
246
- set isAIAssistanceContext(isAIAssistanceContext: boolean) {
247
- this.#isAIAssistanceContext = isAIAssistanceContext;
248
- this.requestUpdate();
249
- }
250
-
251
235
  set selected(selected: boolean) {
252
236
  if (!this.#selected && selected) {
253
237
  const options = this.getOverlayOptionsForInitialOverlays();
@@ -408,7 +392,6 @@ export abstract class BaseInsightComponent<T extends InsightModel> extends UI.Wi
408
392
  selected: this.#selected,
409
393
  estimatedSavingsString: this.getEstimatedSavingsString(),
410
394
  estimatedSavingsAriaLabel: this.#getEstimatedSavingsAriaLabel(),
411
- isAIAssistanceContext: this.#isAIAssistanceContext,
412
395
  showAskAI: this.#canShowAskAI(),
413
396
  dispatchInsightToggle: () => this.#dispatchInsightToggle(),
414
397
  renderContent: () => this.renderContent(),
@@ -514,7 +497,7 @@ export abstract class BaseInsightComponent<T extends InsightModel> extends UI.Wi
514
497
  }
515
498
 
516
499
  #canShowAskAI(): boolean {
517
- if (this.#isAIAssistanceContext || !this.hasAskAiSupport()) {
500
+ if (!this.hasAskAiSupport()) {
518
501
  return false;
519
502
  }
520
503
 
@@ -61,9 +61,9 @@ export class InsightRenderer {
61
61
  renderInsightToWidgetElement(
62
62
  parsedTrace: Trace.TraceModel.ParsedTrace, insightSet: Trace.Insights.Types.InsightSet,
63
63
  model: Trace.Insights.Types.InsightModel, insightName: string,
64
- options: Partial<Pick<
65
- BaseInsightComponent<Trace.Insights.Types.InsightModel>,
66
- 'selected'|'agentFocus'|'fieldMetrics'|'isAIAssistanceContext'>>): InsightWidgetElement {
64
+ options: Partial<
65
+ Pick<BaseInsightComponent<Trace.Insights.Types.InsightModel>, 'selected'|'agentFocus'|'fieldMetrics'>>):
66
+ InsightWidgetElement {
67
67
  let widgetElement = this.#insightWidgetCache.get(model);
68
68
  if (!widgetElement) {
69
69
  widgetElement = document.createElement('devtools-widget') as InsightWidgetElement;
@@ -85,7 +85,6 @@ export class InsightRenderer {
85
85
  insightSetKey: insightSet.id,
86
86
  agentFocus: options.agentFocus ?? null,
87
87
  fieldMetrics: options.fieldMetrics ?? null,
88
- isAIAssistanceContext: options.isAIAssistanceContext ?? false,
89
88
  });
90
89
 
91
90
  return widgetElement;
@@ -60,11 +60,6 @@
60
60
  }
61
61
  }
62
62
 
63
- .insight.ai-assistance-context {
64
- display: block;
65
- min-width: 200px;
66
- }
67
-
68
63
  .insight-hover-icon {
69
64
  position: absolute;
70
65
  top: var(--sys-size-5);
@@ -300,7 +300,7 @@
300
300
  font-weight: var(--ref-typeface-weight-medium);
301
301
  }
302
302
 
303
- x-link {
303
+ devtools-link {
304
304
  color: var(--sys-color-primary);
305
305
  text-decoration-line: underline;
306
306
  }
@@ -90,7 +90,7 @@ export class ReleaseNoteView extends UI.Panel.Panel {
90
90
  return html`
91
91
  <devtools-link
92
92
  href=${value.link}
93
- .jslogContext=${'learn-more'}>
93
+ jslogcontext="learn-more">
94
94
  <div class="video">
95
95
  <img class="thumbnail" src=${input.getThumbnailPath(value.type ?? VideoType.WHATS_NEW)}>
96
96
  <div class="thumbnail-description"><span>${value.description}</span></div>
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: https://chromium.googlesource.com/chromium/src
3
3
  Version: N/A
4
- Revision: 68ce69fc7f71cb8b57403cba5397e1d12753b37c
4
+ Revision: 1eaa7f85927d5066cf8a8c7dfc076e8b2b3665d6
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE
@@ -83,6 +83,10 @@ button {
83
83
  border: none;
84
84
  overflow: hidden;
85
85
 
86
+ devtools-icon {
87
+ color: var(--override-button-icon-color, var(--icon-default));
88
+ }
89
+
86
90
  &.small {
87
91
  --button-height: var(--sys-size-9);
88
92
  --button-width: var(--sys-size-9);
@@ -204,7 +204,7 @@ export class CodeBlock extends HTMLElement {
204
204
  #renderNotice(): Lit.TemplateResult {
205
205
  // clang-format off
206
206
  return html`<p class="notice">
207
- <devtools-link class="link" href="https://support.google.com/legal/answer/13505487" .jslogContext=${'code-disclaimer'}>
207
+ <devtools-link class="link" href="https://support.google.com/legal/answer/13505487" jslogcontext="code-disclaimer">
208
208
  ${i18nString(UIStrings.disclaimer)}
209
209
  </devtools-link>
210
210
  </p>`;
@@ -74,7 +74,7 @@ export class PanelFeedback extends HTMLElement {
74
74
  </div>
75
75
  <div class="video-description">
76
76
  <h3>${i18nString(UIStrings.videoAndDocumentation)}</h3>
77
- <devtools-link class="quick-start-link" href=${this.#props.quickStartUrl} .jslogContext=${'css-overview.quick-start'}>${this.#props.quickStartLinkText}</devtools-link>
77
+ <devtools-link class="quick-start-link" href=${this.#props.quickStartUrl} jslogcontext="css-overview.quick-start">${this.#props.quickStartLinkText}</devtools-link>
78
78
  </div>
79
79
  </div>
80
80
  </div>
@@ -16,7 +16,7 @@ export interface PreviewToggleData {
16
16
  name: string;
17
17
  helperText: string|null;
18
18
  feedbackURL: string|null;
19
- experiment: Root.Runtime.ExperimentName;
19
+ experiment: Root.ExperimentNames.ExperimentName;
20
20
  learnMoreURL?: string;
21
21
  onChangeCallback?: (checked: boolean) => void;
22
22
  }
@@ -46,7 +46,7 @@ export class PreviewToggle extends HTMLElement {
46
46
  #helperText: string|null = null;
47
47
  #feedbackURL: string|null = null;
48
48
  #learnMoreURL: string|undefined;
49
- #experiment: Root.Runtime.ExperimentName|'' = '';
49
+ #experiment: Root.ExperimentNames.ExperimentName|'' = '';
50
50
  #onChangeCallback?: (checked: boolean) => void;
51
51
 
52
52
  set data(data: PreviewToggleData) {
@@ -76,14 +76,14 @@ export class PreviewToggle extends HTMLElement {
76
76
  </devtools-checkbox>
77
77
  <div class="spacer"></div>
78
78
  ${this.#feedbackURL && !this.#helperText
79
- ? html`<div class="feedback"><devtools-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.shortFeedbackLink)}</devtools-link></div>`
79
+ ? html`<div class="feedback"><devtools-link class="devtools-link" href=${this.#feedbackURL} jslogContext=${'feedback'}>${i18nString(UIStrings.shortFeedbackLink)}</devtools-link></div>`
80
80
  : nothing}
81
81
  ${this.#learnMoreURL
82
- ? html`<div class="learn-more"><devtools-link class="x-link" href=${this.#learnMoreURL}>${i18nString(UIStrings.learnMoreLink)}</devtools-link></div>`
82
+ ? html`<div class="learn-more"><devtools-link class="devtools-link" href=${this.#learnMoreURL} jslogContext=${'learn-more'}>${i18nString(UIStrings.learnMoreLink)}</devtools-link></div>`
83
83
  : nothing}
84
84
  <div class="helper">
85
85
  ${this.#helperText && this.#feedbackURL
86
- ? html`<p>${this.#helperText} <devtools-link class="x-link" href=${this.#feedbackURL}>${i18nString(UIStrings.previewTextFeedbackLink)}</devtools-link></p>`
86
+ ? html`<p>${this.#helperText} <devtools-link class="devtools-link" href=${this.#feedbackURL} jslogContext=${'feedback'}>${i18nString(UIStrings.previewTextFeedbackLink)}</devtools-link></p>`
87
87
  : nothing}
88
88
  </div>
89
89
  </div>`,
@@ -30,12 +30,12 @@
30
30
  flex: 1;
31
31
  }
32
32
 
33
- .x-link {
33
+ .devtools-link {
34
34
  color: var(--sys-color-primary);
35
35
  text-decoration-line: underline;
36
36
  margin: 0 4px;
37
37
  }
38
38
 
39
- .feedback .x-link {
39
+ .feedback .devtools-link {
40
40
  color: var(--sys-color-token-subtle);
41
41
  }
@@ -9,6 +9,11 @@ const BLOCK_COMMENT_START_PATTERN = /^\/\*+\s*/;
9
9
  const BLOCK_COMMENT_END_PATTERN = /\s*\*+\/$/;
10
10
  const BLOCK_COMMENT_LINE_PREFIX_PATTERN = /^\s*\*\s?/;
11
11
 
12
+ export interface CommentNodeInfo {
13
+ text: string;
14
+ to: number;
15
+ }
16
+
12
17
  function findLastNonWhitespacePos(state: CodeMirror.EditorState, cursorPosition: number): number {
13
18
  const line = state.doc.lineAt(cursorPosition);
14
19
  const textBefore = line.text.substring(0, cursorPosition - line.from);
@@ -23,8 +28,8 @@ function resolveCommentNode(state: CodeMirror.EditorState, cursorPosition: numbe
23
28
  // The bias of -1 makes it check the character to the left of the position.
24
29
  const node = tree.resolveInner(lookupPos, -1);
25
30
  const nodeType = node.type.name;
26
- // Check if the node type is a comment AND the cursor is within the node's range.
27
- if (nodeType.includes('Comment') && cursorPosition >= node.to) {
31
+ // Check if the node type is a comment
32
+ if (nodeType.includes('Comment')) {
28
33
  if (!nodeType.includes('BlockComment')) {
29
34
  return node;
30
35
  }
@@ -48,7 +53,14 @@ function resolveCommentNode(state: CodeMirror.EditorState, cursorPosition: numbe
48
53
 
49
54
  function extractBlockComment(rawText: string): string|undefined {
50
55
  // Remove /* and */, whitespace, and common leading asterisks on new lines
51
- let cleaned = rawText.replace(BLOCK_COMMENT_START_PATTERN, '').replace(BLOCK_COMMENT_END_PATTERN, '');
56
+ if (!rawText.match(BLOCK_COMMENT_START_PATTERN)) {
57
+ return;
58
+ }
59
+ let cleaned = rawText.replace(BLOCK_COMMENT_START_PATTERN, '');
60
+ if (!cleaned.match(BLOCK_COMMENT_END_PATTERN)) {
61
+ return;
62
+ }
63
+ cleaned = cleaned.replace(BLOCK_COMMENT_END_PATTERN, '');
52
64
  // Remove leading " * " from multi-line block comments
53
65
  cleaned = cleaned.split('\n').map(line => line.replace(BLOCK_COMMENT_LINE_PREFIX_PATTERN, '')).join('\n').trim();
54
66
  return cleaned;
@@ -59,19 +71,26 @@ function extractLineComment(rawText: string): string {
59
71
  }
60
72
 
61
73
  export class AiCodeGenerationParser {
62
- static extractCommentText(state: CodeMirror.EditorState, cursorPosition: number): string|undefined {
74
+ static extractCommentNodeInfo(state: CodeMirror.EditorState, cursorPosition: number): CommentNodeInfo|undefined {
63
75
  const node = resolveCommentNode(state, cursorPosition);
64
76
  if (!node) {
65
77
  return;
66
78
  }
67
79
  const nodeType = node.type.name;
68
80
  const rawText = state.doc.sliceString(node.from, node.to);
81
+ let text = '';
69
82
  if (nodeType.includes('LineComment')) {
70
- return extractLineComment(rawText);
83
+ text = extractLineComment(rawText);
84
+ } else if (nodeType.includes('BlockComment')) {
85
+ text = extractBlockComment(rawText) ?? '';
86
+ } else {
87
+ text = rawText;
71
88
  }
72
- if (nodeType.includes('BlockComment')) {
73
- return extractBlockComment(rawText);
89
+
90
+ if (!Boolean(text)) {
91
+ return;
74
92
  }
75
- return rawText;
93
+
94
+ return {text, to: node.to};
76
95
  }
77
96
  }
@@ -258,13 +258,20 @@ export class AiCodeGenerationProvider {
258
258
  }
259
259
 
260
260
  this.#aiCodeGenerationCitations = [];
261
- this.#generationTeaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING;
262
261
  const cursor = this.#editor.state.selection.main.head;
263
- const query = AiCodeGenerationParser.extractCommentText(this.#editor.state, cursor);
262
+ const commentNodeInfo = AiCodeGenerationParser.extractCommentNodeInfo(this.#editor.state, cursor);
263
+ if (!commentNodeInfo) {
264
+ return;
265
+ }
266
+ // Move cursor to end of comment node before triggering generation.
267
+ this.#editor.dispatch({selection: {anchor: commentNodeInfo.to}});
268
+
269
+ const query = commentNodeInfo.text;
264
270
  if (!query || query.trim().length === 0) {
265
271
  return;
266
272
  }
267
273
 
274
+ this.#generationTeaser.displayState = PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.LOADING;
268
275
  try {
269
276
  const startTime = performance.now();
270
277
  this.#aiCodeGenerationConfig?.onRequestTriggered();
@@ -297,7 +304,7 @@ export class AiCodeGenerationProvider {
297
304
  effects: [
298
305
  setAiAutoCompleteSuggestion.of({
299
306
  text: '\n' + suggestionText,
300
- from: cursor,
307
+ from: commentNodeInfo.to,
301
308
  rpcGlobalId: generationResponse.metadata.rpcGlobalId,
302
309
  sampleId: topSample.sampleId,
303
310
  startTime,
@@ -359,14 +366,23 @@ function aiCodeGenerationTeaserExtension(teaser: PanelCommon.AiCodeGenerationTea
359
366
  const isEmptyLine = line.length === 0;
360
367
  const canShowDiscoveryState =
361
368
  UI.UIUtils.PromotionManager.instance().canShowPromotion(PanelCommon.AiCodeGenerationTeaser.PROMOTION_ID);
362
- const isComment = Boolean(AiCodeGenerationParser.extractCommentText(this.#view.state, cursorPosition));
363
- const isCursorAtEndOfLine = cursorPosition >= line.to;
364
369
 
365
- if ((isEmptyLine && canShowDiscoveryState) || (isComment && isCursorAtEndOfLine)) {
370
+ if ((isEmptyLine && canShowDiscoveryState)) {
366
371
  return CodeMirror.Decoration.set([
367
372
  CodeMirror.Decoration.widget({widget: new AccessiblePlaceholder(teaser), side: 1}).range(cursorPosition),
368
373
  ]);
369
374
  }
375
+
376
+ const commentInfo = AiCodeGenerationParser.extractCommentNodeInfo(this.#view.state, cursorPosition);
377
+ if (commentInfo) {
378
+ // If cursor is inside the comment, show at the end of the comment node.
379
+ // If cursor is after the comment (but on same line), show at the cursor.
380
+ const decorationPos = Math.max(cursorPosition, commentInfo.to);
381
+ return CodeMirror.Decoration.set([
382
+ CodeMirror.Decoration.widget({widget: new AccessiblePlaceholder(teaser), side: 1}).range(decorationPos),
383
+ ]);
384
+ }
385
+
370
386
  return CodeMirror.Decoration.none;
371
387
  }
372
388
 
@@ -397,6 +413,20 @@ function aiCodeGenerationTeaserExtension(teaser: PanelCommon.AiCodeGenerationTea
397
413
  // Required for mouse click to propagate to the info tooltip in teaser.
398
414
  return (event.target instanceof Node && teaser.contentElement.contains(event.target));
399
415
  },
416
+ keydown(event: KeyboardEvent): boolean {
417
+ if (!UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event) ||
418
+ teaser.displayState !== PanelCommon.AiCodeGenerationTeaser.AiCodeGenerationTeaserDisplayState.TRIGGER) {
419
+ return false;
420
+ }
421
+ if (event.key === '.') {
422
+ event.consume(true);
423
+ void VisualLogging.logKeyDown(
424
+ event.currentTarget, event, 'ai-code-generation-teaser.show-disclaimer-info-tooltip');
425
+ teaser.showTooltip();
426
+ return true;
427
+ }
428
+ return false;
429
+ }
400
430
  },
401
431
  });
402
432
  }
@@ -20,6 +20,12 @@ export class AutocompleteHistory {
20
20
  #historyOffset = 1;
21
21
  #uncommittedIsTop = false;
22
22
 
23
+ /**
24
+ * Tracks session-local edits made to history entries during navigation.
25
+ * Maps history index to edited text. Cleared when a new command is committed.
26
+ */
27
+ #editedEntries = new Map<number, string>();
28
+
23
29
  /**
24
30
  * Creates a new settings-backed history. The class assumes it has sole
25
31
  * ownership of the setting.
@@ -33,6 +39,7 @@ export class AutocompleteHistory {
33
39
  this.#data = [];
34
40
  this.#setting.set([]);
35
41
  this.#historyOffset = 1;
42
+ this.#editedEntries.clear();
36
43
  }
37
44
 
38
45
  length(): number {
@@ -49,6 +56,7 @@ export class AutocompleteHistory {
49
56
  }
50
57
 
51
58
  this.#historyOffset = 1;
59
+ this.#editedEntries.clear();
52
60
  if (text !== this.#currentHistoryItem()) {
53
61
  this.#data.push(text);
54
62
  }
@@ -72,11 +80,33 @@ export class AutocompleteHistory {
72
80
  }
73
81
  if (this.#historyOffset === 1) {
74
82
  this.#pushCurrentText(currentText);
83
+ } else {
84
+ this.#saveCurrentEdit(currentText);
75
85
  }
76
86
  ++this.#historyOffset;
77
87
  return this.#currentHistoryItem();
78
88
  }
79
89
 
90
+ /**
91
+ * Saves the current text as an edit if it differs from the current history item
92
+ * (which may already have edits from a previous navigation).
93
+ * Only saves non-empty edits to avoid issues with navigation-only calls.
94
+ */
95
+ #saveCurrentEdit(text: string): void {
96
+ const index = this.#data.length - this.#historyOffset;
97
+ const currentValue = this.#currentHistoryItem();
98
+ if (text === currentValue) {
99
+ return;
100
+ }
101
+ const original = this.#data[index];
102
+ if (text !== original && text.length > 0) {
103
+ this.#editedEntries.set(index, text);
104
+ } else {
105
+ // Remove edit if text was restored to original (or emptied)
106
+ this.#editedEntries.delete(index);
107
+ }
108
+ }
109
+
80
110
  next(): string|undefined {
81
111
  if (this.#historyOffset === 1) {
82
112
  return undefined;
@@ -98,7 +128,9 @@ export class AutocompleteHistory {
98
128
  }
99
129
 
100
130
  #currentHistoryItem(): string|undefined {
101
- return this.#data[this.#data.length - this.#historyOffset];
131
+ const index = this.#data.length - this.#historyOffset;
132
+ // Return edited version if available, otherwise return original
133
+ return this.#editedEntries.get(index) ?? this.#data[index];
102
134
  }
103
135
 
104
136
  #store(): void {
@@ -551,7 +551,7 @@ export interface ActionRegistration {
551
551
  * The name of the experiment an action is associated with. Enabling and disabling the declared
552
552
  * experiment will enable and disable the action respectively.
553
553
  */
554
- experiment?: Root.Runtime.ExperimentName;
554
+ experiment?: Root.ExperimentNames.ExperimentName;
555
555
  /**
556
556
  * Whether an action needs to be promoted. A new badge is shown next to the menu items then.
557
557
  */
@@ -1225,7 +1225,7 @@ export interface ProviderRegistration<T> {
1225
1225
  /** A function that asynchronously loads the provider instance. */
1226
1226
  loadProvider: () => Promise<Provider<T>>;
1227
1227
  /** Optional. The experiment that enables this provider. */
1228
- experiment?: Root.Runtime.ExperimentName;
1228
+ experiment?: Root.ExperimentNames.ExperimentName;
1229
1229
  }
1230
1230
 
1231
1231
  export interface ContextMenuItemRegistration {
@@ -1236,5 +1236,5 @@ export interface ContextMenuItemRegistration {
1236
1236
  /** Optional. A number used for sorting items within the same location. Lower numbers appear first. */
1237
1237
  order?: number;
1238
1238
  /** Optional. The experiment that enables this item. */
1239
- experiment?: Root.Runtime.ExperimentName;
1239
+ experiment?: Root.ExperimentNames.ExperimentName;
1240
1240
  }