chrome-devtools-frontend 1.0.1721762 → 1.0.1726686
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.
- package/.agents/skills/review-ui-widgets/SKILL.md +7 -7
- package/.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md +12 -0
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +3 -3
- package/.agents/skills/ui-widgets/SKILL.md +2 -1
- package/docs/cookbook/dependencies.md +57 -11
- package/docs/get_the_code.md +15 -0
- package/front_end/core/i18n/collect-ui-strings.js +58 -12
- package/front_end/core/i18n/i18nImpl.ts +1 -1
- package/front_end/core/root/Runtime.ts +1 -1
- package/front_end/core/sdk/ResourceTreeModel.ts +16 -0
- package/front_end/core/sdk/WebAuthnModel.ts +17 -10
- package/front_end/entrypoints/js_app/js_app.ts +2 -5
- package/front_end/entrypoints/node_app/node_app.ts +2 -3
- package/front_end/generated/InspectorBackendCommands.ts +3 -3
- package/front_end/generated/protocol.ts +17 -0
- package/front_end/models/ai_assistance/skills/lighthouse.md +2 -1
- package/front_end/models/ai_assistance/skills/network.md +1 -0
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +26 -2
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +1 -1
- package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +2 -7
- package/front_end/models/ai_assistance/tools/RunLighthouse.ts +2 -2
- package/front_end/models/comment_manager/CD4ABridge.ts +4 -0
- package/front_end/models/comment_manager/CommentManager.ts +0 -6
- package/front_end/models/comment_manager/CommentThread.ts +39 -19
- package/front_end/models/elements/StyleChanges.ts +66 -0
- package/front_end/models/trace/EventsSerializer.ts +2 -7
- package/front_end/models/trace/ModelImpl.ts +0 -2
- package/front_end/models/trace/handlers/FlowsHandler.ts +37 -29
- package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +13 -6
- package/front_end/models/trace/helpers/SyntheticEvents.ts +10 -37
- package/front_end/models/trace/insights/RenderBlocking.ts +3 -1
- package/front_end/models/trace/lantern/simulation/Simulator.ts +4 -0
- package/front_end/models/trace/lantern/types/Lantern.ts +1 -0
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +92 -0
- package/front_end/panels/accessibility/SourceOrderView.ts +1 -1
- package/front_end/panels/accessibility/accessibilityAnnouncementRecordingListView.css +3 -1
- package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +12 -1
- package/front_end/panels/application/ApplicationPanelSidebar.ts +90 -0
- package/front_end/panels/application/StorageView.ts +348 -254
- package/front_end/panels/application/SubAppsView.ts +159 -0
- package/front_end/panels/application/application.ts +2 -0
- package/front_end/panels/application/preloading/PreloadingView.ts +360 -336
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +3 -3
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +6 -3
- package/front_end/panels/application/preloading/components/RuleSetGrid.ts +17 -17
- package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +2 -2
- package/front_end/panels/application/preloading/preloadingView.css +12 -4
- package/front_end/panels/application/preloading/preloadingViewDropDown.css +1 -1
- package/front_end/panels/application/storageView.css +16 -21
- package/front_end/panels/application/subAppsView.css +21 -0
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +2 -2
- package/front_end/panels/browser_debugger/browser_debugger-meta.ts +6 -8
- package/front_end/panels/comments/CommentsPane.ts +26 -9
- package/front_end/panels/comments/commentsPane.css +25 -6
- package/front_end/panels/common/CommentThreadWidget.ts +2 -2
- package/front_end/panels/common/CommentsOverlayWidget.ts +94 -35
- package/front_end/panels/common/commentThreadWidget.css +17 -0
- package/front_end/panels/common/commentsOverlay.css +5 -10
- package/front_end/panels/common/common-meta.ts +11 -1
- package/front_end/panels/elements/ClassesPaneWidget.ts +133 -89
- package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +7 -33
- package/front_end/panels/elements/DOMTreeElementWidget.ts +3 -1
- package/front_end/panels/elements/DOMTreeWidget.ts +19 -3
- package/front_end/panels/elements/ElementStatePaneWidget.ts +11 -1
- package/front_end/panels/elements/PropertyRenderer.ts +3 -2
- package/front_end/panels/elements/StyleEditorWidget.ts +87 -39
- package/front_end/panels/elements/StylePropertiesSection.ts +32 -5
- package/front_end/panels/elements/StylePropertyTreeElement.ts +227 -162
- package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
- package/front_end/panels/event_listeners/EventListenersView.ts +11 -8
- package/front_end/panels/layer_viewer/Layers3DView.ts +21 -37
- package/front_end/panels/linear_memory_inspector/components/ValueInterpreterSettings.ts +1 -1
- package/front_end/panels/network/NetworkConfigView.ts +12 -10
- package/front_end/panels/network/NetworkDataGridNode.ts +3 -1
- package/front_end/panels/network/RequestConditionsDrawer.ts +1 -1
- package/front_end/panels/network/RequestPayloadView.ts +12 -5
- package/front_end/panels/network/networkConfigView.css +8 -8
- package/front_end/panels/profiler/HeapProfileView.ts +28 -6
- package/front_end/panels/profiler/HeapSnapshotDataGrids.ts +7 -3
- package/front_end/panels/protocol_monitor/JSONEditor.ts +0 -1
- package/front_end/panels/recorder/RecorderPanel.ts +2 -2
- package/front_end/panels/screencast/ScreencastView.ts +3 -6
- package/front_end/panels/security/SecurityPanelSidebar.ts +0 -31
- package/front_end/panels/settings/SettingsScreen.ts +1 -1
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +9 -16
- package/front_end/panels/settings/emulation/components/UserAgentClientHintsForm.ts +358 -345
- package/front_end/panels/settings/emulation/components/userAgentClientHintsForm.css +136 -121
- package/front_end/panels/sources/NavigatorView.ts +105 -45
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +8 -5
- package/front_end/panels/sources/SourcesNavigator.ts +421 -213
- package/front_end/panels/sources/SourcesPanel.ts +9 -5
- package/front_end/panels/sources/TabbedEditorContainer.ts +41 -18
- package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +10 -5
- package/front_end/panels/sources/sources-meta.ts +4 -15
- package/front_end/panels/sources/sourcesNavigator.css +5 -0
- package/front_end/panels/timeline/ModificationsManager.ts +0 -2
- package/front_end/panels/timeline/README.md +2 -0
- package/front_end/panels/timeline/TimelineCommentContext.ts +171 -0
- package/front_end/panels/timeline/TimelineCommentController.ts +168 -30
- package/front_end/panels/timeline/TimelinePanel.ts +4 -0
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +1 -1
- package/front_end/panels/timeline/timeline.ts +2 -0
- package/front_end/panels/timeline/utils/Treemap.ts +8 -0
- package/front_end/panels/webauthn/WebauthnPane.ts +15 -13
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +113 -3
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +21311 -20981
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +36 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +22 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +20 -18
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts +20 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +40 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +3 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js +41 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/locators/locators.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js +23 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Input.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js +13 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js +18 -11
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/core/Request.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js +8 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +24 -12
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js +13 -7
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/EmulationManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js +5 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts +22 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js +75 -9
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/HTTPRequest.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts +18 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js +8 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkEventManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +65 -26
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js +19 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js +4 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/ScreenRecording.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js +4 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Target.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js +95 -8
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/TargetManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts +0 -8
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +8 -24
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js +5 -4
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserWebSocketTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts +9 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/WaitTask.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +10 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +30 -5
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js +33 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/Poller.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js +1 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/BrowserLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/NodeWebSocketTransport.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/encoding.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +113 -3
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +42 -0
- package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +25 -22
- package/front_end/third_party/puppeteer/package/src/api/HTTPRequest.ts +22 -2
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +45 -2
- package/front_end/third_party/puppeteer/package/src/api/locators/locators.ts +79 -32
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPRequest.ts +32 -12
- package/front_end/third_party/puppeteer/package/src/bidi/Input.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +18 -2
- package/front_end/third_party/puppeteer/package/src/bidi/core/Request.ts +21 -13
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +12 -2
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +37 -16
- package/front_end/third_party/puppeteer/package/src/cdp/EmulationManager.ts +14 -11
- package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +7 -1
- package/front_end/third_party/puppeteer/package/src/cdp/HTTPRequest.ts +101 -14
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkEventManager.ts +26 -6
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +111 -29
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +37 -1
- package/front_end/third_party/puppeteer/package/src/cdp/ScreenRecording.ts +5 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Target.ts +5 -0
- package/front_end/third_party/puppeteer/package/src/cdp/TargetManager.ts +122 -7
- package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +13 -33
- package/front_end/third_party/puppeteer/package/src/common/BrowserWebSocketTransport.ts +10 -5
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +10 -0
- package/front_end/third_party/puppeteer/package/src/common/WaitTask.ts +12 -0
- package/front_end/third_party/puppeteer/package/src/common/util.ts +39 -5
- package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/injected/Poller.ts +35 -3
- package/front_end/third_party/puppeteer/package/src/node/BrowserLauncher.ts +4 -2
- package/front_end/third_party/puppeteer/package/src/node/NodeWebSocketTransport.ts +5 -0
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/encoding.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +3 -0
- package/front_end/ui/comments/CommentOverlayManager.ts +2 -4
- package/front_end/ui/components/lists/List.ts +14 -1
- package/front_end/ui/components/panel_feedback/PreviewToggle.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +23 -14
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +3 -0
- package/front_end/ui/helpers/OpenInNewTab.ts +8 -0
- package/front_end/ui/legacy/LinkContextMenuProvider.ts +1 -1
- package/front_end/ui/legacy/ListWidget.ts +14 -18
- package/front_end/ui/legacy/TabbedPane.ts +46 -3
- package/front_end/ui/legacy/Toolbar.ts +0 -1
- package/front_end/ui/legacy/Treeoutline.ts +10 -3
- package/front_end/ui/legacy/UIUtils.ts +5 -2
- package/front_end/ui/legacy/components/inline_editor/Swatches.ts +19 -6
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +20 -11
- package/front_end/ui/legacy/components/source_frame/XMLView.ts +27 -7
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
|
@@ -55,7 +55,7 @@ import * as Snippets from '../snippets/snippets.js';
|
|
|
55
55
|
|
|
56
56
|
import {CallStackSidebarPane} from './CallStackSidebarPane.js';
|
|
57
57
|
import {DebuggerPausedMessage} from './DebuggerPausedMessage.js';
|
|
58
|
-
import {
|
|
58
|
+
import {SourcesNavigatorView} from './SourcesNavigator.js';
|
|
59
59
|
import sourcesPanelStyles from './sourcesPanel.css.js';
|
|
60
60
|
import {type EditorClosedEvent, Events, SourcesView} from './SourcesView.js';
|
|
61
61
|
import {ThreadsSidebarPane} from './ThreadsSidebarPane.js';
|
|
@@ -781,12 +781,14 @@ export class SourcesPanel extends UI.Panel.Panel implements
|
|
|
781
781
|
const viewManager = UI.ViewManager.ViewManager.instance();
|
|
782
782
|
for (const view of viewManager.viewsForLocation(UI.ViewManager.ViewLocationValues.NAVIGATOR_VIEW)) {
|
|
783
783
|
const navigatorView = await view.widget();
|
|
784
|
-
if (navigatorView instanceof
|
|
785
|
-
navigatorView.revealUISourceCode(uiSourceCode, true);
|
|
784
|
+
if (navigatorView instanceof SourcesNavigatorView && navigatorView.acceptProject(uiSourceCode.project())) {
|
|
786
785
|
this.navigatorTabbedLocation.tabbedPane().selectTab(view.viewId(), true);
|
|
787
786
|
if (!skipReveal) {
|
|
788
787
|
this.#setNavigatorSidebarOpen(true);
|
|
789
|
-
|
|
788
|
+
}
|
|
789
|
+
await navigatorView.updateComplete;
|
|
790
|
+
navigatorView.revealUISourceCode(uiSourceCode, true);
|
|
791
|
+
if (!skipReveal) {
|
|
790
792
|
navigatorView.focus();
|
|
791
793
|
}
|
|
792
794
|
break;
|
|
@@ -916,7 +918,9 @@ export class SourcesPanel extends UI.Panel.Panel implements
|
|
|
916
918
|
|
|
917
919
|
#editorClosed({data: {uiSourceCode}}: Common.EventTarget.EventTargetEvent<EditorClosedEvent>): void {
|
|
918
920
|
const context = UI.Context.Context.instance();
|
|
919
|
-
|
|
921
|
+
const currentFlavor = context.flavor(Workspace.UISourceCode.UISourceCode);
|
|
922
|
+
const flavorScriptId = currentFlavor?.canonicalScriptId();
|
|
923
|
+
if (currentFlavor === uiSourceCode || (flavorScriptId && flavorScriptId === uiSourceCode.canonicalScriptId())) {
|
|
920
924
|
context.setFlavor(Workspace.UISourceCode.UISourceCode, null);
|
|
921
925
|
}
|
|
922
926
|
}
|
|
@@ -346,6 +346,7 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
346
346
|
const icon = !hasLoadError ?
|
|
347
347
|
(PanelCommon.PersistenceUtils.PersistenceUtils.iconForUISourceCode(uiSourceCode) ?? undefined) :
|
|
348
348
|
undefined;
|
|
349
|
+
const viewSourceCode = this.#tabViewSourceCodes.get(tabId) ?? uiSourceCode;
|
|
349
350
|
return {
|
|
350
351
|
tabId,
|
|
351
352
|
title: titleForFile(uiSourceCode),
|
|
@@ -357,8 +358,8 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
357
358
|
disconnectedAutomaticFileSystemRoot,
|
|
358
359
|
icon,
|
|
359
360
|
widget: (this.#currentFile?.canonicalScriptId() === uiSourceCode.canonicalScriptId()) ?
|
|
360
|
-
this.#getOrCreateSourceView(
|
|
361
|
-
this.getCreatedSourceView(
|
|
361
|
+
this.#getOrCreateSourceView(viewSourceCode) :
|
|
362
|
+
this.getCreatedSourceView(viewSourceCode),
|
|
362
363
|
};
|
|
363
364
|
}),
|
|
364
365
|
activeTabId: this.#currentFile ? this.#tabIdForUISourceCode(this.#currentFile) : undefined,
|
|
@@ -457,6 +458,12 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
457
458
|
readonly #tabDelegate: EditorContainerTabDelegate;
|
|
458
459
|
#tabIds: Map<Workspace.UISourceCode.UISourceCode, string>;
|
|
459
460
|
#files: Map<string, Workspace.UISourceCode.UISourceCode>;
|
|
461
|
+
/**
|
|
462
|
+
* Maps a tab id to the UISourceCode whose view is currently bound to that
|
|
463
|
+
* tab. This can differ from the canonical UISourceCode in `#files` when the
|
|
464
|
+
* tab's view was recycled to show a duplicate script with the same URL.
|
|
465
|
+
*/
|
|
466
|
+
readonly #tabViewSourceCodes = new Map<string, Workspace.UISourceCode.UISourceCode>();
|
|
460
467
|
readonly #loadErrorFiles = new Set<Workspace.UISourceCode.UISourceCode>();
|
|
461
468
|
#previouslyViewedFilesSetting: Common.Settings.Setting<SerializedHistoryItem[]>;
|
|
462
469
|
#history: History;
|
|
@@ -602,7 +609,9 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
602
609
|
}
|
|
603
610
|
|
|
604
611
|
fileViews(): UI.Widget.Widget[] {
|
|
605
|
-
return Array.from(this.#files.
|
|
612
|
+
return Array.from(this.#files.entries())
|
|
613
|
+
.map(([tabId, file]) => getViewByUISourceCode(this.#tabViewSourceCodes.get(tabId) ?? file))
|
|
614
|
+
.filter(Boolean) as UI.Widget.Widget[];
|
|
606
615
|
}
|
|
607
616
|
|
|
608
617
|
showSourceLocation(uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
@@ -785,13 +794,30 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
785
794
|
this.#removeViewListeners();
|
|
786
795
|
this.#currentFile = uiSourceCode;
|
|
787
796
|
|
|
797
|
+
let tabId: string;
|
|
788
798
|
try {
|
|
789
799
|
// Selecting the tab may cause showFile to be called again, but with the canonical source code,
|
|
790
800
|
// which is not what we want, so we prevent reentrant calls.
|
|
791
801
|
this.#reentrantShow = true;
|
|
792
|
-
|
|
802
|
+
tabId = this.#tabIds.get(canonicalSourceCode) || this.#appendFileTab(canonicalSourceCode);
|
|
793
803
|
this.#appendHistory(tabId);
|
|
794
804
|
|
|
805
|
+
const tabViewSourceCode = this.#tabViewSourceCodes.get(tabId) ?? canonicalSourceCode;
|
|
806
|
+
const tabView = this.#getOrCreateSourceView(tabViewSourceCode);
|
|
807
|
+
if (tabView instanceof UISourceCodeFrame && tabViewSourceCode !== uiSourceCode) {
|
|
808
|
+
// We are showing a different UISourceCode in the same tab (because it has the same URL). This
|
|
809
|
+
// commonly happens when switching between workers or iframes containing the same code, and while the
|
|
810
|
+
// contents are usually identical they may not be and it is important to show users when they aren't.
|
|
811
|
+
this.#recycleUISourceCodeFrame(tabView, uiSourceCode);
|
|
812
|
+
if (uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.FileSystem) {
|
|
813
|
+
// Disable editing, because it may confuse users that only one of the copies of this code changes.
|
|
814
|
+
uiSourceCode.disableEdit();
|
|
815
|
+
}
|
|
816
|
+
} else {
|
|
817
|
+
this.#getOrCreateSourceView(uiSourceCode);
|
|
818
|
+
}
|
|
819
|
+
this.#tabViewSourceCodes.set(tabId, uiSourceCode);
|
|
820
|
+
|
|
795
821
|
this.#scheduleUpdate();
|
|
796
822
|
} finally {
|
|
797
823
|
this.#reentrantShow = false;
|
|
@@ -802,23 +828,9 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
802
828
|
}
|
|
803
829
|
|
|
804
830
|
const previousView = this.#currentView;
|
|
805
|
-
if (uiSourceCode) {
|
|
806
|
-
this.#getOrCreateSourceView(uiSourceCode);
|
|
807
|
-
}
|
|
808
831
|
this.#currentView = this.visibleView;
|
|
809
832
|
this.#addViewListeners();
|
|
810
833
|
|
|
811
|
-
if (this.#currentView instanceof UISourceCodeFrame && this.#currentView.uiSourceCode() !== uiSourceCode) {
|
|
812
|
-
// We are showing a different UISourceCode in the same tab (because it has the same URL). This
|
|
813
|
-
// commonly happens when switching between workers or iframes containing the same code, and while the
|
|
814
|
-
// contents are usually identical they may not be and it is important to show users when they aren't.
|
|
815
|
-
this.#recycleUISourceCodeFrame(this.#currentView, uiSourceCode);
|
|
816
|
-
if (uiSourceCode.project().type() !== Workspace.Workspace.projectTypes.FileSystem) {
|
|
817
|
-
// Disable editing, because it may confuse users that only one of the copies of this code changes.
|
|
818
|
-
uiSourceCode.disableEdit();
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
|
|
822
834
|
const eventData = {
|
|
823
835
|
currentFile: this.#currentFile,
|
|
824
836
|
currentView: this.#currentView,
|
|
@@ -954,6 +966,11 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
954
966
|
tabIds.push(tabId);
|
|
955
967
|
} else {
|
|
956
968
|
this.#removeSourceFrame(uiSourceCode);
|
|
969
|
+
for (const [k, v] of this.#tabViewSourceCodes) {
|
|
970
|
+
if (v === uiSourceCode) {
|
|
971
|
+
this.#tabViewSourceCodes.delete(k);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
957
974
|
}
|
|
958
975
|
for (const [k, v] of this.#uriToUISourceCode) {
|
|
959
976
|
if (v === uiSourceCode) {
|
|
@@ -999,6 +1016,7 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
999
1016
|
#appendFileTab(uiSourceCode: Workspace.UISourceCode.UISourceCode, index?: number, ignoreHistory?: boolean): string {
|
|
1000
1017
|
const tabId = this.#generateTabId();
|
|
1001
1018
|
this.#tabIds.set(uiSourceCode, tabId);
|
|
1019
|
+
this.#tabViewSourceCodes.set(tabId, uiSourceCode);
|
|
1002
1020
|
|
|
1003
1021
|
if (index !== undefined) {
|
|
1004
1022
|
const entries = Array.from(this.#files.entries());
|
|
@@ -1065,6 +1083,11 @@ export class TabbedEditorContainer extends TabbedEditorContainerBase {
|
|
|
1065
1083
|
this.#currentView = null;
|
|
1066
1084
|
this.#currentFile = null;
|
|
1067
1085
|
}
|
|
1086
|
+
const viewSourceCode = this.#tabViewSourceCodes.get(tabId);
|
|
1087
|
+
if (viewSourceCode) {
|
|
1088
|
+
this.#removeSourceFrame(viewSourceCode);
|
|
1089
|
+
this.#tabViewSourceCodes.delete(tabId);
|
|
1090
|
+
}
|
|
1068
1091
|
if (uiSourceCode) {
|
|
1069
1092
|
this.#tabIds.delete(uiSourceCode);
|
|
1070
1093
|
this.#loadErrorFiles.delete(uiSourceCode);
|
|
@@ -337,7 +337,7 @@ export class UISourceCodeFrame extends UISourceCodeFrameBase {
|
|
|
337
337
|
private reloadPlugins(): void {
|
|
338
338
|
this.disposePlugins();
|
|
339
339
|
this.loadPlugins();
|
|
340
|
-
if (!this.
|
|
340
|
+
if (!pluginCompartment.get(this.textEditor.state)) {
|
|
341
341
|
// Until the content is loaded the editor still holds the placeholder
|
|
342
342
|
// state, which doesn't contain `pluginCompartment` at all. Reconfiguring
|
|
343
343
|
// a compartment that isn't part of the state is a no-op, so the plugins
|
|
@@ -101,7 +101,7 @@ interface ViewInput {
|
|
|
101
101
|
onCopyWatchExpression(watchExpression: WatchExpression): void;
|
|
102
102
|
onDeleteAll(): unknown;
|
|
103
103
|
onAddExpression(): unknown;
|
|
104
|
-
onExpand(e: WatchExpression, expanded: boolean): unknown;
|
|
104
|
+
onExpand(e: WatchExpression, expanded: boolean, recursively?: boolean): unknown;
|
|
105
105
|
watchExpressions: WatchExpression[];
|
|
106
106
|
}
|
|
107
107
|
export interface WatchExpressionPromptViewInput {
|
|
@@ -352,7 +352,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
352
352
|
class=${classMap({'watch-expression-tree-item': true, 'watch-expression-editing': e.editing })}
|
|
353
353
|
?open=${Boolean(e.result?.expanded)}
|
|
354
354
|
@keydown=${onExpressionKeydown.bind(undefined, e)}
|
|
355
|
-
@expand=${(event: UI.TreeOutline.TreeViewElement.ExpandEvent) => input.onExpand(e, event.detail.expanded)}
|
|
355
|
+
@expand=${(event: UI.TreeOutline.TreeViewElement.ExpandEvent) => input.onExpand(e, event.detail.expanded, event.detail.recursively)}
|
|
356
356
|
role=treeitem>
|
|
357
357
|
<devtools-widget ${widget(WatchExpressionPromptWidget, {
|
|
358
358
|
expression: e,
|
|
@@ -549,10 +549,15 @@ export class WatchExpressionsSidebarPane extends UI.Widget.VBox implements UI.Ac
|
|
|
549
549
|
this.saveExpressions();
|
|
550
550
|
this.requestUpdate();
|
|
551
551
|
},
|
|
552
|
-
onExpand: (e: WatchExpression, expanded: boolean): void => {
|
|
553
|
-
if (e.result) {
|
|
554
|
-
|
|
552
|
+
onExpand: (e: WatchExpression, expanded: boolean, recursively = false): void => {
|
|
553
|
+
if (!e.result) {
|
|
554
|
+
return;
|
|
555
|
+
}
|
|
556
|
+
if (expanded && recursively) {
|
|
557
|
+
void e.result.expandRecursively().then(() => this.requestUpdate());
|
|
558
|
+
return;
|
|
555
559
|
}
|
|
560
|
+
e.result.expanded = expanded;
|
|
556
561
|
},
|
|
557
562
|
},
|
|
558
563
|
{}, this.contentElement);
|
|
@@ -227,11 +227,6 @@ const UIStrings = {
|
|
|
227
227
|
* @description Title of an action in the sources tool to create a snippet.
|
|
228
228
|
*/
|
|
229
229
|
createNewSnippet: 'Create new snippet',
|
|
230
|
-
/**
|
|
231
|
-
* @description Button in the Workspace tab of the Sources panel, used to
|
|
232
|
-
* (manually) add a folder to the workspace.
|
|
233
|
-
*/
|
|
234
|
-
addFolderManually: 'Add folder manually',
|
|
235
230
|
/**
|
|
236
231
|
* @description Title of an action in the Sources panel command menu to (manually)
|
|
237
232
|
* add a folder to the workspace.
|
|
@@ -564,9 +559,9 @@ UI.ViewManager.registerViewExtension({
|
|
|
564
559
|
order: 3,
|
|
565
560
|
persistence: UI.ViewManager.ViewPersistence.PERMANENT,
|
|
566
561
|
condition: () => !Root.Runtime.Runtime.isTraceApp(),
|
|
567
|
-
async loadView(
|
|
562
|
+
async loadView() {
|
|
568
563
|
const Sources = await loadSourcesModule();
|
|
569
|
-
return new Sources.SourcesNavigator.FilesNavigatorView(
|
|
564
|
+
return new Sources.SourcesNavigator.FilesNavigatorView();
|
|
570
565
|
},
|
|
571
566
|
});
|
|
572
567
|
|
|
@@ -578,9 +573,9 @@ UI.ViewManager.registerViewExtension({
|
|
|
578
573
|
order: 6,
|
|
579
574
|
persistence: UI.ViewManager.ViewPersistence.PERMANENT,
|
|
580
575
|
condition: () => !Root.Runtime.Runtime.isTraceApp(),
|
|
581
|
-
async loadView(
|
|
576
|
+
async loadView() {
|
|
582
577
|
const Sources = await loadSourcesModule();
|
|
583
|
-
return new Sources.SourcesNavigator.SnippetsNavigatorView(
|
|
578
|
+
return new Sources.SourcesNavigator.SnippetsNavigatorView();
|
|
584
579
|
},
|
|
585
580
|
});
|
|
586
581
|
|
|
@@ -2055,12 +2050,6 @@ Common.Revealer.registerRevealer({
|
|
|
2055
2050
|
},
|
|
2056
2051
|
});
|
|
2057
2052
|
|
|
2058
|
-
UI.Toolbar.registerToolbarItem({
|
|
2059
|
-
actionId: 'sources.add-folder-to-workspace',
|
|
2060
|
-
location: UI.Toolbar.ToolbarItemLocation.FILES_NAVIGATION_TOOLBAR,
|
|
2061
|
-
label: i18nLazyString(UIStrings.addFolderManually),
|
|
2062
|
-
});
|
|
2063
|
-
|
|
2064
2053
|
UI.Context.registerListener({
|
|
2065
2054
|
contextTypes() {
|
|
2066
2055
|
return [SDK.DebuggerModel.DebuggerPausedDetails];
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
flex-shrink: 0;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
.navigator-toolbar {
|
|
13
|
+
border-bottom: var(--sys-size-1) solid var(--sys-color-divider);
|
|
14
|
+
padding-left: var(--sys-size-5);
|
|
15
|
+
}
|
|
16
|
+
|
|
12
17
|
.automatic-workspace-infobar {
|
|
13
18
|
border-top: var(--sys-size-1) solid var(--sys-color-divider);
|
|
14
19
|
}
|
|
@@ -35,7 +35,6 @@ interface ModificationsManagerData {
|
|
|
35
35
|
parsedTrace: Trace.TraceModel.ParsedTrace;
|
|
36
36
|
traceBounds: Trace.Types.Timing.TraceWindowMicro;
|
|
37
37
|
rawTraceEvents: readonly Trace.Types.Events.Event[];
|
|
38
|
-
syntheticEvents: Trace.Types.Events.SyntheticBased[];
|
|
39
38
|
modifications?: Trace.Types.File.Modifications;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -90,7 +89,6 @@ export class ModificationsManager extends EventTarget {
|
|
|
90
89
|
traceBounds,
|
|
91
90
|
rawTraceEvents: parsedTrace.traceEvents,
|
|
92
91
|
modifications: parsedTrace.metadata.modifications,
|
|
93
|
-
syntheticEvents: parsedTrace.syntheticEventsManager.getSyntheticTraces(),
|
|
94
92
|
});
|
|
95
93
|
modificationsManagerByTraceIndex[traceIndex] = newModificationsManager;
|
|
96
94
|
activeManager = newModificationsManager;
|
|
@@ -185,6 +185,8 @@ Comments on flame chart entries use the shared comments UI from `ui/comments` an
|
|
|
185
185
|
|
|
186
186
|
The pin and the `COMMENT_PIN` element are separate elements in separate layers, and moving the element fires no DOM scroll or resize event, so step 2 is what keeps the pin on its entry. See the `CustomAnchorResolver` documentation in `ui/comments/CommentAnchorResolver.ts` for the contract.
|
|
187
187
|
|
|
188
|
+
Entries without an `EventsSerializer` key, such as JS samples, use a synthetic key and are found again by start time, duration and title.
|
|
189
|
+
|
|
188
190
|
## Timeline tree views
|
|
189
191
|
|
|
190
192
|
The `TimelineTreeView` base class provides the foundation for creating various tree-based views within the Performance panel (e.g., Summary, Bottom-Up, Call Tree, Event Log). It handles core functionality like:
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
// Copyright 2026 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.
|
|
4
|
+
|
|
5
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
6
|
+
import * as AIAssistance from '../../models/ai_assistance/ai_assistance.js';
|
|
7
|
+
import * as Trace from '../../models/trace/trace.js';
|
|
8
|
+
import * as SourceMapsResolver from '../../models/trace_source_maps_resolver/trace_source_maps_resolver.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A long call path keeps this many outermost entries, which usually say why
|
|
12
|
+
* the code ran, such as `Task > Event: click > Function call`.
|
|
13
|
+
*/
|
|
14
|
+
const CALL_PATH_OUTER_ENTRIES = 3;
|
|
15
|
+
/**
|
|
16
|
+
* A long call path keeps this many innermost entries, ending with the
|
|
17
|
+
* commented entry itself.
|
|
18
|
+
*/
|
|
19
|
+
const CALL_PATH_INNER_ENTRIES = 15;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Returns the English label of a trace warning. These lines are read by the
|
|
23
|
+
* AI agent, not shown in the UI, so they are not localized.
|
|
24
|
+
*/
|
|
25
|
+
function labelForWarning(warning: Trace.Handlers.ModelHandlers.Warnings.Warning): string {
|
|
26
|
+
switch (warning) {
|
|
27
|
+
case 'LONG_TASK':
|
|
28
|
+
return 'Long task';
|
|
29
|
+
case 'IDLE_CALLBACK_OVER_TIME':
|
|
30
|
+
return 'Idle callback over time';
|
|
31
|
+
case 'FORCED_REFLOW':
|
|
32
|
+
return 'Forced reflow';
|
|
33
|
+
case 'LONG_INTERACTION':
|
|
34
|
+
return 'Long interaction';
|
|
35
|
+
default:
|
|
36
|
+
Platform.assertNever(warning, `Unknown warning: ${warning}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Returns the location of the entry's code as `url:line:column`, with
|
|
42
|
+
* 1-based line and column numbers as editors show them, or null if the entry
|
|
43
|
+
* has no code location. The location is in the authored source if a source
|
|
44
|
+
* map resolved it.
|
|
45
|
+
*
|
|
46
|
+
* This follows SourceMapsResolver.codeLocationForEntry() but skips its
|
|
47
|
+
* Workspace lookup, which only maps a bare URL to a workspace URL, so that
|
|
48
|
+
* the controller does not need a Workspace.
|
|
49
|
+
*
|
|
50
|
+
* Network requests are skipped: their URL is the request, not code, and a
|
|
51
|
+
* cross-origin request's final URL must be redacted.
|
|
52
|
+
*/
|
|
53
|
+
function sourceLocationForEntry(event: Trace.Types.Events.Event, parsedTrace: Trace.TraceModel.ParsedTrace): string|
|
|
54
|
+
null {
|
|
55
|
+
if (Trace.Types.Events.isSyntheticNetworkRequest(event)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
let url: string|null = null;
|
|
59
|
+
let line: number|undefined;
|
|
60
|
+
let column: number|undefined;
|
|
61
|
+
const uiLocation = SourceMapsResolver.SourceMapsResolver.resolvedCodeLocationForEntry(event)?.devtoolsLocation;
|
|
62
|
+
const rawCallFrame = uiLocation ? null : Trace.Helpers.Trace.rawCallFrameForEntry(event);
|
|
63
|
+
if (uiLocation) {
|
|
64
|
+
url = uiLocation.uiSourceCode.url();
|
|
65
|
+
line = uiLocation.lineNumber;
|
|
66
|
+
column = uiLocation.columnNumber;
|
|
67
|
+
} else if (rawCallFrame) {
|
|
68
|
+
url = rawCallFrame.url;
|
|
69
|
+
line = rawCallFrame.lineNumber >= 0 ? rawCallFrame.lineNumber : undefined;
|
|
70
|
+
column = rawCallFrame.columnNumber >= 0 ? rawCallFrame.columnNumber : undefined;
|
|
71
|
+
} else {
|
|
72
|
+
url = Trace.Handlers.Helpers.getNonResolvedURL(event, parsedTrace.data);
|
|
73
|
+
}
|
|
74
|
+
if (!url) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
if (line === undefined) {
|
|
78
|
+
return url;
|
|
79
|
+
}
|
|
80
|
+
return column === undefined ? `${url}:${line + 1}` : `${url}:${line + 1}:${column + 1}`;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Returns the names of the entry's ancestors and the entry itself, outermost
|
|
85
|
+
* first, for example `Task > Timer fired > Function call > handleClick`, or
|
|
86
|
+
* null if the entry has no ancestors.
|
|
87
|
+
*
|
|
88
|
+
* JS call stacks can be hundreds of entries deep, so a long call path keeps
|
|
89
|
+
* only its outermost and innermost entries and says how many it skipped, for
|
|
90
|
+
* example `Task > Event: click > Function call > … (240 more) > render > …`.
|
|
91
|
+
*/
|
|
92
|
+
function callPathForEntry(event: Trace.Types.Events.Event, parsedTrace: Trace.TraceModel.ParsedTrace): string|null {
|
|
93
|
+
const node = parsedTrace.data.Renderer.entryToNode.get(event) ?? parsedTrace.data.Samples.entryToNode.get(event);
|
|
94
|
+
if (!node?.parent) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const names: string[] = [];
|
|
98
|
+
for (let current: Trace.Helpers.TreeHelpers.TraceEntryNode|null = node; current; current = current.parent) {
|
|
99
|
+
names.push(Trace.Name.forEntry(current.entry, parsedTrace));
|
|
100
|
+
}
|
|
101
|
+
// The walk goes from the entry up to the root, so reverse it to put the
|
|
102
|
+
// outermost entry first.
|
|
103
|
+
names.reverse();
|
|
104
|
+
const skippedCount = names.length - CALL_PATH_OUTER_ENTRIES - CALL_PATH_INNER_ENTRIES;
|
|
105
|
+
// Replacing a single entry with a placeholder would not shorten the path.
|
|
106
|
+
if (skippedCount > 1) {
|
|
107
|
+
names.splice(CALL_PATH_OUTER_ENTRIES, skippedCount, `… (${skippedCount} more)`);
|
|
108
|
+
}
|
|
109
|
+
return names.join(' > ');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Describes a flame chart entry for the AI agent that receives comments on
|
|
114
|
+
* it. The entry title is already sent as the anchor's text signature, so the
|
|
115
|
+
* lines add what identifies the entry in the trace and where its code is: the
|
|
116
|
+
* trace event name, the entry's timing, its track, its source location, its
|
|
117
|
+
* call path, its warnings and the page that was traced.
|
|
118
|
+
*
|
|
119
|
+
* Times are relative to the start of the trace, which is where the
|
|
120
|
+
* Performance panel's time ruler starts.
|
|
121
|
+
*
|
|
122
|
+
* Lines without a value are omitted.
|
|
123
|
+
*/
|
|
124
|
+
export function agentContextForEntry(
|
|
125
|
+
event: Trace.Types.Events.Event,
|
|
126
|
+
trackName: string|null,
|
|
127
|
+
parsedTrace: Trace.TraceModel.ParsedTrace,
|
|
128
|
+
): string[] {
|
|
129
|
+
const {micros} = AIAssistance.UnitFormatters;
|
|
130
|
+
const lines: string[] = [];
|
|
131
|
+
|
|
132
|
+
lines.push(`Trace event: ${event.name}`);
|
|
133
|
+
|
|
134
|
+
const timing = [`starts at ${micros(event.ts - parsedTrace.data.Meta.traceBounds.min)}`];
|
|
135
|
+
if (event.dur) {
|
|
136
|
+
timing.push(`duration ${micros(event.dur)}`);
|
|
137
|
+
}
|
|
138
|
+
const selfTime = parsedTrace.data.Renderer.entryToNode.get(event)?.selfTime;
|
|
139
|
+
if (selfTime !== undefined) {
|
|
140
|
+
timing.push(`self time ${micros(selfTime)}`);
|
|
141
|
+
}
|
|
142
|
+
lines.push(`Timing: ${timing.join(', ')}`);
|
|
143
|
+
|
|
144
|
+
if (trackName) {
|
|
145
|
+
lines.push(`Track: ${trackName}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const sourceLocation = sourceLocationForEntry(event, parsedTrace);
|
|
149
|
+
if (sourceLocation) {
|
|
150
|
+
lines.push(`Source: ${sourceLocation}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const callPath = callPathForEntry(event, parsedTrace);
|
|
154
|
+
if (callPath) {
|
|
155
|
+
lines.push(`Call path: ${callPath}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const warnings = parsedTrace.data.Warnings.perEvent.get(event);
|
|
159
|
+
if (warnings?.length) {
|
|
160
|
+
lines.push(`Warnings: ${warnings.map(labelForWarning).join(', ')}`);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The main frame URL is same-origin with the trace by definition, so it
|
|
164
|
+
// does not need redaction.
|
|
165
|
+
const mainFrameURL = parsedTrace.data.Meta.mainFrameURL;
|
|
166
|
+
if (mainFrameURL) {
|
|
167
|
+
lines.push(`Traced page: ${mainFrameURL}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return lines;
|
|
171
|
+
}
|