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
@@ -23,10 +23,22 @@ const UIStringsNotTranslate = {
23
23
  * @description Text for teaser to generate code in Mac.
24
24
  */
25
25
  cmdItoGenerateCode: 'Cmd+I to generate code',
26
+ /**
27
+ * @description Aria label for teaser to generate code.
28
+ */
29
+ pressCtrlPeriodToLearnHowYourDataIsBeingUsed: 'Press ctrl . (“period”) to learn how your data is being used.',
30
+ /**
31
+ * @description Aria label for teaser to generate code in Mac.
32
+ */
33
+ pressCmdPeriodToLearnHowYourDataIsBeingUsed: 'Press cmd . (“period”) to learn how your data is being used.',
26
34
  /**
27
35
  * @description Text for teaser when generating suggestion.
28
36
  */
29
37
  generating: 'Generating... (esc to cancel)',
38
+ /**
39
+ * @description Aria label for teaser when generating suggestion.
40
+ */
41
+ generatingAriaLabel: 'Generating. Press escape to cancel.',
30
42
  /**
31
43
  * @description Text for teaser for discoverability.
32
44
  */
@@ -103,6 +115,7 @@ export interface ViewInput {
103
115
 
104
116
  export interface ViewOutput {
105
117
  hideTooltip?: () => void;
118
+ showTooltip?: () => void;
106
119
  setTimerText?: (text: string) => void;
107
120
  }
108
121
 
@@ -123,11 +136,18 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
123
136
  }
124
137
  const toGenerateCode = Host.Platform.isMac() ? lockedString(UIStringsNotTranslate.cmdItoGenerateCode) :
125
138
  lockedString(UIStringsNotTranslate.ctrlItoGenerateCode);
139
+ const toLearnHowYourDataIsBeingUsed = Host.Platform.isMac() ?
140
+ lockedString(UIStringsNotTranslate.pressCmdPeriodToLearnHowYourDataIsBeingUsed) :
141
+ lockedString(UIStringsNotTranslate.pressCtrlPeriodToLearnHowYourDataIsBeingUsed);
126
142
  const tooltipDisclaimerText = getTooltipDisclaimerText(input.noLogging, input.panel);
127
143
  // TODO(b/472291834): Disclaimer icon should match the placeholder's color
128
144
  // clang-format off
129
145
  teaserLabel = html`<div class="ai-code-generation-teaser-trigger">
130
- ${toGenerateCode}&nbsp;<devtools-button
146
+ <span aria-atomic="true" aria-live="assertive">${toGenerateCode}&nbsp;</span>
147
+ <div class="ai-code-generation-teaser-screen-reader-only" aria-atomic="true" aria-live="assertive">
148
+ ${toLearnHowYourDataIsBeingUsed}
149
+ </div>
150
+ <devtools-button
131
151
  .data=${{
132
152
  title: lockedString(UIStringsNotTranslate.learnMoreAboutHowYourDataIsBeingUsed),
133
153
  size: Buttons.Button.Size.MICRO,
@@ -147,6 +167,11 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
147
167
  output.hideTooltip = () => {
148
168
  el.hidePopover();
149
169
  };
170
+ output.showTooltip = () => {
171
+ el.showPopover();
172
+ // Announce the content specifically for screen readers when triggered
173
+ UI.ARIAUtils.LiveAnnouncer.status(tooltipDisclaimerText);
174
+ };
150
175
  }
151
176
  })}>
152
177
  <div class="disclaimer-tooltip-container"><div class="tooltip-text">
@@ -175,10 +200,12 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
175
200
  }
176
201
 
177
202
  case AiCodeGenerationTeaserDisplayState.LOADING: {
203
+ const teaserAriaLabel = lockedString(UIStringsNotTranslate.generatingAriaLabel);
178
204
  // clang-format off
179
205
  teaserLabel = html`
180
- <span class="ai-code-generation-spinner"></span>&nbsp;${lockedString(UIStringsNotTranslate.generating)}&nbsp;
181
- <span class="ai-code-generation-timer" ${Directives.ref(el => {
206
+ <div class="ai-code-generation-teaser-screen-reader-only">${teaserAriaLabel}</div>
207
+ <span class="ai-code-generation-spinner" aria-hidden="true"></span>&nbsp;${lockedString(UIStringsNotTranslate.generating)}&nbsp;
208
+ <span class="ai-code-generation-timer" aria-hidden="true" ${Directives.ref(el => {
182
209
  if (el) {
183
210
  output.setTimerText = (text: string) => {
184
211
  el.textContent = text;
@@ -206,7 +233,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
206
233
  <style>${styles}</style>
207
234
  <style>@scope to (devtools-widget > *) { ${UI.inspectorCommonStyles} }</style>
208
235
  <div class="ai-code-generation-teaser">
209
- ${teaserLabel}
236
+ &nbsp;${teaserLabel}
210
237
  </div>
211
238
  `, target
212
239
  );
@@ -309,4 +336,8 @@ export class AiCodeGenerationTeaser extends UI.Widget.Widget {
309
336
  void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
310
337
  event.consume(true);
311
338
  }
339
+
340
+ showTooltip(): void {
341
+ this.#viewOutput.showTooltip?.();
342
+ }
312
343
  }
@@ -82,7 +82,7 @@ export class AiCodeGenerationUpgradeDialog {
82
82
  @click=${() => {
83
83
  void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
84
84
  }}
85
- .jslogContext=${'ai-code-generation-upgrade-dialog.manage-in-settings'}
85
+ jslogcontext="ai-code-generation-upgrade-dialog.manage-in-settings"
86
86
  .variant=${Buttons.Button.Variant.OUTLINED}
87
87
  aria-label=${lockedString(UIStringsNotTranslate.manageInSettings)}>
88
88
  ${lockedString(UIStringsNotTranslate.manageInSettings)}
@@ -91,7 +91,7 @@ export class AiCodeGenerationUpgradeDialog {
91
91
  @click=${() => {
92
92
  dialog.hide();
93
93
  }}
94
- .jslogContext=${'ai-code-generation-upgrade-dialog.continue'}
94
+ jslogcontext="ai-code-generation-upgrade-dialog.continue"
95
95
  .variant=${Buttons.Button.Variant.PRIMARY}>
96
96
  ${lockedString(UIStringsNotTranslate.gotIt)}
97
97
  </devtools-button>
@@ -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';
@@ -11,6 +13,7 @@ import * as UIHelpers from '../../ui/helpers/helpers.js';
11
13
  import * as uiI18n from '../../ui/i18n/i18n.js';
12
14
  import * as UI from '../../ui/legacy/legacy.js';
13
15
  import * as Lit from '../../ui/lit/lit.js';
16
+ import {type LitTemplate, nothing} from '../../ui/lit/lit.js';
14
17
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
15
18
 
16
19
  import badgeNotificationStyles from './badgeNotification.css.js';
@@ -65,7 +68,7 @@ const UIStrings = {
65
68
 
66
69
  const str_ = i18n.i18n.registerUIStrings('panels/common/BadgeNotification.ts', UIStrings);
67
70
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
68
- const i18nFormatString = uiI18n.getFormatLocalizedString.bind(undefined, str_);
71
+ const i18nFormatStringTemplate = uiI18n.getFormatLocalizedStringTemplate.bind(undefined, str_);
69
72
  const lockedString = i18n.i18n.lockedString;
70
73
 
71
74
  const LEFT_OFFSET = 5;
@@ -80,7 +83,7 @@ export interface BadgeNotificationAction {
80
83
  }
81
84
 
82
85
  export interface BadgeNotificationProperties {
83
- message: HTMLElement|string;
86
+ message: LitTemplate;
84
87
  jslogContext: string;
85
88
  imageUri: string;
86
89
  actions: BadgeNotificationAction[];
@@ -141,7 +144,7 @@ function revealBadgeSettings(): void {
141
144
 
142
145
  export class BadgeNotification extends UI.Widget.Widget {
143
146
  jslogContext = '';
144
- message: HTMLElement|string = '';
147
+ message: LitTemplate = nothing;
145
148
  imageUri = '';
146
149
  actions: BadgeNotificationAction[] = [];
147
150
  isStarterBadge = false;
@@ -198,12 +201,13 @@ export class BadgeNotification extends UI.Widget.Widget {
198
201
  }
199
202
 
200
203
  #presentStarterBadgeSettingsNudge(badge: Badges.Badge): void {
201
- const googleDeveloperProgramLink = UI.XLink.XLink.create(
202
- 'https://developers.google.com/program', lockedString('Google Developer Program'), 'badge-link', undefined,
203
- 'program-link');
204
204
  this.#show({
205
- message: i18nFormatString(
206
- UIStrings.starterBadgeAwardMessageSettingDisabled, {PH1: badge.title, PH2: googleDeveloperProgramLink}),
205
+ message: i18nFormatStringTemplate(UIStrings.starterBadgeAwardMessageSettingDisabled, {
206
+ PH1: badge.title,
207
+ PH2:
208
+ html`<devtools-link class="badge-link" href="https://developers.google.com/program" jslogcontext="program-link">${
209
+ lockedString('Google Developer Program')}</devtools-link>`
210
+ }),
207
211
  jslogContext: badge.jslogContext,
208
212
  actions: [
209
213
  {
@@ -228,12 +232,12 @@ export class BadgeNotification extends UI.Widget.Widget {
228
232
  }
229
233
 
230
234
  #presentStarterBadgeProfileNudge(badge: Badges.Badge): void {
231
- const googleDeveloperProgramLink = UI.XLink.XLink.create(
232
- 'https://developers.google.com/program', lockedString('Google Developer Program'), 'badge-link', undefined,
233
- 'program-link');
234
235
  this.#show({
235
- message: i18nFormatString(
236
- UIStrings.starterBadgeAwardMessageNoGdpProfile, {PH1: badge.title, PH2: googleDeveloperProgramLink}),
236
+ message: i18nFormatStringTemplate(UIStrings.starterBadgeAwardMessageNoGdpProfile, {
237
+ PH1: badge.title,
238
+ PH2: html`<devtools-link class="badge-link" href="https://developers.google.com/program" .jslogContext=${
239
+ 'program-link'}>${lockedString('Google Developer Program')}</devtools-link>`
240
+ }),
237
241
  jslogContext: badge.jslogContext,
238
242
  actions: [
239
243
  {
@@ -262,7 +266,7 @@ export class BadgeNotification extends UI.Widget.Widget {
262
266
 
263
267
  #presentActivityBasedBadge(badge: Badges.Badge): void {
264
268
  this.#show({
265
- message: i18nString(UIStrings.activityBasedBadgeAwardMessage, {PH1: badge.title}),
269
+ message: i18nFormatStringTemplate(UIStrings.activityBasedBadgeAwardMessage, {PH1: badge.title}),
266
270
  jslogContext: badge.jslogContext,
267
271
  actions: [
268
272
  {
@@ -2,6 +2,7 @@
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
  import '../../ui/components/switch/switch.js';
5
+ import '../../ui/kit/kit.js';
5
6
 
6
7
  import * as Common from '../../core/common/common.js';
7
8
  import * as Host from '../../core/host/host.js';
@@ -152,12 +153,10 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
152
153
  <h2 class="section-title">${i18nString(UIStrings.tailorProfile)}</h2>
153
154
  <div class="section-text">
154
155
  <div>${i18nString(UIStrings.tailorProfileBody)}</div><br/>
155
- <div>${uiI18n.getFormatLocalizedString(str_, UIStrings.tailorProfileBodyDisclaimer, {
156
- PH1: UI.XLink.XLink.create(CONTENT_POLICY_URL, i18nString(UIStrings.contentPolicy), 'link', undefined, 'content-policy'),
157
- PH2: UI.XLink.XLink.create(TERMS_OF_SERVICE_URL, i18nString(UIStrings.termsOfService), 'link',
158
- undefined, 'terms-of-service'),
159
- PH3: UI.XLink.XLink.create(PRIVACY_POLICY_URL, i18nString(UIStrings.privacyPolicy), 'link',
160
- undefined, 'privacy-policy'),
156
+ <div>${uiI18n.getFormatLocalizedStringTemplate(str_, UIStrings.tailorProfileBodyDisclaimer, {
157
+ PH1: html`<devtools-link href=${CONTENT_POLICY_URL} class="link" jslogcontext="content-policy">${i18nString(UIStrings.contentPolicy)}</devtools-link>`,
158
+ PH2: html`<devtools-link href=${TERMS_OF_SERVICE_URL} class="link" jslogcontext="terms-of-service">${i18nString(UIStrings.termsOfService)}</devtools-link>`,
159
+ PH3: html`<devtools-link href=${PRIVACY_POLICY_URL} class="link" jslogcontext="privacy-policy">${i18nString(UIStrings.privacyPolicy)}</devtools-link>`,
161
160
  })}</div>
162
161
  </div>
163
162
  </div>
@@ -0,0 +1,192 @@
1
+ // Copyright 2026 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
4
+
5
+ // This dialog will be shown during M146 and removed by M147.
6
+ //
7
+ // To enable:
8
+ // --enable-features=DevToolsGeminiRebranding
9
+
10
+ import '../../ui/components/switch/switch.js';
11
+ import '../../ui/kit/kit.js';
12
+
13
+ import * as Common from '../../core/common/common.js';
14
+ import * as Host from '../../core/host/host.js';
15
+ import * as i18n from '../../core/i18n/i18n.js';
16
+ import * as Root from '../../core/root/root.js';
17
+ import * as Geometry from '../../models/geometry/geometry.js';
18
+ import * as Buttons from '../../ui/components/buttons/buttons.js';
19
+ import * as UI from '../../ui/legacy/legacy.js';
20
+ import {html, render} from '../../ui/lit/lit.js';
21
+ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
22
+
23
+ import styles from './geminiRebrandPromoDialog.css.js';
24
+
25
+ const UIStrings = {
26
+ /**
27
+ * @description Aria label for the dialog
28
+ */
29
+ dialogAriaLabel: 'Gemini 3 Flash in DevTools',
30
+ /**
31
+ *
32
+ * @description Button text for dismissing the dialog.
33
+ */
34
+ dismiss: 'Dismiss',
35
+ /**
36
+ * @description Button text for getting started.
37
+ */
38
+ getStarted: 'Get started',
39
+ /**
40
+ * @description Detail message shown in the dialog.
41
+ */
42
+ detailAiCompanion: 'Meet your AI-powered companion for web dev',
43
+ /**
44
+ * @description Detail message shown in the dialog.
45
+ */
46
+ detailConsoleErrors: 'Get instant, accurate answers for console errors',
47
+ /**
48
+ * @description Detail message shown in the dialog.
49
+ */
50
+ detailGenerateCode: 'Generate CSS and JS snippets on the fly',
51
+ /**
52
+ * @description Detail message shown in the dialog.
53
+ */
54
+ detailPerformance: 'Automatically find issues in performance traces',
55
+ } as const;
56
+
57
+ const str_ = i18n.i18n.registerUIStrings('panels/common/GeminiRebrandPromoDialog.ts', UIStrings);
58
+ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
59
+
60
+ interface ViewInput {
61
+ onGetStartedClick: () => void;
62
+ onCancelClick: () => void;
63
+ }
64
+
65
+ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
66
+
67
+ const PROMO_IMAGE_1X = new URL('../../Images/geminiInDevTools.png', import.meta.url).toString();
68
+ const PROMO_IMAGE_2X = new URL('../../Images/geminiInDevTools_2x.png', import.meta.url).toString();
69
+
70
+ export const DEFAULT_VIEW: View = (input, _output, target): void => {
71
+ // clang-format off
72
+ render(
73
+ html`
74
+ <style>${styles}</style>
75
+
76
+ <div class="header">
77
+ <div class="title">Gemini 3 Flash in DevTools</div>
78
+ <div class="close-button">
79
+ <devtools-button
80
+ .iconName=${'cross'}
81
+ .variant=${Buttons.Button.Variant.ICON}
82
+ .size=${Buttons.Button.Size.REGULAR}
83
+ .title=${i18nString(UIStrings.dismiss)}
84
+ jslog=${VisualLogging.close().track({click: true})}
85
+ @click=${() => {}}
86
+ ></devtools-button>
87
+ </div>
88
+ </div>
89
+
90
+ <img class="banner-image" srcset=${`${PROMO_IMAGE_1X} 1x, ${PROMO_IMAGE_2X} 2x`}>
91
+
92
+ <div class="main-content">
93
+ <div class="detail-row">
94
+ <devtools-icon name="performance"></devtools-icon>
95
+ <div>${i18nString(UIStrings.detailAiCompanion)}</div>
96
+ </div>
97
+ <div class="detail-row">
98
+ <devtools-icon name="lightbulb-spark"></devtools-icon>
99
+ <div>${i18nString(UIStrings.detailConsoleErrors)}</div>
100
+ </div>
101
+ <div class="detail-row">
102
+ <devtools-icon name="text-analysis"></devtools-icon>
103
+ <div>${i18nString(UIStrings.detailGenerateCode)}</div>
104
+ </div>
105
+ <div class="detail-row">
106
+ <devtools-icon name="smart-assistant"></devtools-icon>
107
+ <div>${i18nString(UIStrings.detailPerformance)}</div>
108
+ </div>
109
+ </div>
110
+
111
+ <div class="buttons">
112
+ <devtools-button
113
+ .variant=${Buttons.Button.Variant.OUTLINED}
114
+ .jslogContext=${'cancel'}
115
+ @click=${input.onCancelClick}>${i18nString(UIStrings.dismiss)}</devtools-button>
116
+ <devtools-button
117
+ .variant=${Buttons.Button.Variant.PRIMARY}
118
+ .jslogContext=${'get-started'}
119
+ @click=${input.onGetStartedClick}>${i18nString(UIStrings.getStarted)}</devtools-button>
120
+ </div>
121
+ `,
122
+ target
123
+ );
124
+ // clang-format on
125
+ };
126
+
127
+ export class GeminiRebrandPromoDialog extends UI.Widget.VBox {
128
+ #view: View;
129
+ #dialog: UI.Dialog.Dialog;
130
+
131
+ constructor(
132
+ options: {
133
+ dialog: UI.Dialog.Dialog,
134
+ onSuccess?: () => void,
135
+ onCancel?: () => void,
136
+ },
137
+ view?: View) {
138
+ super();
139
+ this.#dialog = options.dialog;
140
+ this.#view = view ?? DEFAULT_VIEW;
141
+ this.requestUpdate();
142
+ }
143
+
144
+ async #onGetStartedClick(): Promise<void> {
145
+ this.#dialog.hide();
146
+ await UI.ViewManager.ViewManager.instance().showView('freestyler');
147
+ }
148
+
149
+ #onCancelClick(): void {
150
+ this.#dialog.hide();
151
+ }
152
+
153
+ override performUpdate(): void {
154
+ const viewInput: ViewInput = {
155
+ onGetStartedClick: this.#onGetStartedClick.bind(this),
156
+ onCancelClick: this.#onCancelClick.bind(this),
157
+ };
158
+
159
+ this.#view(viewInput, undefined, this.contentElement);
160
+ }
161
+
162
+ static show(): void {
163
+ const dialog = new UI.Dialog.Dialog('gemini-rebranding-dialog');
164
+ dialog.setAriaLabel(i18nString(UIStrings.dialogAriaLabel));
165
+ dialog.setMaxContentSize(new Geometry.Size(384, 500));
166
+ dialog.setSizeBehavior(UI.GlassPane.SizeBehavior.SET_EXACT_WIDTH_MAX_HEIGHT);
167
+ dialog.setDimmed(true);
168
+
169
+ new GeminiRebrandPromoDialog({dialog}).show(dialog.contentElement);
170
+ dialog.show(undefined, /* stack */ true);
171
+ }
172
+
173
+ static async maybeShow(): Promise<void> {
174
+ if (!Root.Runtime.hostConfig.aidaAvailability?.enabled) {
175
+ return;
176
+ }
177
+
178
+ const currentAidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
179
+ if (currentAidaAvailability !== Host.AidaClient.AidaAccessPreconditions.AVAILABLE) {
180
+ return;
181
+ }
182
+
183
+ const setting = Common.Settings.Settings.instance().createSetting<boolean>(
184
+ 'gemini-rebranding-dialog-shown', false, Common.Settings.SettingStorageType.SYNCED);
185
+ if (setting.get()) {
186
+ return;
187
+ }
188
+
189
+ setting.set(true);
190
+ GeminiRebrandPromoDialog.show();
191
+ }
192
+ }
@@ -5,15 +5,29 @@
5
5
  */
6
6
 
7
7
  @scope to (devtools-widget > *) {
8
+ .ai-code-generation-teaser-screen-reader-only {
9
+ position: absolute;
10
+ overflow: hidden;
11
+ clip-path: rect(0 0 0 0);
12
+ height: var(--sys-size-1);
13
+ width: var(--sys-size-1);
14
+ margin: -1 * var(--sys-size-1);;
15
+ padding: 0;
16
+ border: 0;
17
+ }
18
+
8
19
  .ai-code-generation-teaser {
9
20
  pointer-events: all;
10
21
  font-style: italic;
11
- padding-left: var(--sys-size-3);
12
22
  line-height: var(--sys-size-7);
13
23
 
14
24
  .ai-code-generation-teaser-trigger {
15
25
  display: inline-flex;
16
26
  align-items: center;
27
+
28
+ devtools-button {
29
+ --override-button-icon-color: var(--sys-color-token-subtle);
30
+ }
17
31
  }
18
32
 
19
33
  .ai-code-generation-teaser-generated {
@@ -53,6 +67,7 @@
53
67
  .link {
54
68
  margin: var(--sys-size-5) var(--sys-size-8) 0 var(--sys-size-5);
55
69
  display: inline-block;
70
+ color: var(--sys-color-on-surface-subtle);
56
71
  }
57
72
  }
58
73
  }
@@ -100,6 +100,7 @@ export {AiCodeGenerationUpgradeDialog} from './AiCodeGenerationUpgradeDialog.js'
100
100
  export {AnnotationManager} from './AnnotationManager.js';
101
101
  export {FreDialog} from './FreDialog.js';
102
102
  export {GdpSignUpDialog} from './GdpSignUpDialog.js';
103
+ export {GeminiRebrandPromoDialog} from './GeminiRebrandPromoDialog.js';
103
104
  export {AiCodeCompletionDisclaimer} from './AiCodeCompletionDisclaimer.js';
104
105
  export {AiCodeCompletionSummaryToolbar} from './AiCodeCompletionSummaryToolbar.js';
105
106
  export * from './BadgeNotification.js';
@@ -0,0 +1,47 @@
1
+ /*
2
+ * Copyright 2026 The Chromium Authors
3
+ * Use of this source code is governed by a BSD-style license that can be
4
+ * found in the LICENSE file.
5
+ */
6
+
7
+ @scope to (devtools-widget > *) {
8
+ :scope {
9
+ width: 100%;
10
+ box-shadow: none;
11
+ padding: var(--sys-size-8);
12
+ }
13
+
14
+ .header {
15
+ display: flex;
16
+ justify-content: space-between;
17
+ }
18
+
19
+ .title {
20
+ font-size: 20px;
21
+ }
22
+
23
+ .banner-image {
24
+ margin: 10px 0;
25
+ }
26
+
27
+ .main-content {
28
+ display: flex;
29
+ flex-direction: column;
30
+ margin: var(--sys-size-6) 0;
31
+ gap: var(--sys-size-3);
32
+ }
33
+
34
+ .detail-row {
35
+ display: flex;
36
+ align-items: center;
37
+ gap: 5px;
38
+ margin: 5px;
39
+ }
40
+
41
+ .buttons {
42
+ display: flex;
43
+ justify-content: flex-end;
44
+ align-items: center;
45
+ gap: 10px;
46
+ }
47
+ }
@@ -169,7 +169,7 @@ function renderNoModel(input: ViewInput): Lit.TemplateResult {
169
169
  lockedString(UIStringsNotTranslate.getHelpForError)}
170
170
  </h2>
171
171
  <div>You can get quick answers from <devtools-link
172
- .jslogContext=${'insights-teaser-built-in-ai-documentation'}
172
+ jslogcontext="insights-teaser-built-in-ai-documentation"
173
173
  class="link"
174
174
  href=${BUILT_IN_AI_DOCUMENTATION}
175
175
  >
@@ -329,7 +329,7 @@ function renderFooter(input: ViewInput): Lit.TemplateResult {
329
329
  class="devtools-link"
330
330
  title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
331
331
  href=${DATA_USAGE_URL}
332
- .jslogContext=${'explain.teaser.learn-more'}
332
+ jslogcontext="explain.teaser.learn-more"
333
333
  >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</devtools-link>
334
334
  </div>
335
335
  </devtools-tooltip>
@@ -513,7 +513,7 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
513
513
  content: html`<devtools-link
514
514
  href=${CODE_SNIPPET_WARNING_URL}
515
515
  class="link devtools-link"
516
- .jslogContext=${'explain.teaser.code-snippets-explainer'}
516
+ jslogcontext="explain.teaser.code-snippets-explainer"
517
517
  >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
518
518
  // clang-format on
519
519
  }
@@ -54,24 +54,19 @@ export function parseSourcePositionsFromErrorStack(
54
54
  let left = match[0].length;
55
55
  let right = line.length;
56
56
  let enclosedInBraces = false;
57
- while (line[right - 1] === ')') {
57
+ if (line[right - 1] === ')') {
58
58
  right--;
59
59
  enclosedInBraces = true;
60
- do {
61
- left = line.indexOf('(', left);
62
- if (left < 0) {
63
- return null;
64
- }
65
- left++;
66
- if (!line.substring(left).startsWith('eval at ')) {
67
- break;
68
- }
69
- left += 8;
70
- right = line.lastIndexOf(', ', right) - 1;
71
- if (right < 0) {
72
- return null;
73
- }
74
- } while (true);
60
+ left = line.lastIndexOf(' (', right);
61
+ if (left < 0) {
62
+ return null;
63
+ }
64
+ left += 2;
65
+ // Relevant in the `eval at ...` case.
66
+ const newRight = line.indexOf('), ', left);
67
+ if (newRight > left) {
68
+ right = newRight;
69
+ }
75
70
  }
76
71
 
77
72
  const linkCandidate = line.substring(left, right);
@@ -483,7 +483,7 @@ function renderContrastIssue(key: string, issues: ContrastIssue[]): TemplateResu
483
483
  const color = (minContrastIssue.textColor.asString(Common.Color.Format.HEXA));
484
484
  const backgroundColor = (minContrastIssue.backgroundColor.asString(Common.Color.Format.HEXA));
485
485
 
486
- const showAPCA = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.APCA);
486
+ const showAPCA = Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.APCA);
487
487
 
488
488
  const title = i18nString(UIStrings.textColorSOverSBackgroundResults, {
489
489
  PH1: color,
@@ -1041,7 +1041,7 @@ function renderContrastRatio(data: PopulateNodesEventNodeTypes): TemplateResult
1041
1041
  if (!('contrastRatio' in data)) {
1042
1042
  throw new Error('Contrast ratio entry is missing a contrast ratio.');
1043
1043
  }
1044
- const showAPCA = Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.APCA);
1044
+ const showAPCA = Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.APCA);
1045
1045
  const contrastRatio = Platform.NumberUtilities.floor(data.contrastRatio, 2);
1046
1046
  const contrastRatioString = showAPCA ? contrastRatio + '%' : contrastRatio;
1047
1047
  const border = getBorderString(data.backgroundColor);
@@ -267,7 +267,7 @@ export class CSSOverviewModel extends SDK.SDKModel.SDKModel<void> {
267
267
  const formattedTextColor = formatColor(blendedTextColor);
268
268
  const formattedBackgroundColor = formatColor(blendedBackgroundColor.asLegacyColor());
269
269
  const key = `${formattedTextColor}_${formattedBackgroundColor}`;
270
- if (Root.Runtime.experiments.isEnabled(Root.Runtime.ExperimentName.APCA)) {
270
+ if (Root.Runtime.experiments.isEnabled(Root.ExperimentNames.ExperimentName.APCA)) {
271
271
  const contrastRatio = contrastInfo.contrastRatioAPCA();
272
272
  const threshold = contrastInfo.contrastRatioAPCAThreshold();
273
273
  const passes = contrastRatio && threshold ? Math.abs(contrastRatio) >= threshold : false;