chrome-devtools-frontend 1.0.1622369 → 1.0.1624409

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 (33) hide show
  1. package/front_end/Images/src/expand.svg +1 -0
  2. package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +72 -8
  3. package/front_end/entrypoints/greendev_floaty/floaty.html +1 -1
  4. package/front_end/generated/Deprecation.ts +7 -0
  5. package/front_end/generated/InspectorBackendCommands.ts +1 -1
  6. package/front_end/generated/SupportedCSSProperties.js +6 -6
  7. package/front_end/generated/protocol.ts +1 -0
  8. package/front_end/models/ai_assistance/agents/GreenDevAgent.ts +373 -112
  9. package/front_end/models/ai_assistance/agents/NetworkAgent.snapshot.txt +57 -0
  10. package/front_end/models/ai_assistance/agents/NetworkAgent.ts +2 -1
  11. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -10
  12. package/front_end/models/javascript_metadata/NativeFunctions.js +9 -4
  13. package/front_end/panels/ai_assistance/components/ChatMessage.ts +212 -3
  14. package/front_end/panels/console/ConsoleView.ts +86 -7
  15. package/front_end/panels/console/ConsoleViewMessage.ts +23 -1
  16. package/front_end/panels/elements/StylePropertiesSection.ts +1 -2
  17. package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
  18. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +6 -2
  19. package/front_end/panels/elements/StylesSidebarPane.ts +17 -4
  20. package/front_end/panels/emulation/DeviceModeToolbar.ts +37 -13
  21. package/front_end/panels/emulation/deviceModeView.css +25 -0
  22. package/front_end/panels/greendev/GreenDevPanel.ts +30 -3
  23. package/front_end/panels/media/EventDisplayTable.ts +1 -1
  24. package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +48 -27
  25. package/front_end/panels/mobile_throttling/ThrottlingManager.ts +67 -38
  26. package/front_end/panels/network/NetworkConfigView.ts +1 -1
  27. package/front_end/panels/profiler/HeapSnapshotView.ts +1 -22
  28. package/front_end/third_party/chromium/README.chromium +1 -1
  29. package/front_end/ui/legacy/UIUtils.ts +26 -4
  30. package/front_end/ui/visual_logging/KnownContextValues.ts +17 -0
  31. package/package.json +1 -1
  32. package/front_end/panels/emulation/components/DeviceSizeInputElement.ts +0 -134
  33. package/front_end/panels/emulation/components/components.ts +0 -9
@@ -2324,6 +2324,11 @@ export const NativeFunctions = [
2324
2324
  signatures: [["type"]],
2325
2325
  receivers: ["HTMLScriptElement","ClipboardItem"]
2326
2326
  },
