chrome-devtools-frontend 1.0.1672557 → 1.0.1674545

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 (141) hide show
  1. package/front_end/core/common/SettingRegistration.ts +1 -26
  2. package/front_end/core/common/Settings.ts +4 -53
  3. package/front_end/core/host/UserMetrics.ts +127 -117
  4. package/front_end/core/protocol_client/PuppeteerDevToolsConnection.ts +42 -9
  5. package/front_end/core/root/Runtime.ts +10 -0
  6. package/front_end/core/sdk/NetworkManager.ts +0 -35
  7. package/front_end/core/sdk/SourceMap.ts +1 -19
  8. package/front_end/core/sdk/SourceMapManager.ts +75 -48
  9. package/front_end/core/sdk/SourceMapScopesInfo.ts +0 -62
  10. package/front_end/devtools_compatibility.js +1 -1
  11. package/front_end/generated/InspectorBackendCommands.ts +4 -3
  12. package/front_end/generated/SupportedCSSProperties.ts +16 -1
  13. package/front_end/generated/protocol-mapping.d.ts +8 -0
  14. package/front_end/generated/protocol-proxy-api.d.ts +6 -0
  15. package/front_end/generated/protocol.ts +16 -2
  16. package/front_end/models/ai_assistance/AiSetting.ts +66 -3
  17. package/front_end/models/bindings/CompilerScriptMapping.ts +1 -1
  18. package/front_end/models/emulation/DeviceModeModel.ts +25 -34
  19. package/front_end/models/javascript_metadata/NativeFunctions.js +4 -4
  20. package/front_end/models/trace/ModelImpl.ts +5 -0
  21. package/front_end/models/trace/Processor.ts +5 -0
  22. package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +7 -1
  23. package/front_end/models/trace/handlers/MetaHandler.ts +8 -4
  24. package/front_end/models/trace/handlers/PageLoadMetricsHandler.ts +11 -0
  25. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +11 -10
  26. package/front_end/panels/ai_assistance/ai_assistance-meta.ts +3 -45
  27. package/front_end/panels/application/BackgroundServiceView.ts +42 -40
  28. package/front_end/panels/application/KeyValueStorageItemsView.ts +1 -0
  29. package/front_end/panels/common/ExtensionServer.ts +7 -1
  30. package/front_end/panels/common/common.ts +0 -1
  31. package/front_end/panels/console/ConsoleInsightTeaser.ts +7 -6
  32. package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
  33. package/front_end/panels/elements/ClassesPaneWidget.ts +2 -2
  34. package/front_end/panels/elements/ElementsTreeElement.ts +56 -4
  35. package/front_end/panels/elements/StylesSidebarPane.ts +1 -1
  36. package/front_end/panels/elements/components/AdornerManager.ts +1 -0
  37. package/front_end/panels/emulation/AdvancedApp.ts +3 -3
  38. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -11
  39. package/front_end/panels/emulation/DeviceModeView.ts +234 -75
  40. package/front_end/panels/emulation/InspectedPagePlaceholder.ts +1 -1
  41. package/front_end/panels/emulation/deviceModeView.css +4 -21
  42. package/front_end/panels/emulation/emulation-meta.ts +4 -30
  43. package/front_end/panels/emulation/emulation.ts +0 -3
  44. package/front_end/panels/explain/components/ConsoleInsight.ts +11 -7
  45. package/front_end/panels/layers/LayersPanel.ts +2 -2
  46. package/front_end/panels/layers/layers-meta.ts +2 -2
  47. package/front_end/panels/lighthouse/LighthouseController.ts +3 -7
  48. package/front_end/panels/mobile_throttling/CPUThrottlingSelector.ts +313 -0
  49. package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +0 -10
  50. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +21 -10
  51. package/front_end/panels/mobile_throttling/mobile_throttling.ts +3 -0
  52. package/front_end/panels/network/NetworkConfigView.ts +1 -71
  53. package/front_end/panels/network/networkConfigView.css +1 -2
  54. package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +3 -3
  55. package/front_end/panels/profiler/HeapDetachedElementsView.ts +5 -5
  56. package/front_end/panels/profiler/HeapProfileView.ts +32 -32
  57. package/front_end/panels/profiler/HeapProfilerPanel.ts +2 -2
  58. package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +33 -37
  59. package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +26 -27
  60. package/front_end/panels/profiler/HeapSnapshotView.ts +48 -48
  61. package/front_end/panels/profiler/IsolateSelector.ts +10 -10
  62. package/front_end/panels/profiler/ModuleUIStrings.ts +25 -25
  63. package/front_end/panels/profiler/ProfileLauncherView.ts +6 -6
  64. package/front_end/panels/profiler/ProfilesPanel.ts +6 -6
  65. package/front_end/panels/profiler/WritableProfileHeader.ts +6 -6
  66. package/front_end/panels/profiler/profiler-meta.ts +7 -7
  67. package/front_end/panels/recorder/RecorderPanel.ts +1 -1
  68. package/front_end/panels/settings/AISettingsTab.ts +27 -23
  69. package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +12 -17
  70. package/front_end/panels/timeline/TimelinePanel.ts +20 -35
  71. package/front_end/panels/timeline/components/LiveMetricsView.ts +27 -6
  72. package/front_end/panels/timeline/components/NetworkTrackWidget.ts +1 -1
  73. package/front_end/panels/timeline/components/components.ts +0 -4
  74. package/front_end/panels/timeline/components/liveMetricsView.css +7 -0
  75. package/front_end/third_party/chromium/README.chromium +1 -1
  76. package/front_end/third_party/source-map-scopes-codec/package/CONTRIBUTING.md +0 -0
  77. package/front_end/third_party/source-map-scopes-codec/package/LICENSE +0 -0
  78. package/front_end/third_party/source-map-scopes-codec/package/README.md +0 -0
  79. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts +0 -0
  80. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/builder.d.ts.map +1 -1
  81. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts +0 -0
  82. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/builder/safe_builder.d.ts.map +0 -0
  83. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts +0 -0
  84. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/decode/decode.d.ts.map +0 -0
  85. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts +0 -0
  86. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/encode/encode.d.ts.map +0 -0
  87. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts +0 -0
  88. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/mod.d.ts.map +0 -0
  89. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts +0 -0
  90. package/front_end/third_party/source-map-scopes-codec/package/_dist/src/scopes.d.ts.map +0 -0
  91. package/front_end/third_party/source-map-scopes-codec/package/deno.json +1 -1
  92. package/front_end/third_party/source-map-scopes-codec/package/package.json +1 -1
  93. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js +2 -0
  94. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.js.map +1 -1
  95. package/front_end/third_party/source-map-scopes-codec/package/src/builder/builder.ts +2 -0
  96. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js +0 -0
  97. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.js.map +0 -0
  98. package/front_end/third_party/source-map-scopes-codec/package/src/builder/safe_builder.ts +0 -0
  99. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js +0 -0
  100. package/front_end/third_party/source-map-scopes-codec/package/src/codec.js.map +0 -0
  101. package/front_end/third_party/source-map-scopes-codec/package/src/codec.ts +0 -0
  102. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js +0 -0
  103. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.js.map +0 -0
  104. package/front_end/third_party/source-map-scopes-codec/package/src/decode/decode.ts +0 -0
  105. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js +0 -0
  106. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.js.map +0 -0
  107. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encode.ts +0 -0
  108. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js +0 -0
  109. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.js.map +0 -0
  110. package/front_end/third_party/source-map-scopes-codec/package/src/encode/encoder.ts +0 -0
  111. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js +0 -0
  112. package/front_end/third_party/source-map-scopes-codec/package/src/mod.js.map +0 -0
  113. package/front_end/third_party/source-map-scopes-codec/package/src/mod.ts +0 -0
  114. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js +0 -0
  115. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.js.map +0 -0
  116. package/front_end/third_party/source-map-scopes-codec/package/src/scopes.ts +0 -0
  117. package/front_end/third_party/source-map-scopes-codec/package/src/util.js +0 -0
  118. package/front_end/third_party/source-map-scopes-codec/package/src/util.js.map +0 -0
  119. package/front_end/third_party/source-map-scopes-codec/package/src/util.ts +0 -0
  120. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js +0 -0
  121. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.js.map +0 -0
  122. package/front_end/third_party/source-map-scopes-codec/package/src/vlq.ts +0 -0
  123. package/front_end/ui/components/dialogs/ShortcutDialog.ts +2 -0
  124. package/front_end/ui/components/settings/SettingCheckbox.ts +4 -12
  125. package/front_end/ui/components/settings/settingCheckbox.css +0 -7
  126. package/front_end/ui/legacy/Treeoutline.ts +14 -14
  127. package/front_end/ui/legacy/UIUtils.ts +2 -47
  128. package/front_end/ui/legacy/Widget.ts +10 -2
  129. package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +1 -1
  130. package/front_end/ui/lit/Directives.ts +80 -0
  131. package/front_end/ui/lit/lit.ts +1 -0
  132. package/front_end/ui/lit/render.ts +8 -0
  133. package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
  134. package/mcp/mcp.ts +1 -0
  135. package/package.json +1 -1
  136. package/front_end/panels/common/ThrottlingUtils.ts +0 -51
  137. package/front_end/panels/emulation/DeviceModeWrapper.ts +0 -248
  138. package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +0 -235
  139. package/front_end/panels/timeline/components/NetworkThrottlingSelector.ts +0 -245
  140. package/front_end/panels/timeline/components/cpuThrottlingSelector.css +0 -30
  141. package/front_end/panels/timeline/components/networkThrottlingSelector.css +0 -24
