chrome-devtools-frontend 1.0.1667564 → 1.0.1669021
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/devtools-ci/SKILL.md +65 -0
- package/.agents/skills/devtools-setting-migration/SKILL.md +290 -0
- package/.agents/skills/gerrit-cli/SKILL.md +59 -0
- package/.agents/skills/gerrit-cli/references/commands.md +93 -0
- package/.agents/skills/gerrit-cli/references/workflows.md +56 -0
- package/.agents/skills/gerrit-cli/scripts/gerrit_client_wrapper.py +47 -0
- package/.agents/skills/gerrit-cli/scripts/import_upstream.py +230 -0
- package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +11 -4
- package/.agents/skills/ui-widgets/SKILL.md +25 -1
- package/docs/contributing/infrastructure.md +7 -1
- package/docs/ui_engineering.md +44 -1
- package/front_end/core/common/Settings.ts +11 -4
- package/front_end/core/host/AidaClient.ts +66 -47
- package/front_end/core/host/GcaClient.ts +4 -6
- package/front_end/core/host/ResourceLoader.ts +4 -2
- package/front_end/core/root/Runtime.ts +5 -5
- package/front_end/core/sdk/CSSModel.test.api.ts +102 -0
- package/front_end/core/sdk/CSSModel.ts +3 -2
- package/front_end/core/sdk/ConsoleModel.ts +3 -2
- package/front_end/core/sdk/DebuggerModel.ts +16 -7
- package/front_end/core/sdk/SDKSettings.ts +38 -0
- package/front_end/core/sdk/sdk-meta.ts +0 -120
- package/front_end/core/sdk/sdk.ts +2 -0
- package/front_end/entrypoints/main/MainImpl.ts +10 -3
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +2 -2
- package/front_end/generated/protocol.ts +11 -3
- package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
- package/front_end/models/ai_assistance/AiUtils.ts +67 -4
- package/front_end/models/ai_assistance/BuiltInAi.ts +11 -6
- package/front_end/models/ai_assistance/ChangeManager.ts +17 -1
- package/front_end/models/ai_assistance/StorageItem.ts +26 -5
- package/front_end/models/ai_code_completion/AiCodeCompletion.ts +2 -19
- package/front_end/models/ai_code_generation/AiCodeGeneration.ts +2 -3
- package/front_end/models/javascript_metadata/NativeFunctions.js +22 -9
- package/front_end/models/source_map_scopes/NamesResolver.ts +23 -17
- package/front_end/models/trace/handlers/RendererHandler.ts +20 -4
- package/front_end/models/trace/types/File.ts +1 -0
- package/front_end/models/workspace/UISourceCode.ts +0 -10
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +61 -182
- package/front_end/panels/ai_assistance/components/ChatInput.ts +25 -8
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +13 -69
- package/front_end/panels/ai_assistance/components/ChatView.ts +14 -8
- package/front_end/panels/ai_assistance/components/chatMessage.css +2 -20
- package/front_end/panels/application/ApplicationPanelSidebar.ts +2 -2
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +41 -3
- package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +131 -134
- package/front_end/panels/application/ServiceWorkersView.ts +8 -8
- package/front_end/panels/application/application.ts +2 -0
- package/front_end/panels/application/components/AdsView.ts +10 -6
- package/front_end/panels/application/preloading/PreloadingView.ts +53 -45
- package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +111 -119
- package/front_end/panels/application/preloading/components/preloadingDetailsReportView.css +22 -24
- package/front_end/panels/application/serviceWorkerUpdateCycleView.css +105 -102
- package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +107 -96
- package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +17 -19
- package/front_end/panels/common/AiCodeCompletionTeaser.ts +6 -6
- package/front_end/panels/common/AiCodeGenerationTeaser.ts +28 -26
- package/front_end/panels/common/common.ts +1 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +6 -8
- package/front_end/panels/console/ConsoleView.ts +6 -4
- package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
- package/front_end/panels/console/console-meta.ts +28 -0
- package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +3 -2
- package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -2
- package/front_end/panels/emulation/DeviceModeView.ts +63 -104
- package/front_end/panels/emulation/DeviceModeWrapper.ts +18 -4
- package/front_end/panels/explain/components/ConsoleInsight.ts +4 -6
- package/front_end/panels/explain/explain-meta.ts +7 -49
- package/front_end/panels/network/NetworkDataGridNode.ts +1 -1
- package/front_end/panels/network/NetworkLogView.ts +1 -0
- package/front_end/panels/network/OriginalResourceChunkView.ts +340 -0
- package/front_end/panels/network/ResourceChunkView.ts +72 -46
- package/front_end/panels/network/ResourceDirectSocketChunkView.ts +3 -2
- package/front_end/panels/network/ResourceWebSocketFrameView.ts +3 -3
- package/front_end/panels/network/originalResourceChunkView.css +49 -0
- package/front_end/panels/screencast/ScreencastView.ts +401 -260
- package/front_end/panels/screencast/screencastView.css +113 -100
- package/front_end/panels/sensors/LocationsSettingsTab.ts +329 -135
- package/front_end/panels/sensors/locationsSettingsTab.css +78 -4
- package/front_end/panels/settings/AISettingsTab.ts +17 -100
- package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +2 -2
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +4 -4
- package/front_end/panels/sources/AddSourceMapURLDialog.ts +3 -3
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +4 -3
- package/front_end/panels/sources/BreakpointEditDialog.ts +14 -14
- package/front_end/panels/sources/BreakpointsView.ts +14 -14
- package/front_end/panels/sources/CallStackSidebarPane.ts +6 -6
- package/front_end/panels/sources/CategorizedBreakpointL10n.ts +18 -18
- package/front_end/panels/sources/CoveragePlugin.ts +7 -7
- package/front_end/panels/sources/DebuggerPausedMessage.ts +23 -23
- package/front_end/panels/sources/DebuggerPlugin.ts +31 -31
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -2
- package/front_end/panels/sources/GoToLineQuickOpen.ts +10 -10
- package/front_end/panels/sources/NavigatorView.ts +34 -27
- package/front_end/panels/sources/OutlineQuickOpen.ts +3 -3
- package/front_end/panels/sources/PersistenceActions.ts +9 -9
- package/front_end/panels/sources/ProfilePlugin.ts +1 -1
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +5 -5
- package/front_end/panels/sources/SnippetsPlugin.ts +2 -2
- package/front_end/panels/sources/SourcesNavigator.ts +20 -18
- package/front_end/panels/sources/SourcesPanel.ts +26 -25
- package/front_end/panels/sources/SourcesView.ts +5 -6
- package/front_end/panels/sources/TabbedEditorContainer.ts +3 -3
- package/front_end/panels/sources/ThreadsSidebarPane.ts +1 -1
- package/front_end/panels/sources/UISourceCodeFrame.ts +0 -2
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +7 -7
- package/front_end/panels/sources/components/HeadersView.ts +2 -2
- package/front_end/panels/sources/sources-meta.ts +164 -71
- package/front_end/panels/sources/sources.ts +0 -2
- package/front_end/panels/timeline/TimelineHistoryManager.ts +14 -3
- package/front_end/panels/timeline/TimelineLoader.ts +72 -42
- package/front_end/panels/timeline/TimelinePanel.ts +29 -4
- package/front_end/panels/timeline/timelineHistoryManager.css +4 -0
- 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 +187 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +91 -38
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +145 -2
- 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 +0 -2
- 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 +0 -2
- 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 +0 -2
- 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/Dialog.d.ts +3 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.js +8 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.d.ts +0 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js +0 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +1 -3
- 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 +0 -2
- 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/Realm.d.ts +0 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js +0 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js +12 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js +4 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +5 -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 +49 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.d.ts +0 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.js +0 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.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/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +0 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js +0 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.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/util/disposable.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/util/disposable.js +2 -2
- 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 +187 -1
- package/front_end/third_party/puppeteer/package/package.json +5 -5
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +155 -2
- package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +0 -2
- package/front_end/third_party/puppeteer/package/src/api/Dialog.ts +10 -2
- package/front_end/third_party/puppeteer/package/src/api/JSHandle.ts +0 -2
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +1 -3
- package/front_end/third_party/puppeteer/package/src/api/Realm.ts +0 -1
- package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +4 -2
- package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +17 -0
- package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +5 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +66 -0
- package/front_end/third_party/puppeteer/package/src/common/EventEmitter.ts +0 -6
- package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/injected/util.ts +4 -1
- package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +0 -3
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +9 -7
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +7 -8
- package/front_end/ui/legacy/Dialog.ts +103 -4
- package/front_end/ui/legacy/InspectorView.ts +1 -5
- package/front_end/ui/legacy/PopoverHelper.ts +5 -5
- package/front_end/ui/legacy/TabbedPane.ts +7 -2
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +40 -24
- package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -0
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +8 -4
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +14 -7
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
- package/package.json +1 -1
- package/front_end/panels/sources/AiWarningInfobarPlugin.ts +0 -78
|
@@ -1575,6 +1575,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1575
1575
|
|
|
1576
1576
|
private reset(): void {
|
|
1577
1577
|
this.dispatchEventToListeners(Events.RequestActivated, {showPanel: RequestPanelBehavior.HidePanel});
|
|
1578
|
+
this.dispatchEventToListeners(Events.RequestSelected, null);
|
|
1578
1579
|
|
|
1579
1580
|
this.setHoveredNode(null);
|
|
1580
1581
|
this.columnsInternal.reset();
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
|
|
2
|
+
// Copyright 2025 The Chromium Authors
|
|
3
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
// found in the LICENSE file.
|
|
5
|
+
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
6
|
+
|
|
7
|
+
import * as Common from '../../core/common/common.js';
|
|
8
|
+
import * as Host from '../../core/host/host.js';
|
|
9
|
+
import * as i18n from '../../core/i18n/i18n.js';
|
|
10
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
11
|
+
import type * as SDK from '../../core/sdk/sdk.js';
|
|
12
|
+
import * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
13
|
+
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
14
|
+
import * as SourceFrame from '../../ui/legacy/components/source_frame/source_frame.js';
|
|
15
|
+
import * as UI from '../../ui/legacy/legacy.js';
|
|
16
|
+
|
|
17
|
+
import type {BinaryResourceView} from './BinaryResourceView.js';
|
|
18
|
+
import viewStyles from './originalResourceChunkView.css.js';
|
|
19
|
+
|
|
20
|
+
const UIStrings = {
|
|
21
|
+
/**
|
|
22
|
+
* @description Text in Event Source Messages View of the Network panel
|
|
23
|
+
*/
|
|
24
|
+
data: 'Data',
|
|
25
|
+
/**
|
|
26
|
+
* @description Text in Messages View of the Network panel
|
|
27
|
+
*/
|
|
28
|
+
length: 'Length',
|
|
29
|
+
/**
|
|
30
|
+
* @description Text that refers to the time
|
|
31
|
+
*/
|
|
32
|
+
time: 'Time',
|
|
33
|
+
/**
|
|
34
|
+
* @description Text to clear everything
|
|
35
|
+
*/
|
|
36
|
+
clearAll: 'Clear All',
|
|
37
|
+
/**
|
|
38
|
+
* @description Text to filter result items
|
|
39
|
+
*/
|
|
40
|
+
filter: 'Filter',
|
|
41
|
+
/**
|
|
42
|
+
* @description Text in Messages View of the Network panel that shows if no message is selected for viewing its content
|
|
43
|
+
*/
|
|
44
|
+
noMessageSelected: 'No message selected',
|
|
45
|
+
/**
|
|
46
|
+
* @description Text in Messages View of the Network panel
|
|
47
|
+
*/
|
|
48
|
+
selectMessageToBrowseItsContent: 'Select message to browse its content.',
|
|
49
|
+
/**
|
|
50
|
+
* @description Text in Messages View of the Network panel
|
|
51
|
+
*/
|
|
52
|
+
copyMessageD: 'Copy message…',
|
|
53
|
+
/**
|
|
54
|
+
* @description A context menu item in the Messages View of the Network panel
|
|
55
|
+
*/
|
|
56
|
+
copyMessage: 'Copy message',
|
|
57
|
+
/**
|
|
58
|
+
* @description Text for everything
|
|
59
|
+
*/
|
|
60
|
+
all: 'All',
|
|
61
|
+
/**
|
|
62
|
+
* @description Text in Messages View of the Network panel
|
|
63
|
+
*/
|
|
64
|
+
send: 'Send',
|
|
65
|
+
/**
|
|
66
|
+
* @description Text in Messages View of the Network panel
|
|
67
|
+
*/
|
|
68
|
+
receive: 'Receive',
|
|
69
|
+
} as const;
|
|
70
|
+
const str_ = i18n.i18n.registerUIStrings('panels/network/OriginalResourceChunkView.ts', UIStrings);
|
|
71
|
+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
72
|
+
const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
|
|
73
|
+
|
|
74
|
+
export abstract class OriginalResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
75
|
+
private readonly splitWidget: UI.SplitWidget.SplitWidget;
|
|
76
|
+
private dataGrid: DataGrid.SortableDataGrid.SortableDataGrid<unknown>;
|
|
77
|
+
private readonly timeComparator: (arg0: DataGrid.SortableDataGrid.SortableDataGridNode<DataGridItem>,
|
|
78
|
+
arg1: DataGrid.SortableDataGrid.SortableDataGridNode<DataGridItem>) => number;
|
|
79
|
+
private readonly mainToolbar: UI.Toolbar.Toolbar;
|
|
80
|
+
private readonly clearAllButton: UI.Toolbar.ToolbarButton;
|
|
81
|
+
private readonly filterTypeCombobox: UI.Toolbar.ToolbarComboBox;
|
|
82
|
+
protected filterType: string|null = null;
|
|
83
|
+
private readonly filterTextInput: UI.Toolbar.ToolbarInput;
|
|
84
|
+
protected filterRegex: RegExp|null = null;
|
|
85
|
+
private readonly frameEmptyWidget: UI.EmptyWidget.EmptyWidget;
|
|
86
|
+
private currentSelectedNode?: DataGridItem|null;
|
|
87
|
+
readonly request: SDK.NetworkRequest.NetworkRequest;
|
|
88
|
+
private readonly messageFilterSetting: Common.Settings.Setting<string>;
|
|
89
|
+
private sidebarWidget: UI.Widget.Widget|null = null;
|
|
90
|
+
|
|
91
|
+
abstract getRequestChunks(): Chunk[];
|
|
92
|
+
abstract createGridItem(chunk: Chunk): DataGridItem;
|
|
93
|
+
abstract chunkFilter(chunk: Chunk): boolean;
|
|
94
|
+
|
|
95
|
+
constructor(request: SDK.NetworkRequest.NetworkRequest, messageFilterSettingKey: string,
|
|
96
|
+
splitWidgetSettingKey: string, dataGridDisplayName: Common.UIString.LocalizedString,
|
|
97
|
+
filterUsingRegexHint: Common.UIString.LocalizedString) {
|
|
98
|
+
super();
|
|
99
|
+
this.messageFilterSetting = Common.Settings.Settings.instance().createSetting(messageFilterSettingKey, '');
|
|
100
|
+
this.registerRequiredCSS(viewStyles);
|
|
101
|
+
this.request = request;
|
|
102
|
+
this.element.classList.add('resource-chunk-view');
|
|
103
|
+
|
|
104
|
+
this.splitWidget = new UI.SplitWidget.SplitWidget(false, true, splitWidgetSettingKey);
|
|
105
|
+
this.splitWidget.show(this.element);
|
|
106
|
+
|
|
107
|
+
const columns: DataGrid.DataGrid.ColumnDescriptor[] = this.getColumns();
|
|
108
|
+
|
|
109
|
+
this.dataGrid = new DataGrid.SortableDataGrid.SortableDataGrid({
|
|
110
|
+
displayName: dataGridDisplayName,
|
|
111
|
+
columns,
|
|
112
|
+
});
|
|
113
|
+
this.dataGrid.setRowContextMenuCallback((menu, node) => this.onRowContextMenu(menu, node));
|
|
114
|
+
this.dataGrid.setEnableAutoScrollToBottom(true);
|
|
115
|
+
this.dataGrid.setCellClass('resource-chunk-view-td');
|
|
116
|
+
this.timeComparator = (resourceChunkNodeTimeComparator as
|
|
117
|
+
(arg0: DataGrid.SortableDataGrid.SortableDataGridNode<DataGridItem>,
|
|
118
|
+
arg1: DataGrid.SortableDataGrid.SortableDataGridNode<DataGridItem>) => number);
|
|
119
|
+
this.dataGrid.sortNodes(this.timeComparator, false);
|
|
120
|
+
this.dataGrid.markColumnAsSortedBy('time', DataGrid.DataGrid.Order.Ascending);
|
|
121
|
+
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SORTING_CHANGED, this.sortItems, this);
|
|
122
|
+
|
|
123
|
+
this.dataGrid.setName(splitWidgetSettingKey + '_datagrid');
|
|
124
|
+
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.SELECTED_NODE, event => {
|
|
125
|
+
void this.onChunkSelected(event);
|
|
126
|
+
}, this);
|
|
127
|
+
this.dataGrid.addEventListener(DataGrid.DataGrid.Events.DESELECTED_NODE, this.onChunkDeselected, this);
|
|
128
|
+
|
|
129
|
+
this.mainToolbar = document.createElement('devtools-toolbar');
|
|
130
|
+
|
|
131
|
+
this.clearAllButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.clearAll), 'clear');
|
|
132
|
+
this.clearAllButton.addEventListener(UI.Toolbar.ToolbarButton.Events.CLICK, this.clearChunks, this);
|
|
133
|
+
this.mainToolbar.appendToolbarItem(this.clearAllButton);
|
|
134
|
+
|
|
135
|
+
this.filterTypeCombobox =
|
|
136
|
+
new UI.Toolbar.ToolbarComboBox(this.onFilterTypeChanged.bind(this), i18nString(UIStrings.filter));
|
|
137
|
+
for (const filterItem of FILTER_TYPES) {
|
|
138
|
+
const option = this.filterTypeCombobox.createOption(filterItem.label(), filterItem.name);
|
|
139
|
+
this.filterTypeCombobox.addOption(option);
|
|
140
|
+
}
|
|
141
|
+
this.mainToolbar.appendToolbarItem(this.filterTypeCombobox);
|
|
142
|
+
|
|
143
|
+
this.filterTextInput = new UI.Toolbar.ToolbarFilter(filterUsingRegexHint, 0.4);
|
|
144
|
+
this.filterTextInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.onFilterTextChanged, this);
|
|
145
|
+
const filter = this.messageFilterSetting.get();
|
|
146
|
+
if (filter) {
|
|
147
|
+
this.filterTextInput.setValue(filter);
|
|
148
|
+
}
|
|
149
|
+
this.mainToolbar.appendToolbarItem(this.filterTextInput);
|
|
150
|
+
|
|
151
|
+
const mainContainer = new UI.Widget.VBox();
|
|
152
|
+
mainContainer.element.appendChild(this.mainToolbar);
|
|
153
|
+
this.dataGrid.asWidget().show(mainContainer.element);
|
|
154
|
+
mainContainer.setMinimumSize(0, 72);
|
|
155
|
+
this.splitWidget.setMainWidget(mainContainer);
|
|
156
|
+
|
|
157
|
+
this.frameEmptyWidget = new UI.EmptyWidget.EmptyWidget(i18nString(UIStrings.noMessageSelected),
|
|
158
|
+
i18nString(UIStrings.selectMessageToBrowseItsContent));
|
|
159
|
+
this.sidebarWidget = this.frameEmptyWidget;
|
|
160
|
+
this.splitWidget.setSidebarWidget(this.sidebarWidget);
|
|
161
|
+
|
|
162
|
+
if (filter) {
|
|
163
|
+
this.applyFilter(filter);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private onRowContextMenu(contextMenu: UI.ContextMenu.ContextMenu,
|
|
168
|
+
node: DataGrid.DataGrid.DataGridNode<unknown>): void {
|
|
169
|
+
const item = node as DataGridItem;
|
|
170
|
+
const binaryView = item.binaryView();
|
|
171
|
+
if (binaryView) {
|
|
172
|
+
binaryView.addCopyToContextMenu(contextMenu, i18nString(UIStrings.copyMessageD));
|
|
173
|
+
} else {
|
|
174
|
+
const dataVal = item.data.data;
|
|
175
|
+
const textToCopy = typeof dataVal === 'string' ? dataVal : item.dataText();
|
|
176
|
+
contextMenu.clipboardSection().appendItem(
|
|
177
|
+
i18nString(UIStrings.copyMessage),
|
|
178
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText.bind(
|
|
179
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance, textToCopy),
|
|
180
|
+
{jslogContext: 'copy'});
|
|
181
|
+
}
|
|
182
|
+
contextMenu.footerSection().appendItem(i18nString(UIStrings.clearAll), this.clearChunks.bind(this),
|
|
183
|
+
{jslogContext: 'clear-all'});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
getColumns(): DataGrid.DataGrid.ColumnDescriptor[] {
|
|
187
|
+
return [
|
|
188
|
+
{id: 'data', title: i18nString(UIStrings.data), sortable: false, weight: 88},
|
|
189
|
+
{
|
|
190
|
+
id: 'length',
|
|
191
|
+
title: i18nString(UIStrings.length),
|
|
192
|
+
sortable: false,
|
|
193
|
+
align: DataGrid.DataGrid.Align.RIGHT,
|
|
194
|
+
weight: 5,
|
|
195
|
+
},
|
|
196
|
+
{id: 'time', title: i18nString(UIStrings.time), sortable: true, weight: 7},
|
|
197
|
+
];
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
chunkAdded(chunk: Chunk): void {
|
|
201
|
+
if (!this.chunkFilter(chunk)) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
this.dataGrid.insertChild(this.createGridItem(chunk));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
private clearChunks(): void {
|
|
208
|
+
// TODO(allada): actually remove frames from request.
|
|
209
|
+
clearChunkOffsets.set(this.request, this.getRequestChunks().length);
|
|
210
|
+
this.performUpdate();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private onFilterTypeChanged(): void {
|
|
214
|
+
const val = (this.filterTypeCombobox.selectedOption() as HTMLOptionElement).value;
|
|
215
|
+
this.filterType = val === 'all' ? null : val;
|
|
216
|
+
this.performUpdate();
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private onFilterTextChanged(): void {
|
|
220
|
+
const text = this.filterTextInput.value();
|
|
221
|
+
this.messageFilterSetting.set(text);
|
|
222
|
+
this.applyFilter(text);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private applyFilter(text: string): void {
|
|
226
|
+
if (text) {
|
|
227
|
+
try {
|
|
228
|
+
this.filterRegex = new RegExp(text, 'i');
|
|
229
|
+
} catch {
|
|
230
|
+
this.filterRegex = new RegExp(Platform.StringUtilities.escapeForRegExp(text), 'i');
|
|
231
|
+
}
|
|
232
|
+
} else {
|
|
233
|
+
this.filterRegex = null;
|
|
234
|
+
}
|
|
235
|
+
this.performUpdate();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
private async onChunkSelected(event: Common.EventTarget.EventTargetEvent<DataGrid.DataGrid.DataGridNode<unknown>>):
|
|
239
|
+
Promise<void> {
|
|
240
|
+
this.currentSelectedNode = (event.data as DataGridItem);
|
|
241
|
+
await this.updateSidebar();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
private onChunkDeselected(): void {
|
|
245
|
+
this.currentSelectedNode = null;
|
|
246
|
+
void this.updateSidebar();
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async updateSidebar(): Promise<void> {
|
|
250
|
+
if (!this.currentSelectedNode) {
|
|
251
|
+
this.sidebarWidget = null;
|
|
252
|
+
this.updateSidebarWidget();
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const content = this.currentSelectedNode.dataText();
|
|
257
|
+
|
|
258
|
+
const binaryView = this.currentSelectedNode.binaryView();
|
|
259
|
+
if (binaryView) {
|
|
260
|
+
this.sidebarWidget = binaryView;
|
|
261
|
+
this.updateSidebarWidget();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const jsonView = await SourceFrame.JSONView.JSONView.createView(content);
|
|
266
|
+
if (jsonView) {
|
|
267
|
+
this.sidebarWidget = jsonView;
|
|
268
|
+
this.updateSidebarWidget();
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
this.sidebarWidget = new SourceFrame.ResourceSourceFrame.ResourceSourceFrame(
|
|
273
|
+
TextUtils.StaticContentProvider.StaticContentProvider.fromString(this.request.url(),
|
|
274
|
+
this.request.resourceType(), content),
|
|
275
|
+
'');
|
|
276
|
+
this.updateSidebarWidget();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private updateSidebarWidget(): void {
|
|
280
|
+
const activeSidebar = this.sidebarWidget || this.frameEmptyWidget;
|
|
281
|
+
if (this.splitWidget.sidebarWidget() !== activeSidebar) {
|
|
282
|
+
this.splitWidget.setSidebarWidget(activeSidebar);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
override performUpdate(): void {
|
|
287
|
+
this.dataGrid.rootNode().removeChildren();
|
|
288
|
+
let chunks = this.getRequestChunks();
|
|
289
|
+
const offset = clearChunkOffsets.get(this.request) || 0;
|
|
290
|
+
chunks = chunks.slice(offset).filter(this.chunkFilter.bind(this));
|
|
291
|
+
chunks.forEach(chunk => this.dataGrid.insertChild(this.createGridItem(chunk)));
|
|
292
|
+
|
|
293
|
+
this.updateSidebarWidget();
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
refresh(): void {
|
|
297
|
+
this.performUpdate();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
private sortItems(): void {
|
|
301
|
+
this.dataGrid.sortNodes(this.timeComparator, !this.dataGrid.isSortOrderAscending());
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
getDataGridForTest(): DataGrid.SortableDataGrid.SortableDataGrid<unknown> {
|
|
305
|
+
return this.dataGrid;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
getSplitWidgetForTest(): UI.SplitWidget.SplitWidget {
|
|
309
|
+
return this.splitWidget;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
getFilterInputForTest(): UI.Toolbar.ToolbarInput {
|
|
313
|
+
return this.filterTextInput;
|
|
314
|
+
}
|
|
315
|
+
getClearAllButtonForTest(): UI.Toolbar.ToolbarButton {
|
|
316
|
+
return this.clearAllButton;
|
|
317
|
+
}
|
|
318
|
+
getFilterTypeComboboxForTest(): UI.Toolbar.ToolbarComboBox {
|
|
319
|
+
return this.filterTypeCombobox;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const FILTER_TYPES: UI.FilterBar.Item[] = [
|
|
324
|
+
{name: 'all', label: i18nLazyString(UIStrings.all), jslogContext: 'all'},
|
|
325
|
+
{name: 'send', label: i18nLazyString(UIStrings.send), jslogContext: 'send'},
|
|
326
|
+
{name: 'receive', label: i18nLazyString(UIStrings.receive), jslogContext: 'receive'},
|
|
327
|
+
];
|
|
328
|
+
|
|
329
|
+
export abstract class DataGridItem extends DataGrid.SortableDataGrid.SortableDataGridNode<unknown> {
|
|
330
|
+
abstract binaryView(): BinaryResourceView|null;
|
|
331
|
+
abstract getTime(): number;
|
|
332
|
+
abstract dataText(): string;
|
|
333
|
+
abstract isTextFrame?: boolean;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
function resourceChunkNodeTimeComparator(a: DataGridItem, b: DataGridItem): number {
|
|
337
|
+
return a.getTime() - b.getTime();
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const clearChunkOffsets = new WeakMap<SDK.NetworkRequest.NetworkRequest, number>();
|
|
@@ -54,10 +54,6 @@ const UIStrings = {
|
|
|
54
54
|
* @description A context menu item in the Messages View of the Network panel
|
|
55
55
|
*/
|
|
56
56
|
copyMessage: 'Copy message',
|
|
57
|
-
/**
|
|
58
|
-
* @description Text to clear everything
|
|
59
|
-
*/
|
|
60
|
-
clearAllL: 'Clear all',
|
|
61
57
|
/**
|
|
62
58
|
* @description Text for everything
|
|
63
59
|
*/
|
|
@@ -84,13 +80,14 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
84
80
|
private readonly mainToolbar: UI.Toolbar.Toolbar;
|
|
85
81
|
private readonly clearAllButton: UI.Toolbar.ToolbarButton;
|
|
86
82
|
private readonly filterTypeCombobox: UI.Toolbar.ToolbarComboBox;
|
|
87
|
-
protected filterType: string|null;
|
|
83
|
+
protected filterType: string|null = null;
|
|
88
84
|
private readonly filterTextInput: UI.Toolbar.ToolbarInput;
|
|
89
|
-
protected filterRegex: RegExp|null;
|
|
85
|
+
protected filterRegex: RegExp|null = null;
|
|
90
86
|
private readonly frameEmptyWidget: UI.EmptyWidget.EmptyWidget;
|
|
91
87
|
private currentSelectedNode?: DataGridItem|null;
|
|
92
88
|
readonly request: SDK.NetworkRequest.NetworkRequest;
|
|
93
89
|
private readonly messageFilterSetting: Common.Settings.Setting<string>;
|
|
90
|
+
private sidebarWidget: UI.Widget.Widget|null = null;
|
|
94
91
|
|
|
95
92
|
abstract getRequestChunks(): Chunk[];
|
|
96
93
|
abstract createGridItem(chunk: Chunk): DataGridItem;
|
|
@@ -114,7 +111,7 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
114
111
|
displayName: dataGridDisplayName,
|
|
115
112
|
columns,
|
|
116
113
|
});
|
|
117
|
-
this.dataGrid.setRowContextMenuCallback(onRowContextMenu
|
|
114
|
+
this.dataGrid.setRowContextMenuCallback((menu, node) => this.onRowContextMenu(menu, node));
|
|
118
115
|
this.dataGrid.setEnableAutoScrollToBottom(true);
|
|
119
116
|
this.dataGrid.setCellClass('resource-chunk-view-td');
|
|
120
117
|
this.timeComparator =
|
|
@@ -138,21 +135,19 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
138
135
|
this.mainToolbar.appendToolbarItem(this.clearAllButton);
|
|
139
136
|
|
|
140
137
|
this.filterTypeCombobox =
|
|
141
|
-
new UI.Toolbar.ToolbarComboBox(this.
|
|
138
|
+
new UI.Toolbar.ToolbarComboBox(this.onFilterTypeChanged.bind(this), i18nString(UIStrings.filter));
|
|
142
139
|
for (const filterItem of FILTER_TYPES) {
|
|
143
140
|
const option = this.filterTypeCombobox.createOption(filterItem.label(), filterItem.name);
|
|
144
141
|
this.filterTypeCombobox.addOption(option);
|
|
145
142
|
}
|
|
146
143
|
this.mainToolbar.appendToolbarItem(this.filterTypeCombobox);
|
|
147
|
-
this.filterType = null;
|
|
148
144
|
|
|
149
145
|
this.filterTextInput = new UI.Toolbar.ToolbarFilter(filterUsingRegexHint, 0.4);
|
|
150
|
-
this.filterTextInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.
|
|
146
|
+
this.filterTextInput.addEventListener(UI.Toolbar.ToolbarInput.Event.TEXT_CHANGED, this.onFilterTextChanged, this);
|
|
151
147
|
const filter = this.messageFilterSetting.get();
|
|
152
148
|
if (filter) {
|
|
153
149
|
this.filterTextInput.setValue(filter);
|
|
154
150
|
}
|
|
155
|
-
this.filterRegex = null;
|
|
156
151
|
this.mainToolbar.appendToolbarItem(this.filterTextInput);
|
|
157
152
|
|
|
158
153
|
const mainContainer = new UI.Widget.VBox();
|
|
@@ -163,29 +158,31 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
163
158
|
|
|
164
159
|
this.frameEmptyWidget = new UI.EmptyWidget.EmptyWidget(
|
|
165
160
|
i18nString(UIStrings.noMessageSelected), i18nString(UIStrings.selectMessageToBrowseItsContent));
|
|
166
|
-
this.
|
|
161
|
+
this.sidebarWidget = this.frameEmptyWidget;
|
|
162
|
+
this.splitWidget.setSidebarWidget(this.sidebarWidget);
|
|
167
163
|
|
|
168
164
|
if (filter) {
|
|
169
165
|
this.applyFilter(filter);
|
|
170
166
|
}
|
|
167
|
+
}
|
|
171
168
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
contextMenu.footerSection().appendItem(
|
|
187
|
-
i18nString(UIStrings.clearAllL), this.clearChunks.bind(this), {jslogContext: 'clear-all'});
|
|
169
|
+
private onRowContextMenu(contextMenu: UI.ContextMenu.ContextMenu,
|
|
170
|
+
node: DataGrid.DataGrid.DataGridNode<unknown>): void {
|
|
171
|
+
const item = node as DataGridItem;
|
|
172
|
+
const binaryView = item.binaryView();
|
|
173
|
+
if (binaryView) {
|
|
174
|
+
binaryView.addCopyToContextMenu(contextMenu, i18nString(UIStrings.copyMessageD));
|
|
175
|
+
} else {
|
|
176
|
+
const dataVal = item.data.data;
|
|
177
|
+
const textToCopy = typeof dataVal === 'string' ? dataVal : item.dataText();
|
|
178
|
+
contextMenu.clipboardSection().appendItem(
|
|
179
|
+
i18nString(UIStrings.copyMessage),
|
|
180
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText.bind(
|
|
181
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance, textToCopy),
|
|
182
|
+
{jslogContext: 'copy'});
|
|
188
183
|
}
|
|
184
|
+
contextMenu.footerSection().appendItem(i18nString(UIStrings.clearAll), this.clearChunks.bind(this),
|
|
185
|
+
{jslogContext: 'clear-all'});
|
|
189
186
|
}
|
|
190
187
|
|
|
191
188
|
getColumns(): DataGrid.DataGrid.ColumnDescriptor[] {
|
|
@@ -212,17 +209,22 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
212
209
|
private clearChunks(): void {
|
|
213
210
|
// TODO(allada): actually remove frames from request.
|
|
214
211
|
clearChunkOffsets.set(this.request, this.getRequestChunks().length);
|
|
215
|
-
this.
|
|
212
|
+
this.performUpdate();
|
|
216
213
|
}
|
|
217
214
|
|
|
218
|
-
private
|
|
215
|
+
private onFilterTypeChanged(): void {
|
|
216
|
+
const val = (this.filterTypeCombobox.selectedOption() as HTMLOptionElement).value;
|
|
217
|
+
this.filterType = val === 'all' ? null : val;
|
|
218
|
+
this.performUpdate();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
private onFilterTextChanged(): void {
|
|
219
222
|
const text = this.filterTextInput.value();
|
|
220
223
|
this.messageFilterSetting.set(text);
|
|
221
224
|
this.applyFilter(text);
|
|
222
225
|
}
|
|
223
226
|
|
|
224
227
|
private applyFilter(text: string): void {
|
|
225
|
-
const type = (this.filterTypeCombobox.selectedOption() as HTMLOptionElement).value;
|
|
226
228
|
if (text) {
|
|
227
229
|
try {
|
|
228
230
|
this.filterRegex = new RegExp(text, 'i');
|
|
@@ -232,46 +234,69 @@ export abstract class ResourceChunkView<Chunk> extends UI.Widget.VBox {
|
|
|
232
234
|
} else {
|
|
233
235
|
this.filterRegex = null;
|
|
234
236
|
}
|
|
235
|
-
this.
|
|
236
|
-
this.refresh();
|
|
237
|
+
this.performUpdate();
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
private async onChunkSelected(event: Common.EventTarget.EventTargetEvent<DataGrid.DataGrid.DataGridNode<unknown>>):
|
|
240
241
|
Promise<void> {
|
|
241
242
|
this.currentSelectedNode = (event.data as DataGridItem);
|
|
243
|
+
await this.updateSidebar();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private onChunkDeselected(): void {
|
|
247
|
+
this.currentSelectedNode = null;
|
|
248
|
+
void this.updateSidebar();
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async updateSidebar(): Promise<void> {
|
|
252
|
+
if (!this.currentSelectedNode) {
|
|
253
|
+
this.sidebarWidget = null;
|
|
254
|
+
this.updateSidebarWidget();
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
242
258
|
const content = this.currentSelectedNode.dataText();
|
|
243
259
|
|
|
244
260
|
const binaryView = this.currentSelectedNode.binaryView();
|
|
245
261
|
if (binaryView) {
|
|
246
|
-
this.
|
|
262
|
+
this.sidebarWidget = binaryView;
|
|
263
|
+
this.updateSidebarWidget();
|
|
247
264
|
return;
|
|
248
265
|
}
|
|
249
266
|
|
|
250
267
|
const jsonView = await SourceFrame.JSONView.JSONView.createView(content);
|
|
251
268
|
if (jsonView) {
|
|
252
|
-
this.
|
|
269
|
+
this.sidebarWidget = jsonView;
|
|
270
|
+
this.updateSidebarWidget();
|
|
253
271
|
return;
|
|
254
272
|
}
|
|
255
273
|
|
|
256
|
-
this.
|
|
257
|
-
TextUtils.StaticContentProvider.StaticContentProvider.fromString(
|
|
258
|
-
|
|
259
|
-
'')
|
|
274
|
+
this.sidebarWidget = new SourceFrame.ResourceSourceFrame.ResourceSourceFrame(
|
|
275
|
+
TextUtils.StaticContentProvider.StaticContentProvider.fromString(this.request.url(),
|
|
276
|
+
this.request.resourceType(), content),
|
|
277
|
+
'');
|
|
278
|
+
this.updateSidebarWidget();
|
|
260
279
|
}
|
|
261
280
|
|
|
262
|
-
private
|
|
263
|
-
this.
|
|
264
|
-
this.splitWidget.
|
|
281
|
+
private updateSidebarWidget(): void {
|
|
282
|
+
const activeSidebar = this.sidebarWidget || this.frameEmptyWidget;
|
|
283
|
+
if (this.splitWidget.sidebarWidget() !== activeSidebar) {
|
|
284
|
+
this.splitWidget.setSidebarWidget(activeSidebar);
|
|
285
|
+
}
|
|
265
286
|
}
|
|
266
287
|
|
|
267
|
-
|
|
288
|
+
override performUpdate(): void {
|
|
268
289
|
this.dataGrid.rootNode().removeChildren();
|
|
269
|
-
|
|
270
290
|
let chunks = this.getRequestChunks();
|
|
271
291
|
const offset = clearChunkOffsets.get(this.request) || 0;
|
|
272
|
-
chunks = chunks.slice(offset);
|
|
273
|
-
chunks = chunks.filter(this.chunkFilter.bind(this));
|
|
292
|
+
chunks = chunks.slice(offset).filter(this.chunkFilter.bind(this));
|
|
274
293
|
chunks.forEach(chunk => this.dataGrid.insertChild(this.createGridItem(chunk)));
|
|
294
|
+
|
|
295
|
+
this.updateSidebarWidget();
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
refresh(): void {
|
|
299
|
+
this.performUpdate();
|
|
275
300
|
}
|
|
276
301
|
|
|
277
302
|
private sortItems(): void {
|
|
@@ -307,6 +332,7 @@ export abstract class DataGridItem extends DataGrid.SortableDataGrid.SortableDat
|
|
|
307
332
|
abstract binaryView(): BinaryResourceView|null;
|
|
308
333
|
abstract getTime(): number;
|
|
309
334
|
abstract dataText(): string;
|
|
335
|
+
abstract readonly isTextFrame: boolean;
|
|
310
336
|
}
|
|
311
337
|
|
|
312
338
|
function resourceChunkNodeTimeComparator(a: DataGridItem, b: DataGridItem): number {
|
|
@@ -13,7 +13,7 @@ import * as UI from '../../ui/legacy/legacy.js';
|
|
|
13
13
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
14
14
|
|
|
15
15
|
import {BinaryResourceView} from './BinaryResourceView.js';
|
|
16
|
-
import {DataGridItem,
|
|
16
|
+
import {DataGridItem, OriginalResourceChunkView} from './OriginalResourceChunkView.js';
|
|
17
17
|
|
|
18
18
|
const UIStrings = {
|
|
19
19
|
/**
|
|
@@ -48,7 +48,7 @@ const UIStrings = {
|
|
|
48
48
|
const str_ = i18n.i18n.registerUIStrings('panels/network/ResourceDirectSocketChunkView.ts', UIStrings);
|
|
49
49
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
50
50
|
|
|
51
|
-
export class ResourceDirectSocketChunkView extends
|
|
51
|
+
export class ResourceDirectSocketChunkView extends OriginalResourceChunkView<SDK.NetworkRequest.DirectSocketChunk> {
|
|
52
52
|
constructor(request: SDK.NetworkRequest.NetworkRequest) {
|
|
53
53
|
super(
|
|
54
54
|
request, 'network-direct-socket-chunk-filter', 'resource-direct-socket-chunk-split-view-state',
|
|
@@ -134,6 +134,7 @@ export class ResourceDirectSocketChunkView extends ResourceChunkView<SDK.Network
|
|
|
134
134
|
class ResourceChunkNode extends DataGridItem {
|
|
135
135
|
#binaryView: BinaryResourceView|null = null;
|
|
136
136
|
readonly chunk: SDK.NetworkRequest.DirectSocketChunk;
|
|
137
|
+
override readonly isTextFrame = false;
|
|
137
138
|
|
|
138
139
|
constructor(chunk: SDK.NetworkRequest.DirectSocketChunk, boundSocket: boolean) {
|
|
139
140
|
const time = new Date(chunk.timestamp * 1000);
|
|
@@ -30,7 +30,7 @@ import * as UI from '../../ui/legacy/legacy.js';
|
|
|
30
30
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
31
31
|
|
|
32
32
|
import {BinaryResourceView} from './BinaryResourceView.js';
|
|
33
|
-
import {DataGridItem,
|
|
33
|
+
import {DataGridItem, OriginalResourceChunkView} from './OriginalResourceChunkView.js';
|
|
34
34
|
|
|
35
35
|
const UIStrings = {
|
|
36
36
|
/**
|
|
@@ -91,7 +91,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/network/ResourceWebSocketFrameV
|
|
|
91
91
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
92
92
|
const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);
|
|
93
93
|
|
|
94
|
-
export class ResourceWebSocketFrameView extends
|
|
94
|
+
export class ResourceWebSocketFrameView extends OriginalResourceChunkView<SDK.NetworkRequest.WebSocketFrame> {
|
|
95
95
|
constructor(request: SDK.NetworkRequest.NetworkRequest) {
|
|
96
96
|
super(
|
|
97
97
|
request, 'network-web-socket-message-filter', 'resource-web-socket-frame-split-view-state',
|
|
@@ -159,7 +159,7 @@ const opCodeDescriptions: Array<() => string> = (function(): Array<() => Common.
|
|
|
159
159
|
|
|
160
160
|
class ResourceFrameNode extends DataGridItem {
|
|
161
161
|
readonly frame: SDK.NetworkRequest.WebSocketFrame;
|
|
162
|
-
|
|
162
|
+
override readonly isTextFrame: boolean;
|
|
163
163
|
#dataText: string;
|
|
164
164
|
#binaryView: BinaryResourceView|null;
|
|
165
165
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2014 The Chromium Authors
|
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.resource-chunk-view {
|
|
8
|
+
user-select: text;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.resource-chunk-view .data-grid {
|
|
12
|
+
flex: auto;
|
|
13
|
+
border: none;
|
|
14
|
+
|
|
15
|
+
.resource-chunk-view-td {
|
|
16
|
+
border-bottom: 1px solid var(--sys-color-divider);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
& tr {
|
|
20
|
+
&.resource-chunk-view-row-send td:first-child::before {
|
|
21
|
+
content: "\2B06";
|
|
22
|
+
color: var(--sys-color-tertiary);
|
|
23
|
+
padding-right: 4px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
&.resource-chunk-view-row-receive td:first-child::before {
|
|
27
|
+
content: "\2B07";
|
|
28
|
+
color: var(--sys-color-error);
|
|
29
|
+
padding-right: 4px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&.resource-chunk-view-row-send {
|
|
33
|
+
background-color: color-mix(in srgb, var(--sys-color-tertiary-container), transparent 50%);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&.resource-chunk-view-row-error {
|
|
37
|
+
background-color: var(--sys-color-surface-error);
|
|
38
|
+
color: var(--sys-color-on-surface-error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.resource-chunk-view .data-grid .data {
|
|
44
|
+
background-image: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.resource-chunk-view devtools-toolbar {
|
|
48
|
+
border-bottom: 1px solid var(--sys-color-divider);
|
|
49
|
+
}
|