chrome-devtools-frontend 1.0.1697595 → 1.0.1697998

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 (39) hide show
  1. package/.stylelintignore +2 -0
  2. package/front_end/core/common/VersionController.ts +5 -1
  3. package/front_end/core/sdk/AnimationModel.ts +9 -1
  4. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  5. package/front_end/generated/protocol.ts +8 -2
  6. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +26 -0
  7. package/front_end/models/ai_assistance/ai_assistance.ts +4 -4
  8. package/front_end/models/ai_assistance/skills/performance.md +4 -3
  9. package/front_end/models/ai_assistance/tools/{GetFunctionCode.ts → GetTraceFunctionCode.ts} +26 -13
  10. package/front_end/models/ai_assistance/tools/{GetResourceContent.ts → GetTraceResourceContent.ts} +31 -11
  11. package/front_end/models/ai_assistance/tools/Tool.ts +2 -2
  12. package/front_end/models/ai_assistance/tools/ToolRegistry.ts +6 -6
  13. package/front_end/models/elements/DOMChanges.ts +238 -0
  14. package/front_end/models/elements/elements.ts +2 -0
  15. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +3 -1
  16. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +25 -5
  17. package/front_end/panels/browser_debugger/ObjectEventListenersSidebarPane.ts +2 -3
  18. package/front_end/panels/elements/ElementsTreeElement.ts +98 -20
  19. package/front_end/panels/elements/ElementsTreeOutline.ts +271 -43
  20. package/front_end/panels/elements/EventListenersWidget.ts +0 -1
  21. package/front_end/panels/event_listeners/EventListenersView.ts +241 -297
  22. package/front_end/panels/linear_memory_inspector/LinearMemoryInspectorController.ts +1 -1
  23. package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +10 -2
  24. package/front_end/panels/network/NetworkConfigView.ts +141 -116
  25. package/front_end/panels/network/NetworkPanel.ts +7 -4
  26. package/front_end/panels/network/RequestHeadersView.ts +1 -1
  27. package/front_end/panels/network/forward/BackendLinking.ts +5 -2
  28. package/front_end/panels/settings/BackendLinkingSettingsTab.ts +7 -2
  29. package/front_end/panels/timeline/TimelineTreeView.ts +11 -1
  30. package/front_end/third_party/chromium/README.chromium +1 -1
  31. package/front_end/ui/comments/CommentOverlayManager.ts +169 -40
  32. package/front_end/ui/comments/CommentThreadWidget.ts +221 -0
  33. package/front_end/ui/comments/CommentsOverlayWidget.ts +124 -12
  34. package/front_end/ui/comments/commentThreadWidget.css +173 -0
  35. package/front_end/ui/comments/comments.ts +2 -0
  36. package/front_end/ui/comments/commentsOverlay.css +6 -0
  37. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +1 -1
  38. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +4 -0
  39. package/package.json +5 -5
@@ -65,6 +65,19 @@ const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
65
65
  let networkConfigViewInstance: NetworkConfigView;
66
66
 
