chrome-devtools-frontend 1.0.1524741 → 1.0.1526203

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 (66) hide show
  1. package/docs/policy/slow-close.md +22 -19
  2. package/front_end/core/common/Settings.ts +1 -1
  3. package/front_end/core/sdk/PreloadingModel.ts +3 -0
  4. package/front_end/core/sdk/ResourceTreeModel.ts +1 -1
  5. package/front_end/{models/source_map_scopes → core/sdk}/ScopeTreeCache.ts +8 -7
  6. package/front_end/core/sdk/SourceMapScopesInfo.ts +57 -0
  7. package/front_end/core/sdk/sdk.ts +2 -0
  8. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +7 -0
  9. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +15 -12
  10. package/front_end/generated/InspectorBackendCommands.js +4 -4
  11. package/front_end/generated/SupportedCSSProperties.js +0 -19
  12. package/front_end/generated/protocol-mapping.d.ts +1 -1
  13. package/front_end/generated/protocol-proxy-api.d.ts +1 -1
  14. package/front_end/generated/protocol.ts +9 -8
  15. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +43 -8
  16. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +50 -32
  17. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +29 -29
  18. package/front_end/models/formatter/FormatterWorkerPool.ts +1 -1
  19. package/front_end/models/javascript_metadata/NativeFunctions.js +3 -8
  20. package/front_end/models/source_map_scopes/NamesResolver.ts +1 -3
  21. package/front_end/models/source_map_scopes/source_map_scopes.ts +0 -2
  22. package/front_end/models/trace/handlers/UserTimingsHandler.ts +1 -1
  23. package/front_end/models/trace/insights/CLSCulprits.ts +2 -1
  24. package/front_end/models/trace/insights/Cache.ts +2 -1
  25. package/front_end/models/trace/insights/DOMSize.ts +2 -1
  26. package/front_end/models/trace/insights/DocumentLatency.ts +2 -1
  27. package/front_end/models/trace/insights/DuplicatedJavaScript.ts +2 -1
  28. package/front_end/models/trace/insights/FontDisplay.ts +2 -1
  29. package/front_end/models/trace/insights/ForcedReflow.ts +2 -1
  30. package/front_end/models/trace/insights/INPBreakdown.ts +2 -1
  31. package/front_end/models/trace/insights/ImageDelivery.ts +2 -1
  32. package/front_end/models/trace/insights/LCPBreakdown.ts +2 -1
  33. package/front_end/models/trace/insights/LCPDiscovery.ts +2 -1
  34. package/front_end/models/trace/insights/LegacyJavaScript.ts +2 -1
  35. package/front_end/models/trace/insights/ModernHTTP.ts +2 -1
  36. package/front_end/models/trace/insights/NetworkDependencyTree.ts +2 -1
  37. package/front_end/models/trace/insights/RenderBlocking.ts +2 -1
  38. package/front_end/models/trace/insights/SlowCSSSelector.ts +2 -1
  39. package/front_end/models/trace/insights/ThirdParties.ts +2 -1
  40. package/front_end/models/trace/insights/Viewport.ts +2 -1
  41. package/front_end/models/trace/insights/types.ts +2 -1
  42. package/front_end/panels/application/ReportingApiView.ts +8 -7
  43. package/front_end/panels/application/StorageView.ts +2 -1
  44. package/front_end/panels/application/preloading/components/PreloadingString.ts +2 -0
  45. package/front_end/panels/changes/ChangesSidebar.ts +10 -3
  46. package/front_end/panels/changes/ChangesView.ts +69 -69
  47. package/front_end/panels/changes/CombinedDiffView.ts +1 -1
  48. package/front_end/panels/changes/changesView.css +4 -0
  49. package/front_end/panels/console/ConsolePrompt.ts +24 -4
  50. package/front_end/panels/lighthouse/LighthouseController.ts +5 -0
  51. package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorPane.ts +43 -46
  52. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +254 -153
  53. package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +28 -21
  54. package/front_end/panels/timeline/TimelinePanel.ts +10 -8
  55. package/front_end/panels/timeline/components/ExportTraceOptions.ts +1 -1
  56. package/front_end/third_party/chromium/README.chromium +1 -1
  57. package/front_end/ui/components/buttons/Button.ts +17 -0
  58. package/front_end/ui/components/docs/linear_memory_inspector/basic.ts +21 -9
  59. package/front_end/ui/components/highlighting/HighlightManager.ts +21 -1
  60. package/front_end/ui/components/tooltips/Tooltip.ts +22 -5
  61. package/front_end/ui/legacy/SearchableView.ts +1 -1
  62. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +48 -5
  63. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +2 -2
  64. package/front_end/ui/legacy/components/source_frame/JSONView.ts +28 -0
  65. package/front_end/ui/legacy/components/source_frame/StreamingContentHexView.ts +18 -20
  66. package/package.json +22 -22
