chrome-devtools-frontend 1.0.1605219 → 1.0.1606789

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 (78) hide show
  1. package/front_end/Images/src/dots-circle.svg +10 -0
  2. package/front_end/core/host/UserMetrics.ts +0 -1
  3. package/front_end/core/platform/api/HostRuntime.ts +9 -6
  4. package/front_end/core/platform/browser/HostRuntime.ts +2 -2
  5. package/front_end/core/platform/node/HostRuntime.ts +7 -7
  6. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  7. package/front_end/core/root/ExperimentNames.ts +0 -1
  8. package/front_end/core/sdk/CrashReportContextModel.ts +28 -0
  9. package/front_end/core/sdk/sdk.ts +2 -2
  10. package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshotWorkerDispatcher.ts +3 -3
  11. package/front_end/entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.ts +5 -4
  12. package/front_end/entrypoints/main/MainImpl.ts +0 -101
  13. package/front_end/models/ai_assistance/ChangeManager.ts +6 -6
  14. package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +112 -5
  15. package/front_end/models/ai_assistance/agents/AiAgent.ts +9 -25
  16. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +2 -2
  17. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +6 -3
  18. package/front_end/models/ai_assistance/agents/ConversationSummaryAgent.ts +10 -9
  19. package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +313 -0
  20. package/front_end/models/ai_assistance/agents/FileAgent.ts +15 -1
  21. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +15 -1
  22. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +19 -8
  23. package/front_end/models/ai_assistance/agents/StylingAgent.ts +35 -278
  24. package/front_end/models/ai_assistance/ai_assistance.ts +0 -2
  25. package/front_end/models/javascript_metadata/NativeFunctions.js +1 -5
  26. package/front_end/models/web_mcp/WebMCPModel.ts +187 -0
  27. package/front_end/models/web_mcp/web_mcp.ts +9 -0
  28. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +8 -1
  29. package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
  30. package/front_end/panels/ai_assistance/components/AccessibilityAgentMarkdownRenderer.ts +88 -0
  31. package/front_end/panels/ai_assistance/components/ChatMessage.ts +149 -49
  32. package/front_end/panels/ai_assistance/components/ChatView.ts +11 -15
  33. package/front_end/panels/ai_assistance/components/ExportForAgentsDialog.ts +13 -4
  34. package/front_end/panels/ai_assistance/components/chatMessage.css +53 -1
  35. package/front_end/panels/ai_assistance/components/chatView.css +0 -10
  36. package/front_end/panels/ai_assistance/components/exportForAgentsDialog.css +13 -0
  37. package/front_end/panels/application/WebMCPView.ts +471 -25
  38. package/front_end/panels/application/webMCPView.css +53 -2
  39. package/front_end/panels/elements/ElementsTreeElement.ts +1 -1
  40. package/front_end/panels/elements/ElementsTreeOutline.ts +87 -0
  41. package/front_end/panels/elements/StylePropertiesSection.ts +0 -4
  42. package/front_end/panels/elements/elements.ts +3 -0
  43. package/front_end/panels/elements/elementsTreeOutline.css +21 -0
  44. package/front_end/panels/elements/stylePropertiesTreeOutline.css +7 -0
  45. package/front_end/panels/lighthouse/LighthousePanel.ts +7 -1
  46. package/front_end/panels/lighthouse/LighthouseProtocolService.ts +25 -2
  47. package/front_end/panels/profiler/HeapDetachedElementsView.ts +0 -4
  48. package/front_end/panels/profiler/HeapProfileView.ts +0 -4
  49. package/front_end/panels/profiler/HeapProfilerPanel.ts +4 -13
  50. package/front_end/panels/profiler/HeapSnapshotProxy.ts +2 -6
  51. package/front_end/panels/profiler/HeapSnapshotView.ts +19 -32
  52. package/front_end/panels/profiler/ProfileHeader.ts +1 -15
  53. package/front_end/panels/profiler/ProfileTypeRegistry.ts +4 -12
  54. package/front_end/panels/profiler/ProfileView.ts +1 -6
  55. package/front_end/panels/profiler/ProfilesPanel.ts +60 -7
  56. package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +27 -22
  57. package/front_end/panels/timeline/EventsTimelineTreeView.ts +1 -1
  58. package/front_end/panels/timeline/ThirdPartyTreeView.ts +2 -2
  59. package/front_end/panels/timeline/TimelinePanel.ts +11 -153
  60. package/front_end/panels/timeline/TimelineTreeView.ts +147 -48
  61. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
  62. package/front_end/panels/timeline/components/CWVMetrics.ts +18 -2
  63. package/front_end/panels/timeline/timeline-meta.ts +11 -0
  64. package/front_end/panels/timeline/utils/Helpers.ts +5 -0
  65. package/front_end/third_party/chromium/README.chromium +1 -1
  66. package/front_end/ui/components/markdown_view/CodeBlock.ts +47 -1
  67. package/front_end/ui/components/markdown_view/codeBlock.css +8 -0
  68. package/front_end/ui/legacy/FilterBar.ts +2 -0
  69. package/front_end/ui/legacy/SplitWidget.ts +33 -27
  70. package/front_end/ui/legacy/TabbedPane.ts +123 -3
  71. package/front_end/ui/legacy/Widget.ts +95 -48
  72. package/front_end/ui/legacy/components/source_frame/JSONView.ts +1 -1
  73. package/front_end/ui/legacy/components/utils/jsUtils.css +2 -0
  74. package/front_end/ui/legacy/infobar.css +1 -0
  75. package/front_end/ui/visual_logging/KnownContextValues.ts +6 -1
  76. package/package.json +1 -1
  77. package/front_end/core/sdk/WebMCPModel.ts +0 -104
  78. package/front_end/models/ai_assistance/ConversationHandler.ts +0 -325
