chrome-devtools-frontend 1.0.1514545 → 1.0.1515446

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 (77) hide show
  1. package/AUTHORS +1 -0
  2. package/docs/committers_policy.md +1 -1
  3. package/docs/contributing/infrastructure.md +101 -5
  4. package/front_end/Images/gdp-logo-dark.png +0 -0
  5. package/front_end/Images/gdp-logo-light.png +0 -0
  6. package/front_end/core/common/Settings.ts +11 -32
  7. package/front_end/global_typings/global_defs.d.ts +15 -1
  8. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +22 -23
  9. package/front_end/models/ai_assistance/agents/PerformanceAnnotationsAgent.ts +6 -7
  10. package/front_end/models/ai_assistance/ai_assistance.ts +3 -0
  11. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +77 -2
  12. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +76 -10
  13. package/front_end/models/cpu_profile/ProfileTreeModel.ts +1 -1
  14. package/front_end/models/extensions/ExtensionPanel.ts +4 -0
  15. package/front_end/models/heap_snapshot_model/HeapSnapshotModel.ts +5 -1
  16. package/front_end/models/trace/helpers/Trace.ts +1 -1
  17. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +6 -7
  18. package/front_end/panels/ai_assistance/components/ChatView.ts +1 -2
  19. package/front_end/panels/common/GdpSignUpDialog.ts +2 -6
  20. package/front_end/panels/common/gdpSignUpDialog.css +6 -14
  21. package/front_end/panels/console/ConsoleView.ts +4 -0
  22. package/front_end/panels/elements/ElementsPanel.ts +4 -0
  23. package/front_end/panels/elements/StylePropertiesSection.ts +4 -4
  24. package/front_end/panels/network/NetworkConfigView.ts +1 -1
  25. package/front_end/panels/network/NetworkLogView.ts +2 -2
  26. package/front_end/panels/network/components/HeaderSectionRow.ts +2 -3
  27. package/front_end/panels/profiler/HeapProfileView.ts +1 -3
  28. package/front_end/panels/profiler/HeapSnapshotView.ts +5 -1
  29. package/front_end/panels/profiler/ProfileDataGrid.ts +4 -0
  30. package/front_end/panels/profiler/ProfileFlameChartDataProvider.ts +7 -29
  31. package/front_end/panels/profiler/ProfileView.ts +4 -0
  32. package/front_end/panels/recorder/components/CreateRecordingView.ts +2 -2
  33. package/front_end/panels/search/SearchView.ts +219 -205
  34. package/front_end/panels/settings/KeybindsSettingsTab.ts +1 -1
  35. package/front_end/panels/settings/SettingsScreen.ts +1 -1
  36. package/front_end/panels/settings/components/SyncSection.ts +2 -6
  37. package/front_end/panels/settings/components/syncSection.css +11 -4
  38. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +3 -3
  39. package/front_end/panels/sources/SourcesView.ts +4 -0
  40. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +2 -2
  41. package/front_end/panels/timeline/CompatibilityTracksAppender.ts +6 -3
  42. package/front_end/panels/timeline/CountersGraph.ts +5 -5
  43. package/front_end/panels/timeline/TimelineDetailsView.ts +2 -2
  44. package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +4 -3
  45. package/front_end/panels/timeline/TimelineFlameChartView.ts +9 -4
  46. package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -2
  47. package/front_end/panels/timeline/TimelinePanel.ts +4 -3
  48. package/front_end/panels/timeline/TimelineTreeView.ts +6 -2
  49. package/front_end/panels/timeline/TimelineUIUtils.ts +2 -1
  50. package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +2 -2
  51. package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +6 -6
  52. package/front_end/panels/timeline/overlays/OverlaysImpl.ts +2 -2
  53. package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -3
  54. package/front_end/panels/timeline/utils/utils.ts +0 -8
  55. package/front_end/{panels/timeline/utils → services/tracing}/FreshRecording.ts +1 -1
  56. package/front_end/services/tracing/tracing.ts +2 -0
  57. package/front_end/ui/legacy/Dialog.ts +38 -13
  58. package/front_end/ui/legacy/InspectorView.ts +7 -9
  59. package/front_end/ui/legacy/SearchableView.ts +73 -55
  60. package/front_end/ui/legacy/SettingsUI.ts +5 -5
  61. package/front_end/ui/legacy/components/color_picker/Spectrum.ts +1 -4
  62. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +5 -5
  63. package/front_end/ui/legacy/components/perf_ui/ChartViewport.ts +2 -2
  64. package/front_end/ui/legacy/components/perf_ui/FilmStripView.ts +2 -2
  65. package/front_end/ui/legacy/components/perf_ui/LineLevelProfile.ts +1 -4
  66. package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +3 -3
  67. package/front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.ts +2 -2
  68. package/front_end/ui/legacy/components/source_frame/JSONView.ts +10 -10
  69. package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +4 -0
  70. package/front_end/ui/legacy/components/source_frame/XMLView.ts +4 -0
  71. package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -4
  72. package/front_end/ui/legacy/searchableView.css +0 -4
  73. package/package.json +1 -1
  74. package/front_end/Images/src/gdp-logo-standalone.svg +0 -9
  75. /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AICallTree.ts +0 -0
  76. /package/front_end/{panels/timeline/utils → models/ai_assistance/performance}/AIContext.ts +0 -0
  77. /package/front_end/{panels/timeline/utils/InsightAIContext.ts → models/ai_assistance/performance/AIQueries.ts} +0 -0
