chrome-devtools-frontend 1.0.1006211 → 1.0.1007307

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 (125) hide show
  1. package/config/gni/devtools_grd_files.gni +2 -0
  2. package/config/gni/devtools_image_files.gni +2 -0
  3. package/front_end/Images/src/ic_sources_authored.svg +5 -0
  4. package/front_end/Images/src/ic_sources_deployed.svg +5 -0
  5. package/front_end/core/i18n/locales/af.json +202 -43
  6. package/front_end/core/i18n/locales/am.json +201 -42
  7. package/front_end/core/i18n/locales/ar.json +201 -42
  8. package/front_end/core/i18n/locales/as.json +201 -42
  9. package/front_end/core/i18n/locales/az.json +201 -42
  10. package/front_end/core/i18n/locales/be.json +201 -42
  11. package/front_end/core/i18n/locales/bg.json +201 -42
  12. package/front_end/core/i18n/locales/bn.json +201 -42
  13. package/front_end/core/i18n/locales/bs.json +201 -42
  14. package/front_end/core/i18n/locales/ca.json +204 -45
  15. package/front_end/core/i18n/locales/cs.json +201 -42
  16. package/front_end/core/i18n/locales/cy.json +201 -42
  17. package/front_end/core/i18n/locales/da.json +201 -42
  18. package/front_end/core/i18n/locales/de.json +201 -42
  19. package/front_end/core/i18n/locales/el.json +201 -42
  20. package/front_end/core/i18n/locales/en-GB.json +199 -40
  21. package/front_end/core/i18n/locales/en-US.json +43 -1
  22. package/front_end/core/i18n/locales/en-XL.json +43 -1
  23. package/front_end/core/i18n/locales/es-419.json +201 -42
  24. package/front_end/core/i18n/locales/es.json +201 -42
  25. package/front_end/core/i18n/locales/et.json +201 -42
  26. package/front_end/core/i18n/locales/eu.json +202 -43
  27. package/front_end/core/i18n/locales/fa.json +201 -42
  28. package/front_end/core/i18n/locales/fi.json +201 -42
  29. package/front_end/core/i18n/locales/fil.json +201 -42
  30. package/front_end/core/i18n/locales/fr-CA.json +201 -42
  31. package/front_end/core/i18n/locales/fr.json +203 -44
  32. package/front_end/core/i18n/locales/gl.json +203 -44
  33. package/front_end/core/i18n/locales/gu.json +201 -42
  34. package/front_end/core/i18n/locales/he.json +201 -42
  35. package/front_end/core/i18n/locales/hi.json +201 -42
  36. package/front_end/core/i18n/locales/hr.json +201 -42
  37. package/front_end/core/i18n/locales/hu.json +201 -42
  38. package/front_end/core/i18n/locales/hy.json +201 -42
  39. package/front_end/core/i18n/locales/id.json +201 -42
  40. package/front_end/core/i18n/locales/is.json +201 -42
  41. package/front_end/core/i18n/locales/it.json +203 -44
  42. package/front_end/core/i18n/locales/ja.json +203 -44
  43. package/front_end/core/i18n/locales/ka.json +201 -42
  44. package/front_end/core/i18n/locales/kk.json +201 -42
  45. package/front_end/core/i18n/locales/km.json +201 -42
  46. package/front_end/core/i18n/locales/kn.json +201 -42
  47. package/front_end/core/i18n/locales/ko.json +201 -42
  48. package/front_end/core/i18n/locales/ky.json +201 -42
  49. package/front_end/core/i18n/locales/lo.json +201 -42
  50. package/front_end/core/i18n/locales/lt.json +201 -42
  51. package/front_end/core/i18n/locales/lv.json +201 -42
  52. package/front_end/core/i18n/locales/mk.json +201 -42
  53. package/front_end/core/i18n/locales/ml.json +201 -42
  54. package/front_end/core/i18n/locales/mn.json +201 -42
  55. package/front_end/core/i18n/locales/mr.json +201 -42
  56. package/front_end/core/i18n/locales/ms.json +201 -42
  57. package/front_end/core/i18n/locales/my.json +201 -42
  58. package/front_end/core/i18n/locales/ne.json +201 -42
  59. package/front_end/core/i18n/locales/nl.json +201 -42
  60. package/front_end/core/i18n/locales/no.json +201 -42
  61. package/front_end/core/i18n/locales/or.json +201 -42
  62. package/front_end/core/i18n/locales/pa.json +201 -42
  63. package/front_end/core/i18n/locales/pl.json +201 -42
  64. package/front_end/core/i18n/locales/pt-PT.json +201 -42
  65. package/front_end/core/i18n/locales/pt.json +201 -42
  66. package/front_end/core/i18n/locales/ro.json +201 -42
  67. package/front_end/core/i18n/locales/ru.json +203 -44
  68. package/front_end/core/i18n/locales/si.json +201 -42
  69. package/front_end/core/i18n/locales/sk.json +201 -42
  70. package/front_end/core/i18n/locales/sl.json +201 -42
  71. package/front_end/core/i18n/locales/sq.json +201 -42
  72. package/front_end/core/i18n/locales/sr-Latn.json +201 -42
  73. package/front_end/core/i18n/locales/sr.json +201 -42
  74. package/front_end/core/i18n/locales/sv.json +201 -42
  75. package/front_end/core/i18n/locales/sw.json +201 -42
  76. package/front_end/core/i18n/locales/ta.json +201 -42
  77. package/front_end/core/i18n/locales/te.json +202 -43
  78. package/front_end/core/i18n/locales/th.json +201 -42
  79. package/front_end/core/i18n/locales/tr.json +201 -42
  80. package/front_end/core/i18n/locales/uk.json +201 -42
  81. package/front_end/core/i18n/locales/ur.json +201 -42
  82. package/front_end/core/i18n/locales/uz.json +201 -42
  83. package/front_end/core/i18n/locales/vi.json +201 -42
  84. package/front_end/core/i18n/locales/zh-HK.json +201 -42
  85. package/front_end/core/i18n/locales/zh-TW.json +201 -42
  86. package/front_end/core/i18n/locales/zh.json +201 -42
  87. package/front_end/core/i18n/locales/zu.json +201 -42
  88. package/front_end/core/sdk/CPUThrottlingManager.ts +54 -0
  89. package/front_end/core/sdk/DebuggerModel.ts +12 -3
  90. package/front_end/core/sdk/EmulationModel.ts +7 -0
  91. package/front_end/core/sdk/NetworkManager.ts +6 -2
  92. package/front_end/devtools_compatibility.js +1 -0
  93. package/front_end/entrypoints/formatter_worker/FormatterActions.ts +1 -0
  94. package/front_end/entrypoints/formatter_worker/ScopeParser.ts +12 -10
  95. package/front_end/entrypoints/formatter_worker/formatter_worker-entrypoint.ts +4 -0
  96. package/front_end/generated/InspectorBackendCommands.js +3 -0
  97. package/front_end/generated/protocol-mapping.d.ts +2 -0
  98. package/front_end/generated/protocol-proxy-api.d.ts +3 -0
  99. package/front_end/generated/protocol.ts +7 -0
  100. package/front_end/models/formatter/FormatterWorkerPool.ts +6 -0
  101. package/front_end/models/issues_manager/DeprecationIssue.ts +1 -1
  102. package/front_end/models/javascript_metadata/JavaScriptMetadata.ts +13 -20
  103. package/front_end/models/javascript_metadata/NativeFunctions.js +1237 -3962
  104. package/front_end/models/source_map_scopes/NamesResolver.ts +206 -73
  105. package/front_end/models/workspace/UISourceCode.ts +7 -0
  106. package/front_end/panels/accessibility/axBreadcrumbs.css +2 -2
  107. package/front_end/panels/application/components/BackForwardCacheView.ts +16 -0
  108. package/front_end/panels/lighthouse/LighthouseStartView.ts +7 -5
  109. package/front_end/panels/lighthouse/LighthouseStartViewFR.ts +70 -49
  110. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +113 -4
  111. package/front_end/panels/network/components/RequestHeadersView.css +31 -3
  112. package/front_end/panels/network/components/RequestHeadersView.ts +126 -3
  113. package/front_end/panels/sources/NavigatorView.ts +141 -40
  114. package/front_end/panels/sources/SourcesPanel.ts +8 -0
  115. package/front_end/panels/sources/TabbedEditorContainer.ts +2 -2
  116. package/front_end/panels/sources/sources-meta.ts +6 -0
  117. package/front_end/panels/timeline/TimelinePanel.ts +27 -4
  118. package/front_end/panels/timeline/timelinePanel.css +8 -0
  119. package/front_end/ui/components/text_editor/javascript.ts +12 -14
  120. package/front_end/ui/legacy/Treeoutline.ts +5 -2
  121. package/package.json +1 -1
  122. package/scripts/hosted_mode/server.js +14 -1
  123. package/scripts/javascript_natives/helpers.js +26 -7
  124. package/scripts/javascript_natives/index.js +4 -3
  125. package/scripts/javascript_natives/tests.js +2 -2
