chrome-devtools-frontend 1.0.1510848 → 1.0.1512349

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 (45) hide show
  1. package/front_end/Images/src/ai-explorer-badge.svg +114 -0
  2. package/front_end/Images/src/code-whisperer-badge.svg +166 -0
  3. package/front_end/Images/src/devtools-user-badge.svg +129 -0
  4. package/front_end/Images/src/dom-detective-badge.svg +136 -0
  5. package/front_end/Images/src/speedster-badge.svg +166 -0
  6. package/front_end/core/host/AidaClient.ts +2 -0
  7. package/front_end/core/host/GdpClient.ts +38 -2
  8. package/front_end/core/i18n/NumberFormatter.ts +7 -0
  9. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -19
  10. package/front_end/models/ai_assistance/ai_assistance.ts +1 -1
  11. package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +7 -6
  12. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +119 -119
  13. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +43 -52
  14. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +100 -100
  15. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +12 -18
  16. package/front_end/models/ai_assistance/data_formatters/UnitFormatters.ts +151 -0
  17. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +3 -0
  18. package/front_end/models/badges/Badge.ts +7 -4
  19. package/front_end/models/badges/DOMDetectiveBadge.ts +20 -0
  20. package/front_end/models/badges/SpeedsterBadge.ts +4 -1
  21. package/front_end/models/badges/StarterBadge.ts +5 -1
  22. package/front_end/models/badges/UserBadges.ts +33 -7
  23. package/front_end/models/trace/ModelImpl.ts +0 -13
  24. package/front_end/models/trace/insights/Common.ts +19 -0
  25. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +36 -9
  26. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +32 -0
  27. package/front_end/panels/common/AiCodeCompletionTeaser.ts +14 -2
  28. package/front_end/panels/common/BadgeNotification.ts +119 -9
  29. package/front_end/panels/common/badgeNotification.css +4 -0
  30. package/front_end/panels/console/ConsolePrompt.ts +26 -0
  31. package/front_end/panels/elements/ElementsTreeElement.ts +12 -0
  32. package/front_end/panels/elements/ElementsTreeOutline.ts +3 -0
  33. package/front_end/panels/elements/StylePropertiesSection.ts +3 -0
  34. package/front_end/panels/elements/StylePropertyTreeElement.ts +5 -0
  35. package/front_end/panels/settings/SettingsScreen.ts +3 -9
  36. package/front_end/panels/settings/components/SyncSection.ts +6 -2
  37. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +35 -6
  38. package/front_end/panels/timeline/TimelinePanel.ts +22 -10
  39. package/front_end/panels/timeline/TimelineUIUtils.ts +4 -3
  40. package/front_end/panels/timeline/utils/InsightAIContext.ts +0 -19
  41. package/front_end/ui/legacy/filter.css +1 -1
  42. package/front_end/ui/legacy/inspectorCommon.css +1 -1
  43. package/front_end/ui/legacy/softDropDownButton.css +1 -1
  44. package/package.json +1 -1
  45. package/front_end/models/ai_assistance/data_formatters/Types.ts +0 -9
@@ -9,7 +9,7 @@ import type {ConversationSuggestion} from '../agents/AiAgent.js';
9
9
  import {
10
10
  NetworkRequestFormatter,
11
11
  } from './NetworkRequestFormatter.js';
12
- import type {UnitFormatters} from './Types.js';
12
+ import {bytes, micros, millis} from './UnitFormatters.js';
13
13
 
