chrome-devtools-frontend 1.0.1555430 → 1.0.1556696

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 (100) hide show
  1. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +2 -0
  2. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +75 -7
  3. package/front_end/entrypoints/formatter_worker/Substitute.ts +1 -1
  4. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  5. package/front_end/generated/protocol.ts +0 -1
  6. package/front_end/models/ai_assistance/AiConversation.ts +71 -10
  7. package/front_end/models/ai_assistance/ArtifactsManager.ts +67 -0
  8. package/front_end/models/ai_assistance/ConversationHandler.ts +3 -2
  9. package/front_end/models/ai_assistance/agents/AiAgent.ts +17 -27
  10. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +151 -3
  11. package/front_end/models/ai_assistance/agents/StylingAgent.ts +1 -1
  12. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  13. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +0 -2
  14. package/front_end/models/annotations/AnnotationRepository.ts +2 -2
  15. package/front_end/models/greendev/Prototypes.ts +56 -0
  16. package/front_end/models/greendev/README.md +5 -0
  17. package/front_end/models/greendev/greendev.ts +5 -0
  18. package/front_end/models/trace/extras/TraceTree.ts +4 -2
  19. package/front_end/models/trace/insights/LCPDiscovery.ts +0 -2
  20. package/front_end/models/trace/types/TraceEvents.ts +0 -1
  21. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +96 -91
  22. package/front_end/panels/ai_assistance/aiAssistancePanel.css +16 -0
  23. package/front_end/panels/ai_assistance/components/ArtifactsViewer.ts +109 -7
  24. package/front_end/panels/ai_assistance/components/ChatView.ts +2 -2
  25. package/front_end/panels/ai_assistance/components/CollapsibleAssistanceContentWidget.ts +7 -8
  26. package/front_end/panels/ai_assistance/components/PerformanceAgentFlameChart.ts +15 -8
  27. package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +9 -9
  28. package/front_end/panels/ai_assistance/components/artifactsViewer.css +6 -1
  29. package/front_end/panels/ai_assistance/components/collapsibleAssistanceContentWidget.css +5 -6
  30. package/front_end/panels/application/AppManifestView.ts +263 -205
  31. package/front_end/panels/application/ApplicationPanelSidebar.ts +24 -57
  32. package/front_end/panels/application/OpenedWindowDetailsView.ts +2 -0
  33. package/front_end/panels/application/ServiceWorkersView.ts +2 -0
  34. package/front_end/panels/application/StorageView.ts +1 -0
  35. package/front_end/panels/application/appManifestView.css +48 -0
  36. package/front_end/panels/application/components/ProtocolHandlersView.ts +2 -2
  37. package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
  38. package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +4 -8
  39. package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +148 -97
  40. package/front_end/panels/linear_memory_inspector/components/LinearMemoryViewer.ts +1 -1
  41. package/front_end/panels/linear_memory_inspector/components/linearMemoryValueInterpreter.css +37 -35
  42. package/front_end/panels/settings/SettingsScreen.ts +133 -1
  43. package/front_end/panels/settings/settings-meta.ts +24 -0
  44. package/front_end/panels/settings/settingsScreen.css +4 -0
  45. package/front_end/panels/sources/UISourceCodeFrame.ts +3 -17
  46. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +2 -1
  47. package/front_end/third_party/acorn/estree-legacy.d.ts +2 -0
  48. package/front_end/third_party/chromium/README.chromium +1 -1
  49. package/front_end/third_party/puppeteer/README.chromium +2 -2
  50. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/CDPSession.d.ts.map +1 -1
  51. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/CDPSession.js.map +1 -1
  52. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.d.ts.map +1 -1
  53. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/ElementHandle.js.map +1 -1
  54. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.d.ts.map +1 -1
  55. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Frame.js.map +1 -1
  56. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
  57. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
  58. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/Connection.d.ts.map +1 -1
  59. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js +21 -7
  60. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js.map +1 -1
  61. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/EventEmitter.d.ts.map +1 -1
  62. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
  63. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
  64. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
  65. package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
  66. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +15 -6
  67. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/CDPSession.d.ts.map +1 -1
  68. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/CDPSession.js.map +1 -1
  69. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.d.ts.map +1 -1
  70. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/ElementHandle.js.map +1 -1
  71. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.d.ts.map +1 -1
  72. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Frame.js.map +1 -1
  73. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
  74. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
  75. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/Connection.d.ts.map +1 -1
  76. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/BrowserConnector.js +21 -7
  77. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/BrowserConnector.js.map +1 -1
  78. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/EventEmitter.d.ts.map +1 -1
  79. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
  80. package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
  81. package/front_end/third_party/puppeteer/package/package.json +2 -2
  82. package/front_end/third_party/puppeteer/package/src/api/CDPSession.ts +1 -2
  83. package/front_end/third_party/puppeteer/package/src/api/ElementHandle.ts +2 -4
  84. package/front_end/third_party/puppeteer/package/src/api/Frame.ts +2 -4
  85. package/front_end/third_party/puppeteer/package/src/api/Page.ts +2 -4
  86. package/front_end/third_party/puppeteer/package/src/bidi/core/Connection.ts +3 -2
  87. package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +29 -10
  88. package/front_end/third_party/puppeteer/package/src/common/EventEmitter.ts +3 -3
  89. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  90. package/front_end/ui/components/report_view/ReportView.docs.ts +37 -0
  91. package/front_end/ui/components/report_view/ReportView.ts +1 -4
  92. package/front_end/ui/components/settings/SettingCheckbox.ts +1 -1
  93. package/front_end/ui/legacy/Floaty.ts +5 -9
  94. package/front_end/ui/legacy/InspectorView.ts +2 -1
  95. package/front_end/ui/legacy/ReportView.ts +5 -4
  96. package/front_end/ui/legacy/Widget.ts +7 -0
  97. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +0 -1
  98. package/front_end/ui/legacy/reportView.css +0 -24
  99. package/front_end/ui/visual_logging/KnownContextValues.ts +7 -0
  100. package/package.json +1 -1
