chrome-devtools-frontend 1.0.1674545 → 1.0.1676824
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-ux-writing-refactor/SKILL.md +26 -9
- package/WATCHLISTS +0 -4
- package/front_end/core/common/ParsedURL.ts +5 -1
- package/front_end/core/common/SettingRegistration.ts +29 -8
- package/front_end/core/common/Settings.ts +0 -77
- package/front_end/core/root/Runtime.ts +4 -5
- package/front_end/core/sdk/CSSMetadata.ts +5 -9
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +8 -28
- package/front_end/core/sdk/DebuggerModel.ts +50 -30
- package/front_end/core/sdk/ResourceTreeModel.ts +20 -1
- package/front_end/core/sdk/Script.ts +9 -53
- package/front_end/core/sdk/TargetManager.ts +18 -0
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +213 -23
- package/front_end/entrypoints/main/MainImpl.ts +32 -0
- package/front_end/foundation/Universe.ts +44 -29
- package/front_end/generated/InspectorBackendCommands.ts +3 -1
- package/front_end/generated/SupportedCSSProperties.ts +21 -4
- package/front_end/generated/protocol-mapping.d.ts +14 -0
- package/front_end/generated/protocol-proxy-api.d.ts +10 -0
- package/front_end/generated/protocol.ts +35 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +11 -0
- package/front_end/models/ai_assistance/AiConversation.ts +22 -5
- package/front_end/models/ai_assistance/README.md +52 -26
- package/front_end/models/ai_assistance/agents/AiAgent.ts +54 -8
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +1 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +15 -192
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +8 -87
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -1
- package/front_end/models/ai_assistance/ai_assistance.ts +16 -0
- package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +124 -0
- package/front_end/models/ai_assistance/contexts/StorageContext.ts +111 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +69 -1
- package/front_end/models/ai_assistance/skills/README.md +63 -1
- package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
- package/front_end/models/ai_assistance/skills/SkillRegistry.ts +4 -0
- package/front_end/models/ai_assistance/skills/performance.md +8 -0
- package/front_end/models/ai_assistance/skills/sources.md +16 -0
- package/front_end/models/ai_assistance/skills/storage.md +31 -0
- package/front_end/models/ai_assistance/tools/GetSourceContent.ts +101 -0
- package/front_end/models/ai_assistance/tools/GetTraceEventByKey.ts +83 -0
- package/front_end/models/ai_assistance/tools/GetTraceMainThreadSummary.ts +106 -0
- package/front_end/models/ai_assistance/tools/GetTraceNetworkSummary.ts +104 -0
- package/front_end/models/ai_assistance/tools/ListPageOrigins.ts +81 -0
- package/front_end/models/ai_assistance/tools/ListSources.ts +116 -0
- package/front_end/models/ai_assistance/tools/SelectTraceEventByKey.ts +90 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +22 -1
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +14 -0
- package/front_end/models/bindings/CSSWorkspaceBinding.ts +4 -0
- package/front_end/models/bindings/CompilerScriptMapping.ts +4 -0
- package/front_end/models/bindings/DebuggerWorkspaceBinding.ts +8 -0
- package/front_end/models/bindings/ResourceScriptMapping.ts +3 -201
- package/front_end/models/bindings/SASSSourceMapping.ts +6 -0
- package/front_end/models/breakpoints/BreakpointManager.ts +2 -49
- package/front_end/models/emulation/DeviceModeModel.ts +60 -71
- package/front_end/models/emulation/EmulatedDevices.ts +18 -66
- package/front_end/models/heap_snapshot/HeapSnapshotModel.ts +27 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +10 -2
- package/front_end/models/issues_manager/descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
- package/front_end/models/issues_manager/descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +1 -1
- package/front_end/models/persistence/AutomaticFileSystemManager.ts +2 -2
- package/front_end/models/persistence/IsolatedFileSystem.ts +7 -8
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +22 -31
- package/front_end/models/persistence/PlatformFileSystem.ts +1 -1
- package/front_end/models/persistence/persistence-meta.ts +9 -9
- package/front_end/models/trace/types/TraceEvents.ts +36 -0
- package/front_end/models/workspace/FileManager.ts +13 -6
- package/front_end/panels/accessibility/ARIAAttributesView.ts +3 -3
- package/front_end/panels/accessibility/AccessibilityNodeView.ts +36 -36
- package/front_end/panels/accessibility/AccessibilityStrings.ts +168 -168
- package/front_end/panels/accessibility/SourceOrderView.ts +7 -7
- package/front_end/panels/accessibility/accessibility-meta.ts +2 -2
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +5 -5
- package/front_end/panels/ai_assistance/components/AIv2MarkdownRenderer.ts +2 -3
- package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +27 -2
- package/front_end/panels/application/IndexedDBViews.ts +65 -63
- package/front_end/panels/application/WebMCPView.ts +29 -12
- package/front_end/panels/application/components/AdsView.ts +24 -1
- package/front_end/panels/application/components/adsView.css +27 -21
- package/front_end/panels/autofill/AutofillView.ts +12 -12
- package/front_end/panels/autofill/autofill-meta.ts +2 -2
- package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +5 -5
- package/front_end/panels/common/BadgeNotification.ts +8 -8
- package/front_end/panels/common/ExtensionServer.ts +21 -1
- package/front_end/panels/common/GdpSignUpDialog.ts +16 -16
- package/front_end/panels/common/GeminiRebrandPromoDialog.ts +5 -6
- package/front_end/panels/common/PersistenceUtils.ts +2 -2
- package/front_end/panels/common/common.ts +0 -97
- package/front_end/panels/console/ConsoleInsightTeaser.ts +2 -2
- package/front_end/panels/console/ConsolePinPane.ts +2 -2
- package/front_end/panels/console/ConsoleView.ts +20 -19
- package/front_end/panels/elements/ElementsTreeElement.ts +550 -327
- package/front_end/panels/elements/ElementsTreeOutline.ts +1 -1
- package/front_end/panels/elements/LayoutPane.ts +2 -8
- package/front_end/panels/event_listeners/EventListenersView.ts +8 -4
- package/front_end/panels/issues/AffectedTrackingSitesView.ts +25 -14
- package/front_end/panels/js_timeline/js_timeline-meta.ts +8 -8
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +30 -30
- package/front_end/panels/layer_viewer/LayerTreeOutline.ts +6 -6
- package/front_end/panels/layer_viewer/LayerViewHost.ts +1 -1
- package/front_end/panels/layer_viewer/Layers3DView.ts +11 -11
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +8 -8
- package/front_end/panels/layer_viewer/TransformController.ts +3 -3
- package/front_end/panels/layer_viewer/layer_viewer-meta.ts +11 -11
- package/front_end/panels/media/PlayerMessagesView.ts +149 -68
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +1 -58
- package/front_end/panels/mobile_throttling/mobile_throttling.ts +0 -10
- package/front_end/panels/network/NetworkPanel.ts +1 -1
- package/front_end/panels/network/RequestPayloadView.ts +1 -0
- package/front_end/panels/profiler/HeapSnapshotView.ts +0 -2
- package/front_end/panels/profiler/heapProfiler.css +0 -9
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +7 -0
- package/front_end/panels/recorder/RecorderPanel.ts +2 -3
- package/front_end/panels/screencast/ScreencastView.ts +148 -138
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +1 -2
- package/front_end/panels/sources/AiCodeCompletionPlugin.ts +2 -2
- package/front_end/panels/sources/DebuggerPlugin.ts +9 -58
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +1 -1
- package/front_end/panels/sources/UISourceCodeFrame.ts +3 -8
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +4 -2
- package/front_end/panels/timeline/TimelineController.ts +36 -64
- package/front_end/panels/timeline/TimelinePanel.ts +11 -8
- package/front_end/panels/timeline/TimelineUIUtils.ts +5 -2
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +2 -2
- package/front_end/panels/timeline/timelinePanel.css +0 -10
- package/front_end/panels/utils/utils.ts +7 -7
- package/front_end/services/tracing/PerformanceTracing.ts +5 -17
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
- package/front_end/third_party/codemirror.next/package.json +2 -2
- package/front_end/third_party/codemirror.next/rebuild.sh +4 -1
- package/front_end/ui/comments/CommentAnchorResolver.ts +558 -0
- package/front_end/ui/comments/CommentManager.ts +640 -0
- package/front_end/ui/comments/CommentsOverlayWidget.ts +121 -0
- package/front_end/ui/comments/comments.ts +13 -0
- package/front_end/ui/comments/commentsOverlay.css +49 -0
- package/front_end/{panels/common → ui/components/dialogs}/FreDialog.ts +6 -6
- package/front_end/ui/components/dialogs/TypeToAllowDialog.ts +96 -0
- package/front_end/ui/components/dialogs/dialogs.ts +4 -0
- package/front_end/ui/components/settings/SettingCheckbox.ts +3 -3
- package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionDisclaimer.ts +13 -13
- package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +7 -6
- package/front_end/{panels/common → ui/components/text_editor}/AiCodeCompletionTeaser.ts +43 -46
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +22 -26
- package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationTeaser.ts +10 -10
- package/front_end/{panels/common → ui/components/text_editor}/AiCodeGenerationUpgradeDialog.ts +5 -5
- package/front_end/ui/components/text_editor/text_editor.ts +4 -0
- package/front_end/ui/legacy/Toolbar.ts +1 -1
- package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +40 -0
- package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +11 -3
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +270 -162
- package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +5 -0
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -16
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +5 -12
- package/front_end/ui/legacy/components/source_frame/JSONView.ts +8 -1
- package/front_end/ui/legacy/components/source_frame/SourceFrame.ts +2 -2
- package/front_end/ui/legacy/components/utils/Linkifier.ts +1 -0
- package/front_end/ui/settings/SettingUIRegistration.ts +59 -6
- package/front_end/ui/visual_logging/Debugging.ts +1 -5
- package/front_end/ui/visual_logging/KnownContextValues.ts +2 -0
- package/front_end/ui/visual_logging/LoggingConfig.ts +21 -0
- package/front_end/ui/visual_logging/visual_logging.ts +9 -0
- package/mcp/mcp.ts +6 -1
- package/package.json +1 -1
- package/front_end/Images/toolbarResizerVertical.png +0 -0
- package/front_end/emulated_devices/MotoG4-landscape.svg +0 -155
- package/front_end/emulated_devices/MotoG4-portrait.svg +0 -155
- package/front_end/emulated_devices/Nexus5X-landscape.svg +0 -19
- package/front_end/emulated_devices/Nexus5X-portrait.svg +0 -19
- package/front_end/emulated_devices/Nexus6P-landscape.svg +0 -50
- package/front_end/emulated_devices/Nexus6P-portrait.svg +0 -54
- package/front_end/emulated_devices/google-nest-hub-horizontal.png +0 -0
- package/front_end/emulated_devices/google-nest-hub-max-horizontal.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-default-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-default-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-keyboard-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-horizontal-navigation-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-default-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-default-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-keyboard-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-navigation-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5-vertical-navigation-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-default-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-default-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-keyboard-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-horizontal-navigation-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-default-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-default-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-keyboard-2x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-1x.png +0 -0
- package/front_end/emulated_devices/google-nexus-5x-vertical-navigation-2x.png +0 -0
- package/front_end/emulated_devices/iPad-landscape.svg +0 -73
- package/front_end/emulated_devices/iPad-portrait.svg +0 -76
- package/front_end/emulated_devices/iPhone5-landscape.svg +0 -99
- package/front_end/emulated_devices/iPhone5-portrait.svg +0 -83
- package/front_end/emulated_devices/iPhone6-landscape.svg +0 -111
- package/front_end/emulated_devices/iPhone6-portrait.svg +0 -116
- package/front_end/emulated_devices/iPhone6Plus-landscape.svg +0 -118
- package/front_end/emulated_devices/iPhone6Plus-portrait.svg +0 -116
- package/front_end/emulated_devices/optimized/MotoG4-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/MotoG4-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/Nexus5X-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/Nexus5X-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/Nexus6P-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/Nexus6P-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/README.md +0 -9
- package/front_end/emulated_devices/optimized/google-nest-hub-horizontal.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nest-hub-max-horizontal.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-default-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-keyboard-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-horizontal-navigation-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-default-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-keyboard-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5-vertical-navigation-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-default-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-keyboard-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-horizontal-navigation-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-default-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-keyboard-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-1x.avif +0 -0
- package/front_end/emulated_devices/optimized/google-nexus-5x-vertical-navigation-2x.avif +0 -0
- package/front_end/emulated_devices/optimized/iPad-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/iPad-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone5-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone5-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone6-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone6-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone6Plus-landscape.avif +0 -0
- package/front_end/emulated_devices/optimized/iPhone6Plus-portrait.avif +0 -0
- package/front_end/emulated_devices/optimized/optimized_images.gni +0 -53
- package/front_end/models/ai_assistance/agents/README.md +0 -136
- package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +0 -92
- /package/front_end/{panels/common → ui/components/dialogs}/freDialog.css +0 -0
- /package/front_end/{panels/common/common.css → ui/components/dialogs/typeToAllowDialog.css} +0 -0
- /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionDisclaimer.css +0 -0
- /package/front_end/{panels/common → ui/components/text_editor}/aiCodeCompletionTeaser.css +0 -0
- /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationTeaser.css +0 -0
- /package/front_end/{panels/common → ui/components/text_editor}/aiCodeGenerationUpgradeDialog.css +0 -0
|
@@ -3,12 +3,9 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
|
-
import * as i18n from '../../core/i18n/i18n.js';
|
|
7
6
|
import * as Platform from '../../core/platform/platform.js';
|
|
8
|
-
import * as Root from '../../core/root/root.js';
|
|
9
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
8
|
import * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
11
|
-
import * as Protocol from '../../generated/protocol.js';
|
|
12
9
|
import * as Formatter from '../formatter/formatter.js';
|
|
13
10
|
import * as Workspace from '../workspace/workspace.js';
|
|
14
11
|
|
|
@@ -17,21 +14,6 @@ import {type DebuggerSourceMapping, DebuggerWorkspaceBinding} from './DebuggerWo
|
|
|
17
14
|
import {NetworkProject} from './NetworkProject.js';
|
|
18
15
|
import {metadataForURL} from './ResourceUtils.js';
|
|
19
16
|
|
|
20
|
-
const UIStrings = {
|
|
21
|
-
/**
|
|
22
|
-
* @description Error text displayed in the Console panel when editing a live script fails. LiveEdit is the name of the feature for editing code that is already running.
|
|
23
|
-
* @example {warning} PH1
|
|
24
|
-
*/
|
|
25
|
-
liveEditFailed: '`LiveEdit` failed: {PH1}',
|
|
26
|
-
/**
|
|
27
|
-
* @description Error text displayed in the Console panel when compiling a live-edited script fails. LiveEdit is the name of the feature for editing code that is already running.
|
|
28
|
-
* @example {connection lost} PH1
|
|
29
|
-
*/
|
|
30
|
-
liveEditCompileFailed: '`LiveEdit` compile failed: {PH1}',
|
|
31
|
-
} as const;
|
|
32
|
-
const str_ = i18n.i18n.registerUIStrings('models/bindings/ResourceScriptMapping.ts', UIStrings);
|
|
33
|
-
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
34
|
-
|
|
35
17
|
export class ResourceScriptMapping implements DebuggerSourceMapping {
|
|
36
18
|
readonly debuggerModel: SDK.DebuggerModel.DebuggerModel;
|
|
37
19
|
#workspace: Workspace.Workspace.WorkspaceImpl;
|
|
@@ -96,9 +78,6 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
|
|
|
96
78
|
if (!scriptFile) {
|
|
97
79
|
return null;
|
|
98
80
|
}
|
|
99
|
-
if ((scriptFile.hasDivergedFromVM() && !scriptFile.isMergingToVM()) || scriptFile.isDivergingFromVM()) {
|
|
100
|
-
return null;
|
|
101
|
-
}
|
|
102
81
|
if (scriptFile.script !== script) {
|
|
103
82
|
return null;
|
|
104
83
|
}
|
|
@@ -205,8 +184,7 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
|
|
|
205
184
|
}
|
|
206
185
|
|
|
207
186
|
private addScript(script: SDK.Script.Script): void {
|
|
208
|
-
|
|
209
|
-
if (script.isLiveEdit() || script.isBreakpointCondition) {
|
|
187
|
+
if (script.isBreakpointCondition) {
|
|
210
188
|
return;
|
|
211
189
|
}
|
|
212
190
|
|
|
@@ -272,10 +250,6 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
|
|
|
272
250
|
if (!uiSourceCode) {
|
|
273
251
|
continue;
|
|
274
252
|
}
|
|
275
|
-
const scriptFile = this.#uiSourceCodeToScriptFile.get(uiSourceCode);
|
|
276
|
-
if (scriptFile) {
|
|
277
|
-
scriptFile.dispose();
|
|
278
|
-
}
|
|
279
253
|
|
|
280
254
|
this.#uiSourceCodeToScriptFile.delete(uiSourceCode);
|
|
281
255
|
this.#scriptToUISourceCode.delete(script);
|
|
@@ -325,177 +299,17 @@ export class ResourceScriptMapping implements DebuggerSourceMapping {
|
|
|
325
299
|
}
|
|
326
300
|
}
|
|
327
301
|
|
|
328
|
-
export class ResourceScriptFile
|
|
302
|
+
export class ResourceScriptFile {
|
|
329
303
|
readonly #resourceScriptMapping: ResourceScriptMapping;
|
|
330
304
|
readonly uiSourceCode: Workspace.UISourceCode.UISourceCode;
|
|
331
305
|
readonly script: SDK.Script.Script|null;
|
|
332
|
-
|
|
333
|
-
#isDivergingFromVM?: boolean;
|
|
334
|
-
#hasDivergedFromVM?: boolean;
|
|
335
|
-
#isMergingToVM?: boolean;
|
|
336
|
-
#updateMutex = new Common.Mutex.Mutex();
|
|
306
|
+
|
|
337
307
|
constructor(
|
|
338
308
|
resourceScriptMapping: ResourceScriptMapping, uiSourceCode: Workspace.UISourceCode.UISourceCode,
|
|
339
309
|
script: SDK.Script.Script) {
|
|
340
|
-
super();
|
|
341
310
|
this.#resourceScriptMapping = resourceScriptMapping;
|
|
342
311
|
this.uiSourceCode = uiSourceCode;
|
|
343
312
|
this.script = this.uiSourceCode.contentType().isScript() ? script : null;
|
|
344
|
-
|
|
345
|
-
this.uiSourceCode.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged, this.workingCopyChanged, this);
|
|
346
|
-
this.uiSourceCode.addEventListener(
|
|
347
|
-
Workspace.UISourceCode.Events.WorkingCopyCommitted, this.workingCopyCommitted, this);
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
private isDiverged(): boolean {
|
|
351
|
-
if (this.uiSourceCode.isDirty()) {
|
|
352
|
-
return true;
|
|
353
|
-
}
|
|
354
|
-
if (!this.script) {
|
|
355
|
-
return false;
|
|
356
|
-
}
|
|
357
|
-
if (typeof this.#scriptSource === 'undefined' || this.#scriptSource === null) {
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
const workingCopy = this.uiSourceCode.workingCopy();
|
|
361
|
-
if (!workingCopy) {
|
|
362
|
-
return false;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
// Match ignoring sourceURL.
|
|
366
|
-
if (!workingCopy.startsWith(this.#scriptSource.trimEnd())) {
|
|
367
|
-
return true;
|
|
368
|
-
}
|
|
369
|
-
const suffix = this.uiSourceCode.workingCopy().substr(this.#scriptSource.length);
|
|
370
|
-
return Boolean(suffix.length) && !suffix.match(SDK.Script.sourceURLRegex);
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
private workingCopyChanged(): void {
|
|
374
|
-
void this.update();
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
private workingCopyCommitted(): void {
|
|
378
|
-
// This feature flag is for turning down live edit. If it's not present, we keep the feature enabled.
|
|
379
|
-
if (Root.Runtime.hostConfig.devToolsLiveEdit?.enabled === false) {
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (this.uiSourceCode.project().canSetFileContent()) {
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
if (!this.script) {
|
|
387
|
-
return;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
const source = this.uiSourceCode.workingCopy();
|
|
391
|
-
void this.script.editSource(source).then(({status, exceptionDetails}) => {
|
|
392
|
-
void this.scriptSourceWasSet(source, status, exceptionDetails);
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
async scriptSourceWasSet(
|
|
397
|
-
source: string, status: Protocol.Debugger.SetScriptSourceResponseStatus,
|
|
398
|
-
exceptionDetails?: Protocol.Runtime.ExceptionDetails): Promise<void> {
|
|
399
|
-
if (status === Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
|
|
400
|
-
this.#scriptSource = source;
|
|
401
|
-
}
|
|
402
|
-
await this.update();
|
|
403
|
-
|
|
404
|
-
if (status === Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
|
|
405
|
-
return;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (!exceptionDetails) {
|
|
409
|
-
// TODO(crbug.com/1334484): Instead of to the console, report these errors in an "info bar" at the bottom
|
|
410
|
-
// of the text editor, similar to e.g. source mapping errors.
|
|
411
|
-
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
412
|
-
Common.Console.Console.instance().addMessage(
|
|
413
|
-
i18nString(UIStrings.liveEditFailed, {PH1: getErrorText(status)}), Common.Console.MessageLevel.WARNING);
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
const messageText = i18nString(UIStrings.liveEditCompileFailed, {PH1: exceptionDetails.text});
|
|
417
|
-
this.uiSourceCode.addLineMessage(
|
|
418
|
-
Workspace.UISourceCode.Message.Level.ERROR, messageText, exceptionDetails.lineNumber,
|
|
419
|
-
exceptionDetails.columnNumber);
|
|
420
|
-
|
|
421
|
-
function getErrorText(status: Protocol.Debugger.SetScriptSourceResponseStatus): string {
|
|
422
|
-
switch (status) {
|
|
423
|
-
case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByActiveFunction:
|
|
424
|
-
return 'Functions that are on the stack (currently being executed) can’t be edited';
|
|
425
|
-
case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByActiveGenerator:
|
|
426
|
-
return 'Async functions/generators that are active can’t be edited';
|
|
427
|
-
case Protocol.Debugger.SetScriptSourceResponseStatus.BlockedByTopLevelEsModuleChange:
|
|
428
|
-
return 'The top level of JavaScript modules can’t be edited';
|
|
429
|
-
case Protocol.Debugger.SetScriptSourceResponseStatus.CompileError:
|
|
430
|
-
case Protocol.Debugger.SetScriptSourceResponseStatus.Ok:
|
|
431
|
-
throw new Error('Compile errors and Ok status must not be reported on the console');
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
private async update(): Promise<void> {
|
|
437
|
-
// Do not interleave "divergeFromVM" with "mergeToVM" calls.
|
|
438
|
-
const release = await this.#updateMutex.acquire();
|
|
439
|
-
const diverged = this.isDiverged();
|
|
440
|
-
if (diverged && !this.#hasDivergedFromVM) {
|
|
441
|
-
await this.divergeFromVM();
|
|
442
|
-
} else if (!diverged && this.#hasDivergedFromVM) {
|
|
443
|
-
await this.mergeToVM();
|
|
444
|
-
}
|
|
445
|
-
release();
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
private async divergeFromVM(): Promise<void> {
|
|
449
|
-
if (this.script) {
|
|
450
|
-
this.#isDivergingFromVM = true;
|
|
451
|
-
await this.#resourceScriptMapping.debuggerWorkspaceBinding.updateLocations(this.script);
|
|
452
|
-
this.#isDivergingFromVM = undefined;
|
|
453
|
-
this.#hasDivergedFromVM = true;
|
|
454
|
-
this.dispatchEventToListeners(ResourceScriptFile.Events.DID_DIVERGE_FROM_VM);
|
|
455
|
-
}
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
private async mergeToVM(): Promise<void> {
|
|
459
|
-
if (this.script) {
|
|
460
|
-
this.#hasDivergedFromVM = undefined;
|
|
461
|
-
this.#isMergingToVM = true;
|
|
462
|
-
await this.#resourceScriptMapping.debuggerWorkspaceBinding.updateLocations(this.script);
|
|
463
|
-
this.#isMergingToVM = undefined;
|
|
464
|
-
this.dispatchEventToListeners(ResourceScriptFile.Events.DID_MERGE_TO_VM);
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
hasDivergedFromVM(): boolean {
|
|
469
|
-
return Boolean(this.#hasDivergedFromVM);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
isDivergingFromVM(): boolean {
|
|
473
|
-
return Boolean(this.#isDivergingFromVM);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
isMergingToVM(): boolean {
|
|
477
|
-
return Boolean(this.#isMergingToVM);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
checkMapping(): void {
|
|
481
|
-
if (!this.script || typeof this.#scriptSource !== 'undefined') {
|
|
482
|
-
this.mappingCheckedForTest();
|
|
483
|
-
return;
|
|
484
|
-
}
|
|
485
|
-
void this.script.requestContentData().then(content => {
|
|
486
|
-
this.#scriptSource = TextUtils.ContentData.ContentData.textOr(content, null);
|
|
487
|
-
void this.update().then(() => this.mappingCheckedForTest());
|
|
488
|
-
});
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
private mappingCheckedForTest(): void {
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
dispose(): void {
|
|
495
|
-
this.uiSourceCode.removeEventListener(
|
|
496
|
-
Workspace.UISourceCode.Events.WorkingCopyChanged, this.workingCopyChanged, this);
|
|
497
|
-
this.uiSourceCode.removeEventListener(
|
|
498
|
-
Workspace.UISourceCode.Events.WorkingCopyCommitted, this.workingCopyCommitted, this);
|
|
499
313
|
}
|
|
500
314
|
|
|
501
315
|
addSourceMapURL(sourceMapURL: Platform.DevToolsPath.UrlString): void {
|
|
@@ -527,15 +341,3 @@ export class ResourceScriptFile extends Common.ObjectWrapper.ObjectWrapper<Resou
|
|
|
527
341
|
return sources && 'missingSymbolFiles' in sources ? sources.missingSymbolFiles : null;
|
|
528
342
|
}
|
|
529
343
|
}
|
|
530
|
-
|
|
531
|
-
export namespace ResourceScriptFile {
|
|
532
|
-
export const enum Events {
|
|
533
|
-
DID_MERGE_TO_VM = 'DidMergeToVM',
|
|
534
|
-
DID_DIVERGE_FROM_VM = 'DidDivergeFromVM',
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
export interface EventTypes {
|
|
538
|
-
[Events.DID_MERGE_TO_VM]: void;
|
|
539
|
-
[Events.DID_DIVERGE_FROM_VM]: void;
|
|
540
|
-
}
|
|
541
|
-
}
|
|
@@ -140,6 +140,12 @@ export class SASSSourceMapping implements SourceMapping {
|
|
|
140
140
|
return [];
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
static sourceMapURLsForUISourceCode(uiSourceCode: Workspace.UISourceCode.UISourceCode):
|
|
144
|
+
Platform.DevToolsPath.UrlString[] {
|
|
145
|
+
const binding = uiSourceCodeToBinding.get(uiSourceCode);
|
|
146
|
+
return binding?.getReferringSourceMaps().map(sourceMap => sourceMap.url()) ?? [];
|
|
147
|
+
}
|
|
148
|
+
|
|
143
149
|
dispose(): void {
|
|
144
150
|
Common.EventTarget.removeEventListeners(this.#eventListeners);
|
|
145
151
|
this.#project.dispose();
|
|
@@ -8,7 +8,7 @@ import {assertNotNullOrUndefined} from '../../core/platform/platform.js';
|
|
|
8
8
|
import * as Root from '../../core/root/root.js';
|
|
9
9
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
10
10
|
import type * as TextUtils from '../../core/text_utils/text_utils.js';
|
|
11
|
-
import * as Protocol from '../../generated/protocol.js';
|
|
11
|
+
import type * as Protocol from '../../generated/protocol.js';
|
|
12
12
|
import * as Bindings from '../bindings/bindings.js';
|
|
13
13
|
import * as Formatter from '../formatter/formatter.js';
|
|
14
14
|
import * as SourceMapScopes from '../source_map_scopes/source_map_scopes.js';
|
|
@@ -608,7 +608,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
|
608
608
|
|
|
609
609
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasEnabled, this.#onDebuggerEnabled, this);
|
|
610
610
|
debuggerModel.addEventListener(SDK.DebuggerModel.Events.DebuggerWasDisabled, this.#onDebuggerDisabled, this);
|
|
611
|
-
debuggerModel.addEventListener(SDK.DebuggerModel.Events.ScriptSourceWasEdited, this.#onScriptWasEdited, this);
|
|
612
611
|
}
|
|
613
612
|
|
|
614
613
|
modelRemoved(debuggerModel: SDK.DebuggerModel.DebuggerModel): void {
|
|
@@ -622,7 +621,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
|
622
621
|
#removeDebuggerModelListeners(debuggerModel: SDK.DebuggerModel.DebuggerModel): void {
|
|
623
622
|
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.DebuggerWasEnabled, this.#onDebuggerEnabled, this);
|
|
624
623
|
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.DebuggerWasDisabled, this.#onDebuggerDisabled, this);
|
|
625
|
-
debuggerModel.removeEventListener(SDK.DebuggerModel.Events.ScriptSourceWasEdited, this.#onScriptWasEdited, this);
|
|
626
624
|
}
|
|
627
625
|
|
|
628
626
|
#onDebuggerEnabled(event: Common.EventTarget.EventTargetEvent<SDK.DebuggerModel.DebuggerModel>): void {
|
|
@@ -639,29 +637,6 @@ export class Breakpoint implements SDK.TargetManager.SDKModelObserver<SDK.Debugg
|
|
|
639
637
|
model?.cleanUpAfterDebuggerIsGone();
|
|
640
638
|
}
|
|
641
639
|
|
|
642
|
-
async #onScriptWasEdited(
|
|
643
|
-
event: Common.EventTarget
|
|
644
|
-
.EventTargetEvent<{script: SDK.Script.Script, status: Protocol.Debugger.SetScriptSourceResponseStatus}>):
|
|
645
|
-
Promise<void> {
|
|
646
|
-
const {source: debuggerModel, data: {script, status}} = event;
|
|
647
|
-
if (status !== Protocol.Debugger.SetScriptSourceResponseStatus.Ok) {
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// V8 throws away breakpoints on all functions in a live edited script. Here we attempt to re-set them again at the
|
|
652
|
-
// same position. This is because we don't know what was edited and how the breakpoint should move, e.g. if the file
|
|
653
|
-
// was originally changed on the filesystem (via workspace).
|
|
654
|
-
// If the live edit originated in DevTools (in CodeMirror), then the `DebuggerPlugin` will remove the breakpoint
|
|
655
|
-
// wholesale and re-apply based on the diff.
|
|
656
|
-
|
|
657
|
-
console.assert(debuggerModel instanceof SDK.DebuggerModel.DebuggerModel);
|
|
658
|
-
const model = this.#modelBreakpoints.get(debuggerModel as SDK.DebuggerModel.DebuggerModel);
|
|
659
|
-
if (model?.wasSetIn(script.scriptId)) {
|
|
660
|
-
await model.resetBreakpoint();
|
|
661
|
-
void this.#updateModel(model);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
|
|
665
640
|
modelBreakpoint(debuggerModel: SDK.DebuggerModel.DebuggerModel): ModelBreakpoint|undefined {
|
|
666
641
|
return this.#modelBreakpoints.get(debuggerModel);
|
|
667
642
|
}
|
|
@@ -966,11 +941,6 @@ export class ModelBreakpoint {
|
|
|
966
941
|
#cancelCallback = false;
|
|
967
942
|
#currentState: Breakpoint.State|null = null;
|
|
968
943
|
#breakpointIds: Protocol.Debugger.BreakpointId[] = [];
|
|
969
|
-
/**
|
|
970
|
-
* We track all the script IDs this ModelBreakpoint was actually set in. This allows us
|
|
971
|
-
* to properly reset this ModelBreakpoint after a script was live edited.
|
|
972
|
-
*/
|
|
973
|
-
#resolvedScriptIds = new Set<Protocol.Runtime.ScriptId>();
|
|
974
944
|
|
|
975
945
|
constructor(
|
|
976
946
|
debuggerModel: SDK.DebuggerModel.DebuggerModel, breakpoint: Breakpoint,
|
|
@@ -991,7 +961,6 @@ export class ModelBreakpoint {
|
|
|
991
961
|
|
|
992
962
|
this.#uiLocations.clear();
|
|
993
963
|
this.#liveLocations.disposeAll();
|
|
994
|
-
this.#resolvedScriptIds.clear();
|
|
995
964
|
}
|
|
996
965
|
|
|
997
966
|
async scheduleUpdateInDebugger(): Promise<ScheduleUpdateResult> {
|
|
@@ -1021,16 +990,6 @@ export class ModelBreakpoint {
|
|
|
1021
990
|
return result;
|
|
1022
991
|
}
|
|
1023
992
|
|
|
1024
|
-
private scriptDiverged(): boolean {
|
|
1025
|
-
for (const uiSourceCode of this.#breakpoint.getUiSourceCodes()) {
|
|
1026
|
-
const scriptFile = this.#debuggerWorkspaceBinding.scriptFile(uiSourceCode, this.#debuggerModel);
|
|
1027
|
-
if (scriptFile?.hasDivergedFromVM()) {
|
|
1028
|
-
return true;
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
return false;
|
|
1032
|
-
}
|
|
1033
|
-
|
|
1034
993
|
async #updateInDebugger(): Promise<DebuggerUpdateResult> {
|
|
1035
994
|
if (this.#debuggerModel.target().isDisposed()) {
|
|
1036
995
|
this.cleanUpAfterDebuggerIsGone();
|
|
@@ -1042,7 +1001,7 @@ export class ModelBreakpoint {
|
|
|
1042
1001
|
|
|
1043
1002
|
// Calculate the new state.
|
|
1044
1003
|
let newState: Breakpoint.State|null = null;
|
|
1045
|
-
if (!this.#breakpoint.getIsRemoved() && this.#breakpoint.enabled()
|
|
1004
|
+
if (!this.#breakpoint.getIsRemoved() && this.#breakpoint.enabled()) {
|
|
1046
1005
|
let debuggerLocations: SDK.DebuggerModel.Location[] = [];
|
|
1047
1006
|
for (const uiSourceCode of this.#breakpoint.getUiSourceCodes()) {
|
|
1048
1007
|
const {lineNumber: uiLineNumber, columnNumber: uiColumnNumber} =
|
|
@@ -1226,7 +1185,6 @@ export class ModelBreakpoint {
|
|
|
1226
1185
|
}
|
|
1227
1186
|
|
|
1228
1187
|
private async addResolvedLocation(location: SDK.DebuggerModel.Location): Promise<ResolveLocationResult> {
|
|
1229
|
-
this.#resolvedScriptIds.add(location.scriptId);
|
|
1230
1188
|
const uiLocation = await this.#debuggerWorkspaceBinding.rawLocationToUILocation(location);
|
|
1231
1189
|
if (!uiLocation) {
|
|
1232
1190
|
return ResolveLocationResult.OK;
|
|
@@ -1249,11 +1207,6 @@ export class ModelBreakpoint {
|
|
|
1249
1207
|
this.didRemoveFromDebugger();
|
|
1250
1208
|
}
|
|
1251
1209
|
}
|
|
1252
|
-
|
|
1253
|
-
/** @returns true, iff this `ModelBreakpoint` was set (at some point) in `scriptId` */
|
|
1254
|
-
wasSetIn(scriptId: Protocol.Runtime.ScriptId): boolean {
|
|
1255
|
-
return this.#resolvedScriptIds.has(scriptId);
|
|
1256
|
-
}
|
|
1257
1210
|
}
|
|
1258
1211
|
|
|
1259
1212
|
/**
|
|
@@ -124,21 +124,23 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
124
124
|
#touchMobile: boolean;
|
|
125
125
|
#emulationModel: SDK.EmulationModel.EmulationModel|null;
|
|
126
126
|
#onModelAvailable: (() => void)|null;
|
|
127
|
-
#outlineRect?: Rect;
|
|
128
127
|
#screenOrientationLocked: boolean;
|
|
129
128
|
readonly #targetManager: SDK.TargetManager.TargetManager;
|
|
130
129
|
readonly #settings: Common.Settings.Settings;
|
|
131
130
|
readonly #multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager;
|
|
131
|
+
readonly #fileManager: Workspace.FileManager.FileManager;
|
|
132
132
|
|
|
133
133
|
constructor(
|
|
134
134
|
targetManager: SDK.TargetManager.TargetManager,
|
|
135
135
|
settings: Common.Settings.Settings,
|
|
136
136
|
multitargetNetworkManager: SDK.NetworkManager.MultitargetNetworkManager,
|
|
137
|
+
fileManager: Workspace.FileManager.FileManager,
|
|
137
138
|
) {
|
|
138
139
|
super();
|
|
139
140
|
this.#targetManager = targetManager;
|
|
140
141
|
this.#settings = settings;
|
|
141
142
|
this.#multitargetNetworkManager = multitargetNetworkManager;
|
|
143
|
+
this.#fileManager = fileManager;
|
|
142
144
|
this.#screenRect = new Rect(0, 0, 1, 1);
|
|
143
145
|
this.#visiblePageRect = new Rect(0, 0, 1, 1);
|
|
144
146
|
this.#availableSize = new Geometry.Size(1, 1);
|
|
@@ -207,6 +209,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
207
209
|
Common.Settings.Settings.instance(),
|
|
208
210
|
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
209
211
|
SDK.NetworkManager.MultitargetNetworkManager.instance(),
|
|
212
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
213
|
+
Workspace.FileManager.FileManager.instance(),
|
|
210
214
|
));
|
|
211
215
|
}
|
|
212
216
|
|
|
@@ -313,8 +317,7 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
313
317
|
#updateFitScale(): void {
|
|
314
318
|
if (this.#type === Type.Device && this.#device && this.#mode) {
|
|
315
319
|
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
316
|
-
this.#scaleSetting.set(
|
|
317
|
-
this.calculateFitScale(orientation.width, orientation.height, this.currentOutline(), this.currentInsets()));
|
|
320
|
+
this.#scaleSetting.set(this.calculateFitScale(orientation.width, orientation.height, this.currentInsets()));
|
|
318
321
|
}
|
|
319
322
|
}
|
|
320
323
|
|
|
@@ -401,18 +404,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
401
404
|
return this.#type;
|
|
402
405
|
}
|
|
403
406
|
|
|
404
|
-
screenImage(): string {
|
|
405
|
-
return (this.#device && this.#mode) ? this.#device.modeImage(this.#mode) : '';
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
canShowDeviceFrame(): boolean {
|
|
409
|
-
return Boolean(this.#device && this.#mode && this.#device.outlineImage(this.#mode));
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
outlineRect(): Rect|null {
|
|
413
|
-
return this.#outlineRect || null;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
407
|
screenRect(): Rect {
|
|
417
408
|
return this.#screenRect;
|
|
418
409
|
}
|
|
@@ -604,10 +595,6 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
604
595
|
return Math.floor(this.#preferredSize.height / (this.#scaleSetting.get() || 1));
|
|
605
596
|
}
|
|
606
597
|
|
|
607
|
-
private currentOutline(): Insets {
|
|
608
|
-
return new Insets(0, 0, 0, 0);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
598
|
private currentInsets(): Insets {
|
|
612
599
|
if (this.#type !== Type.Device || !this.#mode) {
|
|
613
600
|
return new Insets(0, 0, 0, 0);
|
|
@@ -660,25 +647,22 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
660
647
|
}
|
|
661
648
|
if (this.#type === Type.Device && this.#device && this.#mode) {
|
|
662
649
|
const orientation = this.#device.orientationByName(this.#mode.orientation);
|
|
663
|
-
const outline = this.currentOutline();
|
|
664
650
|
const insets = this.currentInsets();
|
|
665
|
-
this.#fitScale = this.calculateFitScale(orientation.width, orientation.height,
|
|
651
|
+
this.#fitScale = this.calculateFitScale(orientation.width, orientation.height, insets);
|
|
666
652
|
if (mobile) {
|
|
667
653
|
this.#appliedUserAgentType = this.#device.touch() ? UA.MOBILE : UA.MOBILE_NO_TOUCH;
|
|
668
654
|
} else {
|
|
669
655
|
this.#appliedUserAgentType = this.#device.touch() ? UA.DESKTOP_TOUCH : UA.DESKTOP;
|
|
670
656
|
}
|
|
671
|
-
this.applyDeviceMetrics(
|
|
672
|
-
|
|
673
|
-
|
|
657
|
+
this.applyDeviceMetrics(new Geometry.Size(orientation.width, orientation.height), insets,
|
|
658
|
+
this.#scaleSetting.get(), this.#device.deviceScaleFactor, mobile,
|
|
659
|
+
this.getScreenOrientationType(), resetPageScaleFactor);
|
|
674
660
|
this.applyUserAgent(this.#device.userAgent, this.#device.userAgentMetadata);
|
|
675
661
|
this.applyTouch(this.#device.touch(), mobile);
|
|
676
662
|
} else if (this.#type === Type.None) {
|
|
677
663
|
this.#fitScale = this.calculateFitScale(this.#availableSize.width, this.#availableSize.height);
|
|
678
664
|
this.#appliedUserAgentType = UA.DESKTOP;
|
|
679
|
-
this.applyDeviceMetrics(
|
|
680
|
-
this.#availableSize, new Insets(0, 0, 0, 0), new Insets(0, 0, 0, 0), 1, 0, mobile, null,
|
|
681
|
-
resetPageScaleFactor);
|
|
665
|
+
this.applyDeviceMetrics(this.#availableSize, new Insets(0, 0, 0, 0), 1, 0, mobile, null, resetPageScaleFactor);
|
|
682
666
|
this.applyUserAgent('', null);
|
|
683
667
|
this.applyTouch(false, false);
|
|
684
668
|
} else if (this.#type === Type.Responsive) {
|
|
@@ -693,12 +677,12 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
693
677
|
const defaultDeviceScaleFactor = mobile ? defaultMobileScaleFactor : 0;
|
|
694
678
|
this.#fitScale = this.calculateFitScale(this.#widthSetting.get(), this.#heightSetting.get());
|
|
695
679
|
this.#appliedUserAgentType = this.#uaSetting.get();
|
|
696
|
-
this.applyDeviceMetrics(
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
680
|
+
this.applyDeviceMetrics(new Geometry.Size(screenWidth, screenHeight), new Insets(0, 0, 0, 0),
|
|
681
|
+
this.#scaleSetting.get(),
|
|
682
|
+
this.#deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile,
|
|
683
|
+
screenHeight >= screenWidth ? Protocol.Emulation.ScreenOrientationType.PortraitPrimary :
|
|
684
|
+
Protocol.Emulation.ScreenOrientationType.LandscapePrimary,
|
|
685
|
+
resetPageScaleFactor);
|
|
702
686
|
this.applyUserAgent(
|
|
703
687
|
mobile ? DeviceModeModel.defaultMobileUserAgent() : '',
|
|
704
688
|
mobile ? DeviceModeModel.defaultMobileUserAgentMetadata() : null);
|
|
@@ -714,14 +698,11 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
714
698
|
this.dispatchEventToListeners(Events.UPDATED);
|
|
715
699
|
}
|
|
716
700
|
|
|
717
|
-
private calculateFitScale(screenWidth: number, screenHeight: number,
|
|
718
|
-
const outlineWidth = outline ? outline.left + outline.right : 0;
|
|
719
|
-
const outlineHeight = outline ? outline.top + outline.bottom : 0;
|
|
701
|
+
private calculateFitScale(screenWidth: number, screenHeight: number, insets?: Insets): number {
|
|
720
702
|
const insetsWidth = insets ? insets.left + insets.right : 0;
|
|
721
703
|
const insetsHeight = insets ? insets.top + insets.bottom : 0;
|
|
722
|
-
let scale = Math.min(
|
|
723
|
-
|
|
724
|
-
screenHeight ? this.#preferredSize.height / (screenHeight + outlineHeight) : 1);
|
|
704
|
+
let scale = Math.min(screenWidth ? this.#preferredSize.width / screenWidth : 1,
|
|
705
|
+
screenHeight ? this.#preferredSize.height / screenHeight : 1);
|
|
725
706
|
scale = Math.min(Math.floor(scale * 100), 100);
|
|
726
707
|
|
|
727
708
|
let sharpScale = scale;
|
|
@@ -754,10 +735,9 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
754
735
|
this.#multitargetNetworkManager.setUserAgentOverride(userAgent, userAgent ? userAgentMetadata : null);
|
|
755
736
|
}
|
|
756
737
|
|
|
757
|
-
private applyDeviceMetrics(
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
resetPageScaleFactor: boolean): void {
|
|
738
|
+
private applyDeviceMetrics(screenSize: Geometry.Size, insets: Insets, scale: number, deviceScaleFactor: number,
|
|
739
|
+
mobile: boolean, screenOrientation: Protocol.Emulation.ScreenOrientationType|null,
|
|
740
|
+
resetPageScaleFactor: boolean): void {
|
|
761
741
|
screenSize.width = Math.max(1, Math.floor(screenSize.width));
|
|
762
742
|
screenSize.height = Math.max(1, Math.floor(screenSize.height));
|
|
763
743
|
|
|
@@ -771,12 +751,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
771
751
|
|
|
772
752
|
this.#appliedDeviceSize = screenSize;
|
|
773
753
|
this.#appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
|
|
774
|
-
this.#screenRect = new Rect(
|
|
775
|
-
|
|
776
|
-
screenSize.width * scale, screenSize.height * scale);
|
|
777
|
-
this.#outlineRect = new Rect(
|
|
778
|
-
this.#screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale,
|
|
779
|
-
(outline.top + screenSize.height + outline.bottom) * scale);
|
|
754
|
+
this.#screenRect = new Rect(Math.max(0, (this.#availableSize.width - screenSize.width * scale) / 2), 0,
|
|
755
|
+
screenSize.width * scale, screenSize.height * scale);
|
|
780
756
|
this.#visiblePageRect = new Rect(
|
|
781
757
|
positionX * scale, positionY * scale,
|
|
782
758
|
Math.min(pageWidth * scale, this.#availableSize.width - this.#screenRect.left - positionX * scale),
|
|
@@ -898,29 +874,21 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
898
874
|
pageImage.src = 'data:image/png;base64,' + screenshot;
|
|
899
875
|
pageImage.onload = async () => {
|
|
900
876
|
const scale = pageImage.naturalWidth / this.screenRect().width;
|
|
901
|
-
const outlineRectFromModel = this.outlineRect();
|
|
902
|
-
if (!outlineRectFromModel) {
|
|
903
|
-
throw new Error('Unable to take screenshot: no outlineRect available.');
|
|
904
|
-
}
|
|
905
|
-
const outlineRect = outlineRectFromModel.scale(scale);
|
|
906
877
|
const screenRect = this.screenRect().scale(scale);
|
|
907
878
|
const visiblePageRect = this.visiblePageRect().scale(scale);
|
|
908
|
-
const contentLeft =
|
|
909
|
-
const contentTop =
|
|
879
|
+
const contentLeft = visiblePageRect.left;
|
|
880
|
+
const contentTop = visiblePageRect.top;
|
|
910
881
|
|
|
911
|
-
const canvas = new OffscreenCanvas(Math.floor(
|
|
882
|
+
const canvas = new OffscreenCanvas(Math.floor(screenRect.width),
|
|
912
883
|
// Cap the height to not hit the GPU limit.
|
|
913
884
|
// https://crbug.com/1260828
|
|
914
|
-
Math.min((1 << 14), Math.floor(
|
|
885
|
+
Math.min((1 << 14), Math.floor(screenRect.height)));
|
|
915
886
|
const ctx = canvas.getContext('2d', {willReadFrequently: true});
|
|
916
887
|
if (!ctx) {
|
|
917
888
|
throw new Error('Could not get 2d context from canvas.');
|
|
918
889
|
}
|
|
919
890
|
ctx.imageSmoothingEnabled = false;
|
|
920
891
|
|
|
921
|
-
if (this.screenImage()) {
|
|
922
|
-
await this.paintImage(ctx, this.screenImage(), screenRect.relativeTo(outlineRect));
|
|
923
|
-
}
|
|
924
892
|
ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
|
|
925
893
|
void this.saveScreenshot(canvas);
|
|
926
894
|
};
|
|
@@ -976,17 +944,41 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
976
944
|
|
|
977
945
|
private async saveScreenshot(canvas: OffscreenCanvas): Promise<void> {
|
|
978
946
|
const url = this.inspectedURL();
|
|
979
|
-
let
|
|
947
|
+
let baseName = '';
|
|
980
948
|
if (url) {
|
|
981
|
-
const
|
|
982
|
-
|
|
949
|
+
const parsedURL = Common.ParsedURL.ParsedURL.fromString(url);
|
|
950
|
+
if (parsedURL) {
|
|
951
|
+
const host = parsedURL.host;
|
|
952
|
+
const path = parsedURL.path.replace(/^\/+/, '').replace(/\/+$/, '');
|
|
953
|
+
baseName = host;
|
|
954
|
+
if (path) {
|
|
955
|
+
baseName += '-' + path.replaceAll('/', '-');
|
|
956
|
+
}
|
|
957
|
+
baseName = baseName.replace(/[^a-z0-9._-]/gi, '_');
|
|
958
|
+
}
|
|
983
959
|
}
|
|
984
960
|
|
|
961
|
+
if (!baseName) {
|
|
962
|
+
baseName = 'screenshot';
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
let suffix = '';
|
|
985
966
|
const device = this.device();
|
|
986
967
|
if (device && this.type() === Type.Device) {
|
|
987
|
-
|
|
968
|
+
suffix += `(${device.title})`;
|
|
969
|
+
}
|
|
970
|
+
suffix += '.png';
|
|
971
|
+
|
|
972
|
+
// The Windows save dialog / Chrome wrapper limits the suggested filename
|
|
973
|
+
// to 63 characters (due to a 64-byte null-terminated buffer).
|
|
974
|
+
// Capping the total filename length at 63 avoids truncation of the extension.
|
|
975
|
+
const maxBaseNameLength = Math.max(0, 63 - suffix.length);
|
|
976
|
+
baseName = Platform.StringUtilities.truncateToCodeUnitLength(baseName, maxBaseNameLength);
|
|
977
|
+
|
|
978
|
+
let fileName = baseName + suffix;
|
|
979
|
+
if (fileName.length > 63) {
|
|
980
|
+
fileName = Platform.StringUtilities.truncateToCodeUnitLength(fileName, 59) + '.png';
|
|
988
981
|
}
|
|
989
|
-
fileName += '.png';
|
|
990
982
|
const blob = await canvas.convertToBlob({type: 'image/png'});
|
|
991
983
|
const dataUrl = await new Promise<string>((resolve, reject) => {
|
|
992
984
|
const reader = new FileReader();
|
|
@@ -996,11 +988,8 @@ export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper<EventTyp
|
|
|
996
988
|
});
|
|
997
989
|
const base64 = dataUrl.slice(dataUrl.indexOf(',') + 1);
|
|
998
990
|
const contentData = new TextUtils.ContentData.ContentData(base64, /* isBase64=*/ true, 'image/png');
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
contentData, /* forceSaveAs=*/ true);
|
|
1002
|
-
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
1003
|
-
Workspace.FileManager.FileManager.instance().close(fileName as Platform.DevToolsPath.RawPathString);
|
|
991
|
+
await this.#fileManager.save(fileName as Platform.DevToolsPath.RawPathString, contentData, /* forceSaveAs=*/ true);
|
|
992
|
+
this.#fileManager.close(fileName as Platform.DevToolsPath.RawPathString);
|
|
1004
993
|
}
|
|
1005
994
|
|
|
1006
995
|
private applyTouch(touchEnabled: boolean, mobile: boolean): void {
|