@@ -24,7 +24,7 @@ export const UIStrings = {
24
24
  * This is displayed after a user expands the section to see more. No character length limits.
25
25
  */
26
26
  description: '3rd party code can significantly impact load performance. ' +
27
- '[Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page\'s content.',
27
+ '[Reduce and defer loading of 3rd party code](https://developer.chrome.com/docs/performance/insights/third-parties) to prioritize your page\'s content.',
28
28
  /** Label for a table column that displays the name of a third-party provider. */
29
29
  columnThirdParty: '3rd party',
30
30
  /** Label for a column in a data table; entries will be the download size of a web resource in kilobytes. */
@@ -65,6 +65,7 @@ function finalize(partialModel: PartialInsightModel<ThirdPartiesInsightModel>):
65
65
  strings: UIStrings,
66
66
  title: i18nString(UIStrings.title),
67
67
  description: i18nString(UIStrings.description),
68
+ docs: 'https://developer.chrome.com/docs/performance/insights/third-parties',
68
69
  category: InsightCategory.ALL,
69
70
  state: partialModel.entitySummaries.find(summary => summary.entity !== partialModel.firstPartyEntity) ?
70
71
  'informative' :
@@ -24,7 +24,7 @@ export const UIStrings = {
24
24
  * @description Text to tell the user how a viewport meta element can improve performance. \xa0 is a non-breaking space
25
25
  */
26
26
  description:
27
- 'Tap interactions may be [delayed by up to 300\xA0ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.',
27
+ 'Tap interactions may be [delayed by up to 300\xA0ms](https://developer.chrome.com/docs/performance/insights/viewport) if the viewport is not optimized for mobile.',
28
28
  /**
29
29
  * @description Text for a label describing the portion of an interaction event that was delayed due to a bad mobile viewport.
30
30
  */
@@ -46,6 +46,7 @@ function finalize(partialModel: PartialInsightModel<ViewportInsightModel>): View
46
46
  strings: UIStrings,
47
47
  title: i18nString(UIStrings.title),
48
48
  description: i18nString(UIStrings.description),
49
+ docs: 'https://developer.chrome.com/docs/performance/insights/viewport',
49
50
  category: InsightCategory.INP,
50
51
  state: partialModel.mobileOptimized === false ? 'fail' : 'pass',
51
52
  ...partialModel,
@@ -76,6 +76,7 @@ export type InsightModel<UIStrings extends Record<string, string> = Record<strin
76
76
  strings: UIStrings,
77
77
  title: Common.UIString.LocalizedString,
78
78
  description: Common.UIString.LocalizedString,
79
+ docs: string,
79
80
  category: InsightCategory,
80
81
  state: 'pass' | 'fail' | 'informative',
81
82
  /** Used by RelatedInsightChips.ts */
@@ -101,7 +102,7 @@ export type InsightModel<UIStrings extends Record<string, string> = Record<strin
101
102
  };
102
103
 
103
104
  export type PartialInsightModel<T> =
104
- Omit<T, 'strings'|'title'|'description'|'category'|'state'|'insightKey'|'navigationId'|'frameId'>;
105
+ Omit<T, 'strings'|'title'|'description'|'docs'|'category'|'state'|'insightKey'|'navigationId'|'frameId'>;
105
106
 
106
107
  /**
107
108
  * Contains insights for a specific navigation. If a trace began after a navigation already started,
@@ -56,12 +56,11 @@ interface ViewInput {
56
56
  onReportSelected: (id: string) => void;
57
57
  }
58
58
 
59
- type View = (input: ViewInput, output: object, target: HTMLElement) => void;
60
-
61
- export const DEFAULT_VIEW: View = (input, _output, target) => {
59
+ export const DEFAULT_VIEW = (input: ViewInput, output: undefined, target: HTMLElement): void => {
62
60
  if (input.hasReports || input.hasEndpoints) {
63
61
  // clang-format off
64
62
  render(html`
63
+ <style>${UI.inspectorCommonStyles}</style>
65
64
  <devtools-split-view sidebar-position="second" sidebar-initial-size="150" jslog=${
66
65
  VisualLogging.pane('reporting-api')}>
67
66
  ${input.hasReports ? html`
@@ -73,9 +72,9 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
73
72
  </div>
74
73
  <div slot="sidebar" class="vbox" jslog=${VisualLogging.pane('preview').track({resize: true})}>
75
74
  ${input.focusedReport ? html`
76
- <devtools-widget .widgetConfig=${widgetConfig(
77
- element => SourceFrame.JSONView.JSONView.createViewSync(input.focusedReport?.body || '', element)
78
- )}></devtools-widget>
75
+ <devtools-widget .widgetConfig=${widgetConfig(SourceFrame.JSONView.SearchableJsonView, {
76
+ jsonObject: input.focusedReport.body,
77
+ })}></devtools-widget>
79
78
  ` : html`
80
79
  <devtools-widget .widgetConfig=${widgetConfig(UI.EmptyWidget.EmptyWidget, {
81
80
  header: i18nString(UIStrings.noReportSelected),
@@ -112,6 +111,8 @@ export const DEFAULT_VIEW: View = (input, _output, target) => {
112
111
  }
113
112
  };
114
113
 
114
+ type View = typeof DEFAULT_VIEW;
115
+
115
116
  export class ReportingApiView extends UI.Widget.VBox implements
116
117
  SDK.TargetManager.SDKModelObserver<SDK.NetworkManager.NetworkManager> {
117
118
  #endpoints: Map<string, Protocol.Network.ReportingApiEndpoint[]>;
@@ -164,7 +165,7 @@ export class ReportingApiView extends UI.Widget.VBox implements
164
165
  focusedReport: this.#focusedReport,
165
166
  onReportSelected: this.#onReportSelected.bind(this),
166
167
  };
167
- this.#view(viewInput, {}, this.element);
168
+ this.#view(viewInput, undefined, this.element);
168
169
  }
169
170
 
170
171
  #onEndpointsChangedForOrigin({data}: {data: Protocol.Network.ReportingApiEndpointsChangedForOriginEvent}): void {
@@ -236,6 +236,7 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
236
236
  this.quotaOverrideCheckbox.addEventListener('click', this.onClickCheckbox.bind(this), false);
237
237
  this.quotaOverrideControlRow = quota.appendRow();
238
238
  this.quotaOverrideEditor = this.quotaOverrideControlRow.createChild('input', 'quota-override-notification-editor');
239
+ this.quotaOverrideEditor.setAttribute('placeholder', i18nString(UIStrings.pleaseEnterANumber));
239
240
  this.quotaOverrideEditor.setAttribute(
240
241
  'jslog', `${VisualLogging.textField('quota-override').track({change: true})}`);
241
242
  this.quotaOverrideControlRow.appendChild(UI.UIUtils.createLabel(i18nString(UIStrings.mb)));
@@ -402,7 +403,7 @@ export class StorageView extends UI.ThrottledWidget.ThrottledWidget {
402
403
  this.quotaOverrideControlRow.classList.remove('hidden');
403
404
  this.quotaOverrideCheckbox.checked = true;
404
405
  this.quotaOverrideEditor.value = this.previousOverrideFieldValue;
405
- this.quotaOverrideEditor.focus();
406
+ window.setTimeout(() => this.quotaOverrideEditor.focus(), 500);
406
407
  } else if (this.target && this.securityOrigin) {
407
408
  this.quotaOverrideControlRow.classList.add('hidden');
408
409
  this.quotaOverrideCheckbox.checked = false;
@@ -736,6 +736,8 @@ export function capitalizedAction(action: Protocol.Preload.SpeculationAction): C
736
736
  return i18n.i18n.lockedString('Prefetch');
737
737
  case Protocol.Preload.SpeculationAction.Prerender:
738
738
  return i18n.i18n.lockedString('Prerender');
739
+ case Protocol.Preload.SpeculationAction.PrerenderUntilScript:
740
+ return i18n.i18n.lockedString('PrerenderUntilScript');
739
741
  }
740
742
  }
741
743
 
@@ -67,14 +67,21 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
67
67
 
68
68
  export class ChangesSidebar extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.Widget.Widget>(
69
69
  UI.Widget.Widget) {
70
- readonly #workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
70
+ #workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl|null = null;
71
71
  readonly #view: View;
72
72
  readonly #sourceCodes = new Set<Workspace.UISourceCode.UISourceCode>();
73
73
  #selectedUISourceCode: Workspace.UISourceCode.UISourceCode|null = null;
74
- constructor(workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl, target?: HTMLElement, view = DEFAULT_VIEW) {
75
- super({jslog: `${VisualLogging.pane('sidebar').track({resize: true})}`});
74
+ constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
75
+ super(target, {jslog: `${VisualLogging.pane('sidebar').track({resize: true})}`});
76
76
  this.#view = view;
77
+ }
77
78
 
79
+ set workspaceDiff(workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl) {
80
+ if (this.#workspaceDiff) {
81
+ this.#workspaceDiff.modifiedUISourceCodes().forEach(this.#removeUISourceCode.bind(this));
82
+ this.#workspaceDiff.removeEventListener(
83
+ WorkspaceDiff.WorkspaceDiff.Events.MODIFIED_STATUS_CHANGED, this.uiSourceCodeModifiedStatusChanged, this);
84
+ }
78
85
  this.#workspaceDiff = workspaceDiff;
79
86
  this.#workspaceDiff.modifiedUISourceCodes().forEach(this.#addUISourceCode.bind(this));
80
87
  this.#workspaceDiff.addEventListener(
@@ -1,7 +1,6 @@
1
1
  // Copyright 2017 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 rulesdir/no-imperative-dom-api */
5
4
 
6
5
  import '../../ui/legacy/legacy.js';
7
6
 
@@ -10,6 +9,7 @@ import type * as Platform from '../../core/platform/platform.js';
10
9
  import type * as Workspace from '../../models/workspace/workspace.js';
11
10
  import * as WorkspaceDiff from '../../models/workspace_diff/workspace_diff.js';
12
11
  import * as UI from '../../ui/legacy/legacy.js';
12
+ import * as Lit from '../../ui/lit/lit.js';
13
13
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
14
14
 
15
15
  import {ChangesSidebar, Events} from './ChangesSidebar.js';
@@ -30,93 +30,93 @@ const UIStrings = {
30
30
  } as const;
31
31
  const str_ = i18n.i18n.registerUIStrings('panels/changes/ChangesView.ts', UIStrings);
32
32
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
33
+ const {render, html} = Lit;
34
+ interface ViewInput {
35
+ selectedSourceCode: Workspace.UISourceCode.UISourceCode|null;
36
+ onSelect(sourceCode: Workspace.UISourceCode.UISourceCode|null): void;
37
+ workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
38
+ }
39
+ type View = (input: ViewInput, output: object, target: HTMLElement) => void;
40
+ export const DEFAULT_VIEW: View = (input, output, target) => {
41
+ const onSidebar = (sidebar: ChangesSidebar): void => {
42
+ sidebar.addEventListener(
43
+ Events.SELECTED_UI_SOURCE_CODE_CHANGED, () => input.onSelect(sidebar.selectedUISourceCode()));
44
+ };
45
+ render(
46
+ // clang-format off
47
+ html`
48
+ <style>${changesViewStyles}</style>
49
+ <devtools-split-view direction=column>
50
+ <div class=vbox slot="main">
51
+ <devtools-widget
52
+ ?hidden=${input.workspaceDiff.modifiedUISourceCodes().length > 0}
53
+ .widgetConfig=${UI.Widget.widgetConfig(UI.EmptyWidget.EmptyWidget, {
54
+ header: i18nString(UIStrings.noChanges),
55
+ text: i18nString(UIStrings.changesViewDescription),
56
+ link: CHANGES_VIEW_URL,
57
+ })}>
58
+ </devtools-widget>
59
+ <div class=diff-container role=tabpanel ?hidden=${input.workspaceDiff.modifiedUISourceCodes().length === 0}>
60
+ <devtools-widget .widgetConfig=${UI.Widget.widgetConfig(CombinedDiffView.CombinedDiffView, {
61
+ selectedFileUrl: input.selectedSourceCode?.url(),
62
+ workspaceDiff: input.workspaceDiff
63
+ })}></devtools-widget>
64
+ </div>
65
+ </div>
66
+ <devtools-widget
67
+ slot="sidebar"
68
+ .widgetConfig=${UI.Widget.widgetConfig(ChangesSidebar, {
69
+ workspaceDiff: input.workspaceDiff
70
+ })}
71
+ ${UI.Widget.widgetRef(ChangesSidebar, onSidebar)}>
72
+ </devtools-widget>
73
+ </devtools-split-view>`,
74
+ // clang-format on
75
+ target);
76
+ };
33
77
 
34
78
  export class ChangesView extends UI.Widget.VBox {
35
- private emptyWidget: UI.EmptyWidget.EmptyWidget;
36
- private readonly workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
37
- readonly changesSidebar: ChangesSidebar;
38
- private selectedUISourceCode: Workspace.UISourceCode.UISourceCode|null;
39
- private readonly diffContainer: HTMLElement;
40
- private readonly combinedDiffView: CombinedDiffView.CombinedDiffView;
79
+ readonly #workspaceDiff: WorkspaceDiff.WorkspaceDiff.WorkspaceDiffImpl;
80
+ #selectedUISourceCode: Workspace.UISourceCode.UISourceCode|null = null;
81
+ readonly #view: View;
41
82
 
42
- constructor() {
43
- super({
83
+ constructor(target?: HTMLElement, view = DEFAULT_VIEW) {
84
+ super(target, {
44
85
  jslog: `${VisualLogging.panel('changes').track({resize: true})}`,
45
86
  useShadowDom: true,
46
87
  });
47
- this.registerRequiredCSS(changesViewStyles);
48
-
49
- const splitWidget = new UI.SplitWidget.SplitWidget(true /* vertical */, false /* sidebar on left */);
50
- const mainWidget = new UI.Widget.VBox();
51
- splitWidget.setMainWidget(mainWidget);
52
- splitWidget.show(this.contentElement);
53
-
54
- this.emptyWidget = new UI.EmptyWidget.EmptyWidget('', '');
55
- this.emptyWidget.show(mainWidget.element);
56
-
57
- this.workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
58
- this.changesSidebar = new ChangesSidebar(this.workspaceDiff);
59
- this.changesSidebar.addEventListener(
60
- Events.SELECTED_UI_SOURCE_CODE_CHANGED, this.selectedUISourceCodeChanged, this);
61
- splitWidget.setSidebarWidget(this.changesSidebar);
62
88
 
63
- this.selectedUISourceCode = null;
89
+ this.#workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
90
+ this.#view = view;
64
91
 
65
- this.diffContainer = mainWidget.element.createChild('div', 'diff-container');
66
- UI.ARIAUtils.markAsTabpanel(this.diffContainer);
67
- this.combinedDiffView = new CombinedDiffView.CombinedDiffView();
68
- this.combinedDiffView.workspaceDiff = this.workspaceDiff;
69
- this.combinedDiffView.show(this.diffContainer);
70
-
71
- this.hideDiff();
72
- this.selectedUISourceCodeChanged();
92
+ this.requestUpdate();
73
93
  }
74
94
 
75
- private renderDiffOrEmptyState(): void {
76
- // There are modified UI source codes, we should render the combined diff view.
77
- if (this.workspaceDiff.modifiedUISourceCodes().length > 0) {
78
- this.showDiff();
79
- } else {
80
- this.hideDiff();
81
- }
82
- }
83
-
84
- private selectedUISourceCodeChanged(): void {
85
- const selectedUISourceCode = this.changesSidebar.selectedUISourceCode();
86
- if (!selectedUISourceCode || this.selectedUISourceCode === selectedUISourceCode) {
87
- return;
88
- }
89
-
90
- this.selectedUISourceCode = selectedUISourceCode;
91
- this.combinedDiffView.selectedFileUrl = selectedUISourceCode.url();
95
+ override performUpdate(): void {
96
+ this.#view(
97
+ {
98
+ workspaceDiff: this.#workspaceDiff,
99
+ selectedSourceCode: this.#selectedUISourceCode,
100
+ onSelect: sourceCode => {
101
+ this.#selectedUISourceCode = sourceCode;
102
+ this.requestUpdate();
103
+ },
104
+ },
105
+ {}, this.contentElement);
92
106
  }
93
107
 
94
108
  override wasShown(): void {
95
109
  UI.Context.Context.instance().setFlavor(ChangesView, this);
96
110
  super.wasShown();
97
- this.renderDiffOrEmptyState();
98
- this.workspaceDiff.addEventListener(
99
- WorkspaceDiff.WorkspaceDiff.Events.MODIFIED_STATUS_CHANGED, this.renderDiffOrEmptyState, this);
111
+ this.requestUpdate();
112
+ this.#workspaceDiff.addEventListener(
113
+ WorkspaceDiff.WorkspaceDiff.Events.MODIFIED_STATUS_CHANGED, this.requestUpdate, this);
100
114
  }
101
115
 
102
116
  override willHide(): void {
103
117
  super.willHide();
104
118
  UI.Context.Context.instance().setFlavor(ChangesView, null);
105
- this.workspaceDiff.removeEventListener(
106
- WorkspaceDiff.WorkspaceDiff.Events.MODIFIED_STATUS_CHANGED, this.renderDiffOrEmptyState, this);
107
- }
108
-
109
- private hideDiff(): void {
110
- this.diffContainer.style.display = 'none';
111
- this.emptyWidget.header = i18nString(UIStrings.noChanges);
112
- this.emptyWidget.text = i18nString(UIStrings.changesViewDescription);
113
-
114
- this.emptyWidget.link = CHANGES_VIEW_URL;
115
- this.emptyWidget.showWidget();
116
- }
117
-
118
- private showDiff(): void {
119
- this.emptyWidget.hideWidget();
120
- this.diffContainer.style.display = 'block';
119
+ this.#workspaceDiff.removeEventListener(
120
+ WorkspaceDiff.WorkspaceDiff.Events.MODIFIED_STATUS_CHANGED, this.requestUpdate, this);
121
121
  }
122
122
  }
@@ -149,7 +149,7 @@ export class CombinedDiffView extends UI.Widget.Widget {
149
149
  void this.#initializeModifiedUISourceCodes();
150
150
  }
151
151
 
152
- set selectedFileUrl(fileUrl: string) {
152
+ set selectedFileUrl(fileUrl: string|undefined) {
153
153
  this.#selectedFileUrl = fileUrl;
154
154
  this.requestUpdate();
155
155
  void this.updateComplete.then(() => {
@@ -36,3 +36,7 @@
36
36
  background-color: var(--sys-color-cdt-base-container);
37
37
  border-top: 1px solid var(--sys-color-divider);
38
38
  }
39
+
40
+ [hidden] {
41
+ display: none !important; /* stylelint-disable-line declaration-no-important */
42
+ }
@@ -343,9 +343,29 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
343
343
  }
344
344
 
345
345
  private editorKeymap(): readonly CodeMirror.KeyBinding[] {
346
- const keymap = [
347
- {key: 'ArrowUp', run: () => this.#editorHistory.moveHistory(Direction.BACKWARD)},
348
- {key: 'ArrowDown', run: () => this.#editorHistory.moveHistory(Direction.FORWARD)},
346
+ const keymap: CodeMirror.KeyBinding[] = [
347
+ {
348
+ // Handle the KeyboardEvent manually.
349
+ any: (_view, event) => {
350
+ // Events with `repeat=true` are excluded from altering the history state because
351
+ // they are often not intended as such. Example:
352
+ // Scrolling through long snippets.
353
+ if (event.repeat) {
354
+ return false;
355
+ }
356
+
357
+ if (event.key === 'ArrowUp') {
358
+ return this.#editorHistory.moveHistory(Direction.BACKWARD);
359
+ }
360
+
361
+ if (event.key === 'ArrowDown') {
362
+ return this.#editorHistory.moveHistory(Direction.FORWARD);
363
+ }
364
+
365
+ return false;
366
+ },
367
+ },
368
+
349
369
  {mac: 'Ctrl-p', run: () => this.#editorHistory.moveHistory(Direction.BACKWARD, true)},
350
370
  {mac: 'Ctrl-n', run: () => this.#editorHistory.moveHistory(Direction.FORWARD, true)},
351
371
  {
@@ -372,7 +392,7 @@ export class ConsolePrompt extends Common.ObjectWrapper.eventMixin<EventTypes, t
372
392
  if (this.isAiCodeCompletionEnabled()) {
373
393
  keymap.push({
374
394
  key: 'Tab',
375
- run: (): boolean => {
395
+ run: () => {
376
396
  const {accepted, suggestion} = TextEditor.Config.acceptAiAutoCompleteSuggestion(this.editor.editor);
377
397
  if (accepted) {
378
398
  this.dispatchEventToListeners(
@@ -401,8 +401,13 @@ export class LighthouseController extends Common.ObjectWrapper.ObjectWrapper<Eve
401
401
  }
402
402
 
403
403
  getCategoryIDs(): string[] {
404
+ const {mode} = this.getFlags();
404
405
  const categoryIDs = [];
405
406
  for (const preset of Presets) {
407
+ if (mode && !preset.supportedModes.includes(mode)) {
408
+ continue;
409
+ }
410
+
406
411
  if (preset.setting.get()) {
407
412
  categoryIDs.push(preset.configID);
408
413
  }
@@ -122,6 +122,8 @@ export interface EventTypes {
122
122
 
123
123
  export class LinearMemoryInspectorView extends UI.Widget.VBox {
124
124
  #memoryWrapper: LazyUint8Array;
125
+ #memory?: Uint8Array<ArrayBuffer>;
126
+ #offset = 0;
125
127
  #address: number;
126
128
  #tabId: string;
127
129
  #inspector: LinearMemoryInspectorComponents.LinearMemoryInspector.LinearMemoryInspector;
@@ -140,32 +142,52 @@ export class LinearMemoryInspectorView extends UI.Widget.VBox {
140
142
  this.#address = address;
141
143
  this.#tabId = tabId;
142
144
  this.#hideValueInspector = Boolean(hideValueInspector);
145
+ this.firstTimeOpen = true;
146
+
143
147
  this.#inspector = new LinearMemoryInspectorComponents.LinearMemoryInspector.LinearMemoryInspector();
144
- this.#inspector.addEventListener(
148
+ this.#inspector.contentElement.addEventListener(
145
149
  LinearMemoryInspectorComponents.LinearMemoryInspector.MemoryRequestEvent.eventName,
146
- (event: LinearMemoryInspectorComponents.LinearMemoryInspector.MemoryRequestEvent) => {
147
- this.#memoryRequested(event);
148
- });
149
- this.#inspector.addEventListener(
150
+ (event: LinearMemoryInspectorComponents.LinearMemoryInspector.MemoryRequestEvent) =>
151
+ this.#memoryRequested(event));
152
+ this.#inspector.contentElement.addEventListener(
150
153
  LinearMemoryInspectorComponents.LinearMemoryInspector.AddressChangedEvent.eventName,
151
- (event: LinearMemoryInspectorComponents.LinearMemoryInspector.AddressChangedEvent) => {
152
- this.updateAddress(event.data);
153
- });
154
- this.#inspector.addEventListener(
154
+ (event: LinearMemoryInspectorComponents.LinearMemoryInspector.AddressChangedEvent) =>
155
+ this.updateAddress(event.data));
156
+ this.#inspector.contentElement.addEventListener(
155
157
  LinearMemoryInspectorComponents.LinearMemoryInspector.SettingsChangedEvent.eventName,
156
158
  (event: LinearMemoryInspectorComponents.LinearMemoryInspector.SettingsChangedEvent) => {
157
159
  // Stop event from bubbling up, since no element further up needs the event.
158
160
  event.stopPropagation();
159
161
  this.saveSettings(event.data);
160
162
  });
161
- this.#inspector.addEventListener(
163
+ this.#inspector.contentElement.addEventListener(
162
164
  LinearMemoryInspectorComponents.LinearMemoryHighlightChipList.DeleteMemoryHighlightEvent.eventName,
163
165
  (event: LinearMemoryInspectorComponents.LinearMemoryHighlightChipList.DeleteMemoryHighlightEvent) => {
164
166
  LinearMemoryInspectorController.instance().removeHighlight(this.#tabId, event.data);
165
167
  this.refreshData();
166
168
  });
167
- this.contentElement.appendChild(this.#inspector);
168
- this.firstTimeOpen = true;
169
+ this.#inspector.show(this.contentElement);
170
+ }
171
+
172
+ render(): void {
173
+ if (this.firstTimeOpen) {
174
+ const settings = LinearMemoryInspectorController.instance().loadSettings();
175
+ this.#inspector.valueTypes = settings.valueTypes;
176
+ this.#inspector.valueTypeModes = settings.modes;
177
+ this.#inspector.endianness = settings.endianness;
178
+ this.firstTimeOpen = false;
179
+ }
180
+
181
+ if (!this.#memory) {
182
+ return;
183
+ }
184
+
185
+ this.#inspector.memory = this.#memory;
186
+ this.#inspector.memoryOffset = this.#offset;
187
+ this.#inspector.address = this.#address;
188
+ this.#inspector.outerMemoryLength = this.#memoryWrapper.length();
189
+ this.#inspector.highlightInfo = this.#getHighlightInfo();
190
+ this.#inspector.hideValueInspector = this.#hideValueInspector;
169
191
  }
170
192
 
171
193
  override wasShown(): void {
@@ -184,32 +206,12 @@ export class LinearMemoryInspectorView extends UI.Widget.VBox {
184
206
  }
185
207
 
186
208
  refreshData(): void {
187
- void LinearMemoryInspectorController.getMemoryForAddress(this.#memoryWrapper, this.#address).then(({
188
- memory,
189
- offset,
190
- }) => {
191
- let valueTypes;
192
- let valueTypeModes;
193
- let endianness;
194
- if (this.firstTimeOpen) {
195
- const settings = LinearMemoryInspectorController.instance().loadSettings();
196
- valueTypes = settings.valueTypes;
197
- valueTypeModes = settings.modes;
198
- endianness = settings.endianness;
199
- this.firstTimeOpen = false;
200
- }
201
- this.#inspector.data = {
202
- memory,
203
- address: this.#address,
204
- memoryOffset: offset,
205
- outerMemoryLength: this.#memoryWrapper.length(),
206
- valueTypes,
207
- valueTypeModes,
208
- endianness,
209
- highlightInfo: this.#getHighlightInfo(),
210
- hideValueInspector: this.#hideValueInspector,
211
- };
212
- });
209
+ void LinearMemoryInspectorController.getMemoryForAddress(this.#memoryWrapper, this.#address)
210
+ .then(({memory, offset}) => {
211
+ this.#memory = memory;
212
+ this.#offset = offset;
213
+ this.render();
214
+ });
213
215
  }
214
216
 
215
217
  #memoryRequested(event: LinearMemoryInspectorComponents.LinearMemoryInspector.MemoryRequestEvent): void {
@@ -219,14 +221,9 @@ export class LinearMemoryInspectorView extends UI.Widget.VBox {
219
221
  }
220
222
 
221
223
  void LinearMemoryInspectorController.getMemoryRange(this.#memoryWrapper, start, end).then(memory => {
222
- this.#inspector.data = {
223
- memory,
224
- address,
225
- memoryOffset: start,
226
- outerMemoryLength: this.#memoryWrapper.length(),
227
- highlightInfo: this.#getHighlightInfo(),
228
- hideValueInspector: this.#hideValueInspector,
229
- };
224
+ this.#memory = memory;
225
+ this.#offset = start;
226
+ this.render();
230
227
  });
231
228
  }
232
229