@@ -830,11 +830,13 @@ URL: https://web.dev/cls/
830
830
  Bounds: {min: 1020034823047, max: 1020036087961}
831
831
  CPU throttling: none
832
832
  Network throttling: none
833
- Metrics:
833
+ Metrics (lab / observed):
834
834
  - LCP: 118 ms, event: (eventKey: r-1802, ts: 1020034953358)
835
+ - LCP breakdown:
835
836
  - TTFB: 31.3 ms, bounds: {min: 1020034834921, max: 1020034866264}
836
837
  - Render delay: 87.1 ms, bounds: {min: 1020034866264, max: 1020034953358}
837
838
  - CLS: 0.00
839
+ Metrics (field / real users): n/a – no data for this page in CrUX
838
840
  Available insights:
839
841
  - insight name: LCPBreakdown
840
842
  description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
@@ -861,13 +863,15 @@ URL: https://news.yahoo.com/
861
863
  Bounds: {min: 157423484442, max: 157427277166}
862
864
  CPU throttling: none
863
865
  Network throttling: none
864
- Metrics:
866
+ Metrics (lab / observed):
865
867
  - LCP: 464 ms, event: (eventKey: r-33210, ts: 157423953162)
868
+ - LCP breakdown:
866
869
  - TTFB: 215.7 ms, bounds: {min: 157423488682, max: 157423704371}
867
870
  - Load delay: 90.3 ms, bounds: {min: 157423704371, max: 157423794709}
868
871
  - Load duration: 64 ms, bounds: {min: 157423794709, max: 157423858674}
869
872
  - Render delay: 94.5 ms, bounds: {min: 157423858674, max: 157423953162}
870
873
  - CLS: 0.04, event: (eventKey: s--1, ts: 157425604232)
874
+ Metrics (field / real users): n/a – no data for this page in CrUX
871
875
  Available insights:
872
876
  - insight name: LCPBreakdown
873
877
  description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
@@ -914,3 +918,74 @@ Available insights:
914
918
  example question: Is my site polyfilling modern JavaScript features?
915
919
  example question: How can I reduce the amount of legacy JavaScript on my page?
916
920
  === end content