@@ -61,6 +61,26 @@ const UIStrings = {
61
61
  *@example {2} PH1
62
62
  */
63
63
  dSlowdown: '{PH1}× slowdown',
64
+ /**
65
+ *@description Tooltip text in Throttling Manager of the Performance panel
66
+ */
67
+ excessConcurrency: 'Exceeding the default value may degrade system performance.',
68
+ /**
69
+ *@description Tooltip text in Throttling Manager of the Performance panel
70
+ */
71
+ resetConcurrency: 'Reset to the default value',
72
+ /**
73
+ *@description Screen reader label for an check box that neables overriding navigator.hardwareConcurrency
74
+ */
75
+ hardwareConcurrency: 'Hardware concurrency',
76
+ /**
77
+ *@description Screen reader label for an input box that overrides navigator.hardwareConcurrency
78
+ */
79
+ hardwareConcurrencyValue: 'Value of navigator.hardwareConcurrency',
80
+ /**
81
+ *@description Icon title in Throttling Manager of the Performance panel
82
+ */
83
+ hardwareConcurrencyIsEnabled: 'Hardware concurrency override is enabled',
64
84
  };
65
85
  const str_ = i18n.i18n.registerUIStrings('panels/mobile_throttling/ThrottlingManager.ts', UIStrings);