@@ -23,6 +23,14 @@
23
23
  flex: auto;
24
24
  }
25
25
 
26
+ devtools-data-grid {
27
+ flex: auto;
28
+ }
29
+
30
+ devtools-data-grid td {
31
+ vertical-align: middle;
32
+ }
33
+
26
34
  .section-title {
27
35
  background-color: var(--sys-color-surface1);
28
36
  padding: 0 5px;
@@ -33,9 +41,17 @@
33
41
  color: var(--sys-color-on-surface);
34
42
  }
35
43
 
44
+ .status-cell {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 4px;
48
+ }
49
+
36
50
  devtools-list {
37
51
  flex: 1 1 auto;
38
- margin: var(--sys-size-4);
52
+ margin: 0;
53
+ padding: var(--sys-size-4);
54
+ box-sizing: border-box;
39
55
  }
40
56
 
41
57
  .tool-item {
@@ -44,22 +60,57 @@
44
60
  padding: 8px 0;
45
61
  gap: 4px;
46
62
  width: 100%;
63
+ min-width: 0;
47
64
  border-bottom: 1px solid var(--sys-color-divider);
48
65
  }
49
66
 
50
67
  .tool-name-container {
51
68
  display: flex;
52
69
  justify-content: space-between;
53
- align-items: center;
70
+ align-items: flex-start;
71
+ gap: 8px;
54
72
  }
55
73
 
56
74
  .tool-name.source-code {
57
75
  color: var(--sys-color-token-string);
76
+ white-space: nowrap;
77
+ overflow: hidden;
78
+ text-overflow: ellipsis;
79
+ min-width: 0;
80
+ flex: 1;
81
+ }
82
+
83
+ /* stylelint-disable-next-line selector-type-no-unknown */
84
+ .tool-name-container icon-button {
85
+ flex-shrink: 0;
86
+ height: 0;
87
+ overflow: visible;
88
+ display: flex;
89
+ align-items: center;
58
90
  }
59
91
 
