chrome-devtools-frontend 1.0.1536371 → 1.0.1537268

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 (165) hide show
  1. package/front_end/core/host/AidaClient.ts +64 -5
  2. package/front_end/core/host/DispatchHttpRequestClient.ts +62 -0
  3. package/front_end/core/host/GdpClient.ts +8 -57
  4. package/front_end/core/host/host.ts +2 -0
  5. package/front_end/core/protocol_client/CDPConnection.ts +10 -8
  6. package/front_end/core/protocol_client/InspectorBackend.ts +36 -42
  7. package/front_end/core/sdk/EnhancedTracesParser.ts +20 -5
  8. package/front_end/core/sdk/RehydratingConnection.ts +112 -4
  9. package/front_end/core/sdk/RehydratingObject.ts +8 -0
  10. package/front_end/core/sdk/TraceObject.ts +5 -1
  11. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
  12. package/front_end/models/trace/types/File.ts +9 -0
  13. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -9
  14. package/front_end/panels/ai_assistance/components/ChatView.ts +58 -70
  15. package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -6
  16. package/front_end/panels/application/components/BackForwardCacheView.ts +74 -69
  17. package/front_end/panels/application/components/FrameDetailsView.ts +8 -11
  18. package/front_end/panels/application/components/OriginTrialTreeView.ts +65 -69
  19. package/front_end/panels/application/components/backForwardCacheView.css +4 -0
  20. package/front_end/panels/application/components/badge.css +1 -1
  21. package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +44 -53
  22. package/front_end/panels/recorder/RecorderController.ts +1 -2
  23. package/front_end/panels/recorder/components/CreateRecordingView.ts +153 -129
  24. package/front_end/panels/settings/AISettingsTab.ts +162 -171
  25. package/front_end/panels/settings/SettingsScreen.ts +3 -7
  26. package/front_end/panels/settings/aiSettingsTab.css +151 -148
  27. package/front_end/panels/settings/settings-meta.ts +1 -2
  28. package/front_end/panels/sources/AddSourceMapURLDialog.ts +23 -26
  29. package/front_end/panels/timeline/TimelinePanel.ts +60 -11
  30. package/front_end/panels/timeline/components/ExportTraceOptions.ts +33 -34
  31. package/front_end/third_party/chromium/README.chromium +2 -2
  32. package/front_end/third_party/puppeteer/README.chromium +2 -2
  33. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +9 -1
  34. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
  35. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
  36. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts +2 -2
  37. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.d.ts.map +1 -1
  38. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BrowserContext.js.map +1 -1
  39. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +13 -1
  40. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  41. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  42. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts +2 -2
  43. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  44. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js +5 -2
  45. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BrowserContext.js.map +1 -1
  46. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +2 -2
  47. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
  48. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +3 -1
  49. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
  50. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts +1 -12
  51. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  52. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts +6 -0
  53. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  54. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -0
  55. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +2 -2
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +6 -1
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts +2 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js +2 -2
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BrowserContext.js.map +1 -1
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +2 -2
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +3 -1
  67. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
  70. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
  71. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  73. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts +2 -2
  74. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.d.ts.map +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js +3 -1
  76. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/disposable.js.map +1 -1
  77. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts +1 -0
  78. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.d.ts.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js +1 -0
  80. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/util.js.map +1 -1
  81. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  82. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  83. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +28 -3
  84. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21 -10
  85. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +9 -1
  86. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
  87. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
  88. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts +2 -2
  89. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.d.ts.map +1 -1
  90. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BrowserContext.js.map +1 -1
  91. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts +1 -1
  92. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Input.d.ts.map +1 -1
  93. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +13 -1
  94. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  95. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  96. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts +2 -2
  97. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.d.ts.map +1 -1
  98. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js +5 -2
  99. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BrowserContext.js.map +1 -1
  100. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +2 -2
  101. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
  102. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +3 -1
  103. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
  104. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts +1 -12
  105. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Realm.d.ts.map +1 -1
  106. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts +6 -0
  107. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.d.ts.map +1 -1
  108. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -0
  109. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
  110. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +2 -2
  111. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
  112. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +6 -1
  113. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
  114. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts +2 -1
  115. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.d.ts.map +1 -1
  116. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js +2 -2
  117. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BrowserContext.js.map +1 -1
  118. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +2 -2
  119. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
  120. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +3 -1
  121. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
  123. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
  124. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
  125. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts +2 -2
  126. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.d.ts.map +1 -1
  127. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js +2 -2
  128. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/disposable.js.map +1 -1
  129. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts +1 -0
  130. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.d.ts.map +1 -1
  131. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js +1 -0
  132. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/util.js.map +1 -1
  133. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  135. package/front_end/third_party/puppeteer/package/lib/types.d.ts +28 -3
  136. package/front_end/third_party/puppeteer/package/package.json +2 -2
  137. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +13 -1
  138. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +7 -2
  139. package/front_end/third_party/puppeteer/package/src/api/Page.ts +14 -1
  140. package/front_end/third_party/puppeteer/package/src/bidi/BrowserContext.ts +8 -5
  141. package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +5 -2
  142. package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +8 -0
  143. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +11 -2
  144. package/front_end/third_party/puppeteer/package/src/cdp/BrowserContext.ts +3 -2
  145. package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +5 -5
  146. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  147. package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
  148. package/front_end/third_party/puppeteer/package/src/util/util.ts +1 -0
  149. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  150. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +280 -0
  151. package/front_end/ui/components/text_editor/text_editor.ts +1 -0
  152. package/front_end/ui/components/tooltips/Tooltip.ts +1 -1
  153. package/front_end/ui/legacy/Dialog.ts +0 -1
  154. package/front_end/ui/legacy/SettingsUI.ts +0 -14
  155. package/front_end/ui/legacy/XLink.ts +0 -3
  156. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +9 -0
  157. package/front_end/ui/legacy/components/utils/Linkifier.ts +9 -3
  158. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -1
  159. package/mcp/mcp.ts +5 -0
  160. package/package.json +1 -1
  161. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +0 -4
  162. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.html +0 -20
  163. package/front_end/ui/components/docs/breadcrumbs_perf/initial-breadcrumb-perf.ts +0 -25
  164. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.html +0 -20
  165. package/front_end/ui/components/docs/breadcrumbs_perf/nested-breadcrumbs-perf.ts +0 -36
