chrome-devtools-frontend 1.0.1568190 → 1.0.1569477

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 (46) hide show
  1. package/front_end/Images/src/grid-direction.svg +6 -0
  2. package/front_end/core/common/ParsedURL.ts +3 -0
  3. package/front_end/core/host/AidaClient.ts +1 -0
  4. package/front_end/core/root/Runtime.ts +4 -8
  5. package/front_end/entrypoints/main/MainImpl.ts +17 -20
  6. package/front_end/generated/InspectorBackendCommands.ts +6 -6
  7. package/front_end/generated/SupportedCSSProperties.js +14 -14
  8. package/front_end/generated/protocol.ts +0 -18
  9. package/front_end/models/ai_assistance/agents/PatchAgent.ts +4 -1
  10. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +12 -0
  11. package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +12 -2
  12. package/front_end/models/ai_assistance/agents/StylingAgent.ts +4 -1
  13. package/front_end/models/ai_assistance/injected.ts +7 -22
  14. package/front_end/models/javascript_metadata/NativeFunctions.js +12 -0
  15. package/front_end/models/stack_trace/StackTraceImpl.ts +12 -2
  16. package/front_end/models/stack_trace/StackTraceModel.ts +9 -1
  17. package/front_end/models/trace/Styles.ts +11 -8
  18. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +3 -2
  19. package/front_end/models/trace/types/TraceEvents.ts +19 -10
  20. package/front_end/panels/application/preloading/PreloadingView.ts +1 -3
  21. package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +13 -28
  22. package/front_end/panels/common/AiCodeCompletionTeaser.ts +58 -15
  23. package/front_end/panels/common/AiCodeGenerationTeaser.ts +1 -1
  24. package/front_end/panels/elements/ElementsPanel.ts +6 -3
  25. package/front_end/panels/elements/ElementsSidebarPane.ts +7 -28
  26. package/front_end/panels/elements/MetricsSidebarPane.ts +208 -216
  27. package/front_end/panels/elements/StylesSidebarPane.ts +6 -6
  28. package/front_end/panels/elements/components/CSSPropertyIconResolver.ts +57 -4
  29. package/front_end/panels/elements/components/StylePropertyEditor.ts +93 -1
  30. package/front_end/panels/elements/metricsSidebarPane.css +3 -11
  31. package/front_end/panels/settings/SettingsScreen.ts +8 -38
  32. package/front_end/panels/settings/settingsScreen.css +0 -4
  33. package/front_end/panels/sources/BreakpointEditDialog.ts +203 -138
  34. package/front_end/panels/sources/DebuggerPlugin.ts +15 -7
  35. package/front_end/panels/timeline/TimelineUIUtils.ts +9 -3
  36. package/front_end/panels/timeline/TimingsTrackAppender.ts +1 -0
  37. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +3 -1
  38. package/front_end/panels/timeline/timelineFlameChartView.css +1 -0
  39. package/front_end/third_party/chromium/README.chromium +1 -1
  40. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +23 -1
  41. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +16 -4
  42. package/front_end/ui/kit/link/Link.ts +14 -8
  43. package/front_end/ui/kit/link/link.css +1 -1
  44. package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
  45. package/mcp/mcp.ts +1 -0
  46. package/package.json +1 -1
@@ -7400,6 +7400,18 @@ export const NativeFunctions = [
7400
7400
  name: "queryFeatureSupport",
7401
7401
  signatures: [["feature"]]
7402
7402
  },
7403
+ {
7404
+ name: "LanguageModelToolCall",
7405
+ signatures: [["init"]]
7406
+ },
7407
+ {
7408
+ name: "LanguageModelToolSuccess",
7409
+ signatures: [["init"]]
7410
+ },
7411
+ {
7412
+ name: "LanguageModelToolError",
7413
+ signatures: [["init"]]
7414
+ },
7403
7415
  {
7404
7416
  name: "registerAnimator",
7405
7417
  signatures: [["name","animatorCtor"]]
@@ -31,7 +31,9 @@ export class StackTraceImpl<SyncFragmentT extends FragmentImpl|DebuggableFragmen
31
31
  }
32
32
 