2327
+ {
2328
+ name: "supports",
2329
+ signatures: [["operation","algorithm","?length"],["operation","algorithm","additionalAlgorithm"]],
2330
+ receivers: ["SubtleCrypto"]
2331
+ },
2327
2332
  {
2328
2333
  name: "toggle",
2329
2334
  signatures: [["token","?force"]]
@@ -7435,10 +7440,6 @@ export const NativeFunctions = [
7435
7440
  name: "setReportEventDataForAutomaticBeacons",
7436
7441
  signatures: [["event"]]
7437
7442
  },
7438
- {
7439
- name: "notifyEvent",
7440
- signatures: [["triggering_event"]]
7441
- },
7442
7443
  {
7443
7444
  name: "FencedFrameConfig",
7444
7445
  signatures: [["url"]]
@@ -9391,6 +9392,10 @@ export const NativeFunctions = [
9391
9392
  name: "startDiagnosticLogging",
9392
9393
  signatures: [["?options"]]
9393
9394
  },
9395
+ {
9396
+ name: "finishDiagnosticLogging",
9397
+ signatures: [["?options"]]
9398
+ },
9394
9399
  {
9395
9400
  name: "CloseEvent",
9396
9401
  signatures: [["type","?eventInitDict"]]
@@ -46,7 +46,7 @@ const {html, Directives: {ref, ifDefined}} = Lit;
46
46
  const lockedString = i18n.i18n.lockedString;
47
47
  const {widget} = UI.Widget;
48
48
 
49
- const REPORT_URL = 'https://crbug.com/364805393' as Platform.DevToolsPath.UrlString;
49
+ const REPORT_URL = 'https://crbug.com/508304827' as Platform.DevToolsPath.UrlString;
50
50
  const SCROLL_ROUNDING_OFFSET = 1;
51
51
  const MAX_NUM_LINES_IN_CODEBLOCK = 11;
52
52
 
@@ -227,6 +227,14 @@ const UIStringsNotTranslate = {
227
227
  * @description Accessible label for the reveal button in the bottom up thread activity widget.
228
228
  */
229
229
  revealBottomUpTree: 'Reveal bottom-up thread activity',
230
+ /**
231
+ * @description Accessible label for the reveal button in the network dependency tree widget.
232
+ */
233
+ revealNetworkDependencyTree: 'Reveal network dependency tree',
234
+ /**
235
+ * @description Accessible label for the reveal button in the 3rd parties widget.
236
+ */
237
+ revealThirdParties: 'Reveal 3rd parties',
230
238
  /**
231
239
  * @description Title for the core web vitals widget.
232
240
  */
@@ -247,6 +255,14 @@ const UIStringsNotTranslate = {
247
255
  * @description Title for the render-blocking requests widget.
248
256
  */
249
257
  renderBlockingBreakdown: 'Render-blocking requests',
258
+ /**
259
+ * @description Title for the network dependency tree widget.
260
+ */
261
+ networkDependencyTree: 'Network dependency tree',
262
+ /**
263
+ * @description Title for the 3rd parties widget.
264
+ */
265
+ thirdParties: '3rd parties',
250
266
  /**
251
267
  * @description Title for the LCP element widget.
252
268
  */
@@ -263,6 +279,110 @@ const UIStringsNotTranslate = {
263
279
  * @description Title for the bottom up thread activity widget.
264
280
  */
265
281
  bottomUpTree: 'Bottom-up thread activity',
282
+ /**
283
+ * @description Accessible label for the reveal button in the forced reflow widget.
284
+ */
285
+ revealForcedReflow: 'Reveal forced reflow',
286
+ /**
287
+ * @description Title for the forced reflow widget.
288
+ */
289
+ forcedReflow: 'Forced reflow',
290
+ /**
291
+ * @description Accessible label for the reveal button in the cache widget.
292
+ */
293
+ revealCache: 'Reveal efficient cache lifetimes',
294
+ /**
295
+ * @description Title for the cache widget.
296
+ */
297
+ cache: 'Efficient cache lifetimes',
298
+ /**
299
+ * @description Accessible label for the reveal button in the INP breakdown widget.
300
+ */
301
+ revealInpBreakdown: 'Reveal INP breakdown',
302
+ /**
303
+ * @description Title for the INP breakdown widget.
304
+ */
305
+ inpBreakdown: 'INP breakdown',
306
+ /**
307
+ * @description Accessible label for the reveal button in the document latency widget.
308
+ */
309
+ revealDocumentLatency: 'Reveal document latency',
310
+ /**
311
+ * @description Title for the document latency widget.
312
+ */
313
+ documentLatency: 'Document latency',
314
+ /**
315
+ * @description Accessible label for the reveal button in the DOM size widget.
316
+ */
317
+ revealDomSize: 'Reveal DOM size',
318
+ /**
319
+ * @description Title for the DOM size widget.
320
+ */
321
+ domSize: 'DOM size',
322
+ /**
323
+ * @description Accessible label for the reveal button in the duplicated JavaScript widget.
324
+ */
325
+ revealDuplicateJavaScript: 'Reveal duplicated JavaScript',
326
+ /**
327
+ * @description Title for the duplicated JavaScript widget.
328
+ */
329
+ duplicateJavaScript: 'Duplicated JavaScript',
330
+ /**
331
+ * @description Accessible label for the reveal button in the image delivery widget.
332
+ */
333
+ revealImageDelivery: 'Reveal image delivery',
334
+ /**
335
+ * @description Title for the image delivery widget.
336
+ */
337
+ imageDelivery: 'Image delivery',
338
+ /**
339
+ * @description Accessible label for the reveal button in the font display widget.
340
+ */
341
+ revealFontDisplay: 'Reveal font display',
342
+ /**
343
+ * @description Title for the font display widget.
344
+ */
345
+ fontDisplay: 'Font display',
346
+ /**
347
+ * @description Accessible label for the reveal button in the slow CSS selectors widget.
348
+ */
349
+ revealSlowCssSelector: 'Reveal slow CSS selectors',
350
+ /**
351
+ * @description Title for the slow CSS selectors widget.
352
+ */
353
+ slowCssSelector: 'Slow CSS selectors',
354
+ /**
355
+ * @description Accessible label for the reveal button in the legacy JavaScript widget.
356
+ */
357
+ revealLegacyJavaScript: 'Reveal legacy JavaScript',
358
+ /**
359
+ * @description Title for the legacy JavaScript widget.
360
+ */
361
+ legacyJavaScript: 'Legacy JavaScript',
362
+ /**
363
+ * @description Accessible label for the reveal button in the viewport optimization widget.
364
+ */
365
+ revealViewport: 'Reveal viewport optimization',
366
+ /**
367
+ * @description Title for the viewport optimization widget.
368
+ */
369
+ viewport: 'Viewport optimization',
370
+ /**
371
+ * @description Accessible label for the reveal button in the modern HTTP usage widget.
372
+ */
373
+ revealModernHttp: 'Reveal modern HTTP usage',
374
+ /**
375
+ * @description Title for the modern HTTP usage widget.
376
+ */
377
+ modernHttp: 'Modern HTTP usage',
378
+ /**
379
+ * @description Accessible label for the reveal button in the character set declaration widget.
380
+ */
381
+ revealCharacterSet: 'Reveal character set declaration',
382
+ /**
383
+ * @description Title for the character set declaration widget.
384
+ */
385
+ characterSet: 'Character set declaration',
266
386
  } as const;
267
387
 
268
388
  export interface Step {
@@ -941,8 +1061,7 @@ async function makeStylePropertiesWidget(widgetData: StylePropertiesAiWidget): P
941
1061
  }
942
1062
 
943
1063
  const INSIGHT_METADATA: Record<string, {
944
- component: typeof TimelineInsights.LCPBreakdown.LCPBreakdown | typeof TimelineInsights.RenderBlocking.RenderBlocking |
945
- typeof TimelineInsights.LCPDiscovery.LCPDiscovery | typeof TimelineInsights.CLSCulprits.CLSCulprits,
1064
+ component: new () => BaseInsightComponent<Trace.Insights.Types.InsightModel>,
946
1065
  accessibleLabel: string,
947
1066
  title: string,
948
1067
  jslog: string,
@@ -971,6 +1090,96 @@ const INSIGHT_METADATA: Record<string, {
971
1090
  title: UIStringsNotTranslate.clsCulprits,
972
1091
  jslog: 'cls-culprits-widget',
973
1092
  },
1093
+ [Trace.Insights.Types.InsightKeys.NETWORK_DEPENDENCY_TREE]: {
1094
+ component: TimelineInsights.NetworkDependencyTree.NetworkDependencyTree,
1095
+ accessibleLabel: UIStringsNotTranslate.revealNetworkDependencyTree,
1096
+ title: UIStringsNotTranslate.networkDependencyTree,
1097
+ jslog: 'network-dependency-tree-widget',
1098
+ },
1099
+ [Trace.Insights.Types.InsightKeys.THIRD_PARTIES]: {
1100
+ component: TimelineInsights.ThirdParties.ThirdParties,
1101
+ accessibleLabel: UIStringsNotTranslate.revealThirdParties,
1102
+ title: UIStringsNotTranslate.thirdParties,
1103
+ jslog: 'third-parties-widget',
1104
+ },
1105
+ [Trace.Insights.Types.InsightKeys.FORCED_REFLOW]: {
1106
+ component: TimelineInsights.ForcedReflow.ForcedReflow,
1107
+ accessibleLabel: UIStringsNotTranslate.revealForcedReflow,
1108
+ title: UIStringsNotTranslate.forcedReflow,
1109
+ jslog: 'forced-reflow-widget',
1110
+ },
1111
+ [Trace.Insights.Types.InsightKeys.CACHE]: {
1112
+ component: TimelineInsights.Cache.Cache,
1113
+ accessibleLabel: UIStringsNotTranslate.revealCache,
1114
+ title: UIStringsNotTranslate.cache,
1115
+ jslog: 'cache-widget',
1116
+ },
1117
+ [Trace.Insights.Types.InsightKeys.INP_BREAKDOWN]: {
1118
+ component: TimelineInsights.INPBreakdown.INPBreakdown,
1119
+ accessibleLabel: UIStringsNotTranslate.revealInpBreakdown,
1120
+ title: UIStringsNotTranslate.inpBreakdown,
1121
+ jslog: 'inp-breakdown-widget',
1122
+ },
1123
+ [Trace.Insights.Types.InsightKeys.DOCUMENT_LATENCY]: {
1124
+ component: TimelineInsights.DocumentLatency.DocumentLatency,
1125
+ accessibleLabel: UIStringsNotTranslate.revealDocumentLatency,
1126
+ title: UIStringsNotTranslate.documentLatency,
1127
+ jslog: 'document-latency-widget',
1128
+ },
1129
+ [Trace.Insights.Types.InsightKeys.DOM_SIZE]: {
1130
+ component: TimelineInsights.DOMSize.DOMSize,
1131
+ accessibleLabel: UIStringsNotTranslate.revealDomSize,
1132
+ title: UIStringsNotTranslate.domSize,
1133
+ jslog: 'dom-size-widget',
1134
+ },
1135
+ [Trace.Insights.Types.InsightKeys.DUPLICATE_JAVASCRIPT]: {
1136
+ component: TimelineInsights.DuplicatedJavaScript.DuplicatedJavaScript,
1137
+ accessibleLabel: UIStringsNotTranslate.revealDuplicateJavaScript,
1138
+ title: UIStringsNotTranslate.duplicateJavaScript,
1139
+ jslog: 'duplicate-javascript-widget',
1140
+ },
1141
+ [Trace.Insights.Types.InsightKeys.IMAGE_DELIVERY]: {
1142
+ component: TimelineInsights.ImageDelivery.ImageDelivery,
1143
+ accessibleLabel: UIStringsNotTranslate.revealImageDelivery,
1144
+ title: UIStringsNotTranslate.imageDelivery,
1145
+ jslog: 'image-delivery-widget',
1146
+ },
1147
+ [Trace.Insights.Types.InsightKeys.FONT_DISPLAY]: {
1148
+ component: TimelineInsights.FontDisplay.FontDisplay,
1149
+ accessibleLabel: UIStringsNotTranslate.revealFontDisplay,
1150
+ title: UIStringsNotTranslate.fontDisplay,
1151
+ jslog: 'font-display-widget',
1152
+ },
1153
+ [Trace.Insights.Types.InsightKeys.SLOW_CSS_SELECTOR]: {
1154
+ component: TimelineInsights.SlowCSSSelector.SlowCSSSelector,
1155
+ accessibleLabel: UIStringsNotTranslate.revealSlowCssSelector,
1156
+ title: UIStringsNotTranslate.slowCssSelector,
1157
+ jslog: 'slow-css-selector-widget',
1158
+ },
1159
+ [Trace.Insights.Types.InsightKeys.LEGACY_JAVASCRIPT]: {
1160
+ component: TimelineInsights.LegacyJavaScript.LegacyJavaScript,
1161
+ accessibleLabel: UIStringsNotTranslate.revealLegacyJavaScript,
1162
+ title: UIStringsNotTranslate.legacyJavaScript,
1163
+ jslog: 'legacy-javascript-widget',
1164
+ },
1165
+ [Trace.Insights.Types.InsightKeys.VIEWPORT]: {
1166
+ component: TimelineInsights.Viewport.Viewport,
1167
+ accessibleLabel: UIStringsNotTranslate.revealViewport,
1168
+ title: UIStringsNotTranslate.viewport,
1169
+ jslog: 'viewport-widget',
1170
+ },
1171
+ [Trace.Insights.Types.InsightKeys.MODERN_HTTP]: {
1172
+ component: TimelineInsights.ModernHTTP.ModernHTTP,
1173
+ accessibleLabel: UIStringsNotTranslate.revealModernHttp,
1174
+ title: UIStringsNotTranslate.modernHttp,
1175
+ jslog: 'modern-http-widget',
1176
+ },
1177
+ [Trace.Insights.Types.InsightKeys.CHARACTER_SET]: {
1178
+ component: TimelineInsights.CharacterSet.CharacterSet,
1179
+ accessibleLabel: UIStringsNotTranslate.revealCharacterSet,
1180
+ title: UIStringsNotTranslate.characterSet,
1181
+ jslog: 'character-set-widget',
1182
+ },
974
1183
  };
975
1184
 
976
1185
  function renderInsightWidget<T extends Trace.Insights.Types.InsightModel>(
@@ -265,6 +265,16 @@ const UIStrings = {
265
265
  * @example {5} PH1
266
266
  */
267
267
  filteredMessagesInConsole: '{PH1} messages in console',
268
+ /**
269
+ * @description Tooltip for the collapse all button in the Console panel toolbar.
270
+ * Clicking this button will collapse all groups and stack traces.
271
+ */
272
+ collapseAll: 'Collapse all',
273
+ /**
274
+ * @description Tooltip for the expand all button in the Console panel toolbar.
275
+ * Clicking this button will expand all groups and stack traces.
276
+ */
277
+ expandAll: 'Expand all',
268
278
 
269
279
  } as const;
270
280
  const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleView.ts', UIStrings);
@@ -337,6 +347,8 @@ export class ConsoleView extends UI.Widget.VBox implements
337
347
  private issueResolver = new IssuesManager.IssueResolver.IssueResolver();
338
348
  #isDetached = false;
339
349
  #onIssuesCountUpdateBound = this.#onIssuesCountUpdate.bind(this);
350
+ #collapseAllButton: UI.Toolbar.ToolbarButton;
351
+ #allCollapsed = false;
340
352
  aiCodeCompletionConfig?: TextEditor.AiCodeCompletionProvider.AiCodeCompletionConfig;
341
353
  private aiCodeCompletionSummaryToolbarContainer?: HTMLElement;
342
354
  private aiCodeCompletionSummaryToolbar?: AiCodeCompletionSummaryToolbar;
@@ -428,6 +440,10 @@ export class ConsoleView extends UI.Widget.VBox implements
428
440
  i18nString(UIStrings.showConsoleSidebar), i18nString(UIStrings.hideConsoleSidebar),
429
441
  i18nString(UIStrings.consoleSidebarShown), i18nString(UIStrings.consoleSidebarHidden), 'console-sidebar'));
430
442
  toolbar.appendToolbarItem(UI.Toolbar.Toolbar.createActionButton('console.clear'));
443
+ this.#collapseAllButton =
444
+ new UI.Toolbar.ToolbarButton(i18nString(UIStrings.collapseAll), 'compress', undefined, 'console.collapse-all');
445
+ this.#collapseAllButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.#toggleCollapseAll, this);
446
+ toolbar.appendToolbarItem(this.#collapseAllButton);
431
447
  toolbar.appendSeparator();
432
448
  toolbar.appendToolbarItem(this.consoleContextSelector.toolbarItem());
433
449
  toolbar.appendSeparator();
@@ -684,6 +700,62 @@ export class ConsoleView extends UI.Widget.VBox implements
684
700
  this.prompt.clearAiCodeCompletionCache();
685
701
  }
686
702
 
703
+ collapseAll(): void {
704
+ for (const message of this.consoleMessages) {
705
+ if (message instanceof ConsoleGroupViewMessage) {
706
+ message.setCollapsedSilent(true);
707
+ }
708
+ message.setTraceExpanded(false);
709
+ }
710
+ this.updateMessageList();
711
+ }
712
+
713
+ expandAll(): void {
714
+ for (const message of this.consoleMessages) {
715
+ if (message instanceof ConsoleGroupViewMessage) {
716
+ message.setCollapsedSilent(false);
717
+ }
718
+ message.setTraceExpanded(true);
719
+ }
720
+ this.updateMessageList();
721
+ }
722
+
723
+ #toggleCollapseAll(): void {
724
+ if (this.#allCollapsed) {
725
+ this.expandAll();
726
+ } else {
727
+ this.collapseAll();
728
+ }
729
+ this.#allCollapsed = !this.#allCollapsed;
730
+ this.#updateCollapseAllButton();
731
+ }
732
+
733
+ #updateCollapseAllButton(): void {
734
+ let hasExpandedMessages = false;
735
+ let hasCollapsedMessages = false;
736
+ for (const message of this.visibleViewMessages) {
737
+ if (message instanceof ConsoleGroupViewMessage) {
738
+ hasExpandedMessages = hasExpandedMessages || !message.collapsed();
739
+ hasCollapsedMessages = hasCollapsedMessages || message.collapsed();
740
+ }
741
+ if (message.isExpandableTrace()) {
742
+ hasExpandedMessages = hasExpandedMessages || message.isTraceExpanded();
743
+ hasCollapsedMessages = hasCollapsedMessages || !message.isTraceExpanded();
744
+ }
745
+ if (hasExpandedMessages && hasCollapsedMessages) {
746
+ break;
747
+ }
748
+ }
749
+ this.#allCollapsed = !hasExpandedMessages && hasCollapsedMessages;
750
+ if (this.#allCollapsed) {
751
+ this.#collapseAllButton.setGlyph('expand');
752
+ this.#collapseAllButton.setTitle(i18nString(UIStrings.expandAll));
753
+ } else {
754
+ this.#collapseAllButton.setGlyph('compress');
755
+ this.#collapseAllButton.setTitle(i18nString(UIStrings.collapseAll));
756
+ }
757
+ }
758
+
687
759
  #onIssuesCountUpdate(): void {
688
760
  void this.issueToolbarThrottle.schedule(async () => this.updateIssuesToolbarItem());
689
761
  this.issuesCountUpdatedForTest();
@@ -1121,11 +1193,13 @@ export class ConsoleView extends UI.Widget.VBox implements
1121
1193
  }
1122
1194
  const parentGroup = currentGroup.consoleGroup();
1123
1195
  if (parentGroup) {
1196
+ // If the parent group has its messages hidden, don't show this group.
1197
+ if (parentGroup.messagesHidden()) {
1198
+ return;
1199
+ }
1124
1200
  showGroup(parentGroup, visibleViewMessages);
1125
1201
  }
1126
- if (!parentGroup?.messagesHidden()) {
1127
- visibleViewMessages.push(currentGroup);
1128
- }
1202
+ visibleViewMessages.push(currentGroup);
1129
1203
  }