@@ -1,7 +1,6 @@
1
1
  // Copyright 2024 The Chromium Authors
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
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
5
  import * as Common from '../../core/common/common.js';
7
6
  import * as Host from '../../core/host/host.js';
@@ -11,7 +10,6 @@ import * as Root from '../../core/root/root.js';
11
10
  import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
12
11
  import * as Buttons from '../../ui/components/buttons/buttons.js';
13
12
  import * as Input from '../../ui/components/input/input.js';
14
- import * as LegacyWrapper from '../../ui/components/legacy_wrapper/legacy_wrapper.js';
15
13
  import * as Switch from '../../ui/components/switch/switch.js';
16
14
  import * as uiI18n from '../../ui/i18n/i18n.js';
17
15
  import * as UI from '../../ui/legacy/legacy.js';
@@ -20,7 +18,7 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
20
18
 
21
19
  import aiSettingsTabStyles from './aiSettingsTab.css.js';
22
20
 
23
- const {html, Directives: {ifDefined, classMap}} = Lit;
21
+ const {html, nothing, render, Directives: {ifDefined, classMap}} = Lit;
24
22
 
25
23
  const UIStrings = {
26
24
  /**
@@ -231,8 +229,143 @@ interface AiSettingParams {
231
229
  };
232
230
  }
233
231
 
234
- export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponent {
235
- readonly #shadow = this.attachShadow({mode: 'open'});
232
+ interface ViewInput {
233
+ disabledReasons: string[];
234
+ sharedDisclaimerBulletPoints: Array<{icon: string, text: Common.UIString.LocalizedString|Lit.TemplateResult}>;
235
+ settingToParams: Map<Common.Settings.Setting<boolean>, AiSettingParams>;
236
+ expandSetting(setting: Common.Settings.Setting<boolean>): void;
237
+ toggleSetting(setting: Common.Settings.Setting<boolean>, ev: Event): void;
238
+ }
239
+
240
+ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
241
+
242
+ export const AI_SETTINGS_TAB_DEFAULT_VIEW: View = (input, _output, target): void => {
243
+ // Disabled until https://crbug.com/1079231 is fixed.
244
+ // clang-format off
245
+ const disabledReasonsExplainer = input.disabledReasons.length ? html`
246
+ <div class="disabled-explainer">
247
+ ${input.disabledReasons.map(reason => html`
248
+ <div class="disabled-explainer-row">
249
+ <devtools-icon name="warning" class="medium" style="color: var(--icon-warning);">
250
+ </devtools-icon>
251
+ ${reason}
252
+ </div>
253
+ `)}
254
+ </div>
255
+ ` : nothing;
256
+
257
+ const sharedDisclaimer = html`
258
+ <div class="shared-disclaimer">
259
+ <h2>${i18nString(UIStrings.boostYourProductivity)}</h2>
260
+ <h3 class="disclaimer-list-header">${i18nString(UIStrings.thingsToConsider)}</h3>
261
+ <div class="disclaimer-list">
262
+ ${input.sharedDisclaimerBulletPoints.map(item =>
263
+ html`<div><devtools-icon .name=${item.icon} class="medium"></devtools-icon>
264
+ </div><div>${item.text}</div>`
265
+ )}
266
+ </div>
267
+ </div>
268
+ `;
269
+
270
+ const renderSettingItem = (settingItem: SettingItem): Lit.TemplateResult => {
271
+ return html`
272
+ <div>
273
+ <devtools-icon class="extra-large" .name=${settingItem.iconName}>
274
+ </devtools-icon>
275
+ </div>
276
+ <div class="padded">${settingItem.text}</div>
277
+ `;
278
+ };
279
+
280
+ const isDisabled = input.disabledReasons.length > 0;
281
+ const disabledReasonsJoined = input.disabledReasons.join('\n') || undefined;
282
+ const settings = Array.from(input.settingToParams.keys()).map(setting => {
283
+ const settingData = input.settingToParams.get(setting);
284
+ if (!settingData) {
285
+ return nothing;
286
+ }
287
+ const detailsClasses = {
288
+ 'whole-row': true,
289
+ open: settingData.settingExpandState.isSettingExpanded,
290
+ };
291
+ const tabindex = settingData.settingExpandState.isSettingExpanded ? '0' : '-1';
292
+ return html`
293
+ <div class="accordion-header" @click=${input.expandSetting.bind(this, setting)}>
294
+ <div class="icon-container centered">
295
+ <devtools-icon name=${settingData.iconName}></devtools-icon>
296
+ </div>
297
+ <div class="setting-card">
298
+ <h2>${settingData.settingName}</h2>
299
+ <div class="setting-description">${settingData.settingDescription}</div>
300
+ </div>
301
+ <div class="dropdown centered">
302
+ <devtools-button
303
+ .data=${{
304
+ title: settingData.settingExpandState.isSettingExpanded ? i18nString(UIStrings.showLess) : i18nString(UIStrings.showMore),
305
+ size: Buttons.Button.Size.SMALL,
306
+ iconName: settingData.settingExpandState.isSettingExpanded ? 'chevron-up' : 'chevron-down',
307
+ variant: Buttons.Button.Variant.ICON,
308
+ jslogContext: settingData.settingExpandState.expandSettingJSLogContext,
309
+ } as Buttons.Button.ButtonData}
310
+ ></devtools-button>
311
+ </div>
312
+ </div>
313
+ <div class="divider"></div>
314
+ <div class="toggle-container centered"
315
+ title=${ifDefined(disabledReasonsJoined)}
316
+ @click=${input.toggleSetting.bind(this, setting)}
317
+ >
318
+ <devtools-switch
319
+ .checked=${Boolean(setting.get()) && !isDisabled}
320
+ .jslogContext=${setting.name || ''}
321
+ .disabled=${isDisabled}
322
+ .label=${disabledReasonsJoined || settingData.enableSettingText}
323
+ data-testid=${settingData.enableSettingText}
324
+ @switchchange=${input.toggleSetting.bind(this, setting)}
325
+ ></devtools-switch>
326
+ </div>
327
+ <div class=${classMap(detailsClasses)}>
328
+ <div class="overflow-hidden">
329
+ <div class="expansion-grid">
330
+ <h3 class="expansion-grid-whole-row">${i18nString(UIStrings.whenOn)}</h3>
331
+ ${settingData.settingItems.map(item => renderSettingItem(item))}
332
+ <h3 class="expansion-grid-whole-row">${i18nString(UIStrings.thingsToConsider)}</h3>
333
+ ${settingData.toConsiderSettingItems.map(item => renderSettingItem(item))}
334
+ <div class="expansion-grid-whole-row">
335
+ <x-link
336
+ href=${settingData.learnMoreLink.url}
337
+ class="link"
338
+ tabindex=${tabindex}
339
+ jslog=${VisualLogging.link(settingData.learnMoreLink.linkJSLogContext).track({
340
+ click: true,
341
+ })}
342
+ >${i18nString(UIStrings.learnMore)}</x-link>
343
+ </div>
344
+ </div>
345
+ </div>
346
+ </div>
347
+ `;
348
+ });
349
+
350
+ render(html`
351
+ <style>${Input.checkboxStyles}</style>
352
+ <style>${aiSettingsTabStyles}</style>
353
+ <div class="ai-settings-container">
354
+ <div class="settings-container-wrapper" jslog=${VisualLogging.pane('chrome-ai')}>
355
+ ${sharedDisclaimer}
356
+ ${input.settingToParams.size ? html`
357
+ ${disabledReasonsExplainer}
358
+ <div class="settings-container">
359
+ ${settings}
360
+ </div>
361
+ ` : nothing}
362
+ </div></div>
363
+ `, target);
364
+ // clang-format on
365
+ };
366
+
367
+ export class AISettingsTab extends UI.Widget.VBox {
368
+ #view: View;
236
369
  #consoleInsightsSetting?: Common.Settings.Setting<boolean>;
237
370
  #aiAnnotationsSetting?: Common.Settings.Setting<boolean>;
238
371
  #aiAssistanceSetting?: Common.Settings.Setting<boolean>;
@@ -243,7 +376,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
243
376
  // To display a a setting, it needs to be added to this map.
244
377
  #settingToParams = new Map<Common.Settings.Setting<boolean>, AiSettingParams>();
245
378
 
246
- constructor() {
379
+ constructor(view?: View) {
247
380
  super();
248
381
  try {
249
382
  this.#consoleInsightsSetting = Common.Settings.Settings.instance().moduleSetting('console-insights-enabled');
@@ -269,15 +402,31 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
269
402
 
270
403
  this.#boundOnAidaAvailabilityChange = this.#onAidaAvailabilityChange.bind(this);
271
404
  this.#initSettings();
405
+ this.#view = view ?? AI_SETTINGS_TAB_DEFAULT_VIEW;
272
406
  }
273
407
 
274
- connectedCallback(): void {
408
+ override performUpdate(): void {
409
+ const disabledReasons = AiAssistanceModel.AiUtils.getDisabledReasons(this.#aidaAvailability);
410
+ const viewInput: ViewInput = {
411
+ disabledReasons,
412
+ sharedDisclaimerBulletPoints: this.#getSharedDisclaimerBulletPoints(),
413
+ settingToParams: this.#settingToParams,
414
+ expandSetting: this.#expandSetting.bind(this),
415
+ toggleSetting: this.#toggleSetting.bind(this),
416
+ };
417
+ this.#view(viewInput, undefined, this.contentElement);
418
+ }
419
+
420
+ override wasShown(): void {
421
+ super.wasShown();
275
422
  Host.AidaClient.HostConfigTracker.instance().addEventListener(
276
423
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
277
424
  void this.#onAidaAvailabilityChange();
425
+ this.requestUpdate();
278
426
  }
279
427
 
280
- disconnectedCallback(): void {
428
+ override willHide(): void {
429
+ super.willHide();
281
430
  Host.AidaClient.HostConfigTracker.instance().removeEventListener(
282
431
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#boundOnAidaAvailabilityChange);
283
432
  }
@@ -400,7 +549,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
400
549
  const currentAidaAvailability = await Host.AidaClient.AidaClient.checkAccessPreconditions();
401
550
  if (currentAidaAvailability !== this.#aidaAvailability) {
402
551
  this.#aidaAvailability = currentAidaAvailability;
403
- void this.render();
552
+ this.requestUpdate();
404
553
  }
405
554
  }
406
555
 
@@ -438,7 +587,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
438
587
  return;
439
588
  }
440
589
  settingData.settingExpandState.isSettingExpanded = !settingData.settingExpandState.isSettingExpanded;
441
- void this.render();
590
+ this.requestUpdate();
442
591
  }
443
592
 
444
593
  #toggleSetting(setting: Common.Settings.Setting<boolean>, ev: Event): void {
@@ -477,24 +626,10 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
477
626
  // If the "AI Assistance" is toggled off, we remove all the history entries related to the feature.
478
627
  void AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().deleteAll();
479
628
  }
480
- void this.render();
481
- }
482
-
483
- #renderSharedDisclaimerItem(icon: string, text: Common.UIString.LocalizedString|Lit.TemplateResult):
484
- Lit.TemplateResult {
485
- // Disabled until https://crbug.com/1079231 is fixed.
486
- // clang-format off
487
- return html`
488
- <div>
489
- <devtools-icon .name=${icon} class="medium">
490
- </devtools-icon>
491
- </div>
492
- <div>${text}</div>
493
- `;
494
- // clang-format on
629
+ this.requestUpdate();
495
630
  }
496
631
 
497
- #renderSharedDisclaimer(): Lit.TemplateResult {
632
+ #getSharedDisclaimerBulletPoints(): Array<{icon: string, text: Common.UIString.LocalizedString|Lit.TemplateResult}> {
498
633
  const tosLink = UI.XLink.XLink.create(
499
634
  'https://policies.google.com/terms', i18nString(UIStrings.termsOfService), undefined, undefined,
500
635
  'terms-of-service');
@@ -504,7 +639,7 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
504
639
  const noLogging = Root.Runtime.hostConfig.aidaAvailability?.enterprisePolicyValue ===
505
640
  Root.Runtime.GenAiEnterprisePolicyValue.ALLOW_WITHOUT_LOGGING;
506
641
 
507
- const bulletPoints = [
642
+ return [
508
643
  {icon: 'psychiatry', text: i18nString(UIStrings.experimentalFeatures)},
509
644
  {
510
645
  icon: 'google',
@@ -522,149 +657,5 @@ export class AISettingsTab extends LegacyWrapper.LegacyWrapper.WrappableComponen
522
657
  })}`,
523
658
  },
524
659
  ];
525
-
526
- return html`
527
- <div class="shared-disclaimer">
528
- <h2>${i18nString(UIStrings.boostYourProductivity)}</h2>
529
- <h3 class="disclaimer-list-header">${i18nString(UIStrings.thingsToConsider)}</h3>
530
- <div class="disclaimer-list">
531
- ${bulletPoints.map(item => this.#renderSharedDisclaimerItem(item.icon, item.text))}
532
- </div>
533
- </div>
534
- `;
535
- }
536
-
537
- #renderSettingItem(settingItem: SettingItem): Lit.TemplateResult {
538
- // Disabled until https://crbug.com/1079231 is fixed.
539
- // clang-format off
540
- return html`
541
- <div>
542
- <devtools-icon class="extra-large" .name=${settingItem.iconName}>
543
- </devtools-icon>
544
- </div>
545
- <div class="padded">${settingItem.text}</div>
546
- `;
547
- // clang-format on
548
- }
549
-
550
- #renderSetting(setting: Common.Settings.Setting<boolean>): Lit.LitTemplate {
551
- const settingData = this.#settingToParams.get(setting);
552
- if (!settingData) {
553
- return Lit.nothing;
554
- }
555
- const disabledReasons = AiAssistanceModel.AiUtils.getDisabledReasons(this.#aidaAvailability);
556
- const isDisabled = disabledReasons.length > 0;
557
- const disabledReasonsJoined = disabledReasons.join('\n') || undefined;
558
- const detailsClasses = {
559
- 'whole-row': true,
560
- open: settingData.settingExpandState.isSettingExpanded,
561
- };
562
- const tabindex = settingData.settingExpandState.isSettingExpanded ? '0' : '-1';
563
-
564
- // Disabled until https://crbug.com/1079231 is fixed.
565
- // clang-format off
566
- return html`
567
- <div class="accordion-header" @click=${this.#expandSetting.bind(this, setting)}>
568
- <div class="icon-container centered">
569
- <devtools-icon name=${settingData.iconName}></devtools-icon>
570
- </div>
571
- <div class="setting-card">
572
- <h2>${settingData.settingName}</h2>
573
- <div class="setting-description">${settingData.settingDescription}</div>
574
- </div>
575
- <div class="dropdown centered">
576
- <devtools-button
577
- .data=${{
578
- title: settingData.settingExpandState.isSettingExpanded ? i18nString(UIStrings.showLess) : i18nString(UIStrings.showMore),
579
- size: Buttons.Button.Size.SMALL,
580
- iconName: settingData.settingExpandState.isSettingExpanded ? 'chevron-up' : 'chevron-down',
581
- variant: Buttons.Button.Variant.ICON,
582
- jslogContext: settingData.settingExpandState.expandSettingJSLogContext,
583
- } as Buttons.Button.ButtonData}
584
- ></devtools-button>
585
- </div>
586
- </div>
587
- <div class="divider"></div>
588
- <div class="toggle-container centered"
589
- title=${ifDefined(disabledReasonsJoined)}
590
- @click=${this.#toggleSetting.bind(this, setting)}
591
- >
592
- <devtools-switch
593
- .checked=${Boolean(setting.get()) && !isDisabled}
594
- .jslogContext=${setting.name || ''}
595
- .disabled=${isDisabled}
596
- .label=${disabledReasonsJoined || settingData.enableSettingText}
597
- data-testid=${settingData.enableSettingText}
598
- @switchchange=${this.#toggleSetting.bind(this, setting)}
599
- ></devtools-switch>
600
- </div>
601
- <div class=${classMap(detailsClasses)}>
602
- <div class="overflow-hidden">
603
- <div class="expansion-grid">
604
- <h3 class="expansion-grid-whole-row">${i18nString(UIStrings.whenOn)}</h3>
605
- ${settingData.settingItems.map(item => this.#renderSettingItem(item))}
606
- <h3 class="expansion-grid-whole-row">${i18nString(UIStrings.thingsToConsider)}</h3>
607
- ${settingData.toConsiderSettingItems.map(item => this.#renderSettingItem(item))}
608
- <div class="expansion-grid-whole-row">
609
- <x-link
610
- href=${settingData.learnMoreLink.url}
611
- class="link"
612
- tabindex=${tabindex}
613
- jslog=${VisualLogging.link(settingData.learnMoreLink.linkJSLogContext).track({
614
- click: true,
615
- })}
616
- >${i18nString(UIStrings.learnMore)}</x-link>
617
- </div>
618
- </div>
619
- </div>
620
- </div>
621
- `;
622
- // clang-format on
623
- }
624
-
625
- #renderDisabledExplainer(disabledReasons: string[]): Lit.LitTemplate {
626
- // Disabled until https://crbug.com/1079231 is fixed.
627
- // clang-format off
628
- return html`
629
- <div class="disabled-explainer">
630
- ${disabledReasons.map(reason => html`
631
- <div class="disabled-explainer-row">
632
- <devtools-icon name="warning" class="medium" style="color: var(--icon-warning);">
633
- </devtools-icon>
634
- ${reason}
635
- </div>
636
- `)}
637
- </div>
638
- `;
639
- // clang-format on
640
- }
641
-
642
- override async render(): Promise<void> {
643
- const disabledReasons = AiAssistanceModel.AiUtils.getDisabledReasons(this.#aidaAvailability);
644
-
645
- // Disabled until https://crbug.com/1079231 is fixed.
646
- // clang-format off
647
- Lit.render(html`
648
- <style>${Input.checkboxStyles}</style>
649
- <style>${aiSettingsTabStyles}</style>
650
- <div class="settings-container-wrapper" jslog=${VisualLogging.pane('chrome-ai')}>
651
- ${this.#renderSharedDisclaimer()}
652
- ${this.#settingToParams.size > 0 ? html`
653
- ${disabledReasons.length ? this.#renderDisabledExplainer(disabledReasons) : Lit.nothing}
654
- <div class="settings-container">
655
- ${this.#settingToParams.keys().map(setting => this.#renderSetting(setting))}
656
- </div>
657
- ` : Lit.nothing}
658
- </div>
659
- `, this.#shadow, {host: this});
660
- // clang-format on
661
- }
662
- }
663
-
664
- customElements.define('devtools-settings-ai-settings-tab', AISettingsTab);
665
-
666
- declare global {
667
- interface HTMLElementTagNameMap {
668
- 'devtools-settings-ai-settings-tab': AISettingsTab;
669
660
  }
670
661
  }
@@ -328,11 +328,9 @@ export class GenericSettingsTab extends UI.Widget.VBox implements SettingsTab {
328
328
 
329
329
  private createExtensionSection(settings: Common.Settings.SettingRegistration[]): void {
330
330
  const sectionName = Common.Settings.SettingCategory.EXTENSIONS;
331
- const settingUI = Components.Linkifier.LinkHandlerSettingUI.instance() as UI.SettingsUI.SettingUI;
331
+ const settingUI = Components.Linkifier.LinkHandlerSettingUI.instance();
332
332
  const element = settingUI.settingElement();
333
- if (element) {
334
- this.createStandardSectionElement(sectionName, settings, element);
335
- }
333
+ this.createStandardSectionElement(sectionName, settings, element);
336
334
  }
337
335
 
338
336
  private createSectionElement(
@@ -403,15 +401,13 @@ export class ExperimentsSettingsTab extends UI.Widget.VBox implements SettingsTa
403
401
  render(
404
402
  html`
405
403
  <devtools-toolbar>
406
- <devtools-toolbar-input type="filter" placeholder=${
404
+ <devtools-toolbar-input autofocus type="filter" placeholder=${
407
405
  i18nString(UIStrings.searchExperiments)} style="flex-grow:1" @change=${
408
406
  this.#onFilterChanged.bind(this)}></devtools-toolbar-input>
409
407
  </devtools-toolbar>
410
408
  `,
411
409
  filterSection);
412
410
  this.renderExperiments('');
413
- const filter = filterSection.querySelector('devtools-toolbar-input') as HTMLElement;
414
- this.setDefaultFocusedElement(filter);
415
411
  }
416
412
 
417
413
  #onFilterChanged(e: CustomEvent<string>): void {