60
92
  .tool-description {
61
93
  color: var(--sys-color-on-surface);
62
94
  }
63
95
 
96
+ tr.status-error {
97
+ color: var(--sys-color-error);
98
+ }
99
+
100
+ devtools-toolbar-input {
101
+ flex-grow: 1;
102
+ flex-shrink: 1;
103
+ }
104
+
105
+ tr.status-cancelled {
106
+ color: var(--sys-color-on-surface-light);
107
+ }
64
108
 
109
+ .toolbar-text.status-error-text {
110
+ color: var(--sys-color-error);
111
+ }
112
+
113
+ .toolbar-text.status-cancelled-text {
114
+ color: var(--sys-color-on-surface-light);
115
+ }
65
116
  }
@@ -878,7 +878,7 @@ function maybeRenderAdAdorner(input: ViewInput): Lit.TemplateResult|typeof nothi
878
878
  // clang-format off
879
879
  return html`
880
880
  <devtools-adorner
881
- aria-describedby=${input.adTooltipId}
881
+ aria-details=${input.adTooltipId}
882
882
  aria-label=${i18nString(UIStrings.thisElementWasIdentifiedAsAnAd)}
883
883
  .name=${ElementsComponents.AdornerManager.RegisteredAdorners.AD}
884
884
  jslog=${VisualLogging.adorner(ElementsComponents.AdornerManager.RegisteredAdorners.AD)}
@@ -72,6 +72,11 @@ const UIStrings = {
72
72
  * @example {3} PH1
73
73
  */
74
74
  showAllNodesDMore: 'Show all nodes ({PH1} more)',
75
+ /**
76
+ * @description Text for a button to show all truncated lines in the tree.
77
+ * @example {5} PH1
78
+ */
79
+ showAllLines: 'Show all ({PH1} lines)',
75
80
  /**
76
81
  * @description Text for popover that directs to Issues panel
77
82
  */
@@ -98,6 +103,7 @@ interface ViewInput {
98
103
  expandRoot?: boolean;
99
104
  visibleWidth?: number;
100
105
  visible?: boolean;
106
+ maxRowsShown?: number;
101
107
  wrap: boolean;
102
108
  showSelectionOnKeyboardFocus: boolean;
103
109
  preventTabOrder: boolean;
@@ -134,6 +140,12 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
134
140
  ElementsTreeOutline.Events.ElementsTreeUpdated, input.onElementsTreeUpdated, this);
135
141
  output.elementsTreeOutline.addEventListener(UI.TreeOutline.Events.ElementExpanded, input.onElementExpanded, this);
136
142
  output.elementsTreeOutline.addEventListener(UI.TreeOutline.Events.ElementCollapsed, input.onElementCollapsed, this);
143
+ output.elementsTreeOutline.addEventListener(ElementsTreeOutline.Events.ShowAllRows, () => {
144
+ if (output.elementsTreeOutline?.maxRowsShown) {
145
+ // Set max to undefined to show all rows
146
+ output.elementsTreeOutline.maxRowsShown = undefined;
147
+ }
148
+ }, this);
137
149
  target.appendChild(output.elementsTreeOutline.element);
138
150
  }
139
151
 
@@ -150,6 +162,7 @@ export const DEFAULT_VIEW = (input: ViewInput, output: ViewOutput, target: HTMLE
150
162
  if (input.visible !== undefined) {
151
163
  output.elementsTreeOutline.setVisible(input.visible);
152
164
  }
165
+ output.elementsTreeOutline.maxRowsShown = input.maxRowsShown;
153
166
  output.elementsTreeOutline.setWordWrap(input.wrap);
154
167
  output.elementsTreeOutline.setShowSelectionOnKeyboardFocus(input.showSelectionOnKeyboardFocus, input.preventTabOrder);
155
168
  if (input.deindentSingleNode) {
@@ -234,6 +247,17 @@ export class DOMTreeWidget extends UI.Widget.Widget {
234
247
  #visible = false;
235
248
  #visibleWidth?: number;
236
249
  #wrap = false;
250
+ #maxRows?: number;
251
+
252
+ // If maxRows is undefined, all rows are shown. If it is set to a number, only that many rows are shown.
253
+ set maxRows(maxRows: number|undefined) {
254
+ this.#maxRows = maxRows;
255
+ this.requestUpdate();
256
+ }
257
+
258
+ get maxRows(): number|undefined {
259
+ return this.#maxRows;
260
+ }
237
261
 
238
262
  set visibleWidth(width: number) {
239
263
  this.#visibleWidth = width;
@@ -402,6 +426,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
402
426
  }
403
427
 
404
428
  override performUpdate(): void {
429
+ const firstRender = !this.#viewOutput.elementsTreeOutline;
405
430
  this.#view(
406
431
  {
407
432
  omitRootDOMNode: this.omitRootDOMNode,
@@ -416,6 +441,7 @@ export class DOMTreeWidget extends UI.Widget.Widget {
416
441
  visibleWidth: this.#visibleWidth,
417
442
  visible: this.#visible,
418
443
  wrap: this.#wrap,
444
+ maxRowsShown: this.#maxRows,
419
445
  showSelectionOnKeyboardFocus: this.showSelectionOnKeyboardFocus,
420
446
  preventTabOrder: this.preventTabOrder,
421
447
  deindentSingleNode: this.deindentSingleNode,
@@ -437,6 +463,11 @@ export class DOMTreeWidget extends UI.Widget.Widget {
437
463
  },
438
464
  },
439
465
  this.#viewOutput, this.contentElement);
466
+ if (firstRender && this.#viewOutput.elementsTreeOutline) {
467
+ this.#viewOutput.elementsTreeOutline.addEventListener(ElementsTreeOutline.Events.ShowAllRows, () => {
468
+ this.maxRows = undefined;
469
+ });
470
+ }
440
471
  }
441
472
 
442
473
  modelAdded(domModel: SDK.DOMModel.DOMModel): void {
@@ -597,6 +628,8 @@ export class ElementsTreeOutline extends
597
628
  showAIButton: boolean;
598
629
  disableEdits: boolean;
599
630
  expandRoot: boolean;
631
+ #maxRowsShown?: number;
632
+ #showAllButton?: HTMLElement;
600
633
 
601
634
  constructor(
602
635
  omitRootDOMNode?: boolean, selectEnabled?: boolean, hideGutter?: boolean, maxTreeDepth?: number,
@@ -1030,6 +1063,58 @@ export class ElementsTreeOutline extends
1030
1063
  }
1031
1064
  }
1032
1065
 
1066
+ set maxRowsShown(maxRows: number|undefined) {
1067
+ this.#maxRowsShown = maxRows;
1068
+ this.#updateShowAllButton();
1069
+ }
1070
+
1071
+ #updateShowAllButton(): void {
1072
+ const container = this.shadowRoot.querySelector('.elements-disclosure') as HTMLElement;
1073
+ if (!container) {
1074
+ return;
1075
+ }
1076
+ if (!this.#maxRowsShown) {
1077
+ this.#showAllButton?.classList.add('hidden');
1078
+ container.style.removeProperty('--max-rows');
1079
+ container.classList.remove('elements-tree-truncated');
1080
+ return;
1081
+ }
1082
+
1083
+ container.style.setProperty('--max-rows', String(this.#maxRowsShown));
1084
+ container.classList.add('elements-tree-truncated');
1085
+
1086
+ // We use a microtask to wait for rendering so all node lines are rendered.
1087
+ window.requestAnimationFrame(() => {
1088
+ // The container has a max-height (based on --max-rows). If the total content height
1089
+ // (scrollHeight) is greater than the visible height (clientHeight), it means
1090
+ // some rows are hidden due to truncation, and we should show the "Show all" button.
1091
+ const isOverflowing = container.scrollHeight > container.clientHeight;
1092
+ if (!isOverflowing) {
1093
+ return;
1094
+ }
1095
+ if (!this.#showAllButton) {
1096
+ this.#showAllButton = UI.UIUtils.createTextButton('', () => {
1097
+ this.dispatchEventToListeners(ElementsTreeOutline.Events.ShowAllRows);
1098
+ this.dispatchEventToListeners(UI.TreeOutline.Events.ElementExpanded, this.rootElement());
1099
+ }, {
1100
+ jslogContext: 'show-all-nodes',
1101
+ });
1102
+ this.#showAllButton.classList.add('elements-tree-show-all');
1103
+ this.shadowRoot.appendChild(this.#showAllButton);
1104
+ }
1105
+ this.#showAllButton.classList.remove('hidden');
1106
+ const computedStyle = window.getComputedStyle(container);
1107
+ const lineHeight = parseFloat(computedStyle.lineHeight) || 16;
1108
+ const truncatedLines = Math.round((container.scrollHeight - container.clientHeight) / lineHeight);
1109
+
1110
+ if (truncatedLines > 0) {
1111
+ this.#showAllButton.textContent = i18nString(UIStrings.showAllLines, {PH1: truncatedLines});
1112
+ } else {
1113
+ this.#showAllButton?.classList.add('hidden');
1114
+ }
1115
+ });
1116
+ }
1117
+
1033
1118
  highlightAdoptedStyleSheet(adoptedStyleSheet: SDK.DOMModel.AdoptedStyleSheet): void {
1034
1119
  const parentDOMNode =
1035
1120
  !this.includeRootDOMNode && adoptedStyleSheet.parent === this.rootDOMNode && this.rootDOMNode ?
@@ -2219,12 +2304,14 @@ export namespace ElementsTreeOutline {
2219
2304
  /* eslint-disable @typescript-eslint/naming-convention -- Used by web_tests. */
2220
2305
  SelectedNodeChanged = 'SelectedNodeChanged',
2221
2306
  ElementsTreeUpdated = 'ElementsTreeUpdated',
2307
+ ShowAllRows = 'ShowAllRows',
2222
2308
  /* eslint-enable @typescript-eslint/naming-convention */
2223
2309
  }
2224
2310
 
2225
2311
  export interface EventTypes {
2226
2312
  [Events.SelectedNodeChanged]: {node: SDK.DOMModel.DOMNode|null, focus: boolean};
2227
2313
  [Events.ElementsTreeUpdated]: SDK.DOMModel.DOMNode[];
2314
+ [Events.ShowAllRows]: void;
2228
2315
  }
2229
2316
  }
2230
2317
 
@@ -1075,10 +1075,6 @@ export class StylePropertiesSection {
1075
1075
 
1076
1076
  protected createContainerQueryElement(containerQuery: SDK.CSSContainerQuery.CSSContainerQuery):
1077
1077
  ElementsComponents.CSSQuery.CSSQuery|undefined {
1078
- if (!containerQuery.text) {
1079
- return;
1080
- }
1081
-
1082
1078
  let onQueryTextClick;
1083
1079
  if (containerQuery.styleSheetId) {
1084
1080
  onQueryTextClick = this.handleQueryRuleClick.bind(this, containerQuery);
@@ -10,6 +10,7 @@ import './ElementsTreeElement.js';
10
10
  import './AdoptedStyleSheetTreeElement.js';
11
11
  import './TopLayerContainer.js';
12
12
  import './ElementsTreeOutline.js';
13
+ import './ImagePreviewPopover.js';
13
14
  import './EventListenersWidget.js';
14
15
  import './MarkerDecorator.js';
15
16
  import './MetricsSidebarPane.js';
@@ -45,6 +46,7 @@ import * as ElementsTreeElement from './ElementsTreeElement.js';
45
46
  import * as ElementsTreeOutline from './ElementsTreeOutline.js';
46
47
  import * as ElementsTreeOutlineRenderer from './ElementsTreeOutlineRenderer.js';
47
48
  import * as EventListenersWidget from './EventListenersWidget.js';
49
+ import * as ImagePreviewPopover from './ImagePreviewPopover.js';
48
50
  import * as InspectElementModeController from './InspectElementModeController.js';
49
51
  import * as LayersWidget from './LayersWidget.js';
50
52
  import * as LayoutPane from './LayoutPane.js';
@@ -82,6 +84,7 @@ export {
82
84
  ElementsTreeOutline,
83
85
  ElementsTreeOutlineRenderer,
84
86
  EventListenersWidget,
87
+ ImagePreviewPopover,
85
88
  InspectElementModeController,
86
89
  LayersWidget,
87
90
  LayoutPane,
@@ -402,3 +402,24 @@ li.hovered:not(.always-parent) + ol.children:not(.shadow-root) {
402
402
  .ad-provenance-tooltip-content {
403
403
  padding-left: 16px;
404
404
  }
405
+
406
+ .elements-disclosure.elements-tree-truncated {
407
+ /* 1.36 is the line-height, 15px is the min-height */
408
+ max-height: calc(var(--max-rows) * 1.36em + 5px);
409
+ overflow: hidden;
410
+ }
411
+
412
+ .elements-tree-show-all {
413
+ border: none;
414
+ color: var(--sys-color-primary);
415
+ cursor: pointer;
416
+ display: block;
417
+ font-size: 12px;
418
+ padding: 4px 12px;
419
+ text-align: center;
420
+ width: 100%;
421
+ }
422
+
423
+ .elements-tree-show-all.hidden {
424
+ display: none;
425
+ }
@@ -21,6 +21,7 @@
21
21
  padding-left: 22px;
22
22
  white-space: normal;
23
23
  text-overflow: ellipsis;
24
+ overflow-wrap: break-word;
24
25
  cursor: auto;
25
26
  display: block;
26
27
 
@@ -74,6 +75,12 @@
74
75
  overflow-wrap: break-word !important; /* stylelint-disable-line declaration-no-important */
75
76
  white-space: normal !important; /* stylelint-disable-line declaration-no-important */
76
77
  padding-left: 0;
78
+
79
+ /* Constrain the TextPrompt proxy span (display: inline-block) so that
80
+ long values wrap instead of overflowing the section. */
81
+ > span:has(> .text-prompt-root) {
82
+ max-width: 100%;
83
+ }
77
84
  }
78
85
 
79
86
  .info {
@@ -19,7 +19,7 @@ import {
19
19
  type PageWarningsChangedEvent
20
20
  } from './LighthouseController.js';
21
21
  import lighthousePanelStyles from './lighthousePanel.css.js';
22
- import {ProtocolService} from './LighthouseProtocolService.js';
22
+ import {CancelledError, ProtocolService} from './LighthouseProtocolService.js';
23
23
  import {LighthouseReportRenderer} from './LighthouseReportRenderer.js';
24
24
  import {Item, ReportSelector} from './LighthouseReportSelector.js';
25
25
  import {StartView} from './LighthouseStartView.js';
@@ -176,6 +176,12 @@ export class LighthousePanel extends UI.Panel.Panel {
176
176
  }
177
177
 
178
178
  private handleError(err: unknown): void {
179
+ if (err instanceof CancelledError) {
180
+ // If the error was an explicit choice to cancel, we don't want to render
181
+ // the bug report view.
182
+ return;
183
+ }
184
+
179
185
  if (err instanceof Error) {
180
186
  this.statusView.renderBugReport(err);
181
187
  }
@@ -58,6 +58,12 @@ export interface LighthouseRun {
58
58
  isAIControlled?: boolean;
59
59
  }
60
60
 
61
+ export class CancelledError extends Error {
62
+ constructor() {
63
+ super('Lighthouse run cancelled');
64
+ }
65
+ }
66
+
61
67
  /**
62
68
  * ProtocolService manages a connection between the frontend (Lighthouse panel) and the Lighthouse worker.
63
69
  */
@@ -71,6 +77,14 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
71
77
  private configForTesting?: object;
72
78
  private connection?: ProtocolClient.CDPConnection.CDPConnection;
73
79
 
80
+ /**
81
+ * Tracks pending requests to the Lighthouse worker.
82
+ * Key: The message ID sent to the worker.
83
+ * Value: The rejection function for the corresponding promise.
84
+ * This is used to gracefully cancel hanging promises if the ProtocolService is detached before the worker replies.
85
+ */
86
+ readonly #pendingRequests = new Map<number, (reason: Error) => void>();
87
+
74
88
  async attach(): Promise<void> {
75
89
  await SDK.TargetManager.TargetManager.instance().suspendAllTargets();
76
90
  const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
@@ -174,6 +188,10 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
174
188
  }
175
189
 
176
190
  async detach(): Promise<void> {
191
+ for (const reject of this.#pendingRequests.values()) {
192
+ reject(new CancelledError());
193
+ }
194
+ this.#pendingRequests.clear();
177
195
  const oldLighthouseWorker = this.lighthouseWorkerPromise;
178
196
  const oldRootTarget = this.rootTarget;
179
197
 
@@ -245,7 +263,7 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
245
263
  return this.lighthouseWorkerPromise;
246
264
  }
247
265
 
248
- private async ensureWorkerExists(): Promise<Worker> {
266
+ async ensureWorkerExists(): Promise<Worker> {
249
267
  let worker: Worker;
250
268
  if (!this.lighthouseWorkerPromise) {
251
269
  worker = await this.initWorker();
@@ -293,16 +311,21 @@ export class ProtocolService implements ProtocolClient.CDPConnection.CDPConnecti
293
311
  Promise<LighthouseModel.ReporterTypes.RunnerResult> {
294
312
  const worker = await this.ensureWorkerExists();
295
313
  const messageId = lastId++;
296
- const messageResult = new Promise<LighthouseModel.ReporterTypes.RunnerResult>(resolve => {
314
+ const messageResult = new Promise<LighthouseModel.ReporterTypes.RunnerResult>((resolve, reject) => {
297
315
  const workerListener = (event: MessageEvent): void => {
298
316
  const lighthouseMessage = event.data;
299
317
 
300
318
  if (lighthouseMessage.id === messageId) {
301
319
  worker.removeEventListener('message', workerListener);
320
+ this.#pendingRequests.delete(messageId);
302
321
  resolve(lighthouseMessage.result);
303
322
  }
304
323
  };
305
324
  worker.addEventListener('message', workerListener);
325
+ this.#pendingRequests.set(messageId, (err: Error) => {
326
+ worker.removeEventListener('message', workerListener);
327
+ reject(err);
328
+ });
306
329
  });
307
330
  worker.postMessage({id: messageId, action, args: {...args, id: messageId}});
308
331
 
@@ -182,10 +182,6 @@ export class DetachedElementsProfileHeader extends WritableProfileHeader {
182
182
  this.#heapProfilerModel = heapProfilerModel;
183
183
  }
184
184
 
185
- override createView(dataDisplayDelegate: DataDisplayDelegate): DetachedElementsProfileView {
186
- return new DetachedElementsProfileView(dataDisplayDelegate, this);
187
- }
188
-
189
185
  heapProfilerModel(): SDK.HeapProfilerModel.HeapProfilerModel|null {
190
186
  return this.#heapProfilerModel;
191
187
  }
@@ -487,10 +487,6 @@ export class SamplingHeapProfileHeader extends WritableProfileHeader {
487
487
  };
488
488
  }
489
489
 
490
- override createView(): HeapProfileView {
491
- return new HeapProfileView(this);
492
- }
493
-
494
490
  protocolProfile(): Protocol.HeapProfiler.SamplingHeapProfile {
495
491
  return this.protocolProfileInternal;
496
492
  }
@@ -8,9 +8,7 @@ import type * as SDK from '../../core/sdk/sdk.js';
8
8
  import * as UI from '../../ui/legacy/legacy.js';
9
9
 
10
10
  import type {HeapSnapshotView} from './HeapSnapshotView.js';
11
- import type {ProfileType} from './ProfileHeader.js';
12
11
  import {ProfilesPanel} from './ProfilesPanel.js';
13
- import {instance} from './ProfileTypeRegistry.js';
14
12
 
15
13
  const UIStrings = {
16
14
  /**
@@ -20,18 +18,12 @@ const UIStrings = {
20
18
  } as const;
21
19
  const str_ = i18n.i18n.registerUIStrings('panels/profiler/HeapProfilerPanel.ts', UIStrings);
22
20
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
21
+
23
22
  let heapProfilerPanelInstance: HeapProfilerPanel;
24
23
  export class HeapProfilerPanel extends ProfilesPanel implements UI.ContextMenu.Provider<SDK.RemoteObject.RemoteObject>,
25
24
  UI.ActionRegistration.ActionDelegate {
26
25
  constructor() {
27
- const registry = instance;
28
- const profileTypes = [
29
- registry.heapSnapshotProfileType,
30
- registry.trackingHeapSnapshotProfileType,
31
- registry.samplingHeapProfileType,
32
- registry.detachedElementProfileType,
33
- ];
34
- super('heap-profiler', profileTypes as ProfileType[], 'profiler.heap-toggle-recording');
26
+ super('heap-profiler', 'profiler.heap-toggle-recording');
35
27
  }
36
28
 
37
29
  static instance(): HeapProfilerPanel {
@@ -52,7 +44,7 @@ export class HeapProfilerPanel extends ProfilesPanel implements UI.ContextMenu.P
52
44
  }
53
45
  const objectId = object.objectId;
54
46
 
55
- const heapProfiles = instance.heapSnapshotProfileType.getProfiles();
47
+ const heapProfiles = ProfilesPanel.registry.heapSnapshotProfileType.getProfiles();
56
48
  if (!heapProfiles.length) {
57
49
  return;
58
50
  }
@@ -97,8 +89,7 @@ export class HeapProfilerPanel extends ProfilesPanel implements UI.ContextMenu.P
97
89
  }
98
90
 
99
91
  override showObject(snapshotObjectId: string, perspectiveName: string): void {
100
- const registry = instance;
101
- const heapProfiles = registry.heapSnapshotProfileType.getProfiles();
92
+ const heapProfiles = ProfilesPanel.registry.heapSnapshotProfileType.getProfiles();
102
93
  for (let i = 0; i < heapProfiles.length; i++) {
103
94
  const profile = heapProfiles[i];
104
95
  // FIXME: allow to choose snapshot if there are several options.
@@ -23,9 +23,7 @@ export class HeapSnapshotWorkerProxy extends Common.ObjectWrapper.ObjectWrapper<
23
23
  readonly eventHandler: (arg0: string, arg1: string) => void;
24
24
  nextObjectId = 1;
25
25
  nextCallId = 1;
26
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
27
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
- callbacks = new Map<number, (arg0: any) => void>();
26
+ callbacks = new Map<number, (...args: any[]) => void>();
29
27
  readonly previousCallbacks = new Set<number>();
30
28
  readonly worker: PlatformApi.HostRuntime.Worker;
31
29
  interval?: number;
@@ -53,9 +51,7 @@ export class HeapSnapshotWorkerProxy extends Common.ObjectWrapper.ObjectWrapper<
53
51
 
54
52
  dispose(): void {
55
53
  this.worker.terminate();
56
- if (this.interval) {
57
- clearInterval(this.interval);
58
- }
54
+ clearInterval(this.interval);
59
55
  }
60
56
 
61
57
  disposeObject(objectId: number): void {