chrome-devtools-mcp 0.10.2 → 0.12.0

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 (121) hide show
  1. package/README.md +73 -10
  2. package/build/node_modules/chrome-devtools-frontend/front_end/core/common/common.js +1 -3
  3. package/build/node_modules/chrome-devtools-frontend/front_end/core/host/AidaClient.js +1 -1
  4. package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHost.js +31 -449
  5. package/build/node_modules/chrome-devtools-frontend/front_end/core/host/InspectorFrontendHostStub.js +430 -0
  6. package/build/node_modules/chrome-devtools-frontend/front_end/core/host/ResourceLoader.js +10 -22
  7. package/build/node_modules/chrome-devtools-frontend/front_end/core/host/UserMetrics.js +2 -5
  8. package/build/node_modules/chrome-devtools-frontend/front_end/core/i18n/collect-ui-strings.js +1 -1
  9. package/build/node_modules/chrome-devtools-frontend/front_end/core/i18n/generate-locales-js.js +1 -1
  10. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/HostRuntime.js +19 -0
  11. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/StringUtilities.js +1 -1
  12. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/api/HostRuntime.js +4 -0
  13. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/api/api.js +5 -0
  14. package/build/node_modules/chrome-devtools-frontend/front_end/core/{common/Worker.js → platform/browser/HostRuntime.js} +18 -7
  15. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/browser/browser.js +5 -0
  16. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/node/HostRuntime.js +72 -0
  17. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/node/node.js +5 -0
  18. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/platform.js +2 -2
  19. package/build/node_modules/chrome-devtools-frontend/front_end/core/root/DevToolsContext.js +4 -0
  20. package/build/node_modules/chrome-devtools-frontend/front_end/core/root/Runtime.js +7 -0
  21. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/AnimationModel.js +1 -1
  22. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMatchedStyles.js +2 -2
  23. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSMetadata.js +17 -5
  24. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSModel.js +3 -3
  25. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSProperty.js +1 -1
  26. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/CSSPropertyParserMatchers.js +10 -10
  27. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ConsoleModel.js +1 -1
  28. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Cookie.js +1 -1
  29. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DOMModel.js +5 -2
  30. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/DebuggerModel.js +1 -1
  31. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkManager.js +46 -34
  32. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/NetworkRequest.js +3 -0
  33. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PageResourceLoader.js +43 -33
  34. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/PreloadingModel.js +1 -1
  35. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/RemoteObject.js +1 -1
  36. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/ResourceTreeModel.js +1 -1
  37. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Script.js +26 -1
  38. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMap.js +4 -0
  39. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapCache.js +16 -0
  40. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapManager.js +11 -5
  41. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/SourceMapScopesInfo.js +129 -20
  42. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/Target.js +4 -13
  43. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/TargetManager.js +35 -4
  44. package/build/node_modules/chrome-devtools-frontend/front_end/core/sdk/sdk-meta.js +72 -0
  45. package/build/node_modules/chrome-devtools-frontend/front_end/foundation/Universe.js +5 -1
  46. package/build/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.js +48 -4
  47. package/build/node_modules/chrome-devtools-frontend/front_end/generated/InspectorBackendCommands.js +45 -42
  48. package/build/node_modules/chrome-devtools-frontend/front_end/generated/SupportedCSSProperties.js +56 -77
  49. package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.js +21 -6
  50. package/build/node_modules/chrome-devtools-frontend/front_end/models/ai_assistance/performance/AICallTree.js +9 -3
  51. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CSSWorkspaceBinding.js +4 -3
  52. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/CompilerScriptMapping.js +34 -0
  53. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/DebuggerWorkspaceBinding.js +15 -0
  54. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceMapping.js +59 -0
  55. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/ResourceScriptMapping.js +38 -0
  56. package/build/node_modules/chrome-devtools-frontend/front_end/models/bindings/SASSSourceMapping.js +5 -4
  57. package/build/node_modules/chrome-devtools-frontend/front_end/models/cpu_profile/CPUProfileDataModel.js +9 -7
  58. package/build/node_modules/chrome-devtools-frontend/front_end/models/crux-manager/CrUXManager.js +5 -3
  59. package/build/node_modules/chrome-devtools-frontend/front_end/models/formatter/FormatterWorkerPool.js +2 -2
  60. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/AttributionReportingIssue.js +5 -6
  61. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/BounceTrackingIssue.js +3 -11
  62. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/ClientHintIssue.js +4 -9
  63. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/ContentSecurityPolicyIssue.js +4 -9
  64. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/ContrastCheckTrigger.js +1 -1
  65. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/CookieDeprecationMetadataIssue.js +5 -11
  66. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/CookieIssue.js +26 -25
  67. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/CorsIssue.js +7 -14
  68. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/CrossOriginEmbedderPolicyIssue.js +4 -6
  69. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/DeprecationIssue.js +6 -11
  70. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/ElementAccessibilityIssue.js +6 -11
  71. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/FederatedAuthRequestIssue.js +3 -8
  72. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/FederatedAuthUserInfoRequestIssue.js +3 -8
  73. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/GenericIssue.js +36 -21
  74. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/HeavyAdIssue.js +3 -8
  75. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/Issue.js +6 -1
  76. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/IssueAggregator.js +6 -1
  77. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/LowTextContrastIssue.js +2 -7
  78. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/MixedContentIssue.js +6 -10
  79. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/PartitioningBlobURLIssue.js +3 -8
  80. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/PropertyRuleIssue.js +5 -10
  81. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/QuirksModeIssue.js +2 -7
  82. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/SRIMessageSignatureIssue.js +6 -10
  83. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/SharedArrayBufferIssue.js +3 -8
  84. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/SharedDictionaryIssue.js +5 -10
  85. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/StylesheetLoadingIssue.js +7 -11
  86. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/UnencodedDigestIssue.js +1 -6
  87. package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/descriptions/genericNavigationEntryMarkedSkippable.md +7 -0
  88. package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/FunctionCodeResolver.js +192 -0
  89. package/build/node_modules/chrome-devtools-frontend/front_end/models/source_map_scopes/source_map_scopes.js +2 -1
  90. package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/handlers/SamplesHandler.js +3 -0
  91. package/build/node_modules/chrome-devtools-frontend/front_end/models/trace/helpers/Trace.js +10 -0
  92. package/build/node_modules/chrome-devtools-frontend/front_end/models/trace_source_maps_resolver/SourceMapsResolver.js +23 -0
  93. package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/IgnoreListManager.js +1 -1
  94. package/build/node_modules/chrome-devtools-frontend/front_end/models/workspace/UISourceCode.js +38 -0
  95. package/build/node_modules/chrome-devtools-frontend/mcp/HostBindings.js +222 -0
  96. package/build/node_modules/chrome-devtools-frontend/mcp/mcp.js +15 -1
  97. package/build/src/DevToolsConnectionAdapter.js +56 -19
  98. package/build/src/DevtoolsUtils.js +143 -1
  99. package/build/src/McpContext.js +33 -11
  100. package/build/src/McpResponse.js +18 -26
  101. package/build/src/PageCollector.js +4 -11
  102. package/build/src/browser.js +52 -2
  103. package/build/src/cli.js +31 -3
  104. package/build/src/formatters/consoleFormatter.js +81 -3
  105. package/build/src/formatters/snapshotFormatter.js +18 -4
  106. package/build/src/issue-descriptions.js +4 -0
  107. package/build/src/main.js +27 -50
  108. package/build/src/third_party/THIRD_PARTY_NOTICES +27 -27
  109. package/build/src/third_party/index.js +21898 -15109
  110. package/build/src/tools/console.js +0 -4
  111. package/build/src/tools/emulation.js +29 -6
  112. package/build/src/tools/screenshot.js +4 -2
  113. package/build/src/tools/snapshot.js +1 -1
  114. package/build/src/tools/tools.js +29 -0
  115. package/build/src/utils/keyboard.js +5 -0
  116. package/package.json +7 -7
  117. package/build/node_modules/chrome-devtools-frontend/front_end/core/common/Linkifier.js +0 -34
  118. package/build/node_modules/chrome-devtools-frontend/front_end/core/platform/DOMUtilities.js +0 -122
  119. package/build/src/features.js +0 -14
  120. /package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/descriptions/{genericFormAriaLabelledByToNonExistingId.md → genericFormAriaLabelledByToNonExistingIdError.md} +0 -0
  121. /package/build/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/descriptions/{genericFormLabelHasNeitherForNorNestedInput.md → genericFormLabelHasNeitherForNorNestedInputError.md} +0 -0