1130
1204
  }
1131
1205
 
@@ -1369,18 +1443,23 @@ export class ConsoleView extends UI.Widget.VBox implements
1369
1443
  for (const consoleMessage of this.consoleMessages) {
1370
1444
  consoleMessage.setInSimilarGroup(false);
1371
1445
  if (consoleMessage.consoleMessage().isGroupable()) {
1372
- // Since grouping similar messages is disabled, we need clear the
1373
- // reference to the artificial console group start.
1374
- consoleMessage.clearConsoleGroup();
1446
+ // Since grouping similar messages is disabled, we need to clear the
1447
+ // reference to the artificial console group start, but preserve
1448
+ // references to real console groups (console.group()/console.groupCollapsed()).
1449
+ const group = consoleMessage.consoleGroup();
1450
+ if (group && !this.consoleGroupStarts.includes(group)) {
1451
+ consoleMessage.clearConsoleGroup();
1452
+ }
1375
1453
  }
1376
1454
  this.appendMessageToEnd(
1377
1455
  consoleMessage,
1378
- true /* crbug.com/1082963: prevent collaps`e of same messages when "Group similar" is false */);
1456
+ true /* crbug.com/1082963: prevent collapse of same messages when "Group similar" is false */);
1379
1457
  }
1380
1458
  }