@@ -1165,71 +1165,38 @@ export class AppManifestTreeElement extends ApplicationPanelTreeElement {
1165
1165
  generateChildren(): void {
1166
1166
  const staticSections = this.view.getStaticSections();
1167
1167
  for (const section of staticSections) {
1168
- const sectionElement = section.getTitleElement();
1169
- const childTitle = section.title();
1170
- const sectionFieldElement = section.getFieldElement();
1171
- const child = new ManifestChildTreeElement(
1172
- this.resourcesPanel, sectionElement, childTitle, sectionFieldElement, section.jslogContext || '');
1173
- this.appendChild(child);
1174
- }
1175
- }
1176
-
1177
- onInvoke(): void {
1178
- this.view.getManifestElement().scrollIntoView();
1179
- UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.onInvokeAlert, {PH1: this.listItemElement.title}));
1180
- }
1168
+ const childTitle = section.title;
1169
+ const child = new ApplicationPanelTreeElement(this.resourcesPanel, childTitle, false, section.jslogContext || '');
1170
+ child.onselect = (selectedByUser?: boolean): boolean => {
1171
+ if (selectedByUser) {
1172
+ this.showView(this.view);
1173
+ this.view.scrollToSection(childTitle);
1174
+ }
1175
+ return true;
1176
+ };
1181
1177
 
1182
- showManifestView(): void {
1183
- this.showView(this.view);
1184
- }
1185
- }
1178
+ const icon = createIcon('document');
1179
+ child.setLeadingIcons([icon]);
1186
1180
 
1187
- export class ManifestChildTreeElement extends ApplicationPanelTreeElement {
1188
- #sectionElement: Element;
1189
- #sectionFieldElement: HTMLElement;
1190
- constructor(
1191
- storagePanel: ResourcesPanel, element: Element, childTitle: string, fieldElement: HTMLElement,
1192
- jslogContext: string) {
1193
- super(storagePanel, childTitle, false, jslogContext);
1194
- const icon = createIcon('document');
1195
- this.setLeadingIcons([icon]);
1196
- this.#sectionElement = element;
1197
- this.#sectionFieldElement = fieldElement;
1198
- self.onInvokeElement(this.listItemElement, this.onInvoke.bind(this));
1199
- this.listItemElement.addEventListener('keydown', this.onInvokeElementKeydown.bind(this));
1200
- UI.ARIAUtils.setLabel(
1201
- this.listItemElement, i18nString(UIStrings.beforeInvokeAlert, {PH1: this.listItemElement.title}));
1202
- }
1181
+ child.listItemElement.addEventListener('keydown', (event: Event) => {
1182
+ if ((event as KeyboardEvent).key !== 'Tab' || (event as KeyboardEvent).shiftKey) {
1183
+ return;
1184
+ }
1203
1185
 
1204
- override get itemURL(): Platform.DevToolsPath.UrlString {
1205
- return 'manifest://' + this.title as Platform.DevToolsPath.UrlString;
1186
+ if (this.view.focusOnSection(childTitle)) {
1187
+ event.consume(true);
1188
+ }
1189
+ });
1190
+ UI.ARIAUtils.setLabel(
1191
+ child.listItemElement, i18nString(UIStrings.beforeInvokeAlert, {PH1: child.listItemElement.title}));
1192
+ this.appendChild(child);
1193
+ }
1206
1194
  }