33
33
  export class FragmentImpl implements StackTrace.StackTrace.Fragment {
34
- readonly node: FrameNode;
34
+ static readonly EMPTY_FRAGMENT = new FragmentImpl();
35
+
36
+ readonly node?: FrameNode;
35
37
  readonly stackTraces = new Set<AnyStackTraceImpl>();
36
38
 
37
39
  /**
@@ -46,11 +48,15 @@ export class FragmentImpl implements StackTrace.StackTrace.Fragment {
46
48
  return node.fragment;
47
49
  }
48
50
 
49
- private constructor(node: FrameNode) {
51
+ private constructor(node?: FrameNode) {
50
52
  this.node = node;
51
53
  }
52
54
 
53
55
  get frames(): FrameImpl[] {
56
+ if (!this.node) {
57
+ return [];
58
+ }
59
+
54
60
  const frames: FrameImpl[] = [];
55
61
 
56
62
  for (const node of this.node.getCallStack()) {
@@ -101,6 +107,10 @@ export class DebuggableFragmentImpl implements StackTrace.StackTrace.DebuggableF
101
107
  }
102
108
 
103
109
  get frames(): DebuggableFrameImpl[] {
110
+ if (!this.fragment.node) {
111
+ return [];
112
+ }
113
+
104
114
  const frames: DebuggableFrameImpl[] = [];
105
115
 
106
116
  let index = 0;
@@ -77,7 +77,7 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
77
77
  // is re-translated as a side-effect.
78
78
  // We just need to remember the stack traces of the skipped over fragments, so we can send the
79
79
  // UPDATED event also to them.
80
- if (fragment.node.children.length === 0) {
80
+ if (fragment.node?.children.length === 0) {
81
81
  translatePromises.push(this.#translateFragment(fragment, translateRawFrames));
82
82
  }
83
83
  stackTracesToUpdate = stackTracesToUpdate.union(fragment.stackTraces);
@@ -133,6 +133,10 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
133
133
  }
134
134
 
135
135
  async #createFragment(frames: RawFrame[], rawFramesToUIFrames: TranslateRawFrames): Promise<FragmentImpl> {
136
+ if (frames.length === 0) {
137
+ return FragmentImpl.EMPTY_FRAGMENT;
138
+ }
139
+
136
140
  const release = await this.#mutex.acquire();
137
141
  try {
138
142
  const node = this.#trie.insert(frames);
@@ -150,6 +154,10 @@ export class StackTraceModel extends SDK.SDKModel.SDKModel<unknown> {
150
154
  }
151
155
 
152
156
  async #translateFragment(fragment: FragmentImpl, rawFramesToUIFrames: TranslateRawFrames): Promise<void> {
157
+ if (!fragment.node) {
158
+ return;
159
+ }
160
+
153
161
  const rawFrames = fragment.node.getCallStack().map(node => node.rawFrame).toArray();
154
162
  const uiFrames = await rawFramesToUIFrames(rawFrames, this.target());
155
163
  console.assert(rawFrames.length === uiFrames.length, 'Broken rawFramesToUIFrames implementation');
@@ -311,6 +311,10 @@ const UIStrings = {
311
311
  * @description Text in Timeline UIUtils of the Performance panel
312
312
  */
313
313
  largestContentfulPaint: 'Largest Contentful Paint',
314
+ /**
315
+ * @description Text in Timeline UIUtils of the Performance panel
316
+ */
317
+ softLargestContentfulPaint: 'Soft Largest Contentful Paint',
314
318
  /**
315
319
  * @description Text for timestamps of items
316
320
  */
@@ -880,7 +884,7 @@ export function maybeInitSylesMap(): EventStylesMap {
880
884
  true,
881
885
  ),
882
886
  [Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION]: new TimelineRecordStyle(
883
- i18nString(UIStrings.largestContentfulPaint),
887
+ i18nString(UIStrings.softLargestContentfulPaint),
884
888
  defaultCategoryStyles.rendering,
885
889
  true,
886
890
  ),
@@ -1125,15 +1129,14 @@ export function markerDetailsForEvent(event: Types.Events.Event): {
1125
1129
  }
1126
1130
  if (Types.Events.isAnyLargestContentfulPaintCandidate(event)) {
1127
1131
  color = 'var(--sys-color-green)';
1128
- title = Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP;
1132
+ title = Types.Events.isSoftLargestContentfulPaintCandidate(event) ?
1133
+ Handlers.ModelHandlers.PageLoadMetrics.MetricName.SOFT_LCP :
1134
+ Handlers.ModelHandlers.PageLoadMetrics.MetricName.LCP;
1129
1135
  }
1130
- if (Types.Events.isNavigationStart(event)) {
1136
+ if (Types.Events.isNavigationStart(event) || Types.Events.isSoftNavigationStart(event)) {
1131
1137
  color = 'var(--color-text-primary)';
1132
- title = Handlers.ModelHandlers.PageLoadMetrics.MetricName.NAV;
1133
- }
1134
- if (Types.Events.isSoftNavigationStart(event)) {
1135
- color = 'var(--sys-color-blue)';
1136
- title = Handlers.ModelHandlers.PageLoadMetrics.MetricName.SOFT_NAV;
1138
+ title = Types.Events.isSoftNavigationStart(event) ? Handlers.ModelHandlers.PageLoadMetrics.MetricName.SOFT_NAV :
1139
+ Handlers.ModelHandlers.PageLoadMetrics.MetricName.NAV;
1137
1140
  }
1138
1141
  if (Types.Events.isMarkDOMContent(event)) {
1139
1142
  color = 'var(--color-text-disabled)';
@@ -460,8 +460,9 @@ export const enum MetricName {
460
460
  CLS = 'CLS',
461
461
  // Navigation
462
462
  NAV = 'Nav',
463
- // Soft Navigation (just "Nav" b/c space is limited in flame chart)
464
- SOFT_NAV = 'Nav',
463
+ // Soft Navigation and Soft Metrics
464
+ SOFT_NAV = 'Nav*',
465
+ SOFT_LCP = 'LCP*',
465
466
  // Note: INP is handled in UserInteractionsHandler
466
467
  }
467
468
 
@@ -678,7 +678,7 @@ export interface Mark extends Event {
678
678
  }
679
679
 
680
680
  export interface NavigationStart extends Mark {
681
- name: 'navigationStart';
681
+ name: Name.NAVIGATION_START;
682
682
  args: Args&{
683
683
  frame: string,
684
684
  data?: ArgsData&{
@@ -738,7 +738,7 @@ export interface FirstContentfulPaint extends Mark {
738
738
  }
739
739
 
740
740
  export interface FirstPaint extends Mark {
741
- name: 'firstPaint';
741
+ name: Name.MARK_FIRST_PAINT;
742
742
  args: Args&{
743
743
  frame: string,
744
744
  data?: ArgsData&{
@@ -761,8 +761,14 @@ const markerTypeGuards = [
761
761
  ];
762
762
 
763
763
  export const MarkerName = [
764
- 'MarkDOMContent', 'MarkLoad', 'firstPaint', 'firstContentfulPaint', 'largestContentfulPaint::Candidate',
765
- 'largestContentfulPaint::CandidateForSoftNavigation'
764
+ Name.MARK_DOM_CONTENT,
765
+ Name.MARK_LOAD,
766
+ Name.MARK_FIRST_PAINT,
767
+ Name.MARK_FCP,
768
+ Name.MARK_LCP_CANDIDATE,
769
+ Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION,
770
+ Name.NAVIGATION_START,
771
+ Name.SOFT_NAVIGATION_START,
766
772
  ] as const;
767
773
 
768
774
  export interface MarkerEvent extends Event {
@@ -968,7 +974,7 @@ export interface CommitLoad extends Instant {
968
974
  }
969
975
 
970
976
  export interface MarkDOMContent extends Instant {
971
- name: 'MarkDOMContent';
977
+ name: Name.MARK_DOM_CONTENT;
972
978
  args: Args&{
973
979
  data?: ArgsData & {
974
980
  frame: string,
@@ -980,7 +986,7 @@ export interface MarkDOMContent extends Instant {
980
986
  }
981
987
 
982
988
  export interface MarkLoad extends Instant {
983
- name: 'MarkLoad';
989
+ name: Name.MARK_LOAD;
984
990
  args: Args&{
985
991
  data?: ArgsData & {
986
992
  frame: string,
@@ -2256,12 +2262,15 @@ export function isLayoutInvalidationTracking(
2256
2262
  }
2257
2263
 
2258
2264
  export function isFirstContentfulPaint(event: Event): event is FirstContentfulPaint {
2259
- return event.name === 'firstContentfulPaint';
2265
+ return event.name === Name.MARK_FCP;
2260
2266
  }
2261
2267
 
2262
2268
  export function isAnyLargestContentfulPaintCandidate(event: Event): event is AnyLargestContentfulPaintCandidate {
2263
2269
  return event.name === Name.MARK_LCP_CANDIDATE || event.name === Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION;
2264
2270
  }
2271
+ export function isSoftLargestContentfulPaintCandidate(event: Event): event is AnyLargestContentfulPaintCandidate {
2272
+ return event.name === Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION;
2273
+ }
2265
2274
  export function isLargestImagePaintCandidate(event: Event): event is LargestImagePaintCandidate {
2266
2275
  return event.name === 'LargestImagePaint::Candidate';
2267
2276
  }
@@ -2270,15 +2279,15 @@ export function isLargestTextPaintCandidate(event: Event): event is LargestTextP
2270
2279
  }
2271
2280
 
2272
2281
  export function isMarkLoad(event: Event): event is MarkLoad {
2273
- return event.name === 'MarkLoad';
2282
+ return event.name === Name.MARK_LOAD;
2274
2283
  }
2275
2284
 
2276
2285
  export function isFirstPaint(event: Event): event is FirstPaint {
2277
- return event.name === 'firstPaint';
2286
+ return event.name === Name.MARK_FIRST_PAINT;
2278
2287
  }
2279
2288
 
2280
2289
  export function isMarkDOMContent(event: Event): event is MarkDOMContent {
2281
- return event.name === 'MarkDOMContent';
2290
+ return event.name === Name.MARK_DOM_CONTENT;
2282
2291
  }
2283
2292
 
2284
2293
  export function isInteractiveTime(event: Event): event is InteractiveTime {
@@ -564,9 +564,7 @@ export class PreloadingSummaryView extends UI.Widget.VBox {
564
564
  this.contentElement.insertBefore(this.warningsContainer, this.contentElement.firstChild);
565
565
  this.warningsView.show(this.warningsContainer);
566
566
 
567
- const usedPreloadingContainer = new UI.Widget.VBox();
568
- usedPreloadingContainer.contentElement.appendChild(this.usedPreloading);
569
- usedPreloadingContainer.show(this.contentElement);
567
+ this.usedPreloading.show(this.contentElement);
570
568
  }
571
569
 
572
570
  override wasShown(): void {
@@ -1,7 +1,6 @@
1
1
  // Copyright 2023 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 '../../../../ui/kit/kit.js';
7
6
  import '../../../../ui/components/report_view/report_view.js';
@@ -13,8 +12,6 @@ import type * as Platform from '../../../../core/platform/platform.js';
13
12
  import {assertNotNullOrUndefined} from '../../../../core/platform/platform.js';
14
13
  import * as SDK from '../../../../core/sdk/sdk.js';
15
14
  import * as Protocol from '../../../../generated/protocol.js';
16
- import * as LegacyWrapper from '../../../../ui/components/legacy_wrapper/legacy_wrapper.js';
17
- import * as RenderCoordinator from '../../../../ui/components/render_coordinator/render_coordinator.js';
18
15
  import * as UI from '../../../../ui/legacy/legacy.js';
19
16
  import {html, type LitTemplate, nothing, render} from '../../../../ui/lit/lit.js';
20
17
  import * as VisualLogging from '../../../../ui/visual_logging/visual_logging.js';
@@ -399,18 +396,17 @@ function renderBadge(config: Badge): LitTemplate {
399
396
 
400
397
  type View = (input: ViewInput, output: undefined, target: HTMLElement|ShadowRoot) => void;
401
398
 
402
- const DEFAULT_VIEW: View =
403
- ({speculativeLoadingStatusData, speculationsInitiatedSummaryData}: ViewInput, output, target): void => {
404
- // Disabled until https://crbug.com/1079231 is fixed.
405
- // clang-format off
399
+ const DEFAULT_VIEW: View = (input, _output, target) => {
400
+ // Disabled until https://crbug.com/1079231 is fixed.
401
+ // clang-format off
406
402
  render(html`
407
403
  <style>${usedPreloadingStyles}</style>
408
404
  <devtools-report>
409
- ${renderSpeculativeLoadingStatusForThisPageSections(speculativeLoadingStatusData)}
405
+ ${renderSpeculativeLoadingStatusForThisPageSections(input.speculativeLoadingStatusData)}
410
406
 
411
407
  <devtools-report-divider></devtools-report-divider>
412
408
 
413
- ${renderSpeculationsInitiatedByThisPageSummarySections(speculationsInitiatedSummaryData)}
409
+ ${renderSpeculationsInitiatedByThisPageSummarySections(input.speculationsInitiatedSummaryData)}
414
410
 
415
411
  <devtools-report-divider></devtools-report-divider>
416
412
 
@@ -423,20 +419,19 @@ const DEFAULT_VIEW: View =
423
419
  .context('learn-more')}
424
420
  >${i18nString(UIStrings.learnMore)}</x-link>
425
421
  </devtools-report-section>
426
- </devtools-report>`, target, {host: target instanceof ShadowRoot ? target.host : undefined});
427
- // clang-format on
428
- };
422
+ </devtools-report>`, target);
423
+ // clang-format on
424
+ };
429
425
 
430
426
  /**
431
427
  * TODO(kenoss): Rename this class and file once https://crrev.com/c/4933567 landed.
432
428
  * This also shows summary of speculations initiated by this page.
433
429
  **/
434
- export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableComponent<UI.Widget.VBox> {
435
- readonly #shadow = this.attachShadow({mode: 'open'});
430
+ export class UsedPreloadingView extends UI.Widget.VBox {
436
431
  readonly #view: View;
437
432
 
438
433
  constructor(view = DEFAULT_VIEW) {
439
- super();
434
+ super({useShadowDom: true});
440
435
  this.#view = view;
441
436
  }
442
437
 
@@ -448,17 +443,15 @@ export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableCom
448
443
 
449
444
  set data(data: UsedPreloadingViewData) {
450
445
  this.#data = data;
451
- void this.#render();
446
+ this.requestUpdate();
452
447
  }
453
448
 
454
- async #render(): Promise<void> {
449
+ override performUpdate(): void {
455
450
  const viewInput: ViewInput = {
456
451
  speculativeLoadingStatusData: this.#getSpeculativeLoadingStatusForThisPageData(),
457
452
  speculationsInitiatedSummaryData: this.#getSpeculationsInitiatedByThisPageSummaryData(),
458
453
  };
459
- await RenderCoordinator.write('UsedPreloadingView render', () => {
460
- this.#view(viewInput, undefined, this.#shadow);
461
- });
454
+ this.#view(viewInput, undefined, this.contentElement);
462
455
  }
463
456
 
464
457
  #isPrerenderLike(speculationAction: Protocol.Preload.SpeculationAction): boolean {
@@ -583,11 +576,3 @@ export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableCom
583
576
  return {badges, revealRuleSetView, revealAttemptViewWithFilter};
584
577
  }
585
578
  }
586
-
587
- customElements.define('devtools-resources-used-preloading-view', UsedPreloadingView);
588
-
589
- declare global {
590
- interface HTMLElementTagNameMap {
591
- 'devtools-resources-used-preloading-view': UsedPreloadingView;
592
- }
593
- }
@@ -6,9 +6,10 @@ import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as Root from '../../core/root/root.js';
9
+ import * as AiCodeGeneration from '../../models/ai_code_generation/ai_code_generation.js';
9
10
  import * as Snackbars from '../../ui/components/snackbars/snackbars.js';
10
11
  import * as UI from '../../ui/legacy/legacy.js';
11
- import {html, nothing, render} from '../../ui/lit/lit.js';
12
+ import {html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
12
13
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
13
14
 
14
15
  import styles from './aiCodeCompletionTeaser.css.js';
@@ -61,17 +62,32 @@ const UIStringsNotTranslate = {
61
62
  */
62
63
  freDisclaimerTextAiWontAlwaysGetItRight: 'This feature uses AI and won’t always get it right',
63
64
  /**
64
- * @description Second disclaimer item text for the fre dialog.
65
+ * @description Code completion disclaimer item text for the fre dialog.
66
+ */
67
+ freDisclaimerTextAsYouType:
68
+ 'As you type, relevant data is being send to Google to generate code suggestions. Press Tab to accept.',
69
+ /**
70
+ * @description Code generation disclaimer item text for the fre dialog.
71
+ */
72
+ freDisclaimerDescribeCodeInComment:
73
+ 'In Console or Sources, describe the code you need in a comment, then press Ctrl+I to generate it.',
74
+ /**
75
+ * @description Code generation disclaimer item text for the fre dialog.
76
+ */
77
+ freDisclaimerDescribeCodeInCommentForMacOs:
78
+ 'In Console or Sources, describe the code you need in a comment, then press Cmd+I to generate it.',
79
+ /**
80
+ * @description Privacy disclaimer item text for the fre dialog.
65
81
  */
66
82
  freDisclaimerTextPrivacy:
67
83
  'To generate code suggestions, your console input, the history of your current console session, the currently inspected CSS, and the contents of the currently open file are shared with Google. This data may be seen by human reviewers to improve this feature.',
68
84
  /**
69
- * @description Second disclaimer item text for the fre dialog when enterprise logging is off.
85
+ * @description Privacy disclaimer item text for the fre dialog when enterprise logging is off.
70
86
  */
71
87
  freDisclaimerTextPrivacyNoLogging:
72
88
  'To generate code suggestions, your console input, the history of your current console session, the currently inspected CSS, and the contents of the currently open file are shared with Google. This data will not be used to improve Google’s AI models. Your organization may change these settings at any time.',
73
89
  /**
74
- * @description Third disclaimer item text for the fre dialog.
90
+ * @description Last disclaimer item text for the fre dialog.
75
91
  */
76
92
  freDisclaimerTextUseWithCaution: 'Use generated code snippets with caution',
77
93
  /**
@@ -192,15 +208,34 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
192
208
  }
193
209
  }
194
210
 
195
- onAction = async(event: Event): Promise<void> => {
196
- event.preventDefault();
197
- const result = await FreDialog.show({
198
- header: {iconName: 'smart-assistant', text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
199
- reminderItems: [
200
- {
201
- iconName: 'psychiatry',
202
- content: lockedString(UIStringsNotTranslate.freDisclaimerTextAiWontAlwaysGetItRight),
203
- },
211
+ #createReminderItems(): Array<{
212
+ iconName: string,
213
+ content: Common.UIString.LocalizedString|LitTemplate,
214
+ }> {
215
+ const reminderItems: Array<{
216
+ iconName: string,
217
+ content: Common.UIString.LocalizedString | LitTemplate,
218
+ }> = [{
219
+ iconName: 'psychiatry',
220
+ content: lockedString(UIStringsNotTranslate.freDisclaimerTextAiWontAlwaysGetItRight),
221
+ }];
222
+
223
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
224
+ if (AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(devtoolsLocale.locale)) {
225
+ reminderItems.push(
226
+ {
227
+ iconName: 'code',
228
+ content: lockedString(UIStringsNotTranslate.freDisclaimerTextAsYouType),
229
+ },
230
+ {
231
+ iconName: 'text-analysis',
232
+ content: Host.Platform.isMac() ?
233
+ lockedString(UIStringsNotTranslate.freDisclaimerDescribeCodeInCommentForMacOs) :
234
+ lockedString(UIStringsNotTranslate.freDisclaimerDescribeCodeInComment),
235
+ });
236
+ }
237
+
238
+ reminderItems.push(
204
239
  {
205
240
  iconName: 'google',
206
241
  content: this.#noLogging ? lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacyNoLogging) :
@@ -217,8 +252,16 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
217
252
  })}
218
253
  >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</x-link>`,
219
254
  // clang-format on
220
- }
221
- ],
255
+ });
256
+ return reminderItems;
257
+ }
258
+
259
+ onAction = async(event: Event): Promise<void> => {
260
+ event.preventDefault();
261
+
262
+ const result = await FreDialog.show({
263
+ header: {iconName: 'smart-assistant', text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
264
+ reminderItems: this.#createReminderItems(),
222
265
  onLearnMoreClick: () => {
223
266
  void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
224
267
  },
@@ -70,7 +70,7 @@ const UIStringsNotTranslate = {
70
70
  } as const;
71
71
 
72
72
  const lockedString = i18n.i18n.lockedString;
73
- const PROMOTION_ID = 'ai-code-generation';
73
+ export const PROMOTION_ID = 'ai-code-generation';
74
74
 
75
75
  export enum AiCodeGenerationTeaserDisplayState {
76
76
  TRIGGER = 'trigger',
@@ -982,7 +982,6 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
982
982
 
983
983
  const showMetricsWidgetInComputedPane = (): void => {
984
984
  this.metricsWidget.show(computedStylePanesWrapper.element, this.computedStyleWidget.element);
985
- this.metricsWidget.toggleVisibility(true /* visible */);
986
985
  this.stylesWidget.removeEventListener(StylesSidebarPaneEvents.STYLES_UPDATE_COMPLETED, toggleMetricsWidget);
987
986
  };
988
987
 
@@ -993,14 +992,18 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
993
992
  } else {
994
993
  this.metricsWidget.show(matchedStylePanesWrapper.element);
995
994
  if (!this.stylesWidget.hasMatchedStyles) {
996
- this.metricsWidget.toggleVisibility(false /* invisible */);
995
+ this.metricsWidget.hideWidget();
997
996
  }
998
997
  this.stylesWidget.addEventListener(StylesSidebarPaneEvents.STYLES_UPDATE_COMPLETED, toggleMetricsWidget);
999
998
  }
1000
999
  };
1001
1000
 
1002
1001
  const toggleMetricsWidget = (event: Common.EventTarget.EventTargetEvent<StylesUpdateCompletedEvent>): void => {
1003
- this.metricsWidget.toggleVisibility(event.data.hasMatchedStyles);
1002
+ if (event.data.hasMatchedStyles) {
1003
+ this.metricsWidget.showWidget();
1004
+ } else {
1005
+ this.metricsWidget.hideWidget();
1006
+ }
1004
1007
  };
1005
1008
 
1006
1009
  const tabSelected = (event: Common.EventTarget.EventTargetEvent<UI.TabbedPane.EventData>): void => {
@@ -2,7 +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
 
5
- import * as Common from '../../core/common/common.js';
5
+ import type * as Common from '../../core/common/common.js';
6
6
  import type * as SDK from '../../core/sdk/sdk.js';
7
7
  import * as UI from '../../ui/legacy/legacy.js';
8
8
 
@@ -10,16 +10,14 @@ import {type ComputedStyleModel, type CSSModelChangedEvent, Events} from './Comp
10
10
 
11
11
  export class ElementsSidebarPane extends UI.Widget.VBox {
12
12
  protected computedStyleModelInternal: ComputedStyleModel;
13
- private readonly updateThrottler: Common.Throttler.Throttler;
14
- private updateWhenVisible: boolean;
15
- constructor(computedStyleModel: ComputedStyleModel, delegatesFocus?: boolean) {
16
- super({useShadowDom: true, delegatesFocus, classes: ['flex-none']});
13
+ constructor(computedStyleModel: ComputedStyleModel, options: UI.Widget.WidgetOptions = {}) {
14
+ options.useShadowDom = options.useShadowDom ?? true;
15
+ options.classes = options.classes ?? [];
16
+ options.classes.push('flex-none');
17
+ super(options);
17
18
  this.computedStyleModelInternal = computedStyleModel;
18
19
  this.computedStyleModelInternal.addEventListener(Events.CSS_MODEL_CHANGED, this.onCSSModelChanged, this);
19
20
  this.computedStyleModelInternal.addEventListener(Events.COMPUTED_STYLE_CHANGED, this.onComputedStyleChanged, this);
20
-
21
- this.updateThrottler = new Common.Throttler.Throttler(100);
22
- this.updateWhenVisible = false;
23
21
  }
24
22
 
25
23
  node(): SDK.DOMModel.DOMNode|null {
@@ -34,29 +32,10 @@ export class ElementsSidebarPane extends UI.Widget.VBox {
34
32
  return this.computedStyleModelInternal;
35
33
  }
36
34
 
37
- async doUpdate(): Promise<void> {
35
+ override async performUpdate(): Promise<void> {
38
36
  return;
39
37
  }
40
38
 
41
- update(): void {
42
- this.updateWhenVisible = !this.isShowing();
43
- if (this.updateWhenVisible) {
44
- return;
45
- }
46
- void this.updateThrottler.schedule(innerUpdate.bind(this));
47
-
48
- function innerUpdate(this: ElementsSidebarPane): Promise<void> {
49
- return this.isShowing() ? this.doUpdate() : Promise.resolve();
50
- }
51
- }
52
-
53
- override wasShown(): void {
54
- super.wasShown();
55
- if (this.updateWhenVisible) {
56
- this.update();
57
- }
58
- }
59
-
60
39
  onCSSModelChanged(_event: Common.EventTarget.EventTargetEvent<CSSModelChangedEvent|null>): void {
61
40
  }
62
41