@@ -33,6 +33,7 @@ export class AiSetting<ValueT> extends Common.ObjectWrapper.ObjectWrapper<EventT
33
33
  readonly #settings: Common.Settings.Settings;
34
34
  readonly #boundOnSettingChanged = this.#onSettingChanged.bind(this);
35
35
  readonly #boundOnAidaAvailabilityChanged = this.#onAidaAvailabilityChanged.bind(this);
36
+ #isSubscribed = false;
36
37
 
37
38
  constructor(
38
39
  descriptor: Common.Settings.ConditionalSettingDescriptor<ValueT, DisabledReason[]>,
@@ -44,11 +45,56 @@ export class AiSetting<ValueT> extends Common.ObjectWrapper.ObjectWrapper<EventT
44
45
  this.#hostConfigTracker = hostConfigTracker;
45
46
  this.#settings = settings;
46
47
 
48
+ this.#tryResolveSetting();
49
+ }
50
+
51
+ override addEventListener<T extends keyof EventTypes>(
52
+ eventType: T,
53
+ listener: Common.EventTarget.EventListener<EventTypes, T>,
54
+ thisObject?: Object,
55
+ ): Common.EventTarget.EventDescriptor<EventTypes, T> {
56
+ const isFirst = !this.hasEventListeners(eventType);
57
+ const descriptor = super.addEventListener(eventType, listener, thisObject);
58
+ if (isFirst) {
59
+ this.#subscribe();
60
+ }
61
+ return descriptor;
62
+ }
63
+
64
+ override removeEventListener<T extends keyof EventTypes>(
65
+ eventType: T,
66
+ listener: Common.EventTarget.EventListener<EventTypes, T>,
67
+ thisObject?: Object,
68
+ ): void {
69
+ super.removeEventListener(eventType, listener, thisObject);
70
+ if (!this.hasEventListeners(eventType)) {
71
+ this.#unsubscribe();
72
+ }
73
+ }
74
+
75
+ #subscribe(): void {
76
+ if (this.#isSubscribed) {
77
+ return;
78
+ }
79
+ this.#tryResolveSetting();
80
+ this.#isSubscribed = true;
47
81
  this.#hostConfigTracker.addEventListener(