@@ -502,6 +502,8 @@ export const generatedProperties = [
502
502
  "grid-auto-rows",
503
503
  "grid-column-end",
504
504
  "grid-column-start",
505
+ "grid-lanes-direction",
506
+ "grid-lanes-fill",
505
507
  "grid-row-end",
506
508
  "grid-row-start",
507
509
  "grid-template-areas",
@@ -558,8 +560,6 @@ export const generatedProperties = [
558
560
  "mask-repeat",
559
561
  "mask-size",
560
562
  "mask-type",
561
- "masonry-direction",
562
- "masonry-fill",
563
563
  "math-depth",
564
564
  "math-shift",
565
565
  "math-style",
@@ -676,10 +676,6 @@ export const generatedProperties = [
676
676
  "scroll-snap-align",
677
677
  "scroll-snap-stop",
678
678
  "scroll-snap-type",
679
- "scroll-start-block",
680
- "scroll-start-inline",
681
- "scroll-start-x",
682
- "scroll-start-y",
683
679
  "scroll-target-group",
684
680
  "scroll-timeline-axis",
685
681
  "scroll-timeline-name",
@@ -2145,8 +2141,8 @@ export const generatedProperties = [
2145
2141
  "math",
2146
2142
  "ruby",
2147
2143
  "ruby-text",
2148
- "masonry",
2149
- "inline-masonry"
2144
+ "grid-lanes",
2145
+ "inline-grid-lanes"
2150
2146
  ],
2151
2147
  "name": "display"
2152
2148
  },
@@ -2646,6 +2642,38 @@ export const generatedProperties = [
2646
2642
  ],
2647
2643
  "name": "grid-column-start"
2648
2644
  },
2645
+ {
2646
+ "longhands": [
2647
+ "grid-template-areas",
2648
+ "grid-template-columns",
2649
+ "grid-lanes-direction",
2650
+ "grid-lanes-fill"
2651
+ ],
2652
+ "name": "grid-lanes"
2653
+ },
2654
+ {
2655
+ "keywords": [
2656
+ "row",
2657
+ "row-reverse",
2658
+ "column",
2659
+ "column-reverse"
2660
+ ],
2661
+ "name": "grid-lanes-direction"
2662
+ },
2663
+ {
2664
+ "keywords": [
2665
+ "normal",
2666
+ "reverse"
2667
+ ],
2668
+ "name": "grid-lanes-fill"
2669
+ },
2670
+ {
2671
+ "longhands": [
2672
+ "grid-lanes-direction",
2673
+ "grid-lanes-fill"
2674
+ ],
2675
+ "name": "grid-lanes-flow"
2676
+ },
2649
2677
  {
2650
2678
  "longhands": [
2651
2679
  "grid-row-start",
@@ -3090,38 +3118,6 @@ export const generatedProperties = [
3090
3118
  ],
3091
3119
  "name": "mask-type"
3092
3120
  },
3093
- {
3094
- "longhands": [
3095
- "grid-template-areas",
3096
- "grid-template-columns",
3097
- "masonry-direction",
3098
- "masonry-fill"
3099
- ],
3100
- "name": "masonry"
3101
- },
3102
- {
3103
- "keywords": [
3104
- "row",
3105
- "row-reverse",
3106
- "column",
3107
- "column-reverse"
3108
- ],
3109
- "name": "masonry-direction"
3110
- },
3111
- {
3112
- "keywords": [
3113
- "normal",
3114
- "reverse"
3115
- ],
3116
- "name": "masonry-fill"
3117
- },
3118
- {
3119
- "longhands": [
3120
- "masonry-direction",
3121
- "masonry-fill"
3122
- ],
3123
- "name": "masonry-flow"
3124
- },
3125
3121
  {
3126
3122
  "inherited": true,
3127
3123
  "name": "math-depth"
@@ -3585,7 +3581,8 @@ export const generatedProperties = [
3585
3581
  },
3586
3582
  {
3587
3583
  "keywords": [
3588
- "auto"
3584
+ "auto",
3585
+ "none"
3589
3586
  ],
3590
3587
  "name": "position-anchor"
3591
3588
  },
@@ -4050,25 +4047,6 @@ export const generatedProperties = [
4050
4047
  ],
4051
4048
  "name": "scroll-snap-type"
4052
4049
  },
4053
- {
4054
- "longhands": [
4055
- "scroll-start-block",
4056
- "scroll-start-inline"
4057
- ],
4058
- "name": "scroll-start"
4059
- },
4060
- {
4061
- "name": "scroll-start-block"
4062
- },
4063
- {
4064
- "name": "scroll-start-inline"
4065
- },
4066
- {
4067
- "name": "scroll-start-x"
4068
- },
4069
- {
4070
- "name": "scroll-start-y"
4071
- },
4072
4050
  {
4073
4051
  "keywords": [
4074
4052
  "none",
@@ -5676,8 +5654,8 @@ export const generatedPropertyValues = {
5676
5654
  "math",
5677
5655
  "ruby",
5678
5656
  "ruby-text",
5679
- "masonry",
5680
- "inline-masonry"
5657
+ "grid-lanes",
5658
+ "inline-grid-lanes"
5681
5659
  ]
5682
5660
  },
5683
5661
  "dominant-baseline": {
@@ -5987,6 +5965,20 @@ export const generatedPropertyValues = {
5987
5965
  "auto"
5988
5966
  ]
5989
5967
  },
5968
+ "grid-lanes-direction": {
5969
+ "values": [
5970
+ "row",
5971
+ "row-reverse",
5972
+ "column",
5973
+ "column-reverse"
5974
+ ]
5975
+ },
5976
+ "grid-lanes-fill": {
5977
+ "values": [
5978
+ "normal",
5979
+ "reverse"
5980
+ ]
5981
+ },
5990
5982
  "grid-row-end": {
5991
5983
  "values": [
5992
5984
  "auto"
@@ -6205,20 +6197,6 @@ export const generatedPropertyValues = {
6205
6197
  "alpha"
6206
6198
  ]
6207
6199
  },
6208
- "masonry-direction": {
6209
- "values": [
6210
- "row",
6211
- "row-reverse",
6212
- "column",
6213
- "column-reverse"
6214
- ]
6215
- },
6216
- "masonry-fill": {
6217
- "values": [
6218
- "normal",
6219
- "reverse"
6220
- ]
6221
- },
6222
6200
  "math-shift": {
6223
6201
  "values": [
6224
6202
  "normal",
@@ -6460,7 +6438,8 @@ export const generatedPropertyValues = {
6460
6438
  },
6461
6439
  "position-anchor": {
6462
6440
  "values": [
6463
- "auto"
6441
+ "auto",
6442
+ "none"
6464
6443
  ]
6465
6444
  },
6466
6445
  "position-area": {
@@ -532,7 +532,7 @@ Network requests data:
532
532
  }
533
533
  static callFrameDataFormatDescription = `Each call frame is presented in the following format:
534
534
 
535
- 'id;eventKey;name;duration;selfTime;urlIndex;childRange;[S]'
535
+ 'id;eventKey;name;duration;selfTime;urlIndex;childRange;[line];[column];[S]'
536
536
 
537
537
  Key definitions:
538
538
 
@@ -543,15 +543,17 @@ Key definitions:
543
543
  * selfTime: The time spent directly within the call frame, excluding its children's execution.
544
544
  * urlIndex: Index referencing the "All URLs" list. Empty if no specific script URL is associated.
545
545
  * childRange: Specifies the direct children of this node using their IDs. If empty ('' or 'S' at the end), the node has no children. If a single number (e.g., '4'), the node has one child with that ID. If in the format 'firstId-lastId' (e.g., '4-5'), it indicates a consecutive range of child IDs from 'firstId' to 'lastId', inclusive.
546
+ * line: An optional field for a call frame's line number. This is where the function is defined.
547
+ * column: An optional field for a call frame's column number. This is where the function is defined.
546
548
  * S: _Optional_. The letter 'S' terminates the line if that call frame was selected by the user.
547
549
 
548
550
  Example Call Tree:
549
551
 
550
- 1;r-123;main;500;100;;
551
- 2;r-124;update;200;50;;3
552
- 3;p-49575-15428179-2834-374;animate;150;20;0;4-5;S
553
- 4;p-49575-15428179-3505-1162;calculatePosition;80;80;;
554
- 5;p-49575-15428179-5391-2767;applyStyles;50;50;;
552
+ 1;r-123;main;500;100;0;1;;
553
+ 2;r-124;update;200;50;;3;0;1;
554
+ 3;p-49575-15428179-2834-374;animate;150;20;0;4-5;0;1;S
555
+ 4;p-49575-15428179-3505-1162;calculatePosition;80;80;0;1;;
556
+ 5;p-49575-15428179-5391-2767;applyStyles;50;50;0;1;;
555
557
  `;
556
558
  /**
557
559
  * Network requests format description that is sent to the model as a fact.
@@ -646,4 +648,17 @@ The order of headers corresponds to an internal fixed list. If a header is not p
646
648
  ];
647
649
  return parts.join(';');
648
650
  }
651
+ formatFunctionCode(code) {
652
+ const { startLine, startColumn } = code.range;
653
+ const { startLine: contextStartLine, startColumn: contextStartColumn, endLine: contextEndLine, endColumn: contextEndColumn } = code.rangeWithContext;
654
+ const name = code.functionBounds.name;
655
+ const url = code.functionBounds.uiSourceCode.url();
656
+ const parts = [];
657
+ parts.push(`${name} @ ${url}:${startLine}:${startColumn}. With added context, chunk is from ${contextStartLine}:${contextStartColumn} to ${contextEndLine}:${contextEndColumn}`);
658
+ parts.push('\nThe following is a markdown block of JavaScript. <FUNCTION_START> and <FUNCTION_END> marks the exact function declaration, and everything outside that is provided for additional context. Comments at the end of each line indicate the runtime performance cost of that code. Do not show the user the function markers or the additional context.\n');
659
+ parts.push('```');
660
+ parts.push(code.codeWithContext);
661
+ parts.push('```');
662
+ return parts.join('\n');
663
+ }
649
664
  }
@@ -244,10 +244,12 @@ export class AICallTree {
244
244
  * 5. `urlIndex`: An index referencing a URL in the `allUrls` array. If no URL is present, this is an empty string.
245
245
  * 6. `childRange`: A string indicating the range of IDs for the node's children. Children should always have consecutive IDs.
246
246
  * If there is only one child, it's a single ID.
247
- * 7. `[S]`: An optional marker indicating that this node is the selected node.
247
+ * 7. `[line]`: An optional field for a call frame's line number.
248
+ * 8. `[column]`: An optional field for a call frame's column number.
249
+ * 9. `[S]`: An optional marker indicating that this node is the selected node.
248
250
  *
249
251
  * Example:
250
- * `1;Parse HTML;2.5;0.3;0;2-5;S`
252
+ * `1;Parse HTML;2.5;0.3;0;2-5;10;11;S`
251
253
  * This represents:
252
254
  * - Node ID 1
253
255
  * - Name "Parse HTML"
@@ -255,6 +257,7 @@ export class AICallTree {
255
257
  * - Self time of 0.3ms
256
258
  * - URL index 0 (meaning the URL is the first one in the `allUrls` array)
257
259
  * - Child range of IDs 2 to 5
260
+ * - Line, column is 10:11
258
261
  * - This node is the selected node (S marker)
259
262
  */
260
263
  stringifyNode(node, nodeId, parsedTrace, selectedNode, allUrls, childStartingNodeIndex) {
@@ -280,7 +283,8 @@ export class AICallTree {
280
283
  // 5. Self Time
281
284
  const selfTimeStr = roundToTenths(node.selfTime);
282
285
  // 6. URL Index
283
- const url = SourceMapsResolver.SourceMapsResolver.resolvedURLForEntry(parsedTrace, event);
286
+ const location = SourceMapsResolver.SourceMapsResolver.codeLocationForEntry(parsedTrace, event);
287
+ const url = location?.url;
284
288
  let urlIndexStr = '';
285
289
  if (url) {
286
290
  const existingIndex = allUrls.indexOf(url);
@@ -308,6 +312,8 @@ export class AICallTree {
308
312
  line += ';' + selfTimeStr;
309
313
  line += ';' + urlIndexStr;
310
314
  line += ';' + childRangeStr;
315
+ line += ';' + (location?.line ?? '');
316
+ line += ';' + (location?.column ?? '');
311
317
  if (selectedMarker) {
312
318
  line += ';' + selectedMarker;
313
319
  }
@@ -39,7 +39,7 @@ export class CSSWorkspaceBinding {
39
39
  return this.#modelToInfo.get(cssModel);
40
40
  }
41
41
  modelAdded(cssModel) {
42
- this.#modelToInfo.set(cssModel, new ModelInfo(cssModel, this.#resourceMapping));
42
+ this.#modelToInfo.set(cssModel, new ModelInfo(cssModel, this.#resourceMapping, this));
43
43
  }
44
44
  modelRemoved(cssModel) {
45
45
  this.getCSSModelInfo(cssModel).dispose();
@@ -110,7 +110,7 @@ export class ModelInfo {
110
110
  #sassSourceMapping;
111
111
  #locations;
112
112
  #unboundLocations;
113
- constructor(cssModel, resourceMapping) {
113
+ constructor(cssModel, resourceMapping, cssWorkspaceBinding) {
114
114
  this.#eventListeners = [
115
115
  cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, event => {
116
116
  void this.styleSheetAdded(event);
@@ -122,7 +122,8 @@ export class ModelInfo {
122
122
  this.#resourceMapping = resourceMapping;
123
123
  this.#stylesSourceMapping = new StylesSourceMapping(cssModel, resourceMapping.workspace);
124
124
  const sourceMapManager = cssModel.sourceMapManager();
125
- this.#sassSourceMapping = new SASSSourceMapping(cssModel.target(), sourceMapManager, resourceMapping.workspace);
125
+ this.#sassSourceMapping =
126
+ new SASSSourceMapping(cssModel.target(), sourceMapManager, resourceMapping.workspace, cssWorkspaceBinding);
126
127
  this.#locations = new Platform.MapUtilities.Multimap();
127
128
  this.#unboundLocations = new Platform.MapUtilities.Multimap();
128
129
  }
@@ -220,6 +220,40 @@ export class CompilerScriptMapping {
220
220
  }
221
221
  return ranges;
222
222
  }
223
+ async functionBoundsAtRawLocation(rawLocation) {
224
+ const script = rawLocation.script();
225
+ if (!script) {
226
+ return null;
227
+ }
228
+ const sourceMap = this.#sourceMapManager.sourceMapForClient(script);
229
+ if (!sourceMap) {
230
+ return null;
231
+ }
232
+ const { lineNumber, columnNumber } = script.rawLocationToRelativeLocation(rawLocation);
233
+ const { url, scope } = sourceMap.findOriginalFunctionScope({ line: lineNumber, column: columnNumber }) ?? {};
234
+ if (!scope || !url) {
235
+ return null;
236
+ }
237
+ const project = this.#sourceMapToProject.get(sourceMap);
238
+ if (!project) {
239
+ return null;
240
+ }
241
+ const uiSourceCode = project.uiSourceCodeForURL(url);
242
+ if (!uiSourceCode) {
243
+ return null;
244
+ }
245
+ // If there's no original source content, callers can't get the source code for
246
+ // the given scope. Presently that's the only reason to get a function's bounds,
247
+ // so in that case return null and allow ResourceScriptMapping to fulfill this
248
+ // request.
249
+ const contentData = await uiSourceCode.requestContentData();
250
+ if ('error' in contentData) {
251
+ return null;
252
+ }
253
+ const name = scope.name ?? '';
254
+ const range = new TextUtils.TextRange.TextRange(scope.start.line, scope.start.column, scope.end.line, scope.end.column);
255
+ return new Workspace.UISourceCode.UIFunctionBounds(uiSourceCode, range, name);
256
+ }
223
257
  translateRawFramesStep(rawFrames, translatedFrames) {
224
258
  const frame = rawFrames[0];
225
259
  if (StackTraceImpl.Trie.isBuiltinFrame(frame)) {
@@ -258,6 +258,11 @@ export class DebuggerWorkspaceBinding {
258
258
  }
259
259
  return [];
260
260
  }
261
+ async functionBoundsAtRawLocation(rawLocation) {
262
+ // TODO(crbug.com/463452667): first try pluginManager.
263
+ const modelData = this.#debuggerModelToData.get(rawLocation.debuggerModel);
264
+ return modelData ? await modelData.functionBoundsAtRawLocation(rawLocation) : null;
265
+ }
261
266
  async normalizeUILocation(uiLocation) {
262
267
  const rawLocations = await this.uiLocationToRawLocations(uiLocation.uiSourceCode, uiLocation.lineNumber, uiLocation.columnNumber);
263
268
  for (const location of rawLocations) {
@@ -458,6 +463,16 @@ class ModelData {
458
463
  ranges ??= this.#defaultMapping.uiLocationRangeToRawLocationRanges(uiSourceCode, textRange);
459
464
  return ranges;
460
465
  }
466
+ async functionBoundsAtRawLocation(rawLocation) {
467
+ let scope = null;
468
+ // Check source maps.
469
+ scope = scope || await this.compilerMapping.functionBoundsAtRawLocation(rawLocation);
470
+ // Check debugger scripts.
471
+ scope = scope || await this.#resourceScriptMapping.functionBoundsAtRawLocation(rawLocation);
472
+ // Check inline scripts inside HTML resources.
473
+ scope = scope || await this.#resourceMapping.functionBoundsAtRawLocation(rawLocation);
474
+ return scope;
475
+ }
461
476
  translateRawFramesStep(rawFrames, translatedFrames) {
462
477
  if (!this.compilerMapping.translateRawFramesStep(rawFrames, translatedFrames)) {
463
478
  this.#defaultTranslateRawFramesStep(rawFrames, translatedFrames);
@@ -3,6 +3,7 @@
3
3
  // found in the LICENSE file.
4
4
  import * as Common from '../../core/common/common.js';
5
5
  import * as SDK from '../../core/sdk/sdk.js';
6
+ import * as Formatter from '../formatter/formatter.js';
6
7
  import * as TextUtils from '../text_utils/text_utils.js';
7
8
  import * as Workspace from '../workspace/workspace.js';
8
9
  import { ContentProviderBasedProject } from './ContentProviderBasedProject.js';
@@ -238,6 +239,64 @@ export class ResourceMapping {
238
239
  }
239
240
  return cssModel.createRawLocationsByURL(uiLocation.uiSourceCode.url(), uiLocation.lineNumber, uiLocation.columnNumber);
240
241
  }
242
+ async functionBoundsAtRawLocation(rawLocation) {
243
+ const script = rawLocation.script();
244
+ if (!script) {
245
+ return null;
246
+ }
247
+ const info = this.infoForTarget(script.debuggerModel.target());
248
+ if (!info) {
249
+ return null;
250
+ }
251
+ const embedderName = script.embedderName();
252
+ if (!embedderName) {
253
+ return null;
254
+ }
255
+ const uiSourceCode = info.getProject().uiSourceCodeForURL(embedderName);
256
+ if (!uiSourceCode) {
257
+ return null;
258
+ }
259
+ let { lineNumber, columnNumber } = rawLocation;
260
+ lineNumber -= script.lineOffset;
261
+ if (lineNumber === 0) {
262
+ columnNumber -= script.columnOffset;
263
+ }
264
+ const scopeTreeAndText = script ? await SDK.ScopeTreeCache.scopeTreeForScript(script) : null;
265
+ if (!scopeTreeAndText) {
266
+ return null;
267
+ }
268
+ // Find the inner-most scope that maps to the given position.
269
+ const offset = scopeTreeAndText.text.offsetFromPosition(lineNumber, columnNumber);
270
+ const results = [];
271
+ (function walk(nodes) {
272
+ for (const node of nodes) {
273
+ if (!(offset >= node.start && offset < node.end)) {
274
+ continue;
275
+ }
276
+ results.push(node);
277
+ walk(node.children);
278
+ }
279
+ })([scopeTreeAndText.scopeTree]);
280
+ const result = results.findLast(node => node.kind === 2 /* Formatter.FormatterWorkerPool.ScopeKind.FUNCTION */ ||
281
+ node.kind === 4 /* Formatter.FormatterWorkerPool.ScopeKind.ARROW_FUNCTION */);
282
+ if (!result) {
283
+ return null;
284
+ }
285
+ // Map back to positions.
286
+ const startPosition = scopeTreeAndText.text.positionFromOffset(result.start);
287
+ const endPosition = scopeTreeAndText.text.positionFromOffset(result.end);
288
+ startPosition.lineNumber += script.lineOffset;
289
+ if (startPosition.lineNumber === script.lineOffset) {
290
+ startPosition.columnNumber += script.columnOffset;
291
+ }
292
+ endPosition.lineNumber += script.lineOffset;
293
+ if (endPosition.lineNumber === script.lineOffset) {
294
+ endPosition.columnNumber += script.columnOffset;
295
+ }
296
+ const name = ''; // TODO(crbug.com/452333154): update ScopeVariableAnalysis to include function name.
297
+ const range = new TextUtils.TextRange.TextRange(startPosition.lineNumber, startPosition.columnNumber, endPosition.lineNumber, endPosition.columnNumber);
298
+ return new Workspace.UISourceCode.UIFunctionBounds(uiSourceCode, range, name);
299
+ }
241
300
  resetForTest(target) {
242
301
  const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
243
302
  const info = resourceTreeModel ? this.#modelToInfo.get(resourceTreeModel) : null;
@@ -6,6 +6,7 @@ import * as i18n from '../../core/i18n/i18n.js';
6
6
  import * as Platform from '../../core/platform/platform.js';
7
7
  import * as Root from '../../core/root/root.js';
8
8
  import * as SDK from '../../core/sdk/sdk.js';
9
+ import * as Formatter from '../formatter/formatter.js';
9
10
  import * as TextUtils from '../text_utils/text_utils.js';
10
11
  import * as Workspace from '../workspace/workspace.js';
11
12
  import { ContentProviderBasedProject } from './ContentProviderBasedProject.js';
@@ -125,6 +126,43 @@ export class ResourceScriptMapping {
125
126
  this.addScript(script);
126
127
  }
127
128
  }
129
+ async functionBoundsAtRawLocation(rawLocation) {
130
+ const script = rawLocation.script();
131
+ if (!script) {
132
+ return null;
133
+ }
134
+ const uiSourceCode = this.#scriptToUISourceCode.get(script);
135
+ if (!uiSourceCode) {
136
+ return null;
137
+ }
138
+ const scopeTreeAndText = script ? await SDK.ScopeTreeCache.scopeTreeForScript(script) : null;
139
+ if (!scopeTreeAndText) {
140
+ return null;
141
+ }
142
+ // Find the inner-most scope that maps to the given position.
143
+ const offset = scopeTreeAndText.text.offsetFromPosition(rawLocation.lineNumber, rawLocation.columnNumber);
144
+ const results = [];
145
+ (function walk(nodes) {
146
+ for (const node of nodes) {
147
+ if (!(offset >= node.start && offset < node.end)) {
148
+ continue;
149
+ }
150
+ results.push(node);
151
+ walk(node.children);
152
+ }
153
+ })([scopeTreeAndText.scopeTree]);
154
+ const result = results.findLast(node => node.kind === 2 /* Formatter.FormatterWorkerPool.ScopeKind.FUNCTION */ ||
155
+ node.kind === 4 /* Formatter.FormatterWorkerPool.ScopeKind.ARROW_FUNCTION */);
156
+ if (!result) {
157
+ return null;
158
+ }
159
+ // Map back to positions.
160
+ const startPosition = scopeTreeAndText.text.positionFromOffset(result.start);
161
+ const endPosition = scopeTreeAndText.text.positionFromOffset(result.end);
162
+ const name = ''; // TODO(crbug.com/452333154): update ScopeVariableAnalysis to include function name.
163
+ const range = new TextUtils.TextRange.TextRange(startPosition.lineNumber, startPosition.columnNumber, endPosition.lineNumber, endPosition.columnNumber);
164
+ return new Workspace.UISourceCode.UIFunctionBounds(uiSourceCode, range, name);
165
+ }
128
166
  addScript(script) {
129
167
  // Ignore live edit scripts here.
130
168
  if (script.isLiveEdit() || script.isBreakpointCondition) {
@@ -6,15 +6,16 @@ import * as SDK from '../../core/sdk/sdk.js';
6
6
  import * as TextUtils from '../text_utils/text_utils.js';
7
7
  import * as Workspace from '../workspace/workspace.js';
8
8
  import { ContentProviderBasedProject } from './ContentProviderBasedProject.js';
9
- import { CSSWorkspaceBinding } from './CSSWorkspaceBinding.js';
10
9
  import { NetworkProject } from './NetworkProject.js';
11
10
  export class SASSSourceMapping {
12
11
  #sourceMapManager;
13
12
  #project;
14
13
  #eventListeners;
15
14
  #bindings;
16
- constructor(target, sourceMapManager, workspace) {
15
+ #cssWorkspaceBinding;
16
+ constructor(target, sourceMapManager, workspace, cssWorkspaceBinding) {
17
17
  this.#sourceMapManager = sourceMapManager;
18
+ this.#cssWorkspaceBinding = cssWorkspaceBinding;
18
19
  this.#project = new ContentProviderBasedProject(workspace, 'cssSourceMaps:' + target.id(), Workspace.Workspace.projectTypes.Network, '', false /* isServiceProject */);
19
20
  NetworkProject.setTargetForProject(this.#project, target);
20
21
  this.#bindings = new Map();
@@ -38,7 +39,7 @@ export class SASSSourceMapping {
38
39
  }
39
40
  binding.addSourceMap(sourceMap, header.frameId);
40
41
  }
41
- await CSSWorkspaceBinding.instance().updateLocations(header);
42
+ await this.#cssWorkspaceBinding.updateLocations(header);
42
43
  this.sourceMapAttachedForTest(sourceMap);
43
44
  }
44
45
  async sourceMapDetached(event) {
@@ -54,7 +55,7 @@ export class SASSSourceMapping {
54
55
  }
55
56
  }
56
57
  }
57
- await CSSWorkspaceBinding.instance().updateLocations(header);
58
+ await this.#cssWorkspaceBinding.updateLocations(header);
58
59
  }
59
60
  rawLocationToUILocation(rawLocation) {
60
61
  const header = rawLocation.header();
@@ -50,7 +50,15 @@ export class CPUProfileDataModel extends ProfileTreeModel {
50
50
  * for CPU profiles coming from traces.
51
51
  */
52
52
  traceIds;
53
+ /**
54
+ * Each item in the `lines` array contains the script line executing
55
+ * when the sample in that array position was taken.
56
+ */
53
57
  lines;
58
+ /**
59
+ * Same as `lines` above, but with the script column.
60
+ */
61
+ columns;
54
62
  totalHitCount;
55
63
  profileHead;
56
64
  /**
@@ -84,14 +92,8 @@ export class CPUProfileDataModel extends ProfileTreeModel {
84
92
  }
85
93
  this.traceIds = profile.traceIds;
86
94
  this.samples = profile.samples;
87
- // Lines are available only in profiles coming from tracing.
88
- // Elements in the lines array have a 1 to 1 correspondence with
89
- // samples, by array position. They can be 1 or 0 and indicate if
90
- // there is line data for a given sample, i.e. if a given sample
91
- // needs to be included to calculate the line level execution time
92
- // data, which we show in the sources panel after recording a
93
- // profile.
94
95
  this.lines = profile.lines;
96
+ this.columns = profile.columns;
95
97
  this.totalHitCount = 0;
96
98
  this.profileHead = this.translateProfileTree(profile.nodes);
97
99
  this.initialize(this.profileHead);
@@ -92,9 +92,11 @@ export class CrUXManager extends Common.ObjectWrapper.ObjectWrapper {
92
92
  'url-PHONE': null,
93
93
  'url-TABLET': null,
94
94
  warnings: [],
95
+ normalizedUrl: '',
95
96
  };
96
97
  try {
97
98
  const normalizedUrl = this.#normalizeUrl(pageUrl);
99
+ pageResult.normalizedUrl = normalizedUrl.href;
98
100
  const promises = [];
99
101
  for (const pageScope of pageScopeList) {
100
102
  for (const deviceScope of DEVICE_SCOPE_LIST) {
@@ -143,10 +145,10 @@ export class CrUXManager extends Common.ObjectWrapper.ObjectWrapper {
143
145
  */
144
146
  async #getFieldDataForCurrentPage() {
145
147
  const currentUrl = this.#mainDocumentUrl || await this.#getInspectedURL();
146
- const urlForCrux = this.#configSetting.get().overrideEnabled ? this.#configSetting.get().override || '' :
148
+ const normalizedUrl = this.#configSetting.get().overrideEnabled ? this.#configSetting.get().override || '' :
147
149
  this.#getMappedUrl(currentUrl);
148
- const result = await this.getFieldDataForPage(urlForCrux);
149
- if (currentUrl !== urlForCrux) {
150
+ const result = await this.getFieldDataForPage(normalizedUrl);
151
+ if (currentUrl !== normalizedUrl) {
150
152
  result.warnings.push(i18nString(UIStrings.fieldOverrideWarning));
151
153
  }
152
154
  return result;
@@ -1,7 +1,7 @@
1
1
  // Copyright 2016 The Chromium Authors
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
- import * as Common from '../../core/common/common.js';
4
+ import * as Platform from '../../core/platform/platform.js';
5
5
  let formatterWorkerPoolInstance;
6
6
  export class FormatterWorkerPool {
7
7
  taskQueue;
@@ -31,7 +31,7 @@ export class FormatterWorkerPool {
31
31
  formatterWorkerPoolInstance = undefined;
32
32
  }
33
33
  createWorker() {
34
- const worker = Common.Worker.WorkerWrapper.fromURL(new URL('../../entrypoints/formatter_worker/formatter_worker-entrypoint.js', import.meta.url));
34
+ const worker = Platform.HostRuntime.HOST_RUNTIME.createWorker(new URL('../../entrypoints/formatter_worker/formatter_worker-entrypoint.js', import.meta.url).toString());
35
35
  worker.onmessage = this.onWorkerMessage.bind(this, worker);
36
36
  worker.onerror = this.onWorkerError.bind(this, worker);
37
37
  return worker;