1381
1459
  this.updateFilterStatus();
1382
1460
  this.#searchableView.updateSearchMatchesCount(this.regexMatchRanges.length);
1383
1461
  this.highlightMatch(this.currentMatchRangeIndex, false); // Re-highlight current match without scrolling.
1462
+ this.#updateCollapseAllButton();
1384
1463
  this.viewport.invalidate();
1385
1464
  this.messagesCountElement.setAttribute(
1386
1465
  'aria-label', i18nString(UIStrings.filteredMessagesInConsole, {PH1: this.visibleViewMessages.length}));
@@ -299,6 +299,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
299
299
  protected messageIcon: Icon|null;
300
300
  private traceExpanded: boolean;
301
301
  private expandTrace: ((arg0: boolean) => void)|null;
302
+ private hasStackTrace: boolean;
302
303
  protected anchorElement: HTMLElement|null;
303
304
  protected contentElementInternal: HTMLElement|null;
304
305
  private nestingLevelMarkers: HTMLElement[]|null;
@@ -340,6 +341,7 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
340
341
  this.messageIcon = null;
341
342
  this.traceExpanded = false;
342
343
  this.expandTrace = null;
344
+ this.hasStackTrace = false;
343
345
  this.anchorElement = null;
344
346
  this.contentElementInternal = null;