1207
1195
 
1208
1196
  onInvoke(): void {
1209
- (this.parent as AppManifestTreeElement)?.showManifestView();
1210
- this.#sectionElement.scrollIntoView();
1197
+ this.view.getManifestElement().scrollIntoView();
1211
1198
  UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.onInvokeAlert, {PH1: this.listItemElement.title}));
1212
1199
  }
1213
- // direct focus to the corresponding element
1214
- onInvokeElementKeydown(event: KeyboardEvent): void {
1215
- if (event.key !== 'Tab' || event.shiftKey) {
1216
- return;
1217
- }
1218
- const checkBoxElement = this.#sectionFieldElement.querySelector('.mask-checkbox');
1219
- let focusableElement: HTMLElement|null = this.#sectionFieldElement.querySelector('[tabindex="0"]');
1220
- if (checkBoxElement?.shadowRoot) {
1221
- focusableElement = checkBoxElement.shadowRoot.querySelector('input') || null;
1222
- } else if (!focusableElement) {
1223
- // special case for protocol handler section since it is a custom Element and has different structure than the others
1224
- focusableElement = this.#sectionFieldElement.querySelector('devtools-protocol-handlers-view')
1225
- ?.shadowRoot?.querySelector('[tabindex="0"]') ||
1226
- null;
1227
- }
1228
- if (focusableElement) {
1229
- focusableElement?.focus();
1230
- event.consume(true);
1231
- }
1232
- }
1233
1200
  }
1234
1201
 
1235
1202
  export class ClearStorageTreeElement extends ApplicationPanelTreeElement {
@@ -153,6 +153,7 @@ export class OpenedWindowDetailsView extends UI.Widget.VBox {
153
153
  this.isWindowClosed = isWindowClosed;
154
154
 
155
155
  this.contentElement.classList.add('frame-details-container');
156
+ // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
156
157
  this.reportView = new UI.ReportView.ReportView(this.buildTitle());
157
158
 
158
159
  this.reportView.show(this.contentElement);
@@ -220,6 +221,7 @@ export class WorkerDetailsView extends UI.Widget.VBox {
220
221
  this.targetInfo = targetInfo;
221
222
 
222
223
  this.contentElement.classList.add('frame-details-container');
224
+ // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
223
225
  this.reportView =
224
226
  new UI.ReportView.ReportView(this.targetInfo.title || this.targetInfo.url || i18nString(UIStrings.worker));
225
227
 
@@ -202,6 +202,7 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
202
202
  });
203
203
  this.registerRequiredCSS(serviceWorkersViewStyles);
204
204
 
205
+ // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
205
206
  this.currentWorkersView = new UI.ReportView.ReportView(i18n.i18n.lockedString('Service workers'));
206
207
  this.currentWorkersView.setBodyScrollable(false);
207
208
  this.contentElement.classList.add('service-worker-list');
@@ -220,6 +221,7 @@ export class ServiceWorkersView extends UI.Widget.VBox implements
220
221
 
221
222
  const othersDiv = this.contentElement.createChild('div', 'service-workers-other-origin');
222
223
  othersDiv.setAttribute('jslog', `${VisualLogging.section('other-origin')}`);
224
+ // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
223
225
  const othersView = new UI.ReportView.ReportView();
224
226
  othersView.setHeaderVisible(false);
225
227
  othersView.show(othersDiv);
@@ -181,6 +181,7 @@ export class StorageView extends UI.Widget.VBox {
181
181
  [Protocol.Storage.StorageType.Service_workers, 'rgb(255, 167, 36)'], // orange
182
182
  ]);
183
183
 
184
+ // TODO(crbug.com/1156978): Replace UI.ReportView.ReportView with ReportView.ts web component.
184
185
  this.reportView = new UI.ReportView.ReportView(i18nString(UIStrings.storageTitle));
185
186
  this.reportView.registerRequiredCSS(storageViewStyles);
186
187
 