48
82
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED,
49
83
  this.#boundOnAidaAvailabilityChanged,
50
84
  );
51
- this.#tryResolveSetting();
85
+ this.#setting?.addChangeListener(this.#boundOnSettingChanged);
86
+ }
87
+
88
+ #unsubscribe(): void {
89
+ if (!this.#isSubscribed) {
90
+ return;
91
+ }
92
+ this.#isSubscribed = false;
93
+ this.#hostConfigTracker.removeEventListener(
94
+ Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED,
95
+ this.#boundOnAidaAvailabilityChanged,
96
+ );
97
+ this.#setting?.removeChangeListener(this.#boundOnSettingChanged);
52
98
  }
53
99
 
54
100
  #tryResolveSetting(): void {
@@ -56,12 +102,19 @@ export class AiSetting<ValueT> extends Common.ObjectWrapper.ObjectWrapper<EventT
56
102
  Common.Settings.ConditionalSettingDescriptor<unknown, DisabledReason[]>);
57
103
  if ('setting' in result) {
58
104
  if (this.#setting !== result.setting) {
59
- if (this.#setting) {
105
+ if (this.#setting && this.#isSubscribed) {
60
106
  this.#setting.removeChangeListener(this.#boundOnSettingChanged);
61
107
  }
62
108
  this.#setting = result.setting as Common.Settings.Setting<ValueT>;
63
- this.#setting.addChangeListener(this.#boundOnSettingChanged);
109
+ if (this.#isSubscribed) {
110
+ this.#setting.addChangeListener(this.#boundOnSettingChanged);
111
+ }
64
112
  }
113
+ } else if (this.#setting) {
114
+ if (this.#isSubscribed) {
115
+ this.#setting.removeChangeListener(this.#boundOnSettingChanged);
116
+ }
117
+ this.#setting = undefined;
65
118
  }
66
119
  }
67
120
 
@@ -87,6 +140,7 @@ export class AiSetting<ValueT> extends Common.ObjectWrapper.ObjectWrapper<EventT
87
140
  if (this.disabled || this.unavailable) {
88
141
  return undefined;
89
142
  }
143
+ this.#tryResolveSetting();
90
144
  return this.#setting?.get();
91
145
  }
92
146
 
@@ -94,9 +148,18 @@ export class AiSetting<ValueT> extends Common.ObjectWrapper.ObjectWrapper<EventT
94
148
  if (this.disabled || this.unavailable) {
95
149
  return;
96
150
  }
151
+ this.#tryResolveSetting();
97
152
  this.#setting?.set(value);
98
153
  }
99
154
 
155
+ get(): ValueT|undefined {
156
+ return this.getIfNotDisabled();
157
+ }
158
+
159
+ set(value: ValueT): void {
160
+ this.setIfNotDisabled(value);
161
+ }
162
+
100
163
  #onSettingChanged(): void {
101
164
  this.dispatchEventToListeners(Events.CHANGED);
102
165
  }
@@ -193,7 +193,7 @@ export class CompilerScriptMapping implements DebuggerSourceMapping {
193
193
  return null;
194
194
  }
195
195
 
196
- const entry = sourceMap.findEntry(lineNumber, columnNumber, rawLocation.inlineFrameIndex);
196
+ const entry = sourceMap.findEntry(lineNumber, columnNumber);
197
197
  if (!entry?.sourceURL) {
198
198
  return null;
199
199
  }
@@ -104,6 +104,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
104
104
  #availableSize: Geometry.Size;
105
105
  #preferredSize: Geometry.Size;
106
106
  #initialized: boolean;
107
+ #autoFitScaleOnInitialize: boolean;
107
108
  #appliedDeviceSize: Geometry.Size;
108
109
  #appliedDeviceScaleFactor: number;
109
110
  #appliedUserAgentType: UA;
@@ -113,7 +114,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
113
114
  #heightSetting: Common.Settings.Setting<number>;
114
115
  #uaSetting: Common.Settings.Setting<UA>;
115
116
  readonly #deviceScaleFactorSetting: Common.Settings.Setting<number>;
116
- readonly #deviceOutlineSetting: Common.Settings.Setting<boolean>;
117
+
117
118
  readonly #toolbarControlsEnabledSetting: Common.Settings.Setting<boolean>;
118
119
  #type: Type;
119
120
  #device: EmulatedDevice|null;
@@ -143,6 +144,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
143
144
  this.#availableSize = new Geometry.Size(1, 1);
144
145
  this.#preferredSize = new Geometry.Size(1, 1);
145
146
  this.#initialized = false;
147
+ this.#autoFitScaleOnInitialize = false;
146
148
  this.#appliedDeviceSize = new Geometry.Size(1, 1);
147
149
  this.#appliedDeviceScaleFactor = globalThis.devicePixelRatio;
148
150
  this.#appliedUserAgentType = UA.DESKTOP;
@@ -178,9 +180,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
178
180
  this.#deviceScaleFactorSetting = this.#settings.createSetting('emulation.device-scale-factor', 0);
179
181
  this.#deviceScaleFactorSetting.addChangeListener(this.deviceScaleFactorSettingChanged, this);
180
182
 
181
- this.#deviceOutlineSetting = this.#settings.moduleSetting('emulation.show-device-outline');
182
- this.#deviceOutlineSetting.addChangeListener(this.deviceOutlineSettingChanged, this);
183
-
184
183
  this.#toolbarControlsEnabledSetting = this.#settings.createSetting('emulation.toolbar-controls-enabled', true,
185
184
  Common.Settings.SettingStorageType.SESSION);
186
185
 
@@ -311,10 +310,22 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
311
310
  return this.#scaleSetting;
312
311
  }
313
312
 