67
67
  export class NetworkConfigView extends UI.Widget.VBox {
68
+ readonly #cacheDisabledSetting =
69
+ Common.Settings.Settings.instance().resolve(SDK.SDKSettings.cacheDisabledSettingDescriptor);
70
+ readonly #customUserAgentSetting = Common.Settings.Settings.instance().createSetting('custom-user-agent', '');
71
+ readonly #customUserAgentMetadataSetting =
72
+ Common.Settings.Settings.instance().createSetting<Protocol.Emulation.UserAgentMetadata|null>(
73
+ 'custom-user-agent-metadata', null);
74
+
75
+ #autoCheckbox?: UI.UIUtils.CheckboxLabel;
76
+ #customUserAgentSelectBox?: HTMLElement;
77
+ #customSelectAndInput?: {select: HTMLSelectElement, input: HTMLInputElement, error: HTMLElement};
78
+ #clientHints?: EmulationComponents.UserAgentClientHintsForm.UserAgentClientHintsForm;
79
+ #userAgentUpdateButtonStatusText?: HTMLElement;
80
+
68
81
  constructor() {
69
82
  super({
70
83
  jslog: `${VisualLogging.panel('network-conditions').track({resize: true})}`,
@@ -91,18 +104,14 @@ export class NetworkConfigView extends UI.Widget.VBox {
91
104
  return networkConfigViewInstance;
92
105
  }
93
106
 
94
- static createUserAgentSelectAndInput(title: string): {
107
+ private createUserAgentSelectAndInput(title: string): {
95
108
  select: HTMLSelectElement,
96
109
  input: HTMLInputElement,
97
110
  error: HTMLElement,
98
111
  } {
99
- const userAgentSetting = Common.Settings.Settings.instance().createSetting('custom-user-agent', '');
100
- const userAgentMetadataSetting =
101
- Common.Settings.Settings.instance().createSetting<Protocol.Emulation.UserAgentMetadata|null>(
102
- 'custom-user-agent-metadata', null);
103
112
  const userAgentSelectElement = document.createElement('select');
104
113
  userAgentSelectElement.setAttribute(
105
- 'jslog', `${VisualLogging.dropDown().track({change: true}).context(userAgentSetting.name)}`);
114
+ 'jslog', `${VisualLogging.dropDown().track({change: true}).context(this.#customUserAgentSetting.name)}`);
106
115
  UI.ARIAUtils.setLabel(userAgentSelectElement, title);
107
116
 
108
117
  const customOverride = {title: i18nString(UIStrings.custom), value: 'custom'};
@@ -132,9 +141,9 @@ export class NetworkConfigView extends UI.Widget.VBox {
132
141
 
133
142
  const otherUserAgentElement = UI.UIUtils.createInput('', 'text');
134
143
  otherUserAgentElement.setAttribute(
135
- 'jslog', `${VisualLogging.textField().track({change: true}).context(userAgentSetting.name)}`);
136
- otherUserAgentElement.value = userAgentSetting.get();
137
- UI.Tooltip.Tooltip.install(otherUserAgentElement, userAgentSetting.get());
144
+ 'jslog', `${VisualLogging.textField().track({change: true}).context(this.#customUserAgentSetting.name)}`);
145
+ otherUserAgentElement.value = this.#customUserAgentSetting.get();
146
+ UI.Tooltip.Tooltip.install(otherUserAgentElement, this.#customUserAgentSetting.get());
138
147
  otherUserAgentElement.placeholder = i18nString(UIStrings.enterACustomUserAgent);
139
148
  otherUserAgentElement.required = true;
140
149
  UI.ARIAUtils.setLabel(otherUserAgentElement, otherUserAgentElement.placeholder);
@@ -146,57 +155,11 @@ export class NetworkConfigView extends UI.Widget.VBox {
146
155
  errorElement.textContent = i18nString(UIStrings.customUserAgentFieldIsRequired);
147
156
  }
148
157
 
149
- settingChanged();
150
- userAgentSelectElement.addEventListener('change', userAgentSelected, false);
151
- otherUserAgentElement.addEventListener('input', applyOtherUserAgent, false);
152
-
153
- function userAgentSelected(): void {
154
- const value = userAgentSelectElement.options[userAgentSelectElement.selectedIndex].value;
155
- if (value !== customOverride.value) {
156
- userAgentSetting.set(value);
157
- otherUserAgentElement.value = value;
158
- UI.Tooltip.Tooltip.install(otherUserAgentElement, value);
159
- const userAgentMetadata = getUserAgentMetadata(value);
160
- userAgentMetadataSetting.set(userAgentMetadata);
161
- SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(value, userAgentMetadata);
162
- } else {
163
- userAgentMetadataSetting.set(null);
164
- otherUserAgentElement.select();
165
- }
166
- errorElement.textContent = '';
167
- const userAgentChangeEvent = new CustomEvent('user-agent-change', {detail: {value}});
168
- userAgentSelectElement.dispatchEvent(userAgentChangeEvent);
169
- }
170
-
171
- function settingChanged(): void {
172
- const value = userAgentSetting.get();
173
- const options = userAgentSelectElement.options;
174
- let selectionRestored = false;
175
- for (let i = 0; i < options.length; ++i) {
176
- if (options[i].value === value) {
177
- userAgentSelectElement.selectedIndex = i;
178
- selectionRestored = true;
179
- break;
180
- }
181
- }
182
-
183
- if (!selectionRestored) {
184
- userAgentSelectElement.selectedIndex = 0;
185
- }
186
- }
187
-
188
- function applyOtherUserAgent(): void {
189
- if (userAgentSetting.get() !== otherUserAgentElement.value) {
190
- if (!otherUserAgentElement.value) {
191
- errorElement.textContent = i18nString(UIStrings.customUserAgentFieldIsRequired);
192
- } else {
193
- errorElement.textContent = '';
194
- }
195
- userAgentSetting.set(otherUserAgentElement.value);
196
- UI.Tooltip.Tooltip.install(otherUserAgentElement, otherUserAgentElement.value);
197
- settingChanged();
198
- }
199
- }
158
+ this.#settingChanged(userAgentSelectElement);
159
+ userAgentSelectElement.addEventListener('change', () => this.#onUserAgentSelect(userAgentSelectElement.value),
160
+ false);
161
+ otherUserAgentElement.addEventListener('input', () => this.#onCustomUserAgentInput(otherUserAgentElement.value),
162
+ false);
200
163
 
201
164
  return {select: userAgentSelectElement, input: otherUserAgentElement, error: errorElement};
202
165
  }
@@ -212,9 +175,8 @@ export class NetworkConfigView extends UI.Widget.VBox {
212
175
 
213
176
  private createCacheSection(): void {
214
177
  const section = this.createSection(i18nString(UIStrings.caching), 'network-config-disable-cache');
215
- section.appendChild(SettingsUI.SettingsUI.createSettingCheckbox(
216
- i18nString(UIStrings.disableCache),
217
- Common.Settings.Settings.instance().resolve(SDK.SDKSettings.cacheDisabledSettingDescriptor)));
178
+ section.appendChild(
179
+ SettingsUI.SettingsUI.createSettingCheckbox(i18nString(UIStrings.disableCache), this.#cacheDisabledSetting));
218
180
  }
219
181
 
220
182
  private createNetworkThrottlingSection(): void {
@@ -227,82 +189,145 @@ export class NetworkConfigView extends UI.Widget.VBox {
227
189
  }
228
190
 
229
191
  private createUserAgentSection(): void {
230
- const userAgentMetadataSetting =
231
- Common.Settings.Settings.instance().createSetting<Protocol.Emulation.UserAgentMetadata|null>(
232
- 'custom-user-agent-metadata', null);
233
- const customUserAgentSetting = Common.Settings.Settings.instance().createSetting('custom-user-agent', '');
234
-
235
192
  const title = i18nString(UIStrings.userAgent);
236
193
  const section = this.createSection(title, 'network-config-ua');
237
- const autoCheckbox = UI.UIUtils.CheckboxLabel.create(
238
- i18nString(UIStrings.selectAutomatically), true, undefined, customUserAgentSetting.name);
239
- section.appendChild(autoCheckbox);
194
+ this.#autoCheckbox = UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.selectAutomatically), true, undefined,
195
+ this.#customUserAgentSetting.name);
196
+ section.appendChild(this.#autoCheckbox);
240
197
 
241
- customUserAgentSetting.addChangeListener(() => {
242
- if (autoCheckbox.checked) {
198
+ this.#customUserAgentSetting.addChangeListener(() => {
199
+ if (this.#autoCheckbox?.checked) {
243
200
  return;
244
201
  }
245
- const customUA = customUserAgentSetting.get();
202
+ const customUA = this.#customUserAgentSetting.get();
246
203
  const userAgentMetadata = getUserAgentMetadata(customUA);
247
204
  SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(customUA, userAgentMetadata);
248
205
  });
249
- const customUserAgentSelectBox = section.createChild('div', 'network-config-ua-custom');
250
- autoCheckbox.addEventListener('change', userAgentSelectBoxChanged);
251
- const customSelectAndInput = NetworkConfigView.createUserAgentSelectAndInput(title);
252
- customUserAgentSelectBox.appendChild(customSelectAndInput.select);
253
- customUserAgentSelectBox.appendChild(customSelectAndInput.input);
254
- customUserAgentSelectBox.appendChild(customSelectAndInput.error);
255
-
256
- const clientHints = new EmulationComponents.UserAgentClientHintsForm.UserAgentClientHintsForm();
257
- const userAgentMetaDataSetting = userAgentMetadataSetting.get();
258
- const initialUserAgentMetaData = getUserAgentMetadata(customSelectAndInput.select.value);
259
- clientHints.value = {
206
+ this.#customUserAgentSelectBox = section.createChild('div', 'network-config-ua-custom');
207
+ this.#autoCheckbox.addEventListener('change',
208
+ () => this.#onAutoCheckboxChange(this.#autoCheckbox?.checked ?? false));
209
+ this.#customSelectAndInput = this.createUserAgentSelectAndInput(title);
210
+ this.#customUserAgentSelectBox.appendChild(this.#customSelectAndInput.select);
211
+ this.#customUserAgentSelectBox.appendChild(this.#customSelectAndInput.input);
212
+ this.#customUserAgentSelectBox.appendChild(this.#customSelectAndInput.error);
213
+
214
+ this.#clientHints = new EmulationComponents.UserAgentClientHintsForm.UserAgentClientHintsForm();
215
+ const userAgentMetaDataSetting = this.#customUserAgentMetadataSetting.get();
216
+ const initialUserAgentMetaData = getUserAgentMetadata(this.#customSelectAndInput.select.value);
217
+ this.#clientHints.value = {
260
218
  showMobileCheckbox: true,
261
219
  showSubmitButton: true,
262
220
  metaData: userAgentMetaDataSetting || initialUserAgentMetaData || undefined,
263
221
  };
264
- customUserAgentSelectBox.appendChild(clientHints);
222
+ this.#customUserAgentSelectBox.appendChild(this.#clientHints);
223
+
224
+ this.#clientHints.addEventListener('clienthintschange', () => this.#onClientHintsChange());
225
+ this.#clientHints.addEventListener('clienthintssubmit',
226
+ event => this.#onClientHintsSubmit((event as CustomEvent).detail.value as
227
+ Protocol.Emulation.UserAgentMetadata));
228
+
229
+ this.#userAgentUpdateButtonStatusText = section.createChild('span', 'status-text');
230
+ this.#userAgentUpdateButtonStatusText.textContent = '';
231
+
232
+ this.#onAutoCheckboxChange(this.#autoCheckbox.checked);
233
+ }
234
+
235
+ #onAutoCheckboxChange(checked: boolean): void {
236
+ const useCustomUA = !checked;
237
+ if (this.#customUserAgentSelectBox && this.#customSelectAndInput && this.#clientHints) {
238
+ this.#customUserAgentSelectBox.classList.toggle('checked', useCustomUA);
239
+ this.#customSelectAndInput.select.disabled = !useCustomUA;
240
+ this.#customSelectAndInput.input.disabled = !useCustomUA;
241
+ this.#customSelectAndInput.error.hidden = !useCustomUA;
242
+ this.#clientHints.disabled = !useCustomUA;
243
+ }
244
+ const customUA = useCustomUA ? this.#customUserAgentSetting.get() : '';
245
+ const userAgentMetadata = useCustomUA ? getUserAgentMetadata(customUA) : null;
246
+ SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(customUA, userAgentMetadata);
247
+ }
265
248
 
266
- customSelectAndInput.select.addEventListener('user-agent-change', (event: Event) => {
267
- const userStringValue = (event as CustomEvent).detail.value;
268
- const userAgentMetadata = userStringValue ? getUserAgentMetadata(userStringValue) : null;
269
- clientHints.value = {
249
+ #onUserAgentSelect(value: string): void {
250
+ if (!this.#customSelectAndInput || !this.#clientHints || !this.#userAgentUpdateButtonStatusText) {
251
+ return;
252
+ }
253
+ const customOverride = 'custom';
254
+ if (value !== customOverride) {
255
+ this.#customUserAgentSetting.set(value);
256
+ this.#customSelectAndInput.input.value = value;
257
+ UI.Tooltip.Tooltip.install(this.#customSelectAndInput.input, value);
258
+ const userAgentMetadata = getUserAgentMetadata(value);
259
+ this.#customUserAgentMetadataSetting.set(userAgentMetadata);
260
+ SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(value, userAgentMetadata);
261
+ this.#clientHints.value = {
270
262
  metaData: userAgentMetadata || undefined,
271
263
  showMobileCheckbox: true,
272
264
  showSubmitButton: true,
273
265
  };
274
- userAgentUpdateButtonStatusText.textContent = '';
275
- });
266
+ } else {
267
+ this.#customUserAgentMetadataSetting.set(null);
268
+ this.#clientHints.value = {
269
+ showMobileCheckbox: true,
270
+ showSubmitButton: true,
271
+ };
272
+ this.#customSelectAndInput.input.select();
273
+ }
274
+ this.#customSelectAndInput.error.textContent = '';
275
+ this.#userAgentUpdateButtonStatusText.textContent = '';
276
+ }
276
277
 
277
- clientHints.addEventListener('clienthintschange', () => {
278
- customSelectAndInput.select.value = 'custom';
279
- userAgentUpdateButtonStatusText.textContent = '';
280
- });
278
+ #onCustomUserAgentInput(value: string): void {
279
+ if (!this.#customSelectAndInput) {
280
+ return;
281
+ }
282
+ if (this.#customUserAgentSetting.get() !== value) {
283
+ if (!value) {
284
+ this.#customSelectAndInput.error.textContent = i18nString(UIStrings.customUserAgentFieldIsRequired);
285
+ } else {
286
+ this.#customSelectAndInput.error.textContent = '';
287
+ }
288
+ this.#customUserAgentSetting.set(value);
289
+ UI.Tooltip.Tooltip.install(this.#customSelectAndInput.input, value);
290
+ this.#settingChanged(this.#customSelectAndInput.select);
291
+ }
292
+ }
281
293
 
282
- clientHints.addEventListener('clienthintssubmit', event => {
283
- const metaData: Protocol.Emulation.UserAgentMetadata = (event as CustomEvent).detail.value;
284
- const customUA = customUserAgentSetting.get();
285
- userAgentMetadataSetting.set(metaData);
286
- SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(customUA, metaData);
287
- userAgentUpdateButtonStatusText.textContent = i18nString(UIStrings.clientHintsStatusText);
288
- });
294
+ #settingChanged(selectElement?: HTMLSelectElement): void {
295
+ const select = selectElement ?? this.#customSelectAndInput?.select;
296
+ if (!select) {
297
+ return;
298
+ }
299
+ const value = this.#customUserAgentSetting.get();
300
+ const options = select.options;
301
+ let selectionRestored = false;
302
+ for (let i = 0; i < options.length; ++i) {
303
+ if (options[i].value === value) {
304
+ select.selectedIndex = i;
305
+ selectionRestored = true;
306
+ break;
307
+ }
308
+ }
289
309
 
290
- const userAgentUpdateButtonStatusText = section.createChild('span', 'status-text');
291
- userAgentUpdateButtonStatusText.textContent = '';
310
+ if (!selectionRestored) {
311
+ select.selectedIndex = 0;
312
+ }
313
+ }
292
314
 
293
- userAgentSelectBoxChanged();
315
+ #onClientHintsChange(): void {
316
+ if (!this.#customSelectAndInput || !this.#userAgentUpdateButtonStatusText) {
317
+ return;
318
+ }
319
+ this.#customSelectAndInput.select.value = 'custom';
320
+ this.#userAgentUpdateButtonStatusText.textContent = '';
321
+ }
294
322
 
295
- function userAgentSelectBoxChanged(): void {
296
- const useCustomUA = !autoCheckbox.checked;
297
- customUserAgentSelectBox.classList.toggle('checked', useCustomUA);
298
- customSelectAndInput.select.disabled = !useCustomUA;
299
- customSelectAndInput.input.disabled = !useCustomUA;
300
- customSelectAndInput.error.hidden = !useCustomUA;
301
- clientHints.disabled = !useCustomUA;
302
- const customUA = useCustomUA ? customUserAgentSetting.get() : '';
303
- const userAgentMetadata = useCustomUA ? getUserAgentMetadata(customUA) : null;
304
- SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(customUA, userAgentMetadata);
323
+ #onClientHintsSubmit(metaData: Protocol.Emulation.UserAgentMetadata): void {
324
+ if (!this.#userAgentUpdateButtonStatusText) {
325
+ return;
305
326
  }
327
+ const customUA = this.#customUserAgentSetting.get();
328
+ this.#customUserAgentMetadataSetting.set(metaData);
329
+ SDK.NetworkManager.MultitargetNetworkManager.instance().setCustomUserAgentOverride(customUA, metaData);
330
+ this.#userAgentUpdateButtonStatusText.textContent = i18nString(UIStrings.clientHintsStatusText);
306
331
  }
307
332
 
308
333
  override wasShown(): void {
@@ -266,7 +266,8 @@ export class BackendLinking {
266
266
  }
267
267
  let backendLink = rule.template;
268
268
  for (const placeholder of rule.placeholders) {
269
- backendLink = backendLink.replaceAll(placeholder, placeholderValues[placeholder] as string);
269
+ backendLink =
270
+ backendLink.replaceAll(placeholder, () => encodeURIComponent(placeholderValues[placeholder] as string));
270
271
  }
271
272
  try {
272
273
  return {label: rule.label, url: new URL(backendLink)};
@@ -311,14 +312,16 @@ export class NetworkPanel extends UI.Panel.Panel implements
311
312
  recordLogSetting: Common.Settings.Setting<boolean>;
312
313
  private readonly throttlingSelect: UI.Toolbar.ToolbarItem;
313
314
  private readonly displayScreenshotDelay: number;
314
- readonly backendLinkingRulesSetting: Common.Settings.Setting<BackendLinkingRule[]> =
315
- Common.Settings.Settings.instance().resolve(backendLinkingRulesSettingDescriptor);
316
- readonly backendLinking: BackendLinking = new BackendLinking(this.backendLinkingRulesSetting);
315
+ readonly backendLinking: BackendLinking|null;
317
316
 
318
317
  constructor(displayScreenshotDelay: number) {
319
318
  super('network');
320
319
  this.registerRequiredCSS(networkPanelStyles);
321
320
 
321
+ const backendLinkingSetting =
322
+ Common.Settings.Settings.instance().maybeResolve(backendLinkingRulesSettingDescriptor);
323
+ this.backendLinking = 'setting' in backendLinkingSetting ? new BackendLinking(backendLinkingSetting.setting) : null;
324
+
322
325
  this.displayScreenshotDelay = displayScreenshotDelay;
323
326
  this.networkLogShowOverviewSetting =
324
327
  Common.Settings.Settings.instance().createSetting('network-log-show-overview', true);
@@ -391,7 +391,7 @@ export class RequestHeadersView extends UI.Widget.Widget {
391
391
  showResponseHeadersText: this.#showResponseHeadersText,
392
392
  showRequestHeadersText: this.#showRequestHeadersText,
393
393
  backendLink: Root.Runtime.hostConfig.devToolsNetworkBackendLinking?.enabled ?
394
- NetworkPanel.instance().backendLinking.getLink(this.#request) :
394
+ NetworkPanel.instance().backendLinking?.getLink(this.#request) ?? null :
395
395
  null,
396
396
  };
397
397
 
@@ -41,9 +41,12 @@ export const BACKEND_LINKING_PLACEHOLDERS = [
41
41
 
42
42
  export type BackendLinkingPlaceholder = typeof BACKEND_LINKING_PLACEHOLDERS[number];
43
43
 
44
- export const backendLinkingRulesSettingDescriptor: Common.Settings.SettingDescriptor<BackendLinkingRule[]> = {
44
+ export const backendLinkingRulesSettingDescriptor:
45
+ Common.Settings.ConditionalSettingDescriptor<BackendLinkingRule[], void> = {
45
46
  name: 'network.backend-linking-rules',
46
47
  type: Common.Settings.SettingType.ARRAY,
47
48
  defaultValue: [],
48
- storageType: Common.Settings.SettingStorageType.SYNCED,
49
+ isAvailable: config => config.devToolsNetworkBackendLinking?.enabled ?
50
+ {status: Common.Settings.SettingAvailability.AVAILABLE} :
51
+ {status: Common.Settings.SettingAvailability.UNAVAILABLE, reason: undefined},
49
52
  };
@@ -250,12 +250,17 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
250
250
 
251
251
  export class BackendLinkingSettingsTab extends UI.Widget.VBox {
252
252
  readonly #view: View;
253
- readonly #rulesSetting: Common.Settings.Setting<NetworkForward.BackendLinking.BackendLinkingRule[]> =
254
- Common.Settings.Settings.instance().resolve(NetworkForward.BackendLinking.backendLinkingRulesSettingDescriptor);
253
+ readonly #rulesSetting: Common.Settings.Setting<NetworkForward.BackendLinking.BackendLinkingRule[]>;
255
254
 
256
255
  constructor(target?: HTMLElement, view: View = DEFAULT_VIEW) {
257
256
  super(target);
258
257
  this.#view = view;
258
+ const res = Common.Settings.Settings.instance().maybeResolve(
259
+ NetworkForward.BackendLinking.backendLinkingRulesSettingDescriptor);
260
+ if (!('setting' in res)) {
261
+ throw new Error('Backend linking setting is not available');
262
+ }
263
+ this.#rulesSetting = res.setting;
259
264
  }
260
265
 
261
266
  override wasShown(): void {
@@ -200,6 +200,9 @@ export class TimelineTreeView extends TimelineTreeViewBase implements UI.Searcha
200
200
  #compactMode = false;
201
201
  #maxLinkLength: number|undefined = undefined;
202
202
  #maxRows: number|undefined = undefined;
203
+ // Tracks whether a tree refresh was deferred while detached from the DOM,
204
+ // so it can be performed when the widget becomes visible again.
205
+ #dirty = false;
203
206
 
204
207
  /**
205
208
  * Determines if the first child in the data grid will be selected
@@ -392,7 +395,11 @@ export class TimelineTreeView extends TimelineTreeViewBase implements UI.Searcha
392
395
 
393
396
  override wasShown(): void {
394
397
  super.wasShown();
395
- this.refreshTree();
398
+ // Only refresh if data or configuration changed while detached,
399
+ // avoiding rebuilding the DataGrid which resets expanded nodes and selection.
400
+ if (this.#dirty) {
401
+ this.refreshTree();
402
+ }
396
403
  this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, this.#onDataGridSelectionChange, this);
397
404
  this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.#onDataGridDeselection, this);
398
405
  }
@@ -510,8 +517,11 @@ export class TimelineTreeView extends TimelineTreeViewBase implements UI.Searcha
510
517
  // dropdown changes value. Thus, we bail out whenever the view is
511
518
  // not visible, which we know if the related element is detached
512
519
  // from the document.
520
+ // Mark dirty so that the refresh is deferred until shown.
521
+ this.#dirty = true;
513
522
  return;
514
523
  }
524
+ this.#dirty = false;
515
525
  this.linkifier.reset();
516
526
  this.dataGrid.rootNode().removeChildren();
517
527
  if (!this.#parsedTrace) {
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: Internal
3
3
  Version: N/A
4
- Revision: 199ac2cd7ab289e11c2236bd2cede848781213da
4
+ Revision: c6c44ec6a59862a1b0027bc453fcacb9dce75c9e
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE