chrome-devtools-frontend 1.0.1721762 → 1.0.1724140
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/docs/cookbook/dependencies.md +55 -11
- package/docs/get_the_code.md +15 -0
- package/front_end/core/i18n/collect-ui-strings.js +58 -12
- package/front_end/core/sdk/WebAuthnModel.ts +17 -10
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/protocol.ts +16 -0
- package/front_end/models/comment_manager/CD4ABridge.ts +4 -0
- package/front_end/models/comment_manager/CommentThread.ts +16 -0
- package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +13 -6
- package/front_end/panels/accessibility/AccessibilityAnnouncementRecordingView.ts +92 -0
- package/front_end/panels/accessibility/accessibilityAnnouncementRecordingListView.css +3 -1
- package/front_end/panels/accessibility/accessibilityAnnouncementRecordingView.css +12 -1
- package/front_end/panels/application/StorageView.ts +250 -178
- package/front_end/panels/application/SubAppsView.ts +159 -0
- package/front_end/panels/application/application.ts +2 -0
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +1 -1
- package/front_end/panels/application/subAppsView.css +21 -0
- package/front_end/panels/elements/ClassesPaneWidget.ts +3 -1
- package/front_end/panels/elements/DOMTreeElementWidget.ts +3 -1
- package/front_end/panels/elements/DOMTreeWidget.ts +12 -0
- package/front_end/panels/elements/StyleEditorWidget.ts +29 -0
- package/front_end/panels/elements/StylesSidebarPane.ts +1 -0
- package/front_end/panels/layer_viewer/Layers3DView.ts +21 -37
- package/front_end/panels/network/NetworkConfigView.ts +12 -10
- package/front_end/panels/network/networkConfigView.css +8 -8
- package/front_end/panels/screencast/ScreencastView.ts +3 -6
- package/front_end/panels/security/SecurityPanelSidebar.ts +0 -31
- 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/SourcesPanel.ts +3 -1
- package/front_end/panels/sources/TabbedEditorContainer.ts +41 -18
- package/front_end/panels/sources/UISourceCodeFrame.ts +1 -1
- package/front_end/panels/timeline/TimelineCommentContext.ts +171 -0
- package/front_end/panels/timeline/TimelineCommentController.ts +36 -0
- package/front_end/panels/timeline/timeline.ts +2 -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/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/Treeoutline.ts +3 -1
- package/front_end/ui/legacy/UIUtils.ts +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +4 -0
- package/package.json +1 -1
|
@@ -4,155 +4,170 @@
|
|
|
4
4
|
* found in the LICENSE file.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
@scope to (devtools-widget > *) {
|
|
8
|
+
/* Host styles can now reach the elements of this form. For example,
|
|
9
|
+
* the inspector common styles set "box-sizing: border-box" on all
|
|
10
|
+
* elements, and ListWidget editors set margins on all inputs. Restore
|
|
11
|
+
* the default box sizing and input margins of the browser. */
|
|
12
|
+
:scope * {
|
|
13
|
+
box-sizing: revert;
|
|
14
|
+
}
|
|
11
15
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
align-items: center;
|
|
16
|
+
:scope input {
|
|
17
|
+
margin: revert;
|
|
18
|
+
}
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
.root {
|
|
21
|
+
color: var(--sys-color-on-surface);
|
|
22
|
+
width: 100%;
|
|
23
|
+
}
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
.tree-title {
|
|
26
|
+
font-weight: 700;
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
25
29
|
|
|
26
|
-
&
|
|
27
|
-
|
|
28
|
-
|
|
30
|
+
& > [aria-controls="form-container"] {
|
|
31
|
+
margin-left: var(--sys-size-2);
|
|
32
|
+
padding-right: var(--sys-size-3);
|
|
33
|
+
|
|
34
|
+
& > [name="triangle-right"],
|
|
35
|
+
& > [name="triangle-down"] {
|
|
36
|
+
vertical-align: bottom;
|
|
37
|
+
}
|
|
29
38
|
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
&[aria-expanded="true"] > [name="triangle-right"] {
|
|
40
|
+
display: none;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&[aria-expanded="false"] > [name="triangle-down"] {
|
|
44
|
+
display: none;
|
|
45
|
+
}
|
|
32
46
|
}
|
|
33
47
|
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
.form-container {
|
|
37
|
-
display: grid;
|
|
38
|
-
grid-template-columns: 1fr 1fr 1fr auto;
|
|
39
|
-
align-items: center;
|
|
40
|
-
gap: var(--sys-size-5) 10px;
|
|
41
|
-
padding: 0 10px;
|
|
42
|
-
}
|
|
43
48
|
|
|
44
|
-
.
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
.form-container {
|
|
50
|
+
display: grid;
|
|
51
|
+
grid-template-columns: 1fr 1fr 1fr auto;
|
|
52
|
+
align-items: center;
|
|
53
|
+
gap: var(--sys-size-5) 10px;
|
|
54
|
+
padding: 0 10px;
|
|
55
|
+
}
|
|
47
56
|
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
gap: var(--sys-size-4) 10px;
|
|
52
|
-
}
|
|
57
|
+
.full-row {
|
|
58
|
+
grid-column: 1 / 5;
|
|
59
|
+
}
|
|
53
60
|
|
|
54
|
-
.form-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
61
|
+
.form-factors-checkbox-group {
|
|
62
|
+
display: grid;
|
|
63
|
+
grid-template-columns: repeat(2, 1fr);
|
|
64
|
+
gap: var(--sys-size-4) 10px;
|
|
65
|
+
}
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
.form-factor-checkbox-label {
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
gap: var(--sys-size-4);
|
|
71
|
+
white-space: nowrap;
|
|
72
|
+
}
|
|
66
73
|
|
|
67
|
-
.
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
hr.section-separator {
|
|
75
|
+
grid-column: 1 / 5; /* Ensures the separator spans all columns */
|
|
76
|
+
border: none;
|
|
77
|
+
margin-top: var(--sys-size-1);
|
|
78
|
+
}
|
|
70
79
|
|
|
71
|
-
.
|
|
72
|
-
|
|
73
|
-
}
|
|
80
|
+
.half-row {
|
|
81
|
+
grid-column: span 2;
|
|
82
|
+
}
|
|
74
83
|
|
|
75
|
-
.
|
|
76
|
-
|
|
77
|
-
}
|
|
84
|
+
.mobile-checkbox-container {
|
|
85
|
+
display: flex;
|
|
86
|
+
}
|
|
78
87
|
|
|
79
|
-
.input
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
border-radius: var(--sys-size-2);
|
|
83
|
-
border: var(--sys-size-1) solid var(--sys-color-neutral-outline);
|
|
84
|
-
background-color: var(--sys-color-cdt-base-container);
|
|
85
|
-
font-size: inherit;
|
|
86
|
-
height: 18px;
|
|
87
|
-
}
|
|
88
|
+
.device-model-input {
|
|
89
|
+
grid-column: 1 / 4;
|
|
90
|
+
}
|
|
88
91
|
|
|
89
|
-
.input-field
|
|
90
|
-
color: var(--sys-color-on-surface
|
|
91
|
-
|
|
92
|
+
.input-field {
|
|
93
|
+
color: var(--sys-color-on-surface);
|
|
94
|
+
padding: 3px var(--sys-size-4);
|
|
95
|
+
border-radius: var(--sys-size-2);
|
|
96
|
+
border: var(--sys-size-1) solid var(--sys-color-neutral-outline);
|
|
97
|
+
background-color: var(--sys-color-cdt-base-container);
|
|
98
|
+
font-family: inherit;
|
|
99
|
+
font-size: inherit;
|
|
100
|
+
height: 18px;
|
|
101
|
+
}
|
|
92
102
|
|
|
93
|
-
.input-field
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}
|
|
103
|
+
.input-field::placeholder {
|
|
104
|
+
color: var(--sys-color-on-surface-subtle);
|
|
105
|
+
}
|
|
97
106
|
|
|
98
|
-
.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
gap: var(--sys-size-4);
|
|
103
|
-
}
|
|
107
|
+
.input-field:focus {
|
|
108
|
+
border: var(--sys-size-1) solid var(--sys-color-state-focus-ring);
|
|
109
|
+
outline-style: none;
|
|
110
|
+
}
|
|
104
111
|
|
|
105
|
-
.add-
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
.add-container {
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
gap: var(--sys-size-4);
|
|
117
|
+
}
|
|
108
118
|
|
|
109
|
-
.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
gap: 10px;
|
|
113
|
-
justify-content: space-between;
|
|
114
|
-
}
|
|
119
|
+
.add-icon {
|
|
120
|
+
margin-right: 5px;
|
|
121
|
+
}
|
|
115
122
|
|
|
116
|
-
.brand-row
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
.brand-row {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
gap: 10px;
|
|
127
|
+
justify-content: space-between;
|
|
128
|
+
}
|
|
119
129
|
|
|
120
|
-
.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
height: var(--sys-size-8);
|
|
124
|
-
width: var(--sys-size-8);
|
|
125
|
-
}
|
|
130
|
+
.brand-row > input {
|
|
131
|
+
width: 100%;
|
|
132
|
+
}
|
|
126
133
|
|
|
127
|
-
.
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
font-weight: 400;
|
|
134
|
-
}
|
|
134
|
+
.info-icon {
|
|
135
|
+
margin-left: 5px;
|
|
136
|
+
margin-right: var(--sys-size-1);
|
|
137
|
+
height: var(--sys-size-8);
|
|
138
|
+
width: var(--sys-size-8);
|
|
139
|
+
}
|
|
135
140
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
141
|
+
.link,
|
|
142
|
+
.devtools-link {
|
|
143
|
+
color: var(--sys-color-primary);
|
|
144
|
+
text-decoration: underline;
|
|
145
|
+
cursor: pointer;
|
|
146
|
+
outline-offset: var(--sys-size-2);
|
|
147
|
+
font-weight: 400;
|
|
148
|
+
}
|
|
139
149
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
}
|
|
150
|
+
devtools-icon + .link {
|
|
151
|
+
margin-inline-start: var(--sys-size-2);
|
|
152
|
+
}
|
|
143
153
|
|
|
144
|
-
.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
gap: 10px;
|
|
148
|
-
}
|
|
154
|
+
.hide-container {
|
|
155
|
+
display: none;
|
|
156
|
+
}
|
|
149
157
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
158
|
+
.input-field-label-container {
|
|
159
|
+
display: flex;
|
|
160
|
+
flex-direction: column;
|
|
161
|
+
gap: 10px;
|
|
153
162
|
}
|
|
154
163
|
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
@media (forced-colors: active) {
|
|
165
|
+
.input-field {
|
|
166
|
+
border: var(--sys-size-1) solid;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.tree-title[aria-disabled="true"] {
|
|
170
|
+
color: GrayText;
|
|
171
|
+
}
|
|
157
172
|
}
|
|
158
173
|
}
|
|
@@ -916,7 +916,9 @@ export class SourcesPanel extends UI.Panel.Panel implements
|
|
|
916
916
|
|
|
917
917
|
#editorClosed({data: {uiSourceCode}}: Common.EventTarget.EventTargetEvent<EditorClosedEvent>): void {
|
|
918
918
|
const context = UI.Context.Context.instance();
|
|
919
|
-
|
|
919
|
+
const currentFlavor = context.flavor(Workspace.UISourceCode.UISourceCode);
|
|
920
|
+
const flavorScriptId = currentFlavor?.canonicalScriptId();
|
|
921
|
+
if (currentFlavor === uiSourceCode || (flavorScriptId && flavorScriptId === uiSourceCode.canonicalScriptId())) {
|
|
920
922
|
context.setFlavor(Workspace.UISourceCode.UISourceCode, null);
|
|
921
923
|
}
|
|
922
924
|
}
|
|
@@ -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
|
|
@@ -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
|
+
}
|
|
@@ -9,6 +9,7 @@ import type * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
|
|
9
9
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
10
10
|
|
|
11
11
|
import * as Overlays from './overlays/overlays.js';
|
|
12
|
+
import {agentContextForEntry} from './TimelineCommentContext.js';
|
|
12
13
|
import type {TimelineFlameChartDataProvider} from './TimelineFlameChartDataProvider.js';
|
|
13
14
|
import type {TimelineFlameChartNetworkDataProvider} from './TimelineFlameChartNetworkDataProvider.js';
|
|
14
15
|
|
|
@@ -338,9 +339,44 @@ export class TimelineCommentController {
|
|
|
338
339
|
durationMicro,
|
|
339
340
|
chartLocation,
|
|
340
341
|
},
|
|
342
|
+
agentContext: this.#agentContextFor(entry),
|
|
341
343
|
},
|
|
342
344
|
anchorElement: canvas,
|
|
343
345
|
highlightRect,
|
|
344
346
|
};
|
|
345
347
|
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Returns the lines that describe the entry to the AI agent, or undefined
|
|
351
|
+
* if no trace is active.
|
|
352
|
+
*/
|
|
353
|
+
#agentContextFor(entry: ResolvedEntry): string[]|undefined {
|
|
354
|
+
if (!this.#parsedTrace) {
|
|
355
|
+
return undefined;
|
|
356
|
+
}
|
|
357
|
+
return agentContextForEntry(entry.event, this.#trackNameFor(entry), this.#parsedTrace);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Returns the name of the track that contains the entry. Groups are stored
|
|
362
|
+
* in level order and nested groups follow their parent, so the entry's
|
|
363
|
+
* track is the last group that starts at or above the entry's level. The
|
|
364
|
+
* data provider's groupForEvent() is not used because it only knows tracks
|
|
365
|
+
* built by track appenders, and not, for example, the Frames track.
|
|
366
|
+
*/
|
|
367
|
+
#trackNameFor(entry: ResolvedEntry): string|null {
|
|
368
|
+
const timelineData = entry.flameChart.timelineData();
|
|
369
|
+
if (!timelineData) {
|
|
370
|
+
return null;
|
|
371
|
+
}
|
|
372
|
+
const level = timelineData.entryLevels[entry.entryIndex];
|
|
373
|
+
let trackName: string|null = null;
|
|
374
|
+
for (const group of timelineData.groups) {
|
|
375
|
+
if (group.startLevel > level) {
|
|
376
|
+
break;
|
|
377
|
+
}
|
|
378
|
+
trackName = group.name;
|
|
379
|
+
}
|
|
380
|
+
return trackName;
|
|
381
|
+
}
|
|
346
382
|
}
|
|
@@ -23,6 +23,7 @@ import * as StatusDialog from './StatusDialog.js';
|
|
|
23
23
|
import * as TargetForEvent from './TargetForEvent.js';
|
|
24
24
|
import * as ThirdPartyTreeView from './ThirdPartyTreeView.js';
|
|
25
25
|
import * as ThreadAppender from './ThreadAppender.js';
|
|
26
|
+
import * as TimelineCommentContext from './TimelineCommentContext.js';
|
|
26
27
|
import * as TimelineCommentController from './TimelineCommentController.js';
|
|
27
28
|
import * as TimelineController from './TimelineController.js';
|
|
28
29
|
import * as TimelineDetailsView from './TimelineDetailsView.js';
|
|
@@ -69,6 +70,7 @@ export {
|
|
|
69
70
|
TargetForEvent,
|
|
70
71
|
ThirdPartyTreeView,
|
|
71
72
|
ThreadAppender,
|
|
73
|
+
TimelineCommentContext,
|
|
72
74
|
TimelineCommentController,
|
|
73
75
|
TimelineController,
|
|
74
76
|
TimelineDetailsView,
|