313
+ #updateFitScale(): void {
314
+ if (this.#type === Type.Device && this.#device && this.#mode) {
315
+ const orientation = this.#device.orientationByName(this.#mode.orientation);
316
+ this.#scaleSetting.set(
317
+ this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
318
+ }
319
+ }
320
+
314
321
  setAvailableSize(availableSize: Geometry.Size, preferredSize: Geometry.Size): void {
315
322
  this.#availableSize = availableSize;
316
323
  this.#preferredSize = preferredSize;
317
324
  this.#initialized = true;
325
+ if (this.#autoFitScaleOnInitialize) {
326
+ this.#autoFitScaleOnInitialize = false;
327
+ this.#updateFitScale();
328
+ }
318
329
  this.calculateAndEmulate(false);
319
330
  }
320
331
 
@@ -326,15 +337,19 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
326
337
  console.assert(Boolean(device) && Boolean(mode), 'Must pass device and mode for device emulation');
327
338
  this.#mode = mode;
328
339
  this.#device = device;
329
- if (this.#initialized) {
330
- const orientation = device.orientationByName(mode.orientation);
331
- this.#scaleSetting.set(
332
- scale ||
333
- this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
340
+ if (scale !== undefined) {
341
+ this.#autoFitScaleOnInitialize = false;
342
+ this.#scaleSetting.set(scale);
343
+ } else if (this.#initialized) {
344
+ this.#autoFitScaleOnInitialize = false;
345
+ this.#updateFitScale();
346
+ } else {
347
+ this.#autoFitScaleOnInitialize = true;
334
348
  }
335
349
  } else {
336
350
  this.#device = null;
337
351
  this.#mode = null;
352
+ this.#autoFitScaleOnInitialize = false;
338
353
  }
339
354
 
