chrome-devtools-frontend 1.0.1571007 → 1.0.1572937

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 (168) 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/Images/geminiInDevTools.png +0 -0
  5. package/front_end/Images/geminiInDevTools_2x.png +0 -0
  6. package/front_end/Images/src/database-off.svg +1 -0
  7. package/front_end/Images/src/lock-person.svg +1 -1
  8. package/front_end/core/common/Debouncer.ts +10 -1
  9. package/front_end/core/common/SettingRegistration.ts +1 -1
  10. package/front_end/core/host/AidaClient.ts +8 -0
  11. package/front_end/core/host/InspectorFrontendHostAPI.ts +0 -6
  12. package/front_end/core/host/UserMetrics.ts +1 -31
  13. package/front_end/core/root/ExperimentNames.ts +30 -0
  14. package/front_end/core/root/Runtime.ts +47 -48
  15. package/front_end/core/root/root.ts +2 -0
  16. package/front_end/core/sdk/CSSModel.ts +36 -13
  17. package/front_end/core/sdk/CSSProperty.ts +1 -1
  18. package/front_end/core/sdk/CSSPropertyParserMatchers.ts +9 -0
  19. package/front_end/core/sdk/CookieModel.ts +2 -1
  20. package/front_end/core/sdk/DOMModel.ts +1 -1
  21. package/front_end/core/sdk/DebuggerModel.ts +1 -1
  22. package/front_end/core/sdk/OverlayModel.ts +3 -2
  23. package/front_end/core/sdk/SourceMap.ts +1 -1
  24. package/front_end/devtools_compatibility.js +0 -6
  25. package/front_end/entrypoints/main/MainImpl.ts +44 -24
  26. package/front_end/entrypoints/main/main-meta.ts +1 -1
  27. package/front_end/generated/SupportedCSSProperties.js +6 -14
  28. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +0 -180
  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/javascript_metadata/NativeFunctions.js +8 -0
  33. package/front_end/models/source_map_scopes/NamesResolver.ts +1 -1
  34. package/front_end/models/trace/EventsSerializer.ts +5 -1
  35. package/front_end/models/trace/ModelImpl.ts +0 -4
  36. package/front_end/models/trace/types/TraceEvents.ts +4 -0
  37. package/front_end/panels/accessibility/AXBreadcrumbsPane.ts +1 -1
  38. package/front_end/panels/accessibility/AccessibilitySidebarView.ts +1 -1
  39. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -63
  40. package/front_end/panels/ai_assistance/PatchWidget.ts +10 -15
  41. package/front_end/panels/ai_assistance/SelectWorkspaceDialog.ts +5 -4
  42. package/front_end/panels/ai_assistance/aiAssistancePanel.css +0 -16
  43. package/front_end/panels/ai_assistance/ai_assistance.ts +0 -1
  44. package/front_end/panels/ai_assistance/components/ChatMessage.ts +3 -2
  45. package/front_end/panels/ai_assistance/components/ChatView.ts +123 -108
  46. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +1 -145
  47. package/front_end/panels/application/DeviceBoundSessionsModel.ts +23 -1
  48. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +23 -0
  49. package/front_end/panels/application/FrameDetailsView.ts +12 -10
  50. package/front_end/panels/application/components/BackForwardCacheView.ts +6 -8
  51. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +4 -3
  52. package/front_end/panels/application/components/ProtocolHandlersView.ts +5 -6
  53. package/front_end/panels/application/components/ReportsGrid.ts +9 -9
  54. package/front_end/panels/application/components/SharedStorageAccessGrid.ts +5 -4
  55. package/front_end/panels/application/components/TrustTokensView.ts +4 -6
  56. package/front_end/panels/application/preloading/PreloadingView.ts +9 -8
  57. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +237 -230
  58. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +3 -2
  59. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +6 -10
  60. package/front_end/panels/application/resourcesSidebar.css +8 -0
  61. package/front_end/panels/autofill/AutofillView.ts +4 -3
  62. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +3 -5
  63. package/front_end/panels/common/AiCodeCompletionTeaser.ts +5 -5
  64. package/front_end/panels/common/AiCodeGenerationTeaser.ts +35 -4
  65. package/front_end/panels/common/BadgeNotification.ts +17 -14
  66. package/front_end/panels/common/GdpSignUpDialog.ts +5 -6
  67. package/front_end/panels/common/GeminiRebrandPromoDialog.ts +192 -0
  68. package/front_end/panels/common/aiCodeGenerationTeaser.css +16 -1
  69. package/front_end/panels/common/common.ts +1 -0
  70. package/front_end/panels/common/geminiRebrandPromoDialog.css +47 -0
  71. package/front_end/panels/console/ConsoleInsightTeaser.ts +10 -11
  72. package/front_end/panels/console/ErrorStackParser.ts +11 -16
  73. package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +2 -2
  74. package/front_end/panels/css_overview/CSSOverviewModel.ts +1 -1
  75. package/front_end/panels/elements/ComputedStyleModel.ts +16 -65
  76. package/front_end/panels/elements/ComputedStyleWidget.ts +3 -3
  77. package/front_end/panels/elements/ElementsPanel.ts +35 -5
  78. package/front_end/panels/elements/ElementsSidebarPane.ts +1 -1
  79. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  80. package/front_end/panels/elements/PlatformFontsWidget.ts +1 -1
  81. package/front_end/panels/elements/StylePropertiesSection.ts +16 -8
  82. package/front_end/panels/elements/StylePropertyTreeElement.ts +67 -32
  83. package/front_end/panels/elements/StylesSidebarPane.ts +28 -11
  84. package/front_end/panels/elements/components/CSSHintDetailsView.ts +3 -2
  85. package/front_end/panels/elements/components/CSSPropertyDocsView.ts +3 -2
  86. package/front_end/panels/elements/elements-meta.ts +1 -1
  87. package/front_end/panels/emulation/DeviceModeWrapper.ts +101 -62
  88. package/front_end/panels/explain/components/ConsoleInsight.ts +27 -23
  89. package/front_end/panels/explain/components/consoleInsight.css +1 -1
  90. package/front_end/panels/issues/IssueView.ts +6 -6
  91. package/front_end/panels/network/RequestConditionsDrawer.ts +4 -3
  92. package/front_end/panels/network/RequestCookiesView.ts +3 -4
  93. package/front_end/panels/network/RequestTimingView.ts +6 -10
  94. package/front_end/panels/network/components/HeaderSectionRow.ts +3 -2
  95. package/front_end/panels/network/components/RequestHeaderSection.ts +3 -1
  96. package/front_end/panels/network/components/RequestHeadersView.css +2 -2
  97. package/front_end/panels/network/components/RequestHeadersView.ts +7 -6
  98. package/front_end/panels/profiler/HeapProfileView.ts +3 -3
  99. package/front_end/panels/profiler/HeapSnapshotView.ts +2 -2
  100. package/front_end/panels/profiler/profiler-meta.ts +3 -3
  101. package/front_end/panels/protocol_monitor/protocol_monitor-meta.ts +1 -1
  102. package/front_end/panels/recorder/RecorderController.ts +7 -13
  103. package/front_end/panels/recorder/components/CreateRecordingView.ts +6 -6
  104. package/front_end/panels/recorder/components/RecordingView.ts +0 -38
  105. package/front_end/panels/recorder/components/ReplaySection.ts +0 -14
  106. package/front_end/panels/recorder/components/StepEditor.ts +2 -40
  107. package/front_end/panels/recorder/recorderController.css +4 -4
  108. package/front_end/panels/security/CookieControlsView.ts +2 -2
  109. package/front_end/panels/security/CookieReportView.ts +21 -21
  110. package/front_end/panels/security/cookieControlsView.css +1 -1
  111. package/front_end/panels/security/cookieReportView.css +1 -1
  112. package/front_end/panels/settings/AISettingsTab.ts +13 -15
  113. package/front_end/panels/settings/components/SyncSection.ts +4 -3
  114. package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +4 -12
  115. package/front_end/panels/settings/settings-meta.ts +1 -1
  116. package/front_end/panels/sources/BreakpointEditDialog.ts +4 -3
  117. package/front_end/panels/sources/CallStackSidebarPane.ts +4 -1
  118. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +1 -1
  119. package/front_end/panels/sources/NavigatorView.ts +4 -4
  120. package/front_end/panels/sources/SourcesPanel.ts +7 -4
  121. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  122. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +3 -2
  123. package/front_end/panels/timeline/ThreadAppender.ts +2 -1
  124. package/front_end/panels/timeline/TimelineController.ts +4 -3
  125. package/front_end/panels/timeline/TimelinePanel.ts +7 -4
  126. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -2
  127. package/front_end/panels/timeline/components/ExportTraceOptions.ts +4 -4
  128. package/front_end/panels/timeline/components/FieldSettingsDialog.ts +13 -6
  129. package/front_end/panels/timeline/components/LiveMetricsView.ts +13 -9
  130. package/front_end/panels/timeline/components/exportTraceOptions.css +1 -1
  131. package/front_end/panels/timeline/components/fieldSettingsDialog.css +1 -1
  132. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -19
  133. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +3 -4
  134. package/front_end/panels/timeline/components/insights/baseInsightComponent.css +0 -5
  135. package/front_end/panels/timeline/components/liveMetricsView.css +1 -1
  136. package/front_end/panels/whats_new/ReleaseNoteView.ts +4 -3
  137. package/front_end/third_party/chromium/README.chromium +1 -1
  138. package/front_end/ui/components/buttons/button.css +4 -0
  139. package/front_end/ui/components/markdown_view/CodeBlock.ts +3 -6
  140. package/front_end/ui/components/markdown_view/MarkdownLink.ts +3 -4
  141. package/front_end/ui/components/panel_feedback/PanelFeedback.ts +3 -4
  142. package/front_end/ui/components/panel_feedback/PreviewToggle.ts +10 -7
  143. package/front_end/ui/components/panel_feedback/panelFeedback.css +2 -2
  144. package/front_end/ui/components/panel_feedback/previewToggle.css +2 -2
  145. package/front_end/ui/components/text_editor/AiCodeGenerationParser.ts +27 -8
  146. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +36 -6
  147. package/front_end/ui/kit/link/Link.ts +1 -14
  148. package/front_end/ui/legacy/ActionRegistration.ts +1 -1
  149. package/front_end/ui/legacy/ContextMenu.ts +2 -2
  150. package/front_end/ui/legacy/EmptyWidget.ts +3 -3
  151. package/front_end/ui/legacy/LinkContextMenuProvider.ts +42 -0
  152. package/front_end/ui/legacy/ViewRegistration.ts +1 -1
  153. package/front_end/ui/legacy/XLink.ts +0 -27
  154. package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +1 -1
  155. package/front_end/ui/legacy/components/color_picker/ContrastOverlay.ts +5 -4
  156. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +2 -2
  157. package/front_end/ui/legacy/components/perf_ui/perf_ui-meta.ts +1 -1
  158. package/front_end/ui/legacy/inspectorCommon.css +2 -1
  159. package/front_end/ui/legacy/legacy.ts +3 -1
  160. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -1
  161. package/front_end/ui/visual_logging/LoggingDriver.ts +3 -0
  162. package/package.json +1 -1
  163. package/front_end/models/ai_assistance/ArtifactsManager.ts +0 -67
  164. package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +0 -183
  165. package/front_end/panels/ai_assistance/components/CollapsibleAssistanceContentWidget.ts +0 -89
  166. package/front_end/panels/ai_assistance/components/PerformanceAgentFlameChart.ts +0 -133
  167. package/front_end/panels/ai_assistance/components/artifactsViewer.css +0 -15
  168. package/front_end/panels/ai_assistance/components/collapsibleAssistanceContentWidget.css +0 -32
@@ -4,13 +4,13 @@
4
4
 
5
5
  import '../../ui/components/spinners/spinners.js';
6
6
  import '../../ui/components/tooltips/tooltips.js';
7
+ import '../../ui/kit/kit.js';
7
8
 
8
9
  import * as Host from '../../core/host/host.js';
9
10
  import * as i18n from '../../core/i18n/i18n.js';
10
11
  import type * as AiCodeCompletion from '../../models/ai_code_completion/ai_code_completion.js';
11
12
  import * as UI from '../../ui/legacy/legacy.js';
12
13
  import {Directives, html, nothing, render} from '../../ui/lit/lit.js';
13
- import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
14
14
 
15
15
  import {AiCodeCompletionDisclaimer} from './AiCodeCompletionDisclaimer.js';
16
16
  import styles from './aiCodeCompletionSummaryToolbar.css.js';
@@ -86,12 +86,10 @@ export const DEFAULT_SUMMARY_TOOLBAR_VIEW: View = (input, _output, target) => {
86
86
  variant="rich"
87
87
  jslogContext="ai-code-completion-citations"
88
88
  ><div class="citations-tooltip-container">
89
- ${Directives.repeat(input.citations, citation => html`<x-link
89
+ ${Directives.repeat(input.citations, citation => html`<devtools-link
90
90
  tabIndex="0"
91
91
  href=${citation}
92
- jslog=${VisualLogging.link('ai-code-completion-citations.citation-link').track({
93
- click: true
94
- })}>${citation}</x-link>`)}</div></devtools-tooltip>
92
+ .jslogContext=${'ai-code-completion-citations.citation-link'}>${citation}</devtools-link>`)}</div></devtools-tooltip>
95
93
  </div>` : nothing;
96
94
 
97
95
  render(
@@ -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';
@@ -244,13 +246,11 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
244
246
  {
245
247
  iconName: 'warning',
246
248
  // clang-format off
247
- content: html`<x-link
249
+ content: html`<devtools-link
248
250
  href=${CODE_SNIPPET_WARNING_URL}
249
251
  class="link devtools-link"
250
- jslog=${VisualLogging.link('code-snippets-explainer.ai-code-completion-teaser').track({
251
- click: true
252
- })}
253
- >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</x-link>`,
252
+ .jslogContext=${'code-snippets-explainer.ai-code-completion-teaser'}
253
+ >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
254
254
  // clang-format on
255
255
  });