@@ -39,3 +39,51 @@ select {
39
39
  .inline-button {
40
40
  vertical-align: sub;
41
41
  }
42
+
43
+ devtools-report .report-row {
44
+ margin: var(--sys-size-3) 0 var(--sys-size-3) var(--sys-size-9);
45
+ grid-column: 1 / 3;
46
+
47
+ > devtools-checkbox:first-child {
48
+ margin-left: calc(var(--sys-size-4) * -1);
49
+ }
50
+
51
+ > devtools-icon:first-child {
52
+ /* We have inline icons that would otherwise be mis-aligned */
53
+ margin-inline-start: 0;
54
+ }
55
+ }
56
+
57
+ devtools-report .report-section {
58
+ display: grid;
59
+ grid-column: 1 / 3;
60
+ grid-template-columns: subgrid;
61
+ padding-bottom: var(--sys-size-5);
62
+ border-bottom: 1px solid var(--sys-color-divider);
63
+ margin-bottom: var(--sys-size-5);
64
+ }
65
+
66
+ .image-wrapper,
67
+ .image-wrapper img {
68
+ max-width: 200px;
69
+ max-height: 200px;
70
+ display: block;
71
+ object-fit: contain;
72
+ }
73
+
74
+ .image-wrapper {
75
+ display: inline-block;
76
+ height: fit-content;
77
+ margin-right: 8px;
78
+ }
79
+
80
+ .show-mask img {
81
+ /* The safe zone is a centrally positioned circle, with radius 2/5
82
+ * (40%) of the minimum of the icon's width and height.
83
+ * https://w3c.github.io/manifest/#icon-masks */
84
+ clip-path: circle(40% at 50% 50%);
85
+ }
86
+
87
+ .show-mask .image-wrapper {
88
+ background: var(--image-file-checker);
89
+ }
@@ -144,7 +144,7 @@ const DEFAULT_VIEW: View = (input, _output, target) => {
144
144
  ${renderStatusMessage(input.protocolHandler, input.manifestLink)}
145
145
  <div class="protocol-handlers-row">
146
146
  ${i18nTemplate(UIStrings.needHelpReadOur, {PH1: html`
147
- <x-link href=${PROTOCOL_DOCUMENT_URL} tabindex=0 class="devtools-link" jslog=${
147
+ <x-link href=${PROTOCOL_DOCUMENT_URL} tabindex=0 class="devtools-link" autofocus jslog=${
148
148
  VisualLogging.link('learn-more').track({click: true, keydown: 'Enter|Space'})}>
149
149
  ${i18nString(UIStrings.protocolHandlerRegistrations)}
150
150
  </x-link>`})}
@@ -173,7 +173,7 @@ export class ProtocolHandlersView extends UI.Widget.Widget {
173
173
  #view: View;
174
174
 
175
175
  constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
176
- super(element, {useShadowDom: false});
176
+ super(element, {useShadowDom: false, classes: ['vbox']});
177
177
  this.#view = view;
178
178
  }
179
179
 
@@ -2000,7 +2000,7 @@ export class ElementsTreeOutline extends
2000
2000
  this.insertChildElement(treeElement, node, treeElement.childCount(), true);
2001
2001
  }
2002
2002
 
2003
- if (node instanceof SDK.DOMModel.DOMDocument) {
2003
+ if (node instanceof SDK.DOMModel.DOMDocument && !this.isXMLMimeType) {
2004
2004
  let topLayerContainer = this.#topLayerContainerByDocument.get(node);
2005
2005
  if (!topLayerContainer) {
2006
2006
  topLayerContainer = new TopLayerContainer(this, node);
@@ -2,7 +2,6 @@
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 './LinearMemoryValueInterpreter.js';
6
5
  import './LinearMemoryViewer.js';
7
6
 
8
7
  import * as Common from '../../../core/common/common.js';
@@ -20,6 +19,7 @@ import {
20
19
  Navigation,
21
20
  type PageNavigationEvent,
22
21
  } from './LinearMemoryNavigator.js';
22
+ import {LinearMemoryValueInterpreter} from './LinearMemoryValueInterpreter.js';
23
23
  import type {ByteSelectedEvent, ResizeEvent} from './LinearMemoryViewer.js';
24
24
  import type {HighlightInfo} from './LinearMemoryViewerUtils.js';
25
25
  import {
@@ -186,10 +186,8 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: Record<string, unknown>,
186
186
  ${
187
187
  input.hideValueInspector ? nothing : html`
188
188
  <div class="value-interpreter">
189
- <devtools-linear-memory-inspector-interpreter
190
- .data=${
191
- {
192
- value: input.memory
189
+ <devtools-widget .widgetConfig=${widgetConfig(LinearMemoryValueInterpreter, {
190
+ buffer: input.memory
193
191
  .slice(
194
192
  input.address - input.memoryOffset,
195
193
  input.address + VALUE_INTEPRETER_MAX_NUM_BYTES,
@@ -203,9 +201,7 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: Record<string, unknown>,
203
201
  onJumpToAddressClicked: input.onJumpToAddress,
204
202
  onValueTypeToggled: input.onValueTypeToggled,
205
203
  onEndiannessChanged: input.onEndiannessChanged,
206
- }}
207
- >
208
- </devtools-linear-memory-inspector-interpreter>
204
+ })}></devtools-widget>
209
205
  </div>`}
210
206
  `,
211
207
  target);
@@ -1,7 +1,6 @@
1
1
  // Copyright 2020 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
 
@@ -35,42 +34,149 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
35
34
  const {render, html} = Lit;
36
35
  const {widgetConfig} = UI.Widget;
37
36
 
38
- export interface LinearMemoryValueInterpreterData {
39
- value: ArrayBuffer;
40
- valueTypes: Set<ValueType>;
37
+ export interface ViewInput {
41
38
  endianness: Endianness;
42
- valueTypeModes?: Map<ValueType, ValueTypeMode>;
39
+ buffer: ArrayBuffer;
40
+ valueTypes: Set<ValueType>;
41
+ valueTypeModes: Map<ValueType, ValueTypeMode>;
43
42
  memoryLength: number;
43
+ showSettings: boolean;
44
44
  onValueTypeModeChange: (type: ValueType, mode: ValueTypeMode) => void;
45
45
  onJumpToAddressClicked: (address: number) => void;
46
46
  onEndiannessChanged: (endianness: Endianness) => void;
47
47
  onValueTypeToggled: (type: ValueType, checked: boolean) => void;
48
+ onSettingsToggle: () => void;
48
49
  }
49
50
 
50
- export class LinearMemoryValueInterpreter extends HTMLElement {
51
- readonly #shadow = this.attachShadow({mode: 'open'});
52
- #onValueTypeModeChange: (type: ValueType, mode: ValueTypeMode) => void = () => {};
53
- #onJumpToAddressClicked: (address: number) => void = () => {};
54
- #onEndiannessChanged: (endianness: Endianness) => void = () => {};
55
- #onValueTypeToggled: (type: ValueType, checked: boolean) => void = () => {};
51
+ function renderEndiannessSetting(
52
+ onEndiannessChanged: (endianness: Endianness) => void, currentEndiannes: Endianness): Lit.TemplateResult {
53
+ // Disabled until https://crbug.com/1079231 is fixed.
54
+ // clang-format off
55
+ return html`
56
+ <label data-endianness-setting="true" title=${i18nString(UIStrings.changeEndianness)}>
57
+ <select
58
+ jslog=${VisualLogging.dropDown('linear-memory-inspector.endianess').track({change: true})}
59
+ style="border: none;"
60
+ data-endianness="true" @change=${(e: Event) => onEndiannessChanged((e.target as HTMLSelectElement).value as Endianness)}>
61
+ ${[Endianness.LITTLE, Endianness.BIG].map(endianness => {
62
+ return html`<option value=${endianness} .selected=${currentEndiannes === endianness}
63
+ jslog=${VisualLogging.item(Platform.StringUtilities.toKebabCase(endianness)).track({click: true})}>${
64
+ i18n.i18n.lockedString(endianness)}</option>`;
65
+ })}
66
+ </select>
67
+ </label>
68
+ `;
69
+ // clang-format on
70
+ }
71
+
72
+ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
73
+ // Disabled until https://crbug.com/1079231 is fixed.
74
+ // clang-format off
75
+ render(html`
76
+ <style>${UI.inspectorCommonStyles}</style>
77
+ <style>${linearMemoryValueInterpreterStyles}</style>
78
+ <div class="value-interpreter">
79
+ <div class="settings-toolbar">
80
+ ${renderEndiannessSetting(input.onEndiannessChanged, input.endianness)}
81
+ <devtools-button data-settings="true" class="toolbar-button ${input.showSettings ? '' : 'disabled'}"
82
+ title=${i18nString(UIStrings.toggleValueTypeSettings)} @click=${input.onSettingsToggle}
83
+ jslog=${VisualLogging.toggleSubpane('linear-memory-inspector.toggle-value-settings').track({ click: true })}
84
+ .iconName=${'gear'}
85
+ .toggledIconName=${'gear-filled'}
86
+ .toggleType=${Buttons.Button.ToggleType.PRIMARY}
87
+ .variant=${Buttons.Button.Variant.ICON_TOGGLE}
88
+ ></devtools-button>
89
+ </div>
90
+ <span class="divider"></span>
91
+ <div>
92
+ ${input.showSettings ?
93
+ html`
94
+ <devtools-widget .widgetConfig=${widgetConfig(ValueInterpreterSettings, {
95
+ valueTypes: input.valueTypes, onToggle: input.onValueTypeToggled
96
+ })}>
97
+ </devtools-widget>` :
98
+ html`
99
+ <devtools-widget .widgetConfig=${widgetConfig(ValueInterpreterDisplay, {
100
+ buffer: input.buffer,
101
+ valueTypes: input.valueTypes,
102
+ endianness: input.endianness,
103
+ valueTypeModes: input.valueTypeModes,
104
+ memoryLength: input.memoryLength,
105
+ onValueTypeModeChange: input.onValueTypeModeChange,
106
+ onJumpToAddressClicked: input.onJumpToAddressClicked,
107
+ })}>
108
+ </devtools-widget>`}
109
+ </div>
110
+ </div>
111
+ `,
112
+ target,
113
+ );
114
+ // clang-format on
115
+ };
116
+
117
+ export type View = typeof DEFAULT_VIEW;
118
+
119
+ export class LinearMemoryValueInterpreter extends UI.Widget.Widget {
120
+ readonly #view: View;
56
121
  #endianness = Endianness.LITTLE;
57
122
  #buffer = new ArrayBuffer(0);
58
123
  #valueTypes = new Set<ValueType>();
59
124
  #valueTypeModeConfig = new Map<ValueType, ValueTypeMode>();
60
125
  #memoryLength = 0;
61
126
  #showSettings = false;
127
+ #onValueTypeModeChange: (type: ValueType, mode: ValueTypeMode) => void = () => {};
128
+ #onJumpToAddressClicked: (address: number) => void = () => {};
129
+ #onEndiannessChanged: (endianness: Endianness) => void = () => {};
130
+ #onValueTypeToggled: (type: ValueType, checked: boolean) => void = () => {};
131
+
132
+ constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
133
+ super(element);
134
+ this.#view = view;
135
+ }
136
+
137
+ set buffer(value: ArrayBuffer) {
138
+ this.#buffer = value;
139
+ this.requestUpdate();
140
+ }
62
141
 
63
- set data(data: LinearMemoryValueInterpreterData) {
64
- this.#endianness = data.endianness;
65
- this.#buffer = data.value;
66
- this.#valueTypes = data.valueTypes;
67
- this.#valueTypeModeConfig = data.valueTypeModes || new Map();
68
- this.#memoryLength = data.memoryLength;
69
- this.#onValueTypeModeChange = data.onValueTypeModeChange;
70
- this.#onJumpToAddressClicked = data.onJumpToAddressClicked;
71
- this.#onEndiannessChanged = data.onEndiannessChanged;
72
- this.#onValueTypeToggled = data.onValueTypeToggled;
73
- this.#render();
142
+ get buffer(): ArrayBuffer {
143
+ return this.#buffer;
144
+ }
145
+
146
+ set valueTypes(value: Set<ValueType>) {
147
+ this.#valueTypes = value;
148
+ this.requestUpdate();
149
+ }
150
+
151
+ get valueTypes(): Set<ValueType> {
152
+ return this.#valueTypes;
153
+ }
154
+
155
+ set valueTypeModes(value: Map<ValueType, ValueTypeMode>) {
156
+ this.#valueTypeModeConfig = value;
157
+ this.requestUpdate();
158
+ }
159
+
160
+ get valueTypeModes(): Map<ValueType, ValueTypeMode> {
161
+ return this.#valueTypeModeConfig;
162
+ }
163
+
164
+ set endianness(value: Endianness) {
165
+ this.#endianness = value;
166
+ this.requestUpdate();
167
+ }
168
+
169
+ get endianness(): Endianness {
170
+ return this.#endianness;
171
+ }
172
+
173
+ set memoryLength(value: number) {
174
+ this.#memoryLength = value;
175
+ this.requestUpdate();
176
+ }
177
+
178
+ get memoryLength(): number {
179
+ return this.#memoryLength;
74
180
  }
75
181
 
76
182
  get onValueTypeModeChange(): (type: ValueType, mode: ValueTypeMode) => void {
@@ -79,7 +185,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
79
185
 
80
186
  set onValueTypeModeChange(value: (type: ValueType, mode: ValueTypeMode) => void) {
81
187
  this.#onValueTypeModeChange = value;
82
- this.#render();
188
+ this.requestUpdate();
83
189
  }
84
190
 
85
191
  get onJumpToAddressClicked(): (address: number) => void {
@@ -88,7 +194,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
88
194
 
89
195
  set onJumpToAddressClicked(value: (address: number) => void) {
90
196
  this.#onJumpToAddressClicked = value;
91
- this.#render();
197
+ this.requestUpdate();
92
198
  }
93
199
 
94
200
  get onEndiannessChanged(): (endianness: Endianness) => void {
@@ -97,7 +203,7 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
97
203
 
98
204
  set onEndiannessChanged(value: (endianness: Endianness) => void) {
99
205
  this.#onEndiannessChanged = value;
100
- this.#render();
206
+ this.performUpdate();
101
207
  }
102
208
 
103
209
  get onValueTypeToggled(): (type: ValueType, checked: boolean) => void {
@@ -106,83 +212,28 @@ export class LinearMemoryValueInterpreter extends HTMLElement {
106
212
 
107
213
  set onValueTypeToggled(value: (type: ValueType, checked: boolean) => void) {
108
214
  this.#onValueTypeToggled = value;
109
- this.#render();
110
- }
111
-
112
- #render(): void {
113
- // Disabled until https://crbug.com/1079231 is fixed.
114
- // clang-format off
115
- render(html`
116
- <style>${UI.inspectorCommonStyles}</style>
117
- <style>${linearMemoryValueInterpreterStyles}</style>
118
- <div class="value-interpreter">
119
- <div class="settings-toolbar">
120
- ${this.#renderEndiannessSetting()}
121
- <devtools-button data-settings="true" class="toolbar-button ${this.#showSettings ? '' : 'disabled'}"
122
- title=${i18nString(UIStrings.toggleValueTypeSettings)} @click=${this.#onSettingsToggle}
123
- jslog=${VisualLogging.toggleSubpane('linear-memory-inspector.toggle-value-settings').track({click: true})}
124
- .iconName=${'gear'}
125
- .toggledIconName=${'gear-filled'}
126
- .toggleType=${Buttons.Button.ToggleType.PRIMARY}
127
- .variant=${Buttons.Button.Variant.ICON_TOGGLE}
128
- ></devtools-button>
129
- </div>
130
- <span class="divider"></span>
131
- <div>
132
- ${this.#showSettings ?
133
- html`
134
- <devtools-widget .widgetConfig=${widgetConfig(ValueInterpreterSettings, {
135
- valueTypes: this.#valueTypes, onToggle: this.#onValueTypeToggled })}>
136
- </devtools-widget>` :
137
- html`
138
- <devtools-widget .widgetConfig=${widgetConfig(ValueInterpreterDisplay, {
139
- buffer: this.#buffer,
140
- valueTypes: this.#valueTypes,
141
- endianness: this.#endianness,
142
- valueTypeModes: this.#valueTypeModeConfig,
143
- memoryLength: this.#memoryLength,
144
- onValueTypeModeChange: this.#onValueTypeModeChange,
145
- onJumpToAddressClicked: this.#onJumpToAddressClicked,
146
- })}>
147
- </devtools-widget>`}
148
- </div>
149
- </div>
150
- `,
151
- this.#shadow, { host: this },
152
- );
153
- // clang-format on
215
+ this.performUpdate();
154
216
  }
155
217
 
156
- #renderEndiannessSetting(): Lit.TemplateResult {
157
- // Disabled until https://crbug.com/1079231 is fixed.
158
- // clang-format off
159
- return html`
160
- <label data-endianness-setting="true" title=${i18nString(UIStrings.changeEndianness)}>
161
- <select
162
- jslog=${VisualLogging.dropDown('linear-memory-inspector.endianess').track({change: true})}
163
- style="border: none;"
164
- data-endianness="true" @change=${(e: Event) => this.#onEndiannessChanged((e.target as HTMLSelectElement).value as Endianness)}>
165
- ${[Endianness.LITTLE, Endianness.BIG].map(endianness => {
166
- return html`<option value=${endianness} .selected=${this.#endianness === endianness}
167
- jslog=${VisualLogging.item(Platform.StringUtilities.toKebabCase(endianness)).track({click: true})}>${
168
- i18n.i18n.lockedString(endianness)}</option>`;
169
- })}
170
- </select>
171
- </label>
172
- `;
173
- // clang-format on
218
+ override performUpdate(): void {
219
+ const viewInput: ViewInput = {
220
+ endianness: this.#endianness,
221
+ buffer: this.#buffer,
222
+ valueTypes: this.#valueTypes,
223
+ valueTypeModes: this.#valueTypeModeConfig,
224
+ memoryLength: this.#memoryLength,
225
+ showSettings: this.#showSettings,
226
+ onValueTypeModeChange: this.#onValueTypeModeChange,
227
+ onJumpToAddressClicked: this.#onJumpToAddressClicked,
228
+ onEndiannessChanged: this.#onEndiannessChanged,
229
+ onValueTypeToggled: this.#onValueTypeToggled,
230
+ onSettingsToggle: this.#onSettingsToggle.bind(this),
231
+ };
232
+ this.#view(viewInput, undefined, this.contentElement);
174
233
  }
175
234
 
176
235
  #onSettingsToggle(): void {
177
236
  this.#showSettings = !this.#showSettings;
178
- this.#render();
179
- }
180
- }
181
-
182
- customElements.define('devtools-linear-memory-inspector-interpreter', LinearMemoryValueInterpreter);
183
-
184
- declare global {
185
- interface HTMLElementTagNameMap {
186
- 'devtools-linear-memory-inspector-interpreter': LinearMemoryValueInterpreter;
237
+ this.requestUpdate();
187
238
  }
188
239
  }
@@ -47,7 +47,7 @@ const BYTE_GROUP_SIZE = 4;
47
47
  export class LinearMemoryViewer extends HTMLElement {
48
48
  readonly #shadow = this.attachShadow({mode: 'open'});
49
49
 
50
- readonly #resizeObserver = new ResizeObserver(() => this.#resize());
50
+ readonly #resizeObserver = new ResizeObserver(() => requestAnimationFrame(this.#resize.bind(this)));
51
51
  #isObservingResize = false;
52
52
 
53
53
  #memory = new Uint8Array();
@@ -4,44 +4,46 @@
4
4
  * found in the LICENSE file.
5
5
  */
6
6
 
7
- :host {
8
- flex: auto;
9
- display: flex;
10
- }
7
+ @scope to (devtools-widget > *) {
8
+ :scope {
9
+ flex: auto;
10
+ display: flex;
11
+ }
11
12
 
12
- .value-interpreter {
13
- border: 1px solid var(--sys-color-divider);
14
- background-color: var(--sys-color-cdt-base-container);
15
- overflow: hidden;
16
- width: 400px;
17
- }
13
+ .value-interpreter {
14
+ border: 1px solid var(--sys-color-divider);
15
+ background-color: var(--sys-color-cdt-base-container);
16
+ overflow: hidden;
17
+ width: 400px;
18
+ }
18
19
 
19
- .settings-toolbar {
20
- min-height: 26px;
21
- display: flex;
22
- flex-wrap: nowrap;
23
- justify-content: space-between;
24
- padding-left: var(--sys-size-3);
25
- padding-right: var(--sys-size-3);
26
- align-items: center;
27
- }
20
+ .settings-toolbar {
21
+ min-height: 26px;
22
+ display: flex;
23
+ flex-wrap: nowrap;
24
+ justify-content: space-between;
25
+ padding-left: var(--sys-size-3);
26
+ padding-right: var(--sys-size-3);
27
+ align-items: center;
28
+ }
28
29
 
29
- .settings-toolbar-button {
30
- padding: 0;
31
- width: 20px;
32
- height: 20px;
33
- border: none;
34
- outline: none;
35
- background-color: transparent;
36
- }
30
+ .settings-toolbar-button {
31
+ padding: 0;
32
+ width: 20px;
33
+ height: 20px;
34
+ border: none;
35
+ outline: none;
36
+ background-color: transparent;
37
+ }
37
38
 
38
- .settings-toolbar-button.active devtools-icon {
39
- color: var(--icon-toggled);
40
- }
39
+ .settings-toolbar-button.active devtools-icon {
40
+ color: var(--icon-toggled);
41
+ }
41
42
 
42
- .divider {
43
- display: block;
44
- height: 1px;
45
- margin-bottom: 12px;
46
- background-color: var(--sys-color-divider);
43
+ .divider {
44
+ display: block;
45
+ height: 1px;
46
+ margin-bottom: 12px;
47
+ background-color: var(--sys-color-divider);
48
+ }
47
49
  }