345
347
  this.nestingLevelMarkers = null;
@@ -653,6 +655,8 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
653
655
  this.expandTrace(true);
654
656
  }
655
657
 
658
+ this.hasStackTrace = true;
659
+
656
660
  // @ts-expect-error
657
661
  toggleElement._expandStackTraceForTest = this.expandTrace.bind(this, true);
658
662
  return toggleElement;
@@ -1200,6 +1204,20 @@ export class ConsoleViewMessage implements ConsoleViewportElement {
1200
1204
  return this.consoleGroupInternal;
1201
1205
  }
1202
1206
 
1207
+ isTraceExpanded(): boolean {
1208
+ return this.traceExpanded;
1209
+ }
1210
+
1211
+ isExpandableTrace(): boolean {
1212
+ return this.hasStackTrace;
1213
+ }
1214
+
1215
+ setTraceExpanded(expanded: boolean): void {
1216
+ if (this.expandTrace && this.traceExpanded !== expanded) {
1217
+ this.expandTrace(expanded);
1218
+ }
1219
+ }
1220
+
1203
1221
  setInSimilarGroup(inSimilarGroup: boolean, isLast?: boolean): void {
1204
1222
  this.inSimilarGroup = inSimilarGroup;
1205
1223
  this.lastInSimilarGroup = inSimilarGroup && Boolean(isLast);
@@ -2161,11 +2179,15 @@ export class ConsoleGroupViewMessage extends ConsoleViewMessage {
2161
2179
  }
2162
2180
 
2163
2181
  setCollapsed(collapsed: boolean): void {
2182
+ this.setCollapsedSilent(collapsed);
2183
+ this.onToggle.call(null);
2184
+ }
2185
+
2186
+ setCollapsedSilent(collapsed: boolean): void {
2164
2187
  this.collapsedInternal = collapsed;
2165
2188
  if (this.expandGroupIcon) {
2166
2189
  this.expandGroupIcon.name = this.collapsedInternal ? 'triangle-right' : 'triangle-down';
2167
2190
  }
2168
- this.onToggle.call(null);
2169
2191
  }
2170
2192
 
2171
2193
  collapsed(): boolean {
@@ -907,8 +907,7 @@ export class StylePropertiesSection {
907
907
  return;
908
908
  }
909
909
  const sourceTreeElement = this.closestPropertyForEditing(this.#activeAiSuggestion.cssProperty.index);
910
- if (!(sourceTreeElement instanceof StylePropertyTreeElement) ||
911
- sourceTreeElement.property !== this.#activeAiSuggestion.cssProperty) {
910
+ if (!(sourceTreeElement instanceof StylePropertyTreeElement)) {
912
911
  return;
913
912
  }
914
913
  return sourceTreeElement;
@@ -3515,7 +3515,7 @@ export class StylePropertyTreeElement extends UI.TreeOutline.TreeElement {
3515
3515
  if (this.prompt) {
3516
3516
  this.prompt.detach();
3517
3517
  this.prompt = null;
3518
- this.#clearGhostTextInValue();
3518
+ this.section().activeAiSuggestion = undefined;
3519
3519
  }
3520
3520
  }
3521
3521
 
@@ -55,9 +55,13 @@ export class StylesAiCodeCompletionProvider {
55
55
  // early return as this means that code completion was previously setup
56
56
  return;
57
57
  }
58
+ // Adding '}' as a stop sequence so that suggestion is limited to properties for a given style section
59
+ const stopSequences = ['}'];
60
+ if (this.#aiCodeCompletionConfig.completionContext.stopSequences) {
61
+ stopSequences.push(...this.#aiCodeCompletionConfig.completionContext.stopSequences);
62
+ }
58
63
  this.#aiCodeCompletion = new AiCodeCompletion.AiCodeCompletion.AiCodeCompletion(
59
- {aidaClient: this.#aidaClient}, this.#aiCodeCompletionConfig.panel, undefined,
60
- this.#aiCodeCompletionConfig.completionContext.stopSequences);
64
+ {aidaClient: this.#aidaClient}, this.#aiCodeCompletionConfig.panel, undefined, stopSequences);
61
65
  this.#aiCodeCompletionConfig.onFeatureEnabled();
62
66
  }
63
67
 
@@ -1918,14 +1918,18 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
1918
1918
  return;
1919
1919
  }
1920
1920
  break;
1921
- case 'Enter':
1921
+ case 'Enter': {
1922
1922
  if (keyboardEvent.shiftKey) {
1923
1923
  return;
1924
1924
  }
1925
1925
  // Accept any available autocompletions and advance to the next field.
1926
- this.tabKeyPressed();
1926
+ const handled = this.tabKeyPressed();
1927
+ if (this.aiCodeCompletionProvider && handled) {
1928
+ event.consume(true);
1929
+ }
1927
1930
  keyboardEvent.preventDefault();
1928
1931
  return;
1932
+ }
1929
1933
  case 'Escape':
1930
1934
  if (this.#handleEscape(keyboardEvent)) {
1931
1935
  return;
@@ -2264,9 +2268,18 @@ export class CSSPropertyPrompt extends UI.TextPrompt.TextPrompt {
2264
2268
  if (!this.queryRange) {
2265
2269
  this.queryRange = new TextUtils.TextRange.TextRange(0, 0, 0, this.text().length);
2266
2270
  }
2271
+
2272
+ const properties = this.#getAiSuggestedProperties(args.text);
2273
+ if (properties.length === 0) {
2274
+ this.treeElement.section().activeAiSuggestion = undefined;
2275
+ this.activeAiSuggestionInfo = undefined;
2276
+ return;
2277
+ }
2278
+
2279
+ const styleText = properties.map(p => `${p.name}: ${p.value};`).join(' ');
2267
2280
  this.treeElement.section().activeAiSuggestion = {
2268
- text: args.text,
2269
- properties: this.#getAiSuggestedProperties(args.text),
2281
+ text: styleText,
2282
+ properties,
2270
2283
  cursorPosition: args.from,
2271
2284
  clearCachedRequest: args.clearCachedRequest,
2272
2285
  cssProperty: this.treeElement.property,
@@ -16,7 +16,6 @@ import * as UI from '../../ui/legacy/legacy.js';
16
16
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
17
17
  import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
18
18
 
19
- import * as EmulationComponents from './components/components.js';
20
19
  const UIStrings = {
21
20
  /**
22
21
  * @description Title of the device dimensions selection item in the Device Mode Toolbar.
@@ -219,8 +218,8 @@ export class DeviceModeToolbar {
219
218
  private spanButton!: Buttons.Button.Button;
220
219
  private postureItem!: HTMLSelectElement;
221
220
  private modeButton!: Buttons.Button.Button;
222
- private widthInput: EmulationComponents.DeviceSizeInputElement.SizeInputElement;
223
- private heightInput: EmulationComponents.DeviceSizeInputElement.SizeInputElement;
221
+ private widthInput: HTMLInputElement;
222
+ private heightInput: HTMLInputElement;
224
223
  private deviceScaleItem!: HTMLSelectElement;
225
224
  private deviceScaleItems: HTMLElement[] = [];
226
225
  private deviceSelectItem!: HTMLSelectElement;
@@ -255,10 +254,9 @@ export class DeviceModeToolbar {
255
254
  Common.Settings.Settings.instance().createSetting('emulation.auto-adjust-scale', true);
256
255
 
257
256
  this.lastMode = new Map();
258
- this.widthInput = new EmulationComponents.DeviceSizeInputElement.SizeInputElement(
259
- i18nString(UIStrings.width), {jslogContext: 'width'});
260
- this.heightInput = new EmulationComponents.DeviceSizeInputElement.SizeInputElement(
261
- i18nString(UIStrings.heightLeaveEmptyForFull), {jslogContext: 'height'});
257
+
258
+ this.widthInput = this.createSizeInput(i18nString(UIStrings.width), 'width');
259
+ this.heightInput = this.createSizeInput(i18nString(UIStrings.heightLeaveEmptyForFull), 'height');
262
260
 
263
261
  this.#element = document.createElement('div');
264
262
  this.#element.classList.add('device-mode-toolbar');
@@ -306,6 +304,30 @@ export class DeviceModeToolbar {
306
304
  return element;
307
305
  }
308
306
 
307
+ private createSizeInput(title: string, jslogContext: string): HTMLInputElement {
308
+ const input = document.createElement('input');
309
+ input.type = 'number';
310
+ input.max = String(EmulationModel.DeviceModeModel.MaxDeviceSize);
311
+ input.min = String(EmulationModel.DeviceModeModel.MinDeviceSize);
312
+ input.title = title;
313
+ input.classList.add('device-mode-size-input');
314
+ input.setAttribute('jslog', `${VisualLogging.textField().track({change: true}).context(jslogContext)}`);
315
+
316
+ input.addEventListener('keydown', (event: Event) => {
317
+ let modifiedValue = UI.UIUtils.modifiedFloatNumber(Number(input.value), event);
318
+ if (modifiedValue === null) {
319
+ return;
320
+ }
321
+ modifiedValue = Math.min(modifiedValue, EmulationModel.DeviceModeModel.MaxDeviceSize);
322
+ modifiedValue = Math.max(modifiedValue, EmulationModel.DeviceModeModel.MinDeviceSize);
323
+
324
+ event.preventDefault();
325
+ input.value = String(modifiedValue);
326
+ input.dispatchEvent(new Event('change'));
327
+ });
328
+ return input;
329
+ }
330
+
309
331
  private createMainToolbar(): UI.Toolbar.Toolbar {
310
332
  const mainToolbar = this.#element.createChild('devtools-toolbar', 'main-toolbar');
311
333
 
@@ -320,14 +342,16 @@ export class DeviceModeToolbar {
320
342
  mainToolbar.append(...dimensionsSpan.childNodes);
321
343
  mainToolbar.append(this.deviceSelectItem);
322
344
 
323
- this.widthInput.addEventListener('sizechanged', ({size: width}) => {
345
+ this.widthInput.addEventListener('change', () => {
346
+ const width = Number(this.widthInput.value);
324
347
  if (this.autoAdjustScaleSetting.get()) {
325
348
  this.model.setWidthAndScaleToFit(width);
326
349
  } else {
327
350
  this.model.setWidth(width);
328
351
  }
329
352
  });
330
- this.heightInput.addEventListener('sizechanged', ({size: height}) => {
353
+ this.heightInput.addEventListener('change', () => {
354
+ const height = Number(this.heightInput.value);
331
355
  if (this.autoAdjustScaleSetting.get()) {
332
356
  this.model.setHeightAndScaleToFit(height);
333
357
  } else {
@@ -389,8 +413,8 @@ export class DeviceModeToolbar {
389
413
  MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.createForGlobalConditions(
390
414
  mainToolbar, i18nString(UIStrings.throttling));
391
415
  const saveDataItem = MobileThrottling.ThrottlingManager.throttlingManager().createSaveDataOverrideSelector();
392
- saveDataItem.turnShrinkable();
393
- mainToolbar.appendToolbarItem(saveDataItem);
416
+ saveDataItem.classList.add('dark-text', 'toolbar-has-dropdown-shrinkable');
417
+ mainToolbar.append(saveDataItem);
394
418
 
395
419
  mainToolbar.append(this.createEmptyToolbarElement());
396
420
  this.modeButton = new Buttons.Button.Button();
@@ -947,8 +971,8 @@ export class DeviceModeToolbar {
947
971
  }
948
972
 
949
973
  const size = this.model.appliedDeviceSize();
950
- this.widthInput.size = String(size.width);
951
- this.heightInput.size =
974
+ this.widthInput.value = String(size.width);
975
+ this.heightInput.value =
952
976
  this.model.type() === EmulationModel.DeviceModeModel.Type.Responsive && this.model.isFullHeight() ?
953
977
  '' :
954
978
  String(size.height);