340
355
  if (type !== Type.None) {
@@ -390,11 +405,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
390
405
  return (this.#device && this.#mode) ? this.#device.modeImage(this.#mode) : '';
391
406
  }
392
407
 
393
- outlineImage(): string {
394
- return (this.#device && this.#mode && this.#deviceOutlineSetting.get()) ? this.#device.outlineImage(this.#mode) :
395
- '';
396
- }
397
-
398
408
  canShowDeviceFrame(): boolean {
399
409
  return Boolean(this.#device && this.#mode && this.#device.outlineImage(this.#mode));
400
410
  }
@@ -471,10 +481,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
471
481
  return this.#deviceScaleFactorSetting;
472
482
  }
473
483
 
474
- deviceOutlineSetting(): Common.Settings.Setting<boolean> {
475
- return this.#deviceOutlineSetting;
476
- }
477
-
478
484
  toolbarControlsEnabledSetting(): Common.Settings.Setting<boolean> {
479
485
  return this.#toolbarControlsEnabledSetting;
480
486
  }
@@ -590,10 +596,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
590
596
  this.calculateAndEmulate(false);
591
597
  }
592
598
 
593
- private deviceOutlineSettingChanged(): void {
594
- this.calculateAndEmulate(false);
595
- }
596
-
597
599
  private preferredScaledWidth(): number {
598
600
  return Math.floor(this.#preferredSize.width / (this.#scaleSetting.get() || 1));
599
601
  }
@@ -603,15 +605,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
603
605
  }
604
606
 
605
607
  private currentOutline(): Insets {
606
- let outline: Insets = new Insets(0, 0, 0, 0);
607
- if (this.#type !== Type.Device || !this.#device || !this.#mode) {
608
- return outline;
609
- }
610
- const orientation = this.#device.orientationByName(this.#mode.orientation);
611
- if (this.#deviceOutlineSetting.get()) {
612
- outline = orientation.outlineInsets || outline;
613
- }
614
- return outline;
608
+ return new Insets(0, 0, 0, 0);
615
609
  }
616
610
 
617
611
  private currentInsets(): Insets {
@@ -924,9 +918,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
924
918
  }
925
919
  ctx.imageSmoothingEnabled = false;
926
920
 
927
- if (this.outlineImage()) {
928
- await this.paintImage(ctx, this.outlineImage(), outlineRect.relativeTo(outlineRect));
929
- }
930
921
  if (this.screenImage()) {
931
922
  await this.paintImage(ctx, this.screenImage(), screenRect.relativeTo(outlineRect));
932
923
  }
@@ -7810,6 +7810,10 @@ export const NativeFunctions = [
7810
7810
  name: "MediaStreamTrackEvent",
7811
7811
  signatures: [["type","eventInitDict"]]
7812
7812
  },
7813
+ {
7814
+ name: "setConstraints",
7815
+ signatures: [["?constraints"]]
7816
+ },
7813
7817
  {
7814
7818
  name: "webkitGetUserMedia",
7815
7819
  signatures: [["constraints","successCallback","errorCallback"]]
@@ -7818,10 +7822,6 @@ export const NativeFunctions = [
7818
7822
  name: "OverconstrainedError",
7819
7823
  signatures: [["constraint","?message"]]
7820
7824
  },
7821
- {
7822
- name: "setConstraints",
7823
- signatures: [["?constraints"]]
7824
- },
7825
7825
  {
7826
7826
  name: "appendEncodedChunks",
7827
7827
  signatures: [["chunks"]]
@@ -51,6 +51,11 @@ export class Model extends EventTarget {
51
51
  this.#processor = new TraceProcessor(handlers, this.#config);
52
52
  }
53
53
 
54
+ updateConfiguration(config: Types.Configuration.Configuration): void {
55
+ this.#config = config;
56
+ this.#processor.updateConfiguration(config);
57
+ }
58
+
54
59
  /**
55
60
  * Parses an array of trace events into a structured object containing all the
56
61
  * information parsed by the trace handlers.
@@ -94,6 +94,11 @@ export class TraceProcessor extends EventTarget {
94
94
  }
95
95
  }
96
96
 
97
+ updateConfiguration(config: Types.Configuration.Configuration): void {
98
+ this.#modelConfiguration = config;
99
+ this.#passConfigToHandlers();
100
+ }
101
+
97
102
  /**
98
103
  * When the user passes in a set of handlers, we want to ensure that we have all
99
104
  * the required handlers. Handlers can depend on other handlers, so if the user
@@ -141,6 +141,11 @@ export function reset(): void {
141
141
  clsWindowID = -1;
142
142
  }
143
143
 
144
+ let enableSoftNavigation = true;
145
+ export function handleUserConfig(userConfig: Types.Configuration.Configuration): void {
146
+ enableSoftNavigation = userConfig.enableSoftNavigation;
147
+ }
148
+
144
149
  export function handleEvent(event: Types.Events.Event): void {
145
150
  if (Types.Events.isLayoutShift(event) && !event.args.data?.had_recent_input) {
146
151
  layoutShiftEvents.push(event);
@@ -290,8 +295,9 @@ export async function finalize(): Promise<void> {
290
295
 
291
296
  async function buildLayoutShiftsClusters(): Promise<void> {
292
297
  const {navigationsByFrameId, mainFrameId, traceBounds, softNavigationsById} = metaHandlerData();
298
+ const softNavigations = enableSoftNavigation ? Array.from(softNavigationsById.values()) : [];
293
299
  const navigations: Types.Events.Event[] =
294
- [...(navigationsByFrameId.get(mainFrameId) || []), ...softNavigationsById.values()].sort((a, b) => a.ts - b.ts);
300
+ [...(navigationsByFrameId.get(mainFrameId) || []), ...softNavigations].sort((a, b) => a.ts - b.ts);
295
301
  if (layoutShiftEvents.length === 0) {
296
302
  return;
297
303
  }
@@ -8,7 +8,11 @@ import * as Types from '../types/types.js';
8
8
 
9
9
  import type {FinalizeOptions} from './types.js';
10
10
 
11
- let config: {showAllEvents: boolean};
11
+ let config: Types.Configuration.Configuration = Types.Configuration.defaults();
12
+
13
+ export function handleUserConfig(userConfig: Types.Configuration.Configuration): void {
14
+ config = userConfig;
15
+ }
12
16
 
13
17
  // We track the renderer processes we see in each frame on the way through the trace.
14
18
  let rendererProcessesByFrameId: FrameProcessData = new Map();
@@ -328,7 +332,7 @@ export function handleEvent(event: Types.Events.Event): void {
328
332
  return;
329
333
  }
330
334
 
331
- if (Types.Events.isSoftNavigationStart(event)) {
335
+ if (config.enableSoftNavigation && Types.Events.isSoftNavigationStart(event)) {
332
336
  softNavigationsById.set(event.args.context.performanceTimelineNavigationId, event);
333
337
  }
334
338
 
@@ -359,7 +363,7 @@ export function handleEvent(event: Types.Events.Event): void {
359
363
  }
360
364
 
361
365
  export async function finalize(options?: FinalizeOptions): Promise<void> {
362
- config = {showAllEvents: Boolean(options?.showAllEvents)};
366
+ config.showAllEvents = Boolean(options?.showAllEvents);
363
367
 
364
368
  // We try to set the minimum time by finding the event with the smallest
365
369
  // timestamp. However, if we also got a timestamp from the
@@ -476,7 +480,7 @@ export async function finalize(options?: FinalizeOptions): Promise<void> {
476
480
  }
477
481
 
478
482
  export interface MetaHandlerData {
479
- config: {showAllEvents: boolean};
483
+ config: Types.Configuration.Configuration;
480
484
  traceIsGeneric: boolean;
481
485
  traceBounds: Types.Timing.TraceWindowMicro;
482
486
  browserProcessId: Types.Events.ProcessID;
@@ -53,6 +53,11 @@ export function reset(): void {
53
53
  metaCharsetCheckEventsArray = [];
54
54
  }
55
55
 
56
+ let enableSoftNavigation = true;
57
+ export function handleUserConfig(userConfig: Types.Configuration.Configuration): void {
58
+ enableSoftNavigation = userConfig.enableSoftNavigation;
59
+ }
60
+
56
61
  let pageLoadEventsArray: Types.Events.PageLoadEvent[] = [];
57
62
 
58
63
  // Once we've found the LCP events in the trace we want to fetch their DOM Node
@@ -74,6 +79,12 @@ export function handleEvent(event: Types.Events.Event): void {
74
79
  if (!Types.Events.eventIsPageLoadEvent(event)) {
75
80
  return;
76
81
  }
82
+ if (!enableSoftNavigation &&
83
+ (Types.Events.isSoftNavigationStart(event) ||
84
+ event.name === Types.Events.Name.MARK_LCP_CANDIDATE_FOR_SOFT_NAVIGATION ||
85
+ Types.Events.isSoftFirstContentfulPaint(event))) {
86
+ return;
87
+ }
77
88
  pageLoadEventsArray.push(event);
78
89
 
79
90
  // A soft nav entry includes the Soft FCP details but we want to process both
@@ -594,7 +594,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
594
594
  #conversationSummary?: AiAssistanceModel.ConversationSummary.ConversationSummary;
595
595
  #viewOutput: PanelViewOutput = {};
596
596
  #serverSideLoggingEnabled = isAiAssistanceServerSideLoggingEnabled();
597
- #aiAssistanceEnabledSetting: Common.Settings.Setting<boolean>|undefined;
597
+ #aiAssistanceEnabledSetting: AiAssistanceModel.AiSetting.AiSetting<boolean>;
598
598
  #changeManager = new AiAssistanceModel.ChangeManager.ChangeManager();
599
599
  #mutex = new Common.Mutex.Mutex();
600
600
 
@@ -860,13 +860,12 @@ export class AiAssistancePanel extends UI.Panel.Panel {
860
860
  this.requestUpdate();
861
861
  }
862
862
 
863
- #getAiAssistanceEnabledSetting(): Common.Settings.Setting<boolean>|undefined {
864
- try {
865
- return Common.Settings.Settings.instance().moduleSetting('ai-assistance-enabled') as
866
- Common.Settings.Setting<boolean>;
867
- } catch {
868
- return;
869
- }
863
+ #getAiAssistanceEnabledSetting(): AiAssistanceModel.AiSetting.AiSetting<boolean> {
864
+ return new AiAssistanceModel.AiSetting.AiSetting(
865
+ AiAssistanceModel.AiUtils.aiAssistanceEnabledSettingDescriptor,
866
+ Host.AidaClient.HostConfigTracker.instance(),
867
+ Common.Settings.Settings.instance(),
868
+ );
870
869
  }
871
870
 
872
871
  static async instance(opts: {
@@ -1061,7 +1060,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1061
1060
 
1062
1061
  AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().addEventListener(
1063
1062
  AiAssistanceModel.AiHistoryStorage.Events.HISTORY_DELETED, this.#onHistoryDeleted, this);
1064
- this.#aiAssistanceEnabledSetting?.addChangeListener(this.requestUpdate, this);
1063
+ this.#aiAssistanceEnabledSetting.addEventListener(AiAssistanceModel.AiSetting.Events.CHANGED, this.requestUpdate,
1064
+ this);
1065
1065
  Host.AidaClient.HostConfigTracker.instance().addEventListener(
1066
1066
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#handleAidaAvailabilityChange);
1067
1067
  const initialAvailability = Host.AidaClient.HostConfigTracker.instance().aidaAvailability;
@@ -1107,7 +1107,8 @@ export class AiAssistancePanel extends UI.Panel.Panel {
1107
1107
  super.willHide();
1108
1108
  AiAssistanceModel.AiHistoryStorage.AiHistoryStorage.instance().removeEventListener(
1109
1109
  AiAssistanceModel.AiHistoryStorage.Events.HISTORY_DELETED, this.#onHistoryDeleted, this);
1110
- this.#aiAssistanceEnabledSetting?.removeChangeListener(this.requestUpdate, this);
1110
+ this.#aiAssistanceEnabledSetting.removeEventListener(AiAssistanceModel.AiSetting.Events.CHANGED, this.requestUpdate,
1111
+ this);
1111
1112
  Host.AidaClient.HostConfigTracker.instance().removeEventListener(
1112
1113
  Host.AidaClient.Events.AIDA_AVAILABILITY_CHANGED, this.#handleAidaAvailabilityChange);
1113
1114
  this.#toggleSearchElementAction?.removeEventListener(
@@ -4,9 +4,10 @@
4
4
 
5
5
  import * as Common from '../../core/common/common.js';
6
6
  import * as i18n from '../../core/i18n/i18n.js';
7
- import type * as Platform from '../../core/platform/platform.js';
8
7
  import * as Root from '../../core/root/root.js';
8
+ import * as AiAssistanceModel from '../../models/ai_assistance/ai_assistance.js';
9
9
  import * as UI from '../../ui/legacy/legacy.js';
10
+ import * as SettingUIRegistration from '../../ui/settings/settings.js';
10
11
 
11
12
  import type * as AiAssistance from './ai_assistance.js';
12
13
 
@@ -50,21 +51,6 @@ const UIStrings = {
50
51
  * @description Text of a context menu item to redirect to the Gemini panel with the current context.
51
52
  */
52
53
  debugWithGemini: 'Debug with Gemini',
53
- /**
54
- * @description Message shown to the user if the DevTools locale is not
55
- * supported.
56
- */
57
- wrongLocale: 'To use this feature, set your language preference to English in DevTools settings.',
58
- /**
59
- * @description Message shown to the user if the user's region is not
60
- * supported.
61
- */
62
- geoRestricted: 'This feature is unavailable in your region.',
63
- /**
64
- * @description Message shown to the user if the enterprise policy does
65
- * not allow this feature.
66
- */
67
- policyRestricted: 'This setting is managed by your administrator.',
68
54
  } as const;
69
55
 
70
56
  const str_ = i18n.i18n.registerUIStrings('panels/ai_assistance/ai_assistance-meta.ts', UIStrings);
@@ -76,13 +62,6 @@ function i18nAiBrandedString(gemini: string, assistance: string) {
76
62
  return () => Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled ? i18nString(gemini) : i18nString(assistance);
77
63
  }
78
64
 
79
- const setting = 'ai-assistance-enabled';
80
-
81
- function isLocaleRestricted(): boolean {
82
- const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
83
- return !devtoolsLocale.locale.startsWith('en-');
84
- }
85
-
86
65
  function isGeoRestricted(config?: Root.Runtime.HostConfig): boolean {
87
66
  return config?.aidaAvailability?.blockedByGeo === true;
88
67
  }
@@ -140,30 +119,9 @@ UI.ViewManager.registerViewExtension({
140
119
  },
141
120
  });
142
121
 
143
- Common.Settings.registerSettingExtension({
122
+ SettingUIRegistration.SettingUIRegistration.register(AiAssistanceModel.AiUtils.aiAssistanceEnabledSettingDescriptor, {
144
123
  category: Common.Settings.SettingCategory.AI,
145
- settingName: setting,
146
- settingType: Common.Settings.SettingType.BOOLEAN,
147
124
  title: i18nAiBrandedString(UIStrings.enableGemini, UIStrings.enableAiAssistance),
148
- defaultValue: false,
149
- reloadRequired: false,
150
- condition: isAnyFeatureAvailable,
151
- disabledCondition: config => {
152
- const reasons: Platform.UIString.LocalizedString[] = [];
153
- if (isGeoRestricted(config)) {
154
- reasons.push(i18nString(UIStrings.geoRestricted));
155
- }
156
- if (isPolicyRestricted(config)) {
157
- reasons.push(i18nString(UIStrings.policyRestricted));
158
- }
159
- if (isLocaleRestricted()) {
160
- reasons.push(i18nString(UIStrings.wrongLocale));
161
- }
162
- if (reasons.length > 0) {
163
- return {disabled: true, reasons};
164
- }
165
- return {disabled: false};
166
- },
167
125
  });
168
126
 
169
127
  UI.ActionRegistration.registerActionExtension({