chrome-devtools-frontend 1.0.1553956 → 1.0.1555430

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 (85) hide show
  1. package/front_end/Images/src/spark.svg +10 -0
  2. package/front_end/core/protocol_client/InspectorBackend.ts +1 -1
  3. package/front_end/core/root/Runtime.ts +0 -4
  4. package/front_end/core/sdk/DOMModel.ts +101 -7
  5. package/front_end/core/sdk/ResourceTreeModel.ts +0 -1
  6. package/front_end/generated/SupportedCSSProperties.js +18 -0
  7. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -1
  8. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  9. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +1 -1
  10. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -1
  11. package/front_end/{ui/components → models}/annotations/AnnotationRepository.ts +3 -3
  12. package/front_end/models/annotations/README.md +7 -0
  13. package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
  14. package/front_end/models/javascript_metadata/NativeFunctions.js +15 -23
  15. package/front_end/models/stack_trace/StackTrace.ts +13 -2
  16. package/front_end/models/stack_trace/StackTraceImpl.ts +81 -6
  17. package/front_end/models/stack_trace/StackTraceModel.ts +35 -3
  18. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +45 -4
  19. package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +57 -0
  20. package/front_end/panels/ai_assistance/components/ChatView.ts +1 -0
  21. package/front_end/panels/ai_assistance/components/artifactsViewer.css +10 -0
  22. package/front_end/panels/application/BounceTrackingMitigationsTreeElement.ts +2 -6
  23. package/front_end/panels/application/components/BounceTrackingMitigationsView.ts +133 -118
  24. package/front_end/panels/application/preloading/PreloadingView.ts +12 -6
  25. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +230 -237
  26. package/front_end/panels/application/preloading/components/PreloadingGrid.ts +96 -79
  27. package/front_end/panels/application/preloading/components/preloadingGrid.css +26 -29
  28. package/front_end/panels/application/preloading/preloadingView.css +6 -0
  29. package/front_end/panels/common/Annotation.ts +1 -1
  30. package/front_end/panels/common/AnnotationManager.ts +1 -1
  31. package/front_end/panels/common/ExtensionView.ts +1 -0
  32. package/front_end/panels/console/ConsoleContextSelector.ts +74 -9
  33. package/front_end/panels/console/consoleContextSelector.css +31 -29
  34. package/front_end/panels/coverage/coverageListView.css +59 -57
  35. package/front_end/panels/elements/ElementsPanel.ts +1 -1
  36. package/front_end/panels/elements/ElementsTreeElement.ts +39 -1
  37. package/front_end/panels/elements/ElementsTreeOutline.ts +23 -21
  38. package/front_end/panels/elements/TopLayerContainer.ts +26 -91
  39. package/front_end/panels/explain/components/ConsoleInsight.ts +3 -3
  40. package/front_end/panels/network/NetworkItemView.ts +1 -1
  41. package/front_end/panels/network/NetworkLogView.ts +1 -1
  42. package/front_end/panels/network/NetworkPanel.ts +1 -1
  43. package/front_end/panels/recorder/RecorderController.ts +0 -1
  44. package/front_end/panels/security/CookieControlsView.ts +21 -10
  45. package/front_end/panels/security/SecurityPanelSidebar.ts +5 -0
  46. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +0 -1
  47. package/front_end/panels/timeline/TimelineUIUtils.ts +5 -8
  48. package/front_end/panels/timeline/components/Sidebar.ts +16 -7
  49. package/front_end/panels/timeline/components/SidebarInsightsTab.ts +169 -129
  50. package/front_end/panels/timeline/components/TimelineSummary.ts +75 -54
  51. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +16 -25
  52. package/front_end/panels/timeline/components/insights/Cache.ts +12 -8
  53. package/front_end/panels/timeline/components/insights/Checklist.ts +53 -43
  54. package/front_end/panels/timeline/components/insights/DOMSize.ts +25 -21
  55. package/front_end/panels/timeline/components/insights/DocumentLatency.ts +6 -3
  56. package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +7 -7
  57. package/front_end/panels/timeline/components/insights/FontDisplay.ts +7 -5
  58. package/front_end/panels/timeline/components/insights/ForcedReflow.ts +11 -9
  59. package/front_end/panels/timeline/components/insights/INPBreakdown.ts +7 -6
  60. package/front_end/panels/timeline/components/insights/ImageDelivery.ts +7 -5
  61. package/front_end/panels/timeline/components/insights/InsightRenderer.ts +20 -18
  62. package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +12 -12
  63. package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +7 -3
  64. package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +7 -7
  65. package/front_end/panels/timeline/components/insights/ModernHTTP.ts +7 -5
  66. package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +15 -13
  67. package/front_end/panels/timeline/components/insights/RenderBlocking.ts +2 -2
  68. package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +15 -14
  69. package/front_end/panels/timeline/components/insights/Table.ts +152 -130
  70. package/front_end/panels/timeline/components/insights/ThirdParties.ts +11 -9
  71. package/front_end/panels/timeline/components/sidebarInsightsTab.css +50 -48
  72. package/front_end/panels/timeline/components/timelineSummary.css +58 -57
  73. package/front_end/panels/timeline/thirdPartyTreeView.css +109 -0
  74. package/front_end/panels/timeline/timelineDetailsView.css +2 -4
  75. package/front_end/panels/timeline/timelinePanel.css +0 -110
  76. package/front_end/third_party/chromium/README.chromium +1 -1
  77. package/front_end/ui/components/settings/SettingCheckbox.ts +4 -6
  78. package/front_end/ui/legacy/TabbedPane.ts +20 -13
  79. package/front_end/ui/legacy/ViewManager.ts +2 -32
  80. package/front_end/ui/legacy/Widget.ts +1 -3
  81. package/front_end/ui/legacy/tabbedPane.css +4 -7
  82. package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
  83. package/package.json +1 -1
  84. /package/front_end/{ui/components → models}/annotations/AnnotationType.ts +0 -0
  85. /package/front_end/{ui/components → models}/annotations/annotations.ts +0 -0