14
14
  /**
15
15
  * For a given frame ID and navigation ID, returns the LCP Event and the LCP Request, if the resource was an image.
@@ -43,21 +43,17 @@ function getLCPData(parsedTrace: Trace.Handlers.Types.ParsedTrace, frameId: stri
43
43
  export class PerformanceInsightFormatter {
44
44
  #insight: Trace.Insights.Types.InsightModel;
45
45
  #parsedTrace: Trace.Handlers.Types.ParsedTrace;
46
- #unitFormatters: UnitFormatters;
47
46
 
48
- constructor(
49
- formatters: UnitFormatters, parsedTrace: Trace.Handlers.Types.ParsedTrace,
50
- insight: Trace.Insights.Types.InsightModel) {
47
+ constructor(parsedTrace: Trace.Handlers.Types.ParsedTrace, insight: Trace.Insights.Types.InsightModel) {
51
48
  this.#insight = insight;
52
49
  this.#parsedTrace = parsedTrace;
53
- this.#unitFormatters = formatters;
54
50
  }
55
51
 
56
52
  #formatMilli(x?: number): string {
57
53
  if (x === undefined) {
58
54
  return '';
59
55
  }
60
- return this.#unitFormatters.millis(x);
56
+ return millis(x);
61
57
  }
62
58
 
63
59
  #formatMicro(x?: number): string {
@@ -94,8 +90,7 @@ export class PerformanceInsightFormatter {
94
90
  if (lcpRequest) {
95
91
  parts.push(`${theLcpElement} is an image fetched from \`${lcpRequest.args.data.url}\`.`);
96
92
  const request = TraceEventFormatter.networkRequests(
97
- this.#unitFormatters, [lcpRequest], this.#parsedTrace,
98
- {verbose: true, customTitle: 'LCP resource network request'});
93
+ [lcpRequest], this.#parsedTrace, {verbose: true, customTitle: 'LCP resource network request'});
99
94
  parts.push(request);
100
95
  } else {
101
96
  parts.push(`${theLcpElement} is text and was not fetched from the network.`);
@@ -417,7 +412,7 @@ export class PerformanceInsightFormatter {
417
412
  output += `The following list contains the largest transfer sizes by a 3rd party script:\n\n`;
418
413
  for (const entry of thirdPartyTransferSizeEntries) {
419
414
  if (entry.transferSize > 0) {
420
- output += `- ${entry.entity.name}: ${this.#unitFormatters.bytes(entry.transferSize)}\n`;
415
+ output += `- ${entry.entity.name}: ${bytes(entry.transferSize)}\n`;
421
416
  }
422
417
  }
423
418
  output += '\n';
@@ -475,18 +470,18 @@ ${this.#links()}`;
475
470
  .map(optimization => {
476
471
  const message =
477
472
  Trace.Insights.Models.ImageDelivery.getOptimizationMessage(optimization);
478
- const byteSavings = this.#unitFormatters.bytes(optimization.byteSavings);
473
+ const byteSavings = bytes(optimization.byteSavings);
479
474
  return `${message} (Est ${byteSavings})`;
480
475
  })
481
476
  .join('\n');
482
477
 
483
478
  return `### ${image.request.args.data.url}
484
- - Potential savings: ${this.#unitFormatters.bytes(image.byteSavings)}
479
+ - Potential savings: ${bytes(image.byteSavings)}
485
480
  - Optimizations:\n${optimizations}`;
486
481
  })
487
482
  .join('\n\n');
488
483
 
489
- return `Total potential savings: ${this.#unitFormatters.bytes(this.#insight.wastedBytes)}
484
+ return `Total potential savings: ${bytes(this.#insight.wastedBytes)}
490
485
 
491
486
  The following images could be optimized:\n\n${imageDetails}`;
492
487
  }
@@ -546,8 +541,8 @@ ${checklistBulletPoints.map(point => `- ${point.name}: ${point.passed ? 'PASSED'
546
541
  }
547
542
 
548
543
  if (Trace.Insights.Models.RenderBlocking.isRenderBlocking(this.#insight)) {
549
- const requestSummary = TraceEventFormatter.networkRequests(
550
- this.#unitFormatters, this.#insight.renderBlockingRequests, this.#parsedTrace);
544
+ const requestSummary =
545
+ TraceEventFormatter.networkRequests(this.#insight.renderBlockingRequests, this.#parsedTrace);
551
546
 
552
547
  if (requestSummary.length === 0) {
553
548
  return 'There are no network requests that are render blocking.';
@@ -582,7 +577,7 @@ ${requestSummary}`;
582
577
 
583
578
  return `${this.#lcpMetricSharedContext()}
584
579
 
585
- ${TraceEventFormatter.networkRequests(this.#unitFormatters, [documentRequest], this.#parsedTrace, {
580
+ ${TraceEventFormatter.networkRequests([documentRequest], this.#parsedTrace, {
586
581
  verbose: true,
587
582
  customTitle: 'Document network request'
588
583
  })}
@@ -622,8 +617,7 @@ ${checklistBulletPoints.map(point => `- ${point.name}: ${point.passed ? 'PASSED'
622
617
  } as const;
623
618
 
624
619
  const shiftsFormatted = worstCluster.events.map((layoutShift, index) => {
625
- return TraceEventFormatter.layoutShift(
626
- this.#unitFormatters, layoutShift, index, this.#parsedTrace, shifts.get(layoutShift));
620
+ return TraceEventFormatter.layoutShift(layoutShift, index, this.#parsedTrace, shifts.get(layoutShift));
627
621
  });
628
622
 
629
623
  return `The worst layout shift cluster was the cluster that started at ${
@@ -637,9 +631,8 @@ ${shiftsFormatted.join('\n')}`;
637
631
 
638
632
  if (Trace.Insights.Models.ModernHTTP.isModernHTTP(this.#insight)) {
639
633
  const requestSummary = (this.#insight.http1Requests.length === 1) ?
640
- TraceEventFormatter.networkRequests(
641
- this.#unitFormatters, this.#insight.http1Requests, this.#parsedTrace, {verbose: true}) :
642
- TraceEventFormatter.networkRequests(this.#unitFormatters, this.#insight.http1Requests, this.#parsedTrace);
634
+ TraceEventFormatter.networkRequests(this.#insight.http1Requests, this.#parsedTrace, {verbose: true}) :
635
+ TraceEventFormatter.networkRequests(this.#insight.http1Requests, this.#parsedTrace);
643
636
 
644
637
  if (requestSummary.length === 0) {
645
638
  return 'There are no requests that were served over a legacy HTTP protocol.';
@@ -861,8 +854,7 @@ export interface NetworkRequestFormatOptions {
861
854
 
862
855
  export class TraceEventFormatter {
863
856
  static layoutShift(
864
- formatters: UnitFormatters, shift: Trace.Types.Events.SyntheticLayoutShift, index: number,
865
- parsedTrace: Trace.Handlers.Types.ParsedTrace,
857
+ shift: Trace.Types.Events.SyntheticLayoutShift, index: number, parsedTrace: Trace.Handlers.Types.ParsedTrace,
866
858
  rootCauses?: Trace.Insights.Models.CLSCulprits.LayoutShiftRootCausesData): string {
867
859
  const baseTime = parsedTrace.Meta.traceBounds.min;
868
860
 
@@ -896,15 +888,15 @@ export class TraceEventFormatter {
896
888
 
897
889
  const startTime = Trace.Helpers.Timing.microToMilli(Trace.Types.Timing.Micro(shift.ts - baseTime));
898
890
  return `### Layout shift ${index + 1}:
899
- - Start time: ${formatters.millis(startTime)}
891
+ - Start time: ${millis(startTime)}
900
892
  - Score: ${shift.args.data?.weighted_score_delta.toFixed(4)}
901
893
  ${rootCauseText}`;
902
894
  }
903
895
 
904
896
  // Stringify network requests for the LLM model.
905
897
  static networkRequests(
906
- formatters: UnitFormatters, requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
907
- parsedTrace: Trace.Handlers.Types.ParsedTrace, options?: NetworkRequestFormatOptions): string {
898
+ requests: readonly Trace.Types.Events.SyntheticNetworkRequest[], parsedTrace: Trace.Handlers.Types.ParsedTrace,
899
+ options?: NetworkRequestFormatOptions): string {
908
900
  if (requests.length === 0) {
909
901
  return '';
910
902
  }
@@ -921,12 +913,11 @@ ${rootCauseText}`;
921
913
  // For a single request, use `formatRequestVerbosely`, which formats with all fields specified and does not require a
922
914
  // format description.
923
915
  if (verbose) {
924
- return requests
925
- .map(request => this.#networkRequestVerbosely(formatters, request, parsedTrace, options?.customTitle))
916
+ return requests.map(request => this.#networkRequestVerbosely(request, parsedTrace, options?.customTitle))
926
917
  .join('\n');
927
918
  }
928
919
 
929
- return this.#networkRequestsArrayCompressed(formatters, requests, parsedTrace);
920
+ return this.#networkRequestsArrayCompressed(requests, parsedTrace);
930
921
  }
931
922
 
932
923
  /**
@@ -938,8 +929,8 @@ ${rootCauseText}`;
938
929
  * talk to jacktfranklin@.
939
930
  */
940
931
  static #networkRequestVerbosely(
941
- formatters: UnitFormatters, request: Trace.Types.Events.SyntheticNetworkRequest,
942
- parsedTrace: Trace.Handlers.Types.ParsedTrace, customTitle?: string): string {
932
+ request: Trace.Types.Events.SyntheticNetworkRequest, parsedTrace: Trace.Handlers.Types.ParsedTrace,
933
+ customTitle?: string): string {
943
934
  const {
944
935
  url,
945
936
  statusCode,
@@ -991,8 +982,8 @@ ${rootCauseText}`;
991
982
  const redirects = request.args.data.redirects.map((redirect, index) => {
992
983
  const startTime = redirect.ts - baseTime;
993
984
  return `#### Redirect ${index + 1}: ${redirect.url}
994
- - Start time: ${formatters.micros(startTime)}
995
- - Duration: ${formatters.micros(redirect.dur)}`;
985
+ - Start time: ${micros(startTime)}
986
+ - Duration: ${micros(redirect.dur)}`;
996
987
  });
997
988
 
998
989
  const initiators = this.#getInitiatorChain(parsedTrace, request);
@@ -1000,14 +991,14 @@ ${rootCauseText}`;
1000
991
 
1001
992
  return `${titlePrefix}: ${url}
1002
993
  Timings:
1003
- - Queued at: ${formatters.micros(startTimesForLifecycle.queuedAt)}
1004
- - Request sent at: ${formatters.micros(startTimesForLifecycle.requestSentAt)}
1005
- - Download complete at: ${formatters.micros(startTimesForLifecycle.downloadCompletedAt)}
1006
- - Main thread processing completed at: ${formatters.micros(startTimesForLifecycle.processingCompletedAt)}
994
+ - Queued at: ${micros(startTimesForLifecycle.queuedAt)}
995
+ - Request sent at: ${micros(startTimesForLifecycle.requestSentAt)}
996
+ - Download complete at: ${micros(startTimesForLifecycle.downloadCompletedAt)}
997
+ - Main thread processing completed at: ${micros(startTimesForLifecycle.processingCompletedAt)}
1007
998
  Durations:
1008
- - Download time: ${formatters.micros(downloadTime)}
1009
- - Main thread processing time: ${formatters.micros(mainThreadProcessingDuration)}
1010
- - Total duration: ${formatters.micros(request.dur)}${initiator ? `\nInitiator: ${initiator.args.data.url}` : ''}
999
+ - Download time: ${micros(downloadTime)}
1000
+ - Main thread processing time: ${micros(mainThreadProcessingDuration)}
1001
+ - Total duration: ${micros(request.dur)}${initiator ? `\nInitiator: ${initiator.args.data.url}` : ''}
1011
1002
  Redirects:${redirects.length ? '\n' + redirects.join('\n') : ' no redirects'}
1012
1003
  Status code: ${statusCode}
1013
1004
  MIME Type: ${mimeType}
@@ -1037,7 +1028,7 @@ ${NetworkRequestFormatter.formatHeaders('Response headers', responseHeaders ?? [
1037
1028
  // For a single request, use `formatRequestVerbosely`, which formats with all fields specified and does not require a
1038
1029
  // format description.
1039
1030
  static #networkRequestsArrayCompressed(
1040
- formatters: UnitFormatters, requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
1031
+ requests: readonly Trace.Types.Events.SyntheticNetworkRequest[],
1041
1032
  parsedTrace: Trace.Handlers.Types.ParsedTrace): string {
1042
1033
  const networkDataString = `
1043
1034
  Network requests data:
@@ -1048,7 +1039,7 @@ Network requests data:
1048
1039
  requests
1049
1040
  .map(request => {
1050
1041
  const urlIndex = TraceEventFormatter.#getOrAssignUrlIndex(urlIdToIndex, request.args.data.url);
1051
- return this.#networkRequestCompressedFormat(formatters, urlIndex, request, parsedTrace, urlIdToIndex);
1042
+ return this.#networkRequestCompressedFormat(urlIndex, request, parsedTrace, urlIdToIndex);
1052
1043
  })
1053
1044
  .join('\n');
1054
1045
 
@@ -1104,7 +1095,7 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1104
1095
  * See `networkDataFormatDescription` above for specifics.
1105
1096
  */
1106
1097
  static #networkRequestCompressedFormat(
1107
- formatters: UnitFormatters, urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest,
1098
+ urlIndex: number, request: Trace.Types.Events.SyntheticNetworkRequest,
1108
1099
  parsedTrace: Trace.Handlers.Types.ParsedTrace, urlIdToIndex: Map<string, number>): string {
1109
1100
  const {
1110
1101
  statusCode,
@@ -1123,13 +1114,13 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1123
1114
  parsedTrace.Meta.navigationsByFrameId,
1124
1115
  );
1125
1116
  const baseTime = navigationForEvent?.ts ?? parsedTrace.Meta.traceBounds.min;
1126
- const queuedTime = formatters.micros(request.ts - baseTime);
1127
- const requestSentTime = formatters.micros(syntheticData.sendStartTime - baseTime);
1128
- const downloadCompleteTime = formatters.micros(syntheticData.finishTime - baseTime);
1129
- const processingCompleteTime = formatters.micros(request.ts + request.dur - baseTime);
1130
- const totalDuration = formatters.micros(request.dur);
1131
- const downloadDuration = formatters.micros(syntheticData.finishTime - syntheticData.downloadStart);
1132
- const mainThreadProcessingDuration = formatters.micros(request.ts + request.dur - syntheticData.finishTime);
1117
+ const queuedTime = micros(request.ts - baseTime);
1118
+ const requestSentTime = micros(syntheticData.sendStartTime - baseTime);
1119
+ const downloadCompleteTime = micros(syntheticData.finishTime - baseTime);
1120
+ const processingCompleteTime = micros(request.ts + request.dur - baseTime);
1121
+ const totalDuration = micros(request.dur);
1122
+ const downloadDuration = micros(syntheticData.finishTime - syntheticData.downloadStart);
1123
+ const mainThreadProcessingDuration = micros(request.ts + request.dur - syntheticData.finishTime);
1133
1124
  const renderBlocking = Trace.Helpers.Network.isSyntheticNetworkRequestEventRenderBlocking(request) ? 't' : 'f';
1134
1125
  const finalPriority = priority;
1135
1126
  const headerValues = responseHeaders
@@ -1142,8 +1133,8 @@ The order of headers corresponds to an internal fixed list. If a header is not p
1142
1133
  const redirects = request.args.data.redirects
1143
1134
  .map(redirect => {
1144
1135
  const urlIndex = TraceEventFormatter.#getOrAssignUrlIndex(urlIdToIndex, redirect.url);
1145
- const redirectStartTime = formatters.micros(redirect.ts - baseTime);
1146
- const redirectDuration = formatters.micros(redirect.dur);
1136
+ const redirectStartTime = micros(redirect.ts - baseTime);
1137
+ const redirectDuration = micros(redirect.dur);
1147
1138
  return `[${urlIndex}|${redirectStartTime}|${redirectDuration}]`;
1148
1139
  })
1149
1140
  .join(',');