256
256
  return reminderItems;
@@ -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
  }
@@ -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,12 @@ 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: html`<devtools-link class="badge-link" href="https://developers.google.com/program" .jslogContext=${
208
+ 'program-link'}>${lockedString('Google Developer Program')}</devtools-link>`
209
+ }),
207
210
  jslogContext: badge.jslogContext,
208
211
  actions: [
209
212
  {
@@ -228,12 +231,12 @@ export class BadgeNotification extends UI.Widget.Widget {
228
231
  }
229
232
 
230
233
  #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
234
  this.#show({
235
- message: i18nFormatString(
236
- UIStrings.starterBadgeAwardMessageNoGdpProfile, {PH1: badge.title, PH2: googleDeveloperProgramLink}),
235
+ message: i18nFormatStringTemplate(UIStrings.starterBadgeAwardMessageNoGdpProfile, {
236
+ PH1: badge.title,
237
+ PH2: html`<devtools-link class="badge-link" href="https://developers.google.com/program" .jslogContext=${
238
+ 'program-link'}>${lockedString('Google Developer Program')}</devtools-link>`
239
+ }),
237
240
  jslogContext: badge.jslogContext,
238
241
  actions: [
239
242
  {
@@ -262,7 +265,7 @@ export class BadgeNotification extends UI.Widget.Widget {
262
265
 
263
266
  #presentActivityBasedBadge(badge: Badges.Badge): void {
264
267
  this.#show({
265
- message: i18nString(UIStrings.activityBasedBadgeAwardMessage, {PH1: badge.title}),
268
+ message: i18nFormatStringTemplate(UIStrings.activityBasedBadgeAwardMessage, {PH1: badge.title}),
266
269
  jslogContext: badge.jslogContext,
267
270
  actions: [
268
271
  {
@@ -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
+ }
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
 
5
5
  import '../../ui/components/tooltips/tooltips.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';
@@ -167,13 +168,13 @@ function renderNoModel(input: ViewInput): Lit.TemplateResult {
167
168
  lockedString(UIStringsNotTranslate.getHelpForWarning) :
168
169
  lockedString(UIStringsNotTranslate.getHelpForError)}
169
170
  </h2>
170
- <div>You can get quick answers from <x-link
171
- .jslog=${VisualLogging.link().track({click: true, keydown: 'Enter|Space'}).context('insights-teaser-built-in-ai-documentation')}
171
+ <div>You can get quick answers from <devtools-link
172
+ .jslogContext=${'insights-teaser-built-in-ai-documentation'}
172
173
  class="link"
173
174
  href=${BUILT_IN_AI_DOCUMENTATION}
174
175
  >
175
176
  Chrome’s Built-in AI
176
- </x-link>
177
+ </devtools-link>
177
178
  , without any data leaving your device.
178
179
  </div>
179
180
  <div>${lockedString(UIStringsNotTranslate.toUseDownload)}</div>
@@ -324,12 +325,12 @@ function renderFooter(input: ViewInput): Lit.TemplateResult {
324
325
  >
325
326
  <div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
326
327
  <div class="learn-more">
327
- <x-link
328
+ <devtools-link
328
329
  class="devtools-link"
329
330
  title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
330
331
  href=${DATA_USAGE_URL}
331
- jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
332
- >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
332
+ .jslogContext=${'explain.teaser.learn-more'}
333
+ >${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</devtools-link>
333
334
  </div>
334
335
  </devtools-tooltip>
335
336
  ${renderDontShowCheckbox(input)}
@@ -509,13 +510,11 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
509
510
  {
510
511
  iconName: 'warning',
511
512
  // clang-format off
512
- content: html`<x-link
513
+ content: html`<devtools-link
513
514
  href=${CODE_SNIPPET_WARNING_URL}
514
515
  class="link devtools-link"
515
- jslog=${VisualLogging.link('explain.teaser.code-snippets-explainer').track({
516
- click: true
517
- })}
518
- >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</x-link>`,
516
+ .jslogContext=${'explain.teaser.code-snippets-explainer'}
517
+ >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</devtools-link>`,
519
518
  // clang-format on
520
519
  }
521
520
  ],
@@ -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('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('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);