66
86
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -73,6 +93,11 @@ export class ThrottlingManager {
73
93
  private readonly currentNetworkThrottlingConditionsSetting: Common.Settings.Setting<SDK.NetworkManager.Conditions>;
74
94
  private lastNetworkThrottlingConditions!: SDK.NetworkManager.Conditions;
75
95
  private readonly cpuThrottlingManager: SDK.CPUThrottlingManager.CPUThrottlingManager;
96
+ #hardwareConcurrencyOverrideEnabled = false;
97
+
98
+ get hardwareConcurrencyOverrideEnabled(): boolean {
99
+ return this.#hardwareConcurrencyOverrideEnabled;
100
+ }
76
101
 
77
102
  private constructor() {
78
103
  this.cpuThrottlingManager = SDK.CPUThrottlingManager.CPUThrottlingManager.instance();
@@ -232,19 +257,36 @@ export class ThrottlingManager {
232
257
  }
233
258
  }
234
259
 
260
+ private updatePanelIcon(): void {
261
+ const cpuRate = this.cpuThrottlingManager.cpuThrottlingRate();
262
+
263
+ if (cpuRate === SDK.CPUThrottlingManager.CPUThrottlingRates.NoThrottling &&
264
+ !this.hardwareConcurrencyOverrideEnabled) {
265
+ UI.InspectorView.InspectorView.instance().setPanelIcon('timeline', null);
266
+ return;
267
+ }
268
+ const icon = UI.Icon.Icon.create('smallicon-warning');
269
+ const tooltips: string[] = [];
270
+ if (cpuRate !== SDK.CPUThrottlingManager.CPUThrottlingRates.NoThrottling) {
271
+ tooltips.push(i18nString(UIStrings.cpuThrottlingIsEnabled));
272
+ }
273
+ if (this.hardwareConcurrencyOverrideEnabled) {
274
+ tooltips.push(i18nString(UIStrings.hardwareConcurrencyIsEnabled));
275
+ }
276
+ icon.title = tooltips.join('\n');
277
+ UI.InspectorView.InspectorView.instance().setPanelIcon('timeline', icon);
278
+ }
279
+
235
280
  setCPUThrottlingRate(rate: number): void {
236
281
  this.cpuThrottlingManager.setCPUThrottlingRate(rate);
237
- let icon: UI.Icon.Icon|null = null;
238
282
  if (rate !== SDK.CPUThrottlingManager.CPUThrottlingRates.NoThrottling) {
239
283
  Host.userMetrics.actionTaken(Host.UserMetrics.Action.CpuThrottlingEnabled);
240
- icon = UI.Icon.Icon.create('smallicon-warning');
241
- UI.Tooltip.Tooltip.install(icon, i18nString(UIStrings.cpuThrottlingIsEnabled));
242
284
  }
243
285
  const index = this.cpuThrottlingRates.indexOf(rate);
244
286
  for (const control of this.cpuThrottlingControls) {
245
287
  control.setSelectedIndex(index);
246
288
  }
247
- UI.InspectorView.InspectorView.instance().setPanelIcon('timeline', icon);
289
+ this.updatePanelIcon();
248
290
  }
249
291
 
250
292
  createCPUThrottlingSelector(): UI.Toolbar.ToolbarComboBox {
@@ -266,6 +308,73 @@ export class ThrottlingManager {
266
308
  return control;
267
309
  }
268
310
 
311
+ createHardwareConcurrencySelector(): {
312
+ input: UI.Toolbar.ToolbarItem,
313
+ reset: UI.Toolbar.ToolbarButton,
314
+ warning: UI.Toolbar.ToolbarItem,
315
+ toggle: UI.Toolbar.ToolbarItem,
316
+ } {
317
+ const input = new UI.Toolbar.ToolbarItem(UI.UIUtils.createInput('devtools-text-input', 'number'));
318
+ input.setTitle(i18nString(UIStrings.hardwareConcurrencyValue));
319
+ const inputElement = input.element as HTMLInputElement;
320
+ inputElement.min = '1';
321
+ input.setEnabled(false);
322
+
323
+ const toggle = new UI.Toolbar.ToolbarCheckbox(i18nString(UIStrings.hardwareConcurrency));
324
+ const reset = new UI.Toolbar.ToolbarButton('Reset concurrency', 'largeicon-undo');
325
+ reset.setTitle(i18nString(UIStrings.resetConcurrency));
326
+ const warning = new UI.Toolbar.ToolbarItem(UI.Icon.Icon.create('smallicon-warning'));
327
+ warning.setTitle(i18nString(UIStrings.excessConcurrency));
328
+
329
+ toggle.inputElement.disabled = true; // Prevent modification while still wiring things up asynchronously below
330
+ reset.element.classList.add('timeline-concurrency-hidden');
331
+ warning.element.classList.add('timeline-concurrency-hidden');
332
+
333
+ void this.cpuThrottlingManager.getHardwareConcurrency().then(defaultValue => {
334
+ if (defaultValue === undefined) {
335
+ return;
336
+ }
337
+
338
+ const setHardwareConcurrency = (value: number): void => {
339
+ if (value >= 1) {
340
+ this.cpuThrottlingManager.setHardwareConcurrency(value);
341
+ }
342
+ if (value > defaultValue) {
343
+ warning.element.classList.remove('timeline-concurrency-hidden');
344
+ } else {
345
+ warning.element.classList.add('timeline-concurrency-hidden');
346
+ }
347
+ if (value === defaultValue) {
348
+ reset.element.classList.add('timeline-concurrency-hidden');
349
+ } else {
350
+ reset.element.classList.remove('timeline-concurrency-hidden');
351
+ }
352
+ };
353
+
354
+ inputElement.value = `${defaultValue}`;
355
+ inputElement.oninput = (): void => setHardwareConcurrency(Number(inputElement.value));
356
+ toggle.inputElement.disabled = false;
357
+ toggle.inputElement.addEventListener('change', () => {
358
+ this.#hardwareConcurrencyOverrideEnabled = toggle.checked();
359
+ this.updatePanelIcon();
360
+
361
+ input.setEnabled(this.hardwareConcurrencyOverrideEnabled);
362
+ setHardwareConcurrency(this.hardwareConcurrencyOverrideEnabled ? Number(inputElement.value) : defaultValue);
363
+ });
364
+
365
+ reset.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, () => {
366
+ inputElement.value = `${defaultValue}`;
367
+ setHardwareConcurrency(defaultValue);
368
+ });
369
+ });
370
+
371
+ return {input, reset, warning, toggle};
372
+ }
373
+
374
+ setHardwareConcurrency(concurrency: number): void {
375
+ this.cpuThrottlingManager.setHardwareConcurrency(concurrency);
376
+ }
377
+
269
378
  private isDirty(): boolean {
270
379
  const networkConditions = SDK.NetworkManager.MultitargetNetworkManager.instance().networkConditions();
271
380
  const knownCurrentConditions = this.currentNetworkThrottlingConditionsSetting.get();
@@ -23,10 +23,33 @@
23
23
  background-color: var(--legacy-focus-bg-color);
24
24
  }
25
25
 
26
+ details[open] .header-count {
27
+ display: none;
28
+ }
29
+
30
+ details summary label {
31
+ display: none;
32
+ }
33
+
34
+ details[open] summary label {
35
+ display: inline-flex;
36
+ gap: 2px;
37
+ }
38
+
39
+ .raw-checkbox-container {
40
+ float: right;
41
+ }
42
+
43
+ details summary input {
44
+ vertical-align: middle;
45
+ }
46
+
26
47
  .row {
27
48
  display: flex;
28
49
  line-height: 20px;
29
- padding-left: 25px;
50
+ padding-left: 8px;
51
+ gap: 12px;
52
+ user-select: text;
30
53
  }
31
54
 
32
55
  .row:first-of-type {
@@ -39,14 +62,13 @@
39
62
 
40
63
  .header-name {
41
64
  color: var(--color-primary);
42
- font-weight: bold;
65
+ font-weight: 500;
43
66
  width: 160px;
44
67
  flex-shrink: 0;
45
68
  }
46
69
 
47
70
  .header-value {
48
71
  word-break: break-all;
49
- user-select: text;
50
72
  }
51
73
 
52
74
  .green-circle::before,
@@ -76,3 +98,9 @@
76
98
  .status-with-comment {
77
99
  color: var(--color-text-secondary);
78
100
  }
101
+
102
+ .raw-headers {
103
+ font-family: var(--source-code-font-family);
104
+ font-size: var(--source-code-font-size);
105
+ white-space: pre-wrap;
106
+ }
@@ -44,6 +44,14 @@ const UIStrings = {
44
44
  */
45
45
  general: 'General',
46
46
  /**
47
+ *@description Label for a checkbox to switch between raw and parsed headers
48
+ */
49
+ raw: 'Raw',
50
+ /**
51
+ *@description Text in Request Headers View of the Network panel
52
+ */
53
+ requestHeaders: 'Request Headers',
54
+ /**
47
55
  *@description The URL of a request
48
56
  */
49
57
  requestUrl: 'Request URL',
@@ -52,6 +60,10 @@ const UIStrings = {
52
60
  */
53
61
  requestMethod: 'Request Method',
54
62
  /**
63
+ *@description A context menu item in the Network Log View Columns of the Network panel
64
+ */
65
+ responseHeaders: 'Response Headers',
66
+ /**
55
67
  *@description HTTP response code
56
68
  */
57
69
  statusCode: 'Status Code',
@@ -103,6 +115,8 @@ export class RequestHeadersComponent extends HTMLElement {
103
115
  static readonly litTagName = LitHtml.literal`devtools-request-headers`;
104
116
  readonly #shadow = this.attachShadow({mode: 'open'});
105
117
  #request?: Readonly<SDK.NetworkRequest.NetworkRequest>;
118
+ #showResponseHeadersText = false;
119
+ #showRequestHeadersText = false;
106
120
 
107
121
  set data(data: RequestHeadersComponentData) {
108
122
  this.#request = data.request;
@@ -120,10 +134,84 @@ export class RequestHeadersComponent extends HTMLElement {
120
134
  // clang-format off
121
135
  render(html`
122
136
  ${this.#renderGeneralSection()}
137
+ ${this.#renderResponseHeaders()}
138
+ ${this.#renderRequestHeaders()}
123
139
  `, this.#shadow, {host: this});
124
140
  // clang-format on
125
141
  }
126
142
 
143
+ #renderResponseHeaders(): LitHtml.TemplateResult {
144
+ assertNotNullOrUndefined(this.#request);
145
+
146
+ const toggleShowRaw = (): void => {
147
+ this.#showResponseHeadersText = !this.#showResponseHeadersText;
148
+ this.#render();
149
+ };
150
+
151
+ // Disabled until https://crbug.com/1079231 is fixed.
152
+ // clang-format off
153
+ return html`
154
+ <${Category.litTagName}
155
+ @togglerawevent=${toggleShowRaw}
156
+ .data=${{
157
+ name: 'responseHeaders',
158
+ title: i18nString(UIStrings.responseHeaders),
159
+ headerCount: this.#request.sortedResponseHeaders.length,
160
+ checked: this.#request.responseHeadersText ? this.#showResponseHeadersText : undefined,
161
+ } as CategoryData}
162
+ aria-label=${i18nString(UIStrings.responseHeaders)}
163
+ >
164
+ ${this.#showResponseHeadersText ? html`
165
+ <div class="row raw-headers">${this.#request.responseHeadersText.trim()}</div>
166
+ ` : html`
167
+ ${this.#request.sortedResponseHeaders.map(header => html`
168
+ <div class="row">
169
+ <div class="header-name">${header.name}:</div>
170
+ <div class="header-value">${header.value}</div>
171
+ </div>
172
+ `)}
173
+ `}
174
+ </${Category.litTagName}>
175
+ `;
176
+ }
177
+
178
+ #renderRequestHeaders(): LitHtml.TemplateResult {
179
+ assertNotNullOrUndefined(this.#request);
180
+
181
+ const toggleShowRaw = (): void => {
182
+ this.#showRequestHeadersText = !this.#showRequestHeadersText;
183
+ this.#render();
184
+ };
185
+
186
+ const requestHeadersText = this.#request.requestHeadersText();
187
+
188
+ // Disabled until https://crbug.com/1079231 is fixed.
189
+ // clang-format off
190
+ return html`
191
+ <${Category.litTagName}
192
+ @togglerawevent=${toggleShowRaw}
193
+ .data=${{
194
+ name: 'requestHeaders',
195
+ title: i18nString(UIStrings.requestHeaders),
196
+ headerCount: this.#request.requestHeaders().length,
197
+ checked: requestHeadersText? this.#showRequestHeadersText : undefined,
198
+ } as CategoryData}
199
+ aria-label=${i18nString(UIStrings.requestHeaders)}
200
+ >
201
+ ${(this.#showRequestHeadersText && requestHeadersText) ? html`
202
+ <div class="row raw-headers">${requestHeadersText.trim()}</div>
203
+ ` : html`
204
+ ${this.#request.requestHeaders().map(header => html`
205
+ <div class="row">
206
+ <div class="header-name">${header.name}:</div>
207
+ <div class="header-value">${header.value}</div>
208
+ </div>
209
+ `)}
210
+ `}
211
+ </${Category.litTagName}>
212
+ `;
213
+ }
214
+
127
215
  #renderGeneralSection(): LitHtml.TemplateResult {
128
216
  assertNotNullOrUndefined(this.#request);
129
217
 
@@ -159,7 +247,10 @@ export class RequestHeadersComponent extends HTMLElement {
159
247
  // Disabled until https://crbug.com/1079231 is fixed.
160
248
  // clang-format off
161
249
  return html`
162
- <${Category.litTagName} .data=${{name: 'general', title: i18nString(UIStrings.general)} as CategoryData}>
250
+ <${Category.litTagName}
251
+ .data=${{name: 'general', title: i18nString(UIStrings.general)} as CategoryData}
252
+ aria-label=${i18nString(UIStrings.general)}
253
+ >
163
254
  <div class="row">
164
255
  <div class="header-name">${i18nString(UIStrings.requestUrl)}:</div>
165
256
  <div class="header-value">${this.#request.url()}</div>
@@ -192,9 +283,19 @@ export class RequestHeadersComponent extends HTMLElement {
192
283
  }
193
284
  }
194
285
 
286
+ export class ToggleRawHeadersEvent extends Event {
287
+ static readonly eventName = 'togglerawevent';
288
+
289
+ constructor() {
290
+ super(ToggleRawHeadersEvent.eventName, {});
291
+ }
292
+ }
293
+
195
294
  export interface CategoryData {
196
295
  name: string;
197
296
  title: Common.UIString.LocalizedString;
297
+ headerCount?: number;
298
+ checked?: boolean;
198
299
  }
199
300
 
200
301
  export class Category extends HTMLElement {
@@ -202,6 +303,8 @@ export class Category extends HTMLElement {
202
303
  readonly #shadow = this.attachShadow({mode: 'open'});
203
304
  #expandedSetting?: Common.Settings.Setting<boolean>;
204
305
  #title: Common.UIString.LocalizedString = Common.UIString.LocalizedEmptyString;
306
+ #headerCount?: number = undefined;
307
+ #checked: boolean|undefined = undefined;
205
308
 
206
309
  connectedCallback(): void {
207
310
  this.#shadow.adoptedStyleSheets = [requestHeadersViewStyles];
@@ -211,15 +314,35 @@ export class Category extends HTMLElement {
211
314
  this.#title = data.title;
212
315
  this.#expandedSetting =
213
316
  Common.Settings.Settings.instance().createSetting('request-info-' + data.name + '-category-expanded', true);
317
+ this.#headerCount = data.headerCount;
318
+ this.#checked = data.checked;
214
319
  this.#render();
215
320
  }
216
321
 
322
+ #onCheckboxToggle(): void {
323
+ this.dispatchEvent(new ToggleRawHeadersEvent());
324
+ }
325
+
217
326
  #render(): void {
327
+ const isOpen = this.#expandedSetting ? this.#expandedSetting.get() : true;
218
328
  // Disabled until https://crbug.com/1079231 is fixed.
219
329
  // clang-format off
220
330
  render(html`
221
- <details ?open=${this.#expandedSetting ? this.#expandedSetting.get() : true} @toggle=${this.#onToggle}>
222
- <summary class="header" @keydown=${this.#onSummaryKeyDown}>${this.#title}</summary>
331
+ <details ?open=${isOpen} @toggle=${this.#onToggle}>
332
+ <summary class="header" @keydown=${this.#onSummaryKeyDown}>
333
+ ${this.#title}${this.#headerCount ?
334
+ html`<span class="header-count"> (${this.#headerCount})</span>` :
335
+ LitHtml.nothing
336
+ }
337
+ ${this.#checked !== undefined ? html`
338
+ <span class="raw-checkbox-container">
339
+ <label>
340
+ <input type="checkbox" .checked=${this.#checked} @change=${this.#onCheckboxToggle} />
341
+ ${i18nString(UIStrings.raw)}
342
+ </label>
343
+ </span>
344
+ ` : LitHtml.nothing}
345
+ </summary>
223
346
  <slot></slot>
224
347
  </details>
225
348
  `, this.#shadow, {host: this});