@@ -7,15 +7,17 @@ import './Table.js';
7
7
  import * as i18n from '../../../../core/i18n/i18n.js';
8
8
  import type {CacheInsightModel} from '../../../../models/trace/insights/Cache.js';
9
9
  import * as Trace from '../../../../models/trace/trace.js';
10
+ import * as UI from '../../../../ui/legacy/legacy.js';
10
11
  import * as Lit from '../../../../ui/lit/lit.js';
11
12
 
12
13
  import {BaseInsightComponent} from './BaseInsightComponent.js';
13
14
  import {eventRef} from './EventRef.js';
14
- import {createLimitedRows, renderOthersLabel, type TableData, type TableDataRow} from './Table.js';
15
+ import {createLimitedRows, renderOthersLabel, Table, type TableDataRow} from './Table.js';
15
16
 
16
17
  const {UIStrings, i18nString, createOverlayForRequest} = Trace.Insights.Models.Cache;
17
18
 
18
19
  const {html} = Lit;
20
+ const {widgetConfig} = UI.Widget;
19
21
 
20
22
  export class Cache extends BaseInsightComponent<CacheInsightModel> {
21
23
  override internalName = 'cache';
@@ -56,13 +58,15 @@ export class Cache extends BaseInsightComponent<CacheInsightModel> {
56
58
  // clang-format off
57
59
  return html`
58
60
  <div class="insight-section">
59
- <devtools-performance-table
60
- .data=${{
61
- insight: this,
62
- headers: [i18nString(UIStrings.requestColumn), i18nString(UIStrings.cacheTTL)],
63
- rows,
64
- } as TableData}>
65
- </devtools-performance-table>
61
+ <devtools-widget
62
+ .widgetConfig=${widgetConfig(Table, {
63
+ data: {
64
+ insight: this,
65
+ headers: [i18nString(UIStrings.requestColumn), i18nString(UIStrings.cacheTTL)],
66
+ rows,
67
+ },
68
+ })}>
69
+ </devtools-widget>
66
70
  </div>`;
67
71
  // clang-format on
68
72
  }
@@ -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
  /**
7
6
  * @file A list of pass/fail conditions for an insight.
@@ -11,11 +10,13 @@ import '../../../../ui/kit/kit.js';
11
10
 
12
11
  import * as i18n from '../../../../core/i18n/i18n.js';
13
12
  import type * as Trace from '../../../../models/trace/trace.js';
14
- import * as ComponentHelpers from '../../../../ui/components/helpers/helpers.js';
13
+ import * as UI from '../../../../ui/legacy/legacy.js';
15
14
  import * as Lit from '../../../../ui/lit/lit.js';
16
15
 
17
16
  import checklistStyles from './checklist.css.js';
18
17
 
18
+ const {html} = Lit;
19
+
19
20
  const UIStrings = {
20
21
  /**
21
22
  * @description Text for a screen-reader label to tell the user that the icon represents a successful insight check
@@ -32,7 +33,43 @@ const UIStrings = {
32
33
  const str_ = i18n.i18n.registerUIStrings('panels/timeline/components/insights/Checklist.ts', UIStrings);
33
34
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
34
35
 
35
- const {html} = Lit;
36
+ interface ViewInput {
37
+ checklist: GenericChecklist;
38
+ }
39
+
40
+ type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
41
+
42
+ export const DEFAULT_VIEW: View = (input, output, target) => {
43
+ const {
44
+ checklist,
45
+ } = input;
46
+
47
+ function getIcon(check: GenericChecklist['']): Lit.TemplateResult {
48
+ const icon = check.value ? 'check-circle' : 'clear';
49
+
50
+ const ariaLabel = check.value ? i18nString(UIStrings.successAriaLabel, {PH1: check.label}) :
51
+ i18nString(UIStrings.failedAriaLabel, {PH1: check.label});
52
+ return html`
53
+ <devtools-icon
54
+ aria-label=${ariaLabel}
55
+ name=${icon}
56
+ class=${check.value ? 'check-passed' : 'check-failed'}
57
+ ></devtools-icon>
58
+ `;
59
+ }
60
+
61
+ // clang-format off
62
+ Lit.render(html`
63
+ <style>${checklistStyles}</style>
64
+ <ul>
65
+ ${Object.values(checklist).map(check => html`<li>
66
+ ${getIcon(check)}
67
+ <span data-checklist-label>${check.label}</span>
68
+ </li>`)}
69
+ </ul>
70
+ `, target);
71
+ // clang-format on
72
+ };
36
73
 
37
74
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
75
  type GenericChecklist = Trace.Insights.Types.Checklist<any>;
@@ -46,55 +83,28 @@ export interface TableDataRow {
46
83
  overlays?: Trace.Types.Overlays.Overlay[];
47
84
  }
48
85
 
49
- export class Checklist extends HTMLElement {
50
- readonly #shadow = this.attachShadow({mode: 'open'});
86
+ export class Checklist extends UI.Widget.Widget {
87
+ #view: View;
51
88
  #checklist?: GenericChecklist;
52
89
 
53
- set checklist(checklist: GenericChecklist) {
54
- this.#checklist = checklist;
55
- void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
56
- }
57
-
58
- connectedCallback(): void {
59
- void ComponentHelpers.ScheduledRender.scheduleRender(this, this.#render);
90
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
91
+ super(element, {useShadowDom: true});
92
+ this.#view = view;
60
93
  }
61
94
 
62
- #getIcon(check: GenericChecklist['']): Lit.TemplateResult {
63
- const icon = check.value ? 'check-circle' : 'clear';
64
-
65
- const ariaLabel = check.value ? i18nString(UIStrings.successAriaLabel, {PH1: check.label}) :
66
- i18nString(UIStrings.failedAriaLabel, {PH1: check.label});
67
- return html`
68
- <devtools-icon
69
- aria-label=${ariaLabel}
70
- name=${icon}
71
- class=${check.value ? 'check-passed' : 'check-failed'}
72
- ></devtools-icon>
73
- `;
95
+ set checklist(checklist: GenericChecklist) {
96
+ this.#checklist = checklist;
97
+ this.requestUpdate();
74
98
  }
75
99
 
76
- async #render(): Promise<void> {
100
+ override performUpdate(): void {
77
101
  if (!this.#checklist) {
78
102
  return;
79
103
  }
80
104
 
81
- Lit.render(
82
- html`
83
- <style>${checklistStyles}</style>
84
- <ul>
85
- ${Object.values(this.#checklist).map(check => html`<li>
86
- ${this.#getIcon(check)}
87
- <span data-checklist-label>${check.label}</span>
88
- </li>`)}
89
- </ul>`,
90
- this.#shadow, {host: this});
105
+ const input: ViewInput = {
106
+ checklist: this.#checklist,
107
+ };
108
+ this.#view(input, undefined, this.contentElement);
91
109
  }
92
110
  }
93
-
94
- declare global {
95
- interface HTMLElementTagNameMap {
96
- 'devtools-performance-checklist': Checklist;
97
- }
98
- }
99
-
100
- customElements.define('devtools-performance-checklist', Checklist);
@@ -8,17 +8,19 @@ import './Table.js';
8
8
  import * as i18n from '../../../../core/i18n/i18n.js';
9
9
  import type {DOMSizeInsightModel} from '../../../../models/trace/insights/DOMSize.js';
10
10
  import * as Trace from '../../../../models/trace/trace.js';
11
+ import * as UI from '../../../../ui/legacy/legacy.js';
11
12
  import * as Lit from '../../../../ui/lit/lit.js';
12
13
 
13
14
  import {BaseInsightComponent} from './BaseInsightComponent.js';
14
15
  import {eventRef} from './EventRef.js';
15
16
  import {md} from './Helpers.js';
16
17
  import {nodeLink} from './NodeLink.js';
17
- import type {TableData, TableDataRow} from './Table.js';
18
+ import {Table, type TableDataRow} from './Table.js';
18
19
 
19
20
  const {UIStrings, i18nString} = Trace.Insights.Models.DOMSize;
20
21
 
21
22
  const {html} = Lit;
23
+ const {widgetConfig} = UI.Widget;
22
24
 
23
25
  export class DOMSize extends BaseInsightComponent<DOMSizeInsightModel> {
24
26
  override internalName = 'dom-size';
@@ -28,7 +30,7 @@ export class DOMSize extends BaseInsightComponent<DOMSizeInsightModel> {
28
30
  }
29
31
 
30
32
  #renderNodeTable(domStatsData: Trace.Types.Events.DOMStats['args']['data']): Lit.LitTemplate {
31
- const rows: TableData['rows'] = [];
33
+ const rows: TableDataRow[] = [];
32
34
 
33
35
  if (domStatsData.maxDepth) {
34
36
  const {nodeId, nodeName} = domStatsData.maxDepth;
@@ -56,13 +58,13 @@ export class DOMSize extends BaseInsightComponent<DOMSizeInsightModel> {
56
58
 
57
59
  // clang-format off
58
60
  return html`<div class="insight-section">
59
- <devtools-performance-table
60
- .data=${{
61
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
62
+ data: {
61
63
  insight: this,
62
64
  headers: [i18nString(UIStrings.statistic), i18nString(UIStrings.element)],
63
65
  rows,
64
- } as TableData}>
65
- </devtools-performance-table>
66
+ }})}>
67
+ </devtools-widget>
66
68
  </div>`;
67
69
  // clang-format on
68
70
  }
@@ -86,13 +88,13 @@ export class DOMSize extends BaseInsightComponent<DOMSizeInsightModel> {
86
88
  // clang-format off
87
89
  return html`<div class="insight-section">
88
90
  <div class="insight-description">${md(i18nString(UIStrings.topUpdatesDescription))}</div>
89
- <devtools-performance-table
90
- .data=${{
91
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
92
+ data: {
91
93
  insight: this,
92
94
  headers: ['', i18nString(UIStrings.duration)],
93
95
  rows,
94
- } as TableData}>
95
- </devtools-performance-table>
96
+ }})}>
97
+ </devtools-widget>
96
98
  </div>`;
97
99
  // clang-format on
98
100
  }
@@ -109,17 +111,19 @@ export class DOMSize extends BaseInsightComponent<DOMSizeInsightModel> {
109
111
 
110
112
  // clang-format off
111
113
  return html`<div class="insight-section">
112
- <devtools-performance-table
113
- .data=${{
114
- insight: this,
115
- headers: [i18nString(UIStrings.statistic), i18nString(UIStrings.value)],
116
- rows: [
117
- {values: [i18nString(UIStrings.totalElements), domStatsData.totalElements]},
118
- {values: [i18nString(UIStrings.maxDOMDepth), domStatsData.maxDepth?.depth ?? 0]},
119
- {values: [i18nString(UIStrings.maxChildren), domStatsData.maxChildren?.numChildren ?? 0]},
120
- ],
121
- } as TableData}>
122
- </devtools-performance-table>
114
+ <devtools-widget
115
+ .widgetConfig=${widgetConfig(Table, {
116
+ data: {
117
+ insight: this,
118
+ headers: [i18nString(UIStrings.statistic), i18nString(UIStrings.value)],
119
+ rows: [
120
+ {values: [i18nString(UIStrings.totalElements), domStatsData.totalElements]},
121
+ {values: [i18nString(UIStrings.maxDOMDepth), domStatsData.maxDepth?.depth ?? 0]},
122
+ {values: [i18nString(UIStrings.maxChildren), domStatsData.maxChildren?.numChildren ?? 0]},
123
+ ],
124
+ },
125
+ })}>
126
+ </devtools-widget>
123
127
  </div>
124
128
  ${this.#renderNodeTable(domStatsData)}
125
129
  ${this.#renderLargeUpdatesTable()}
@@ -2,15 +2,16 @@
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 './Checklist.js';
6
-
7
5
  import type {DocumentLatencyInsightModel} from '../../../../models/trace/insights/DocumentLatency.js';
8
6
  import type * as Trace from '../../../../models/trace/trace.js';
7
+ import * as UI from '../../../../ui/legacy/legacy.js';
9
8
  import * as Lit from '../../../../ui/lit/lit.js';
10
9
 
11
10
  import {BaseInsightComponent} from './BaseInsightComponent.js';
11
+ import {Checklist} from './Checklist.js';
12
12
 
13
13
  const {html} = Lit;
14
+ const {widgetConfig} = UI.Widget;
14
15
 
15
16
  export class DocumentLatency extends BaseInsightComponent<DocumentLatencyInsightModel> {
16
17
  override internalName = 'document-latency';
@@ -29,7 +30,9 @@ export class DocumentLatency extends BaseInsightComponent<DocumentLatencyInsight
29
30
  }
30
31
 
31
32
  // clang-format off
32
- return html`<devtools-performance-checklist .checklist=${this.model.data.checklist}></devtools-performance-checklist>`;
33
+ return html`<devtools-widget .widgetConfig=${widgetConfig(Checklist, {
34
+ checklist: this.model.data.checklist,
35
+ })}></devtools-widget>`;
33
36
  // clang-format on
34
37
  }
35
38
  }
@@ -2,23 +2,23 @@
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 './Table.js';
6
-
7
5
  import * as i18n from '../../../../core/i18n/i18n.js';
8
6
  import type {DuplicatedJavaScriptInsightModel} from '../../../../models/trace/insights/DuplicatedJavaScript.js';
9
7
  import * as Trace from '../../../../models/trace/trace.js';
10
8
  import * as Buttons from '../../../../ui/components/buttons/buttons.js';
9
+ import * as UI from '../../../../ui/legacy/legacy.js';
11
10
  import * as Lit from '../../../../ui/lit/lit.js';
12
11
  import * as VisualLogging from '../../../../ui/visual_logging/visual_logging.js';
13
12
  import * as Utils from '../../utils/utils.js';
14
13
 
15
14
  import {BaseInsightComponent} from './BaseInsightComponent.js';
16
15
  import {scriptRef} from './ScriptRef.js';
17
- import type {TableData, TableDataRow} from './Table.js';
16
+ import {Table, type TableDataRow} from './Table.js';
18
17
 
19
18
  const {UIStrings, i18nString} = Trace.Insights.Models.DuplicatedJavaScript;
20
19
 
21
20
  const {html} = Lit;
21
+ const {widgetConfig} = UI.Widget;
22
22
 
23
23
  export class DuplicatedJavaScript extends BaseInsightComponent<DuplicatedJavaScriptInsightModel> {
24
24
  override internalName = 'duplicated-javascript';
@@ -105,13 +105,13 @@ export class DuplicatedJavaScript extends BaseInsightComponent<DuplicatedJavaScr
105
105
  return html`
106
106
  ${treemapButton}
107
107
  <div class="insight-section">
108
- <devtools-performance-table
109
- .data=${{
108
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
109
+ data: {
110
110
  insight: this,
111
111
  headers: [i18nString(UIStrings.columnSource), i18nString(UIStrings.columnDuplicatedBytes)],
112
112
  rows,
113
- } as TableData}>
114
- </devtools-performance-table>
113
+ }})}>
114
+ </devtools-widget>
115
115
  </div>
116
116
  `;
117
117
  // clang-format on
@@ -7,15 +7,17 @@ import './Table.js';
7
7
  import * as i18n from '../../../../core/i18n/i18n.js';
8
8
  import type {FontDisplayInsightModel} from '../../../../models/trace/insights/FontDisplay.js';
9
9
  import * as Trace from '../../../../models/trace/trace.js';
10
+ import * as UI from '../../../../ui/legacy/legacy.js';
10
11
  import * as Lit from '../../../../ui/lit/lit.js';
11
12
 
12
13
  import {BaseInsightComponent} from './BaseInsightComponent.js';
13
14
  import {eventRef} from './EventRef.js';
14
- import {createLimitedRows, renderOthersLabel, type TableData, type TableDataRow} from './Table.js';
15
+ import {createLimitedRows, renderOthersLabel, Table, type TableDataRow} from './Table.js';
15
16
 
16
17
  const {UIStrings, i18nString} = Trace.Insights.Models.FontDisplay;
17
18
 
18
19
  const {html} = Lit;
20
+ const {widgetConfig} = UI.Widget;
19
21
 
20
22
  export class FontDisplay extends BaseInsightComponent<FontDisplayInsightModel> {
21
23
  override internalName = 'font-display';
@@ -76,13 +78,13 @@ export class FontDisplay extends BaseInsightComponent<FontDisplayInsightModel> {
76
78
  // clang-format off
77
79
  return html`
78
80
  <div class="insight-section">
79
- ${html`<devtools-performance-table
80
- .data=${{
81
+ ${html`<devtools-widget .widgetConfig=${widgetConfig(Table, {
82
+ data: {
81
83
  insight: this,
82
84
  headers: [i18nString(UIStrings.fontColumn), i18nString(UIStrings.wastedTimeColumn)],
83
85
  rows,
84
- } as TableData}>
85
- </devtools-performance-table>`}
86
+ }})}>
87
+ </devtools-widget>`}
86
88
  </div>`;
87
89
  // clang-format on
88
90
  }
@@ -9,14 +9,16 @@ import type * as Protocol from '../../../../generated/protocol.js';
9
9
  import type {ForcedReflowInsightModel} from '../../../../models/trace/insights/ForcedReflow.js';
10
10
  import * as Trace from '../../../../models/trace/trace.js';
11
11
  import * as LegacyComponents from '../../../../ui/legacy/components/utils/utils.js';
12
+ import * as UI from '../../../../ui/legacy/legacy.js';
12
13
  import * as Lit from '../../../../ui/lit/lit.js';
13
14
 
14
15
  import {BaseInsightComponent} from './BaseInsightComponent.js';
15
- import {createLimitedRows, renderOthersLabel, type TableData, type TableDataRow} from './Table.js';
16
+ import {createLimitedRows, renderOthersLabel, Table, type TableDataRow} from './Table.js';
16
17
 
17
18
  const {UIStrings, i18nString, createOverlayForEvents} = Trace.Insights.Models.ForcedReflow;
18
19
 
19
20
  const {html, nothing} = Lit;
21
+ const {widgetConfig} = UI.Widget;
20
22
 
21
23
  export class ForcedReflow extends BaseInsightComponent<ForcedReflowInsightModel> {
22
24
  override internalName = 'forced-reflow';
@@ -85,8 +87,8 @@ export class ForcedReflow extends BaseInsightComponent<ForcedReflowInsightModel>
85
87
  return html`
86
88
  ${topLevelFunctionCallData ? html`
87
89
  <div class="insight-section">
88
- <devtools-performance-table
89
- .data=${{
90
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
91
+ data: {
90
92
  insight: this,
91
93
  headers: [i18nString(UIStrings.topTimeConsumingFunctionCall), i18nString(UIStrings.totalReflowTime)],
92
94
  rows: [{
@@ -96,18 +98,18 @@ export class ForcedReflow extends BaseInsightComponent<ForcedReflowInsightModel>
96
98
  ],
97
99
  overlays: createOverlayForEvents(topLevelFunctionCallData.topLevelFunctionCallEvents, 'INFO'),
98
100
  }],
99
- } as TableData}>
100
- </devtools-performance-table>
101
+ }})}>
102
+ </devtools-widget>
101
103
  </div>
102
104
  ` : nothing}
103
105
  <div class="insight-section">
104
- <devtools-performance-table
105
- .data=${{
106
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
107
+ data: {
106
108
  insight: this,
107
109
  headers: [i18nString(UIStrings.reflowCallFrames)],
108
110
  rows,
109
- } as TableData}>
110
- </devtools-performance-table>
111
+ }})}>
112
+ </devtools-widget>
111
113
  </div>`;
112
114
  // clang-format on
113
115
  }
@@ -2,19 +2,20 @@
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 './Table.js';
6
-
7
5
  import * as i18n from '../../../../core/i18n/i18n.js';
8
6
  import * as Platform from '../../../../core/platform/platform.js';
9
7
  import type {INPBreakdownInsightModel} from '../../../../models/trace/insights/INPBreakdown.js';
10
8
  import * as Trace from '../../../../models/trace/trace.js';
9
+ import * as UI from '../../../../ui/legacy/legacy.js';
11
10
  import * as Lit from '../../../../ui/lit/lit.js';
12
11
 
13
12
  import {BaseInsightComponent} from './BaseInsightComponent.js';
13
+ import {Table} from './Table.js';
14
14
 
15
15
  const {UIStrings, i18nString, createOverlaysForSubpart} = Trace.Insights.Models.INPBreakdown;
16
16
 
17
17
  const {html} = Lit;
18
+ const {widgetConfig} = UI.Widget;
18
19
 
19
20
  export class INPBreakdown extends BaseInsightComponent<INPBreakdownInsightModel> {
20
21
  override internalName = 'inp';
@@ -35,8 +36,8 @@ export class INPBreakdown extends BaseInsightComponent<INPBreakdownInsightModel>
35
36
  // clang-format off
36
37
  return html`
37
38
  <div class="insight-section">
38
- ${html`<devtools-performance-table
39
- .data=${{
39
+ ${html`<devtools-widget .widgetConfig=${widgetConfig(Table, {
40
+ data: {
40
41
  insight: this,
41
42
  headers: [i18nString(UIStrings.subpart), i18nString(UIStrings.duration)],
42
43
  rows: [
@@ -53,8 +54,8 @@ export class INPBreakdown extends BaseInsightComponent<INPBreakdownInsightModel>
53
54
  overlays: createOverlaysForSubpart(event, 2),
54
55
  },
55
56
  ],
56
- }}>
57
- </devtools-performance-table>`}
57
+ }})}>
58
+ </devtools-widget>`}
58
59
  </div>`;
59
60
  // clang-format on
60
61
  }
@@ -6,15 +6,17 @@ import '../../../../ui/kit/kit.js';
6
6
 
7
7
  import type {ImageDeliveryInsightModel} from '../../../../models/trace/insights/ImageDelivery.js';
8
8
  import * as Trace from '../../../../models/trace/trace.js';
9
+ import * as UI from '../../../../ui/legacy/legacy.js';
9
10
  import * as Lit from '../../../../ui/lit/lit.js';
10
11
 
11
12
  import {BaseInsightComponent} from './BaseInsightComponent.js';
12
13
  import {imageRef} from './ImageRef.js';
13
- import {createLimitedRows, renderOthersLabel, type TableDataRow} from './Table.js';
14
+ import {createLimitedRows, renderOthersLabel, Table, type TableDataRow} from './Table.js';
14
15
 
15
16
  const {UIStrings, i18nString, createOverlayForRequest} = Trace.Insights.Models.ImageDelivery;
16
17
 
17
18
  const {html} = Lit;
19
+ const {widgetConfig} = UI.Widget;
18
20
 
19
21
  export class ImageDelivery extends BaseInsightComponent<ImageDeliveryInsightModel> {
20
22
  override internalName = 'image-delivery';
@@ -56,13 +58,13 @@ export class ImageDelivery extends BaseInsightComponent<ImageDeliveryInsightMode
56
58
  // clang-format off
57
59
  return html`
58
60
  <div class="insight-section">
59
- <devtools-performance-table
60
- .data=${{
61
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
62
+ data: {
61
63
  insight: this,
62
64
  headers: [i18nString(UIStrings.optimizeFile)],
63
65
  rows,
64
- }}>
65
- </devtools-performance-table>
66
+ }})}>
67
+ </devtools-widget>
66
68
  </div>
67
69
  `;
68
70
  // clang-format on
@@ -61,30 +61,32 @@ export class InsightRenderer {
61
61
  renderInsightToWidgetElement(
62
62
  parsedTrace: Trace.TraceModel.ParsedTrace, insightSet: Trace.Insights.Types.InsightSet,
63
63
  model: Trace.Insights.Types.InsightModel, insightName: string,
64
- options: Partial<BaseInsightComponent<Trace.Insights.Types.InsightModel>>): InsightWidgetElement {
64
+ options: Partial<Pick<
65
+ BaseInsightComponent<Trace.Insights.Types.InsightModel>,
66
+ 'selected'|'agentFocus'|'fieldMetrics'|'isAIAssistanceContext'>>): InsightWidgetElement {
65
67
  let widgetElement = this.#insightWidgetCache.get(model);
66
68
  if (!widgetElement) {
67
69
  widgetElement = document.createElement('devtools-widget') as InsightWidgetElement;
68
-
69
- const componentClass = INSIGHT_NAME_TO_COMPONENT[insightName as keyof typeof INSIGHT_NAME_TO_COMPONENT];
70
- const widget = new componentClass(widgetElement) as BaseInsightComponent<Trace.Insights.Types.InsightModel>;
71
- widget.selected = false;
72
- widget.parsedTrace = parsedTrace;
73
- widget.model = model;
74
- widget.bounds = insightSet.bounds;
75
- widget.insightSetKey = insightSet.id;
76
- Object.assign(widget, options);
77
- widgetElement.widgetConfig = widgetConfig(() => {
78
- return widget;
79
- });
80
-
70
+ widgetElement.classList.add('insight-component-widget');
81
71
  this.#insightWidgetCache.set(model, widgetElement);
82
72
  }
83
73
 
84
- const widget = widgetElement.getWidget();
85
- if (widget) {
86
- Object.assign(widget, options);
87
- }
74
+ const componentClass = INSIGHT_NAME_TO_COMPONENT[insightName as keyof typeof INSIGHT_NAME_TO_COMPONENT];
75
+ widgetElement.widgetConfig = widgetConfig(componentClass, {
76
+ selected: options.selected ?? false,
77
+ parsedTrace,
78
+ // The `model` passed in as a parameter is the base type, but since
79
+ // `componentClass` is the union of every derived insight component, the
80
+ // `model` for the widget config is the union of every model. That can't be
81
+ // satisfied, so disable typescript.
82
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
83
+ model: model as any,
84
+ bounds: insightSet.bounds,
85
+ insightSetKey: insightSet.id,
86
+ agentFocus: options.agentFocus ?? null,
87
+ fieldMetrics: options.fieldMetrics ?? null,
88
+ isAIAssistanceContext: options.isAIAssistanceContext ?? false,
89
+ });
88
90
 
89
91
  return widgetElement;
90
92
  }
@@ -2,20 +2,20 @@
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 './Table.js';
6
-
7
5
  import * as i18n from '../../../../core/i18n/i18n.js';
8
6
  import type {LCPBreakdownInsightModel} from '../../../../models/trace/insights/LCPBreakdown.js';
9
7
  import * as Trace from '../../../../models/trace/trace.js';
8
+ import * as UI from '../../../../ui/legacy/legacy.js';
10
9
  import * as Lit from '../../../../ui/lit/lit.js';
11
10
  import type * as Overlays from '../../overlays/overlays.js';
12
11
 
13
12
  import {BaseInsightComponent} from './BaseInsightComponent.js';
14
- import type {TableData} from './Table.js';
13
+ import {Table, type TableDataRow} from './Table.js';
15
14
 
16
15
  const {UIStrings, i18nString} = Trace.Insights.Models.LCPBreakdown;
17
16
 
18
17
  const {html} = Lit;
18
+ const {widgetConfig} = UI.Widget;
19
19
 
20
20
  export class LCPBreakdown extends BaseInsightComponent<LCPBreakdownInsightModel> {
21
21
  override internalName = 'lcp-by-phase';
@@ -69,13 +69,13 @@ export class LCPBreakdown extends BaseInsightComponent<LCPBreakdownInsightModel>
69
69
  // clang-format off
70
70
  return html`
71
71
  <div class="insight-section">
72
- <devtools-performance-table
73
- .data=${{
72
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
73
+ data: {
74
74
  insight: this,
75
75
  headers: [i18nString(UIStrings.subpart), i18nString(UIStrings.fieldDuration)],
76
76
  rows,
77
- } as TableData}>
78
- </devtools-performance-table>
77
+ }})}>
78
+ </devtools-widget>
79
79
  </div>
80
80
  `;
81
81
  // clang-format on
@@ -101,7 +101,7 @@ export class LCPBreakdown extends BaseInsightComponent<LCPBreakdownInsightModel>
101
101
  return html`<div class="insight-section">${i18nString(UIStrings.noLcp)}</div>`;
102
102
  }
103
103
 
104
- const rows = Object.values(subparts).map((subpart: Trace.Insights.Models.LCPBreakdown.Subpart) => {
104
+ const rows: TableDataRow[] = Object.values(subparts).map((subpart: Trace.Insights.Models.LCPBreakdown.Subpart) => {
105
105
  const section = this.#overlay?.sections.find(section => subpart.label === section.label);
106
106
  const timing = Trace.Helpers.Timing.microToMilli(subpart.range);
107
107
  return {
@@ -116,13 +116,13 @@ export class LCPBreakdown extends BaseInsightComponent<LCPBreakdownInsightModel>
116
116
  // clang-format off
117
117
  const sections: Lit.LitTemplate[] = [html`
118
118
  <div class="insight-section">
119
- <devtools-performance-table
120
- .data=${{
119
+ <devtools-widget .widgetConfig=${widgetConfig(Table, {
120
+ data: {
121
121
  insight: this,
122
122
  headers: [i18nString(UIStrings.subpart), i18nString(UIStrings.duration)],
123
123
  rows,
124
- } as TableData}>
125
- </devtools-performance-table>
124
+ }})}>
125
+ </devtools-widget>
126
126
  </div>`
127
127
  ];
128
128
  // clang-format on