921
+
922
+ Title: PerformanceTraceFormatter formatTraceSummary image-delivery.json.gz
923
+ Content:
924
+ URL: http://localhost/image-delivery-cases.html
925
+ Bounds: {min: 59728641874, max: 59734400108}
926
+ CPU throttling: 1x
927
+ Network throttling: No throttling
928
+ Metrics (lab / observed):
929
+ - LCP: 663 ms, event: (eventKey: r-14753, ts: 59729312744)
930
+ - LCP breakdown:
931
+ - TTFB: 7 ms, bounds: {min: 59728649746, max: 59728656735}
932
+ - Load delay: 45.6 ms, bounds: {min: 59728656735, max: 59728702313}
933
+ - Load duration: 506.3 ms, bounds: {min: 59728702313, max: 59729208600}
934
+ - Render delay: 104.1 ms, bounds: {min: 59729208600, max: 59729312744}
935
+ - CLS: 0.31, event: (eventKey: s--1, ts: 59729100192)
936
+ Metrics (field / real users):
937
+ - LCP: 1740 ms (scope: url)
938
+ - INP: 185 ms (scope: url)
939
+ - CLS: 0.08 (scope: url)
940
+ - The above data is from CrUX–Chrome User Experience Report. It's how the page performs for real users.
941
+ - The values shown above are the p75 measure of all real Chrome users
942
+ - The scope indicates if the data came from the entire origin, or a specific url
943
+ - Lab metrics describe how this specific page load performed, while field metrics are an aggregation of results from real-world users. Best practice is to prioritize metrics that are bad in field data. Lab metrics may be better or worse than fields metrics depending on the developer's machine, network, or the actions performed while tracing.
944
+ Available insights:
945
+ - insight name: Cache
946
+ description: A long cache lifetime can speed up repeat visits to your page. [Learn more](https://web.dev/uses-long-cache-ttl/).
947
+ relevant trace bounds: {min: 59728702014, max: 59728867430}
948
+ estimated metric savings: FCP 0 ms, LCP 150 ms
949
+ estimated wasted bytes: 971.5 kB
950
+ example question: What caching strategies can I apply to improve my page performance?
951
+ - insight name: ImageDelivery
952
+ description: Reducing the download time of images can improve the perceived load time of the page and LCP. [Learn more about optimizing image size](https://developer.chrome.com/docs/lighthouse/performance/uses-optimized-images/)
953
+ relevant trace bounds: {min: 59728701403, max: 59729395208}
954
+ estimated metric savings: FCP 0 ms, LCP 100 ms
955
+ estimated wasted bytes: 2 MB
956
+ example question: What should I do to improve and optimize the time taken to fetch and display images on the page?
957
+ example question: Are all images on my site optimized?
958
+ - insight name: LCPBreakdown
959
+ description: Each [subpart has specific improvement strategies](https://web.dev/articles/optimize-lcp#lcp-breakdown). Ideally, most of the LCP time should be spent on loading the resources, not within delays.
960
+ relevant trace bounds: {min: 59728649746, max: 59729312744}
961
+ example question: Help me optimize my LCP score
962
+ example question: Which LCP phase was most problematic?
963
+ example question: What can I do to reduce the LCP time for this page load?
964
+ - insight name: LCPDiscovery
965
+ description: Optimize LCP by making the LCP image [discoverable](https://web.dev/articles/optimize-lcp#1_eliminate_resource_load_delay) from the HTML immediately, and [avoiding lazy-loading](https://web.dev/articles/lcp-lazy-loading)
966
+ relevant trace bounds: {min: 59728656735, max: 59729209036}
967
+ example question: Suggest fixes to reduce my LCP
968
+ example question: What can I do to reduce my LCP discovery time?
969
+ example question: Why is LCP discovery time important?
970
+ - insight name: CLSCulprits
971
+ description: Layout shifts occur when elements move absent any user interaction. [Investigate the causes of layout shifts](https://web.dev/articles/optimize-cls), such as elements being added, removed, or their fonts changing as the page loads.
972
+ relevant trace bounds: {min: 59729100192, max: 59730317334}
973
+ example question: Help me optimize my CLS score
974
+ example question: How can I prevent layout shifts on this page?
975
+ - insight name: DocumentLatency
976
+ description: Your first network request is the most important. Reduce its latency by avoiding redirects, ensuring a fast server response, and enabling text compression.
977
+ relevant trace bounds: {min: 59728651057, max: 59728790724}
978
+ estimated metric savings: FCP 0 ms, LCP 0 ms
979
+ estimated wasted bytes: 1.6 kB
980
+ example question: How do I decrease the initial loading time of my page?
981
+ example question: Did anything slow down the request for this document?
982
+ - insight name: Viewport
983
+ description: Tap interactions may be [delayed by up to 300 ms](https://developer.chrome.com/blog/300ms-tap-delay-gone-away/) if the viewport is not optimized for mobile.
984
+ relevant trace bounds: {min: 59728649746, max: 59734400108}
985
+ estimated metric savings: INP 0 ms
986
+ example question: How do I make sure my page is optimized for mobile viewing?
987
+ - insight name: ThirdParties
988
+ description: 3rd party code can significantly impact load performance. [Reduce and defer loading of 3rd party code](https://web.dev/articles/optimizing-content-efficiency-loading-third-party-javascript/) to prioritize your page's content.
989
+ relevant trace bounds: {min: 59728701403, max: 59729465969}
990
+ example question: Which third parties are having the largest impact on my page performance?
991
+ === end content
@@ -2,8 +2,11 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import * as TimelineUtils from '../../../panels/timeline/utils/utils.js';
5
+ import * as CrUXManager from '../../crux-manager/crux-manager.js';
6
6
  import * as Trace from '../../trace/trace.js';
7
+ import type {AICallTree} from '../performance/AICallTree.js';
8
+ import type {AgentFocus} from '../performance/AIContext.js';
9
+ import {AIQueries} from '../performance/AIQueries.js';
7
10
 
8
11
  import {PerformanceInsightFormatter, TraceEventFormatter} from './PerformanceInsightFormatter.js';
9
12
  import {bytes, micros, millis} from './UnitFormatters.js';
@@ -13,7 +16,7 @@ export class PerformanceTraceFormatter {
13
16
  #insightSet: Trace.Insights.Types.InsightSet|null;
14
17
  #eventsSerializer: Trace.EventsSerializer.EventsSerializer;
15
18
 
16
- constructor(focus: TimelineUtils.AIContext.AgentFocus, eventsSerializer: Trace.EventsSerializer.EventsSerializer) {
19
+ constructor(focus: AgentFocus, eventsSerializer: Trace.EventsSerializer.EventsSerializer) {
17
20
  this.#parsedTrace = focus.data.parsedTrace;
18
21
  this.#insightSet = focus.data.insightSet;
19
22
  this.#eventsSerializer = eventsSerializer;
@@ -45,7 +48,7 @@ export class PerformanceTraceFormatter {
45
48
  parts.push('CPU throttling: ' + (traceMetadata.cpuThrottling ? `${traceMetadata.cpuThrottling}x` : 'none'));
46
49
  parts.push(`Network throttling: ${traceMetadata.networkThrottling ?? 'none'}`);
47
50
  if (lcp || cls || inp) {
48
- parts.push('Metrics:');
51
+ parts.push('Metrics (lab / observed):');
49
52
  if (lcp) {
50
53
  parts.push(` - LCP: ${Math.round(lcp.value / 1000)} ms, event: ${this.serializeEvent(lcp.event)}`);
51
54
  const subparts = insightSet?.model.LCPBreakdown.subparts;
@@ -53,6 +56,7 @@ export class PerformanceTraceFormatter {
53
56
  const serializeSubpart = (subpart: Trace.Insights.Models.LCPBreakdown.Subpart): string => {
54
57
  return `${micros(subpart.range)}, bounds: ${this.serializeBounds(subpart)}`;
55
58
  };
59
+ parts.push(' - LCP breakdown:');
56
60
  parts.push(` - TTFB: ${serializeSubpart(subparts.ttfb)}`);
57
61
  if (subparts.loadDelay !== undefined) {
58
62
  parts.push(` - Load delay: ${serializeSubpart(subparts.loadDelay)}`);
@@ -71,7 +75,69 @@ export class PerformanceTraceFormatter {
71
75
  parts.push(` - CLS: ${cls.value.toFixed(2)}${eventText}`);
72
76
  }
73
77
  } else {
74
- parts.push('Metrics: n/a');
78
+ parts.push('Metrics (lab / observed): n/a');
79
+ }
80
+
81
+ const fieldMetrics = insightSet &&
82
+ Trace.Insights.Common.getFieldMetricsForInsightSet(
83
+ insightSet, traceMetadata, CrUXManager.CrUXManager.instance().getSelectedScope());
84
+ const fieldLcp = fieldMetrics?.lcp;
85
+ const fieldInp = fieldMetrics?.inp;
86
+ const fieldCls = fieldMetrics?.cls;
87
+
88
+ if (fieldLcp || fieldInp || fieldCls) {
89
+ parts.push('Metrics (field / real users):');
90
+
91
+ const serializeFieldMetricTimingResult =
92
+ (fieldMetric: Trace.Insights.Common.CrUXFieldMetricTimingResult): string => {
93
+ return `${Math.round(fieldMetric.value / 1000)} ms (scope: ${fieldMetric.pageScope})`;
94
+ };
95
+
96
+ const serializeFieldMetricNumberResult =
97
+ (fieldMetric: Trace.Insights.Common.CrUXFieldMetricNumberResult): string => {
98
+ return `${fieldMetric.value.toFixed(2)} (scope: ${fieldMetric.pageScope})`;
99
+ };
100
+
101
+ if (fieldLcp) {
102
+ parts.push(` - LCP: ${serializeFieldMetricTimingResult(fieldLcp)}`);
103
+
104
+ const fieldLcpBreakdown = fieldMetrics?.lcpBreakdown;
105
+ if (fieldLcpBreakdown &&
106
+ (fieldLcpBreakdown.ttfb || fieldLcpBreakdown.loadDelay || fieldLcpBreakdown.loadDuration ||
107
+ fieldLcpBreakdown.renderDelay)) {
108
+ parts.push(' - LCP breakdown:');
109
+ if (fieldLcpBreakdown.ttfb) {
110
+ parts.push(` - TTFB: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.ttfb)}`);
111
+ }
112
+ if (fieldLcpBreakdown.loadDelay) {
113
+ parts.push(` - Load delay: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.loadDelay)}`);
114
+ }
115
+ if (fieldLcpBreakdown.loadDuration) {
116
+ parts.push(` - Load duration: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.loadDuration)}`);
117
+ }
118
+ if (fieldLcpBreakdown.renderDelay) {
119
+ parts.push(` - Render delay: ${serializeFieldMetricTimingResult(fieldLcpBreakdown.renderDelay)}`);
120
+ }
121
+ }
122
+ }
123
+ if (fieldInp) {
124
+ parts.push(` - INP: ${serializeFieldMetricTimingResult(fieldInp)}`);
125
+ }
126
+ if (fieldCls) {
127
+ parts.push(` - CLS: ${serializeFieldMetricNumberResult(fieldCls)}`);
128
+ }
129
+
130
+ parts.push(
131
+ ' - The above data is from CrUX–Chrome User Experience Report. It\'s how the page performs for real users.');
132
+ parts.push(' - The values shown above are the p75 measure of all real Chrome users');
133
+ parts.push(' - The scope indicates if the data came from the entire origin, or a specific url');
134
+ parts.push(
135
+ ' - Lab metrics describe how this specific page load performed, while field metrics are an aggregation ' +
136
+ 'of results from real-world users. Best practice is to prioritize metrics that are bad in field data. ' +
137
+ 'Lab metrics may be better or worse than fields metrics depending on the developer\'s machine, network, or the ' +
138
+ 'actions performed while tracing.');
139
+ } else {
140
+ parts.push('Metrics (field / real users): n/a – no data for this page in CrUX');
75
141
  }
76
142
 
77
143
  if (insightSet) {
@@ -176,7 +242,7 @@ export class PerformanceTraceFormatter {
176
242
  const insightSet = this.#insightSet;
177
243
 
178
244
  const bounds = parsedTrace.data.Meta.traceBounds;
179
- const rootNode = TimelineUtils.InsightAIContext.AIQueries.mainThreadActivityBottomUp(
245
+ const rootNode = AIQueries.mainThreadActivityBottomUp(
180
246
  insightSet?.navigation?.args.data?.navigationId,
181
247
  bounds,
182
248
  parsedTrace,
@@ -229,8 +295,8 @@ export class PerformanceTraceFormatter {
229
295
  const insightSet = this.#insightSet;
230
296
 
231
297
  const bounds = parsedTrace.data.Meta.traceBounds;
232
- const longestTaskTrees = TimelineUtils.InsightAIContext.AIQueries.longestTasks(
233
- insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
298
+ const longestTaskTrees =
299
+ AIQueries.longestTasks(insightSet?.navigation?.args.data?.navigationId, bounds, parsedTrace, 3);
234
300
  if (!longestTaskTrees || longestTaskTrees.length === 0) {
235
301
  return 'Longest tasks: none';
236
302
  }
@@ -288,7 +354,7 @@ export class PerformanceTraceFormatter {
288
354
  formatMainThreadTrackSummary(bounds: Trace.Types.Timing.TraceWindowMicro): string {
289
355
  const results = [];
290
356
 
291
- const topDownTree = TimelineUtils.InsightAIContext.AIQueries.mainThreadActivityTopDown(
357
+ const topDownTree = AIQueries.mainThreadActivityTopDown(
292
358
  this.#insightSet?.navigation?.args.data?.navigationId,
293
359
  bounds,
294
360
  this.#parsedTrace,
@@ -298,7 +364,7 @@ export class PerformanceTraceFormatter {
298
364
  results.push(this.formatCallTree(topDownTree, 2 /* headerLevel */));
299
365
  }
300
366
 
301
- const bottomUpRootNode = TimelineUtils.InsightAIContext.AIQueries.mainThreadActivityBottomUp(
367
+ const bottomUpRootNode = AIQueries.mainThreadActivityBottomUp(
302
368
  this.#insightSet?.navigation?.args.data?.navigationId,
303
369
  bounds,
304
370
  this.#parsedTrace,
@@ -349,7 +415,7 @@ export class PerformanceTraceFormatter {
349
415
  return results.join('\n\n');
350
416
  }
351
417
 
352
- formatCallTree(tree: TimelineUtils.AICallTree.AICallTree, headerLevel = 1): string {
418
+ formatCallTree(tree: AICallTree, headerLevel = 1): string {
353
419
  const results = [tree.serialize(headerLevel), ''];
354
420
 
355
421
  // TODO(b/425270067): add eventKey to tree.serialize, but need to wait for other
@@ -12,7 +12,7 @@ export class ProfileNode {
12
12
  total: number;
13
13
  id: number;
14
14
  parent: ProfileNode|null;
15
- children: ProfileNode[];
15
+ children: this[];
16
16
  functionName: string;
17
17
  depth!: number;
18
18
  deoptReason!: string|null;
@@ -69,6 +69,10 @@ export class ExtensionPanel extends UI.Panel.Panel implements UI.SearchableView.
69
69
  return false;
70
70
  }
71
71
 
72
+ supportsWholeWordSearch(): boolean {
73
+ return false;
74
+ }
75
+
72
76
  supportsRegexSearch(): boolean {
73
77
  return false;
74
78
  }
@@ -239,12 +239,16 @@ export class NodeFilter {
239
239
  export class SearchConfig {
240
240
  query: string;
241
241
  caseSensitive: boolean;
242
+ wholeWord: boolean;
242
243
  isRegex: boolean;
243
244
  shouldJump: boolean;
244
245
  jumpBackward: boolean;
245
- constructor(query: string, caseSensitive: boolean, isRegex: boolean, shouldJump: boolean, jumpBackward: boolean) {
246
+ constructor(
247
+ query: string, caseSensitive: boolean, wholeWord: boolean, isRegex: boolean, shouldJump: boolean,
248
+ jumpBackward: boolean) {
246
249
  this.query = query;
247
250
  this.caseSensitive = caseSensitive;
251
+ this.wholeWord = wholeWord;
248
252
  this.isRegex = isRegex;
249
253
  this.shouldJump = shouldJump;
250
254
  this.jumpBackward = jumpBackward;
@@ -766,7 +766,7 @@ export function extractSampleTraceId(event: Types.Events.Event): number|null {
766
766
  return event.args?.sampleTraceId ?? event.args?.data?.sampleTraceId ?? null;
767
767
  }
768
768
 
769
- // This exactly matches EntryStyles.visibleTypes. See the runtime verification in maybeInitSylesMap.
769
+ // This exactly matches Trace.Styles.visibleTypes. See the runtime verification in maybeInitStylesMap.
770
770
  // TODO(crbug.com/410884528)
771
771
  export const VISIBLE_TRACE_EVENT_TYPES = new Set<Types.Events.Name>([
772
772
  Types.Events.Name.ABORT_POST_TASK_CALLBACK,
@@ -22,7 +22,6 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
22
22
  import * as NetworkForward from '../network/forward/forward.js';
23
23
  import * as NetworkPanel from '../network/network.js';
24
24
  import * as TimelinePanel from '../timeline/timeline.js';
25
- import * as TimelineUtils from '../timeline/utils/utils.js';
26
25
 
27
26
  import aiAssistancePanelStyles from './aiAssistancePanel.css.js';
28
27
  import {
@@ -275,7 +274,7 @@ async function getEmptyStateSuggestions(
275
274
  ];
276
275
  case AiAssistanceModel.ConversationType.PERFORMANCE_INSIGHT:
277
276
  case AiAssistanceModel.ConversationType.PERFORMANCE_CALL_TREE: {
278
- const focus = context?.getItem() as TimelineUtils.AIContext.AgentFocus | null;
277
+ const focus = context?.getItem() as AiAssistanceModel.AgentFocus | null;
279
278
  if (focus?.data.type === 'call-tree') {
280
279
  return [
281
280
  {title: 'What\'s the purpose of this work?', jslogContext: 'performance-default'},
@@ -433,7 +432,7 @@ function createRequestContext(request: SDK.NetworkRequest.NetworkRequest|null):
433
432
  return new AiAssistanceModel.RequestContext(request, calculator);
434
433
  }
435
434
 
436
- function createPerformanceTraceContext(focus: TimelineUtils.AIContext.AgentFocus|null):
435
+ function createPerformanceTraceContext(focus: AiAssistanceModel.AgentFocus|null):
437
436
  AiAssistanceModel.PerformanceTraceContext|null {
438
437
  if (!focus) {
439
438
  return null;
@@ -710,7 +709,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
710
709
  this.#selectedRequest =
711
710
  createRequestContext(UI.Context.Context.instance().flavor(SDK.NetworkRequest.NetworkRequest));
712
711
  this.#selectedPerformanceTrace =
713
- createPerformanceTraceContext(UI.Context.Context.instance().flavor(TimelineUtils.AIContext.AgentFocus));
712
+ createPerformanceTraceContext(UI.Context.Context.instance().flavor(AiAssistanceModel.AgentFocus));
714
713
  this.#selectedFile = createFileContext(UI.Context.Context.instance().flavor(Workspace.UISourceCode.UISourceCode));
715
714
  this.#updateConversationState({agent: this.#conversationAgent});
716
715
 
@@ -723,7 +722,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
723
722
  UI.Context.Context.instance().addFlavorChangeListener(
724
723
  SDK.NetworkRequest.NetworkRequest, this.#handleNetworkRequestFlavorChange);
725
724
  UI.Context.Context.instance().addFlavorChangeListener(
726
- TimelineUtils.AIContext.AgentFocus, this.#handlePerformanceTraceFlavorChange);
725
+ AiAssistanceModel.AgentFocus, this.#handlePerformanceTraceFlavorChange);
727
726
  UI.Context.Context.instance().addFlavorChangeListener(
728
727
  Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
729
728
 
@@ -760,7 +759,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
760
759
  UI.Context.Context.instance().removeFlavorChangeListener(
761
760
  SDK.NetworkRequest.NetworkRequest, this.#handleNetworkRequestFlavorChange);
762
761
  UI.Context.Context.instance().removeFlavorChangeListener(
763
- TimelineUtils.AIContext.AgentFocus, this.#handlePerformanceTraceFlavorChange);
762
+ AiAssistanceModel.AgentFocus, this.#handlePerformanceTraceFlavorChange);
764
763
  UI.Context.Context.instance().removeFlavorChangeListener(
765
764
  Workspace.UISourceCode.UISourceCode, this.#handleUISourceCodeFlavorChange);
766
765
  UI.ViewManager.ViewManager.instance().removeEventListener(
@@ -838,7 +837,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
838
837
  };
839
838
 
840
839
  #handlePerformanceTraceFlavorChange =
841
- (ev: Common.EventTarget.EventTargetEvent<TimelineUtils.AIContext.AgentFocus>): void => {
840
+ (ev: Common.EventTarget.EventTargetEvent<AiAssistanceModel.AgentFocus>): void => {
842
841
  if (this.#selectedPerformanceTrace?.getItem() === ev.data) {
843
842
  return;
844
843
  }
@@ -14,7 +14,6 @@ import * as SDK from '../../../core/sdk/sdk.js';
14
14
  import * as AiAssistanceModel from '../../../models/ai_assistance/ai_assistance.js';
15
15
  import * as Workspace from '../../../models/workspace/workspace.js';
16
16
  import * as ElementsPanel from '../../../panels/elements/elements.js';
17
- import * as TimelineUtils from '../../../panels/timeline/utils/utils.js';
18
17
  import * as PanelUtils from '../../../panels/utils/utils.js';
19
18
  import * as Marked from '../../../third_party/marked/marked.js';
20
19
  import * as Buttons from '../../../ui/components/buttons/buttons.js';
@@ -1040,7 +1039,7 @@ function renderContextIcon(context: AiAssistanceModel.ConversationContext<unknow
1040
1039
  if (item instanceof Workspace.UISourceCode.UISourceCode) {
1041
1040
  return PanelUtils.PanelUtils.getIconForSourceFile(item);
1042
1041
  }
1043
- if (item instanceof TimelineUtils.AIContext.AgentFocus) {
1042
+ if (item instanceof AiAssistanceModel.AgentFocus) {
1044
1043
  return html`<devtools-icon name="performance" title="Performance"></devtools-icon>`;
1045
1044
  }
1046
1045
  if (item instanceof SDK.DOMModel.DOMNode) {
@@ -19,10 +19,6 @@ import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
19
19
  import styles from './gdpSignUpDialog.css.js';
20
20
 
21
21
  const UIStrings = {
22
- /**
23
- * @description Heading of the Google Developer Program sign up dialog.
24
- */
25
- gdpSignUp: 'Google Developer Program',
26
22
  /**
27
23
  * @description Aria label for the Google Developer Program sign up dialog
28
24
  */
@@ -110,7 +106,7 @@ export const DEFAULT_VIEW: View = (input, _output, target): void => {
110
106
  render(
111
107
  html`
112
108
  <style>${styles}</style>
113
- <h2 class="gdp-sign-up-dialog-header">${i18nString(UIStrings.gdpSignUp)}</h2>
109
+ <div class="gdp-sign-up-dialog-header"></div>
114
110
  <div class="main-content">
115
111
  <div class="section">
116
112
  <div class="icon-container">
@@ -239,6 +235,6 @@ export class GdpSignUpDialog extends UI.Widget.VBox {
239
235
  dialog.setDimmed(true);
240
236
 
241
237
  new GdpSignUpDialog({dialog}).show(dialog.contentElement);
242
- dialog.show();
238
+ dialog.show(undefined, /* stack */ true);
243
239
  }
244
240
  }
@@ -12,23 +12,15 @@
12
12
  }
13
13
 
14
14
  .gdp-sign-up-dialog-header {
15
- font: var(--sys-typescale-headline5);
16
- color: var(--sys-color-on-surface);
17
- display: flex;
18
- align-items: center;
15
+ background-image: var(--image-file-gdp-logo-light);
16
+ height: 20px;
17
+ background-repeat: no-repeat;
18
+ background-size: contain;
19
19
  margin: 0;
20
20
  }
21
21
 
22
- .gdp-sign-up-dialog-header::before {
23
- content: '';
24
- background-image: var(--image-file-gdp-logo-standalone);
25
- display: inline-block;
26
- width: 34px;
27
- height: 15px;
28
- background-size: contain;
29
- background-repeat: no-repeat;
30
- background-position: center;
31
- margin-right: var(--sys-size-6);
22
+ :host-context(.theme-with-dark-background) & .gdp-sign-up-dialog-header {
23
+ background-image: var(--image-file-gdp-logo-dark);
32
24
  }
33
25
 
34
26
  .main-content {
@@ -1592,6 +1592,10 @@ export class ConsoleView extends UI.Widget.VBox implements
1592
1592
  return true;
1593
1593
  }
1594
1594
 
1595
+ supportsWholeWordSearch(): boolean {
1596
+ return true;
1597
+ }
1598
+
1595
1599
  supportsRegexSearch(): boolean {
1596
1600
  return true;
1597
1601
  }
@@ -713,6 +713,10 @@ export class ElementsPanel extends UI.Panel.Panel implements UI.SearchableView.S
713
713
  return false;
714
714
  }
715
715
 
716
+ supportsWholeWordSearch(): boolean {
717
+ return false;
718
+ }
719
+
716
720
  supportsRegexSearch(): boolean {
717
721
  return false;
718
722
  }
@@ -544,8 +544,8 @@ export class StylePropertiesSection {
544
544
  }
545
545
  }
546
546
 
547
- private onKeyDown(event: Event): void {
548
- const keyboardEvent = (event as KeyboardEvent);
547
+ private onKeyDown(event: KeyboardEvent): void {
548
+ const keyboardEvent = event;
549
549
  if (UI.UIUtils.isEditing() || !this.editable || keyboardEvent.altKey || keyboardEvent.ctrlKey ||
550
550
  keyboardEvent.metaKey) {
551
551
  return;
@@ -1367,12 +1367,12 @@ export class StylePropertiesSection {
1367
1367
  private editingMediaTextCommittedForTest(): void {
1368
1368
  }
1369
1369
 
1370
- private handleSelectorClick(event: Event): void {
1370
+ private handleSelectorClick(event: MouseEvent): void {
1371
1371
  const target = (event.target as Element | null);
1372
1372
  if (!target) {
1373
1373
  return;
1374
1374
  }
1375
- if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey((event as MouseEvent)) && this.navigable &&
1375
+ if (UI.KeyboardShortcut.KeyboardShortcut.eventHasCtrlEquivalentKey(event) && this.navigable &&
1376
1376
  target.classList.contains('simple-selector')) {
1377
1377
  const selectorIndex = this.elementToSelectorIndex.get(target);
1378
1378
  if (selectorIndex) {
@@ -274,7 +274,7 @@ export class NetworkConfigView extends UI.Widget.VBox {
274
274
  userAgentUpdateButtonStatusText.textContent = '';
275
275
  });
276
276
 
277
- clientHints.addEventListener('clienthintssubmit', (event: Event) => {
277
+ clientHints.addEventListener('clienthintssubmit', event => {
278
278
  const metaData: Protocol.Emulation.UserAgentMetadata = (event as CustomEvent).detail.value;
279
279
  const customUA = customUserAgentSetting.get();
280
280
  userAgentMetadataSetting.set(metaData);
@@ -1166,8 +1166,8 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
1166
1166
  return this.dataGrid;
1167
1167
  }
1168
1168
 
1169
- private dataGridMouseMove(event: Event): void {
1170
- const mouseEvent = (event as MouseEvent);
1169
+ private dataGridMouseMove(event: MouseEvent): void {
1170
+ const mouseEvent = event;
1171
1171
  const node = (this.dataGrid.dataGridNodeFromNode((mouseEvent.target as Node)));
1172
1172
  const highlightInitiatorChain = mouseEvent.shiftKey;
1173
1173
  this.setHoveredNode(node as NetworkNode, highlightInitiatorChain);
@@ -400,10 +400,9 @@ export class HeaderSectionRow extends HTMLElement {
400
400
  this.dispatchEvent(new HeaderRemovedEvent(this.#header.name, this.#header.value || ''));
401
401
  }
402
402
 
403
- #onKeyDown(event: Event): void {
404
- const keyboardEvent = event as KeyboardEvent;
403
+ #onKeyDown(event: KeyboardEvent): void {
405
404
  const target = event.target as EditableSpan;
406
- if (keyboardEvent.key === 'Escape') {
405
+ if (event.key === 'Escape') {
407
406
  event.consume();
408
407
  if (target.matches('.header-name devtools-editable-span')) {
409
408
  target.value = this.#header?.name || '';
@@ -303,9 +303,7 @@ export class SamplingHeapProfileTypeBase extends
303
303
  const profile = await this.stopSampling();
304
304
  if (recordedProfile) {
305
305
  console.assert(profile !== undefined);
306
- // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration)
307
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
308
- recordedProfile.setProtocolProfile((profile as any));
306
+ recordedProfile.setProtocolProfile(profile as unknown as Protocol.Profiler.Profile);
309
307
  recordedProfile.updateStatus('');
310
308
  this.setProfileBeingRecorded(null);
311
309
  }
@@ -622,6 +622,10 @@ export class HeapSnapshotView extends UI.View.SimpleView implements DataDisplayD
622
622
  return true;
623
623
  }
624
624
 
625
+ supportsWholeWordSearch(): boolean {
626
+ return false;
627
+ }
628
+
625
629
  supportsRegexSearch(): boolean {
626
630
  return false;
627
631
  }
@@ -639,7 +643,7 @@ export class HeapSnapshotView extends UI.View.SimpleView implements DataDisplayD
639
643
 
640
644
  performSearch(searchConfig: UI.SearchableView.SearchConfig, shouldJump: boolean, jumpBackwards?: boolean): void {
641
645
  const nextQuery = new HeapSnapshotModel.HeapSnapshotModel.SearchConfig(
642
- searchConfig.query.trim(), searchConfig.caseSensitive, searchConfig.isRegex, shouldJump,
646
+ searchConfig.query.trim(), searchConfig.caseSensitive, searchConfig.wholeWord, searchConfig.isRegex, shouldJump,
643
647
  jumpBackwards || false);
644
648
 
645
649
  void this.searchThrottler.schedule(this.performSearchInternal.bind(this, nextQuery));
@@ -641,6 +641,10 @@ export class ProfileDataGridTree implements UI.SearchableView.Searchable {
641
641
  return true;
642
642
  }
643
643
 
644
+ supportsWholeWordSearch(): boolean {
645
+ return false;
646
+ }
647
+
644
648
  supportsRegexSearch(): boolean {
645
649
  return false;
646
650
  }
@@ -1,32 +1,6 @@
1
- /**
2
- * Copyright (C) 2014 Google Inc. All rights reserved.
3
- *
4
- * Redistribution and use in source and binary forms, with or without
5
- * modification, are permitted provided that the following conditions are
6
- * met:
7
- *
8
- * * Redistributions of source code must retain the above copyright
9
- * notice, this list of conditions and the following disclaimer.
10
- * * Redistributions in binary form must reproduce the above
11
- * copyright notice, this list of conditions and the following disclaimer
12
- * in the documentation and/or other materials provided with the
13
- * distribution.
14
- * * Neither the name of Google Inc. nor the names of its
15
- * contributors may be used to endorse or promote products derived from
16
- * this software without specific prior written permission.
17
- *
18
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
- */
1
+ // Copyright 2014 The Chromium Authors
2
+ // Use of this source code is governed by a BSD-style license that can be
3
+ // found in the LICENSE file.
30
4
  /* eslint-disable rulesdir/no-imperative-dom-api */
31
5
 
32
6
  import * as Common from '../../core/common/common.js';
@@ -262,6 +236,10 @@ export class ProfileFlameChart extends
262
236
  return true;
263
237
  }
264
238
 
239
+ supportsWholeWordSearch(): boolean {
240
+ return false;
241
+ }
242
+
265
243
  supportsRegexSearch(): boolean {
266
244
  return false;
267
245
  }
@@ -367,6 +367,10 @@ export class ProfileView extends UI.View.SimpleView implements UI.SearchableView
367
367
  return true;
368
368
  }
369
369
 
370
+ supportsWholeWordSearch(): boolean {
371
+ return false;
372
+ }
373
+
370
374
  supportsRegexSearch(): boolean {
371
375
  return false;
372
376
  }