chrome-devtools-frontend 1.0.1669021 → 1.0.1672557
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/fixing-skipped-tests/SKILL.md +6 -6
- package/.agents/skills/gerrit-cli/SKILL.md +4 -10
- package/.agents/skills/gerrit-cli/references/commands.md +45 -2
- package/.agents/skills/gerrit-cli/references/workflows.md +7 -0
- package/.agents/skills/gerrit-cli/scripts/import_upstream.py +34 -152
- package/config/typescript/tsconfig.eslint.json +1 -1
- package/docs/contributing/settings-experiments-features.md +2 -8
- package/docs/ecosystem/automatic_workspace_folders.md +0 -19
- package/eslint.config.mjs +5 -5
- package/front_end/core/common/Lazy.ts +3 -3
- package/front_end/core/common/SettingRegistration.ts +0 -7
- package/front_end/core/common/Settings.ts +0 -38
- package/front_end/core/host/UserMetrics.ts +187 -953
- package/front_end/core/host/UserMetricsEnums.ts +949 -0
- package/front_end/core/root/Runtime.ts +21 -138
- package/front_end/core/sdk/CSSMetadata.ts +70 -65
- package/front_end/core/sdk/CategorizedBreakpoint.ts +0 -1
- package/front_end/core/sdk/ChildTargetManager.ts +0 -2
- package/front_end/core/sdk/EmulationModel.ts +0 -2
- package/front_end/core/sdk/EventBreakpointsModel.ts +0 -4
- package/front_end/core/sdk/NetworkManager.ts +0 -3
- package/front_end/core/sdk/PageResourceLoader.ts +9 -9
- package/front_end/core/sdk/RehydratingConnection.ts +52 -4
- package/front_end/core/sdk/Target.ts +0 -4
- package/front_end/devtools_compatibility.js +886 -0
- package/front_end/entrypoints/inspector_main/RenderingOptions.ts +7 -6
- package/front_end/entrypoints/main/ExecutionContextSelector.ts +0 -1
- package/front_end/entrypoints/main/MainImpl.ts +18 -22
- package/front_end/foundation/Universe.ts +7 -2
- package/front_end/generated/InspectorBackendCommands.ts +3 -10
- package/front_end/generated/{SupportedCSSProperties.js → SupportedCSSProperties.ts} +16 -0
- package/front_end/generated/protocol-mapping.d.ts +0 -42
- package/front_end/generated/protocol-proxy-api.d.ts +0 -38
- package/front_end/generated/protocol.ts +9 -169
- package/front_end/models/ai_assistance/AiAgent2.ts +11 -3
- package/front_end/models/ai_assistance/AiConversation.ts +1 -0
- package/front_end/models/ai_assistance/AiHistoryStorage.ts +8 -5
- package/front_end/models/ai_assistance/AiSetting.ts +108 -0
- package/front_end/models/ai_assistance/AiUtils.ts +47 -0
- package/front_end/models/ai_assistance/ChangeManager.ts +1 -0
- package/front_end/models/ai_assistance/ExtensionScope.ts +3 -12
- package/front_end/models/ai_assistance/agents/AiAgent.ts +11 -18
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +3 -0
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +42 -17
- package/front_end/models/ai_assistance/agents/PerformanceAgent.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +3 -2
- package/front_end/models/ai_assistance/agents/StorageAgent.ts +253 -155
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +2 -2
- package/front_end/models/ai_assistance/ai_assistance.ts +4 -0
- package/front_end/models/ai_assistance/contexts/PerformanceTraceContext.ts +12 -6
- package/front_end/models/ai_assistance/data_formatters/FileFormatter.ts +3 -1
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +1 -0
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +4 -3
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +1 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -0
- package/front_end/models/ai_assistance/injected.ts +1 -0
- package/front_end/models/ai_assistance/performance/AICallTree.ts +1 -0
- package/front_end/models/ai_assistance/skills/Skill.ts +1 -1
- package/front_end/models/ai_assistance/skills/SkillRegistry.ts +2 -0
- package/front_end/models/ai_assistance/skills/performance.md +10 -0
- package/front_end/models/ai_assistance/tools/ExecuteJavaScript.ts +52 -5
- package/front_end/models/ai_assistance/tools/GetElementAccessibilityDetails.ts +4 -4
- package/front_end/models/ai_assistance/tools/GetLighthouseAudits.ts +4 -4
- package/front_end/models/ai_assistance/tools/GetNetworkRequestDetails.ts +5 -4
- package/front_end/models/ai_assistance/tools/GetStyles.ts +5 -4
- package/front_end/models/ai_assistance/tools/ListNetworkRequests.ts +5 -4
- package/front_end/models/ai_assistance/tools/README.md +1 -1
- package/front_end/models/ai_assistance/tools/RecordPerformanceTrace.ts +63 -0
- package/front_end/models/ai_assistance/tools/ResolveDevtoolsNodePath.ts +5 -5
- package/front_end/models/ai_assistance/tools/Tool.ts +118 -24
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +2 -0
- package/front_end/models/badges/UserBadges.ts +2 -0
- package/front_end/models/bindings/NetworkProject.ts +5 -0
- package/front_end/models/bindings/ResourceScriptMapping.ts +2 -0
- package/front_end/models/bindings/ResourceUtils.ts +3 -0
- package/front_end/models/crux-manager/CrUXManager.ts +1 -0
- package/front_end/models/emulation/DeviceModeModel.ts +140 -7
- package/front_end/models/emulation/EmulatedDevices.ts +246 -793
- package/front_end/models/issues_manager/IssuesManager.ts +10 -2
- package/front_end/models/live-metrics/LiveMetrics.ts +41 -9
- package/front_end/models/logs/LogManager.ts +8 -5
- package/front_end/models/logs/NetworkLog.ts +1 -0
- package/front_end/models/persistence/IsolatedFileSystemManager.ts +21 -3
- package/front_end/models/persistence/NetworkPersistenceManager.ts +6 -0
- package/front_end/models/project_settings/ProjectSettingsModel.ts +8 -12
- package/front_end/models/trace/Processor.ts +42 -10
- package/front_end/models/trace/handlers/LayoutShiftsHandler.ts +12 -19
- package/front_end/models/trace/handlers/MetaHandler.ts +38 -5
- package/front_end/models/trace/insights/CLSCulprits.ts +1 -2
- package/front_end/models/trace/insights/CharacterSet.ts +1 -1
- package/front_end/models/trace/insights/Common.ts +21 -2
- package/front_end/models/trace/insights/DocumentLatency.ts +1 -1
- package/front_end/models/trace/insights/LCPBreakdown.ts +7 -6
- package/front_end/models/trace/insights/LCPDiscovery.ts +1 -1
- package/front_end/models/trace/insights/ModernHTTP.ts +7 -3
- package/front_end/models/trace/insights/NetworkDependencyTree.ts +1 -1
- package/front_end/models/trace/insights/RenderBlocking.ts +1 -1
- package/front_end/models/trace/insights/ThirdParties.ts +5 -2
- package/front_end/models/trace/insights/types.ts +11 -6
- package/front_end/models/trace/types/Configuration.ts +5 -0
- package/front_end/models/trace_source_maps_resolver/SourceMapsResolver.ts +3 -1
- package/front_end/models/workspace/IgnoreListManager.ts +2 -0
- package/front_end/models/workspace/UISourceCode.ts +2 -0
- package/front_end/models/workspace_diff/WorkspaceDiff.ts +4 -0
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +22 -22
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +0 -7
- package/front_end/panels/ai_assistance/components/ChatInput.ts +4 -0
- package/front_end/panels/ai_assistance/components/ChatMessage.ts +79 -34
- package/front_end/panels/ai_assistance/components/WalkthroughView.ts +1 -2
- package/front_end/panels/ai_assistance/components/walkthroughView.css +1 -1
- package/front_end/panels/application/ApplicationPanelSidebar.ts +9 -106
- package/front_end/panels/application/ApplicationPanelTreeElement.ts +1 -1
- package/front_end/panels/application/application.ts +0 -10
- package/front_end/panels/application/components/components.ts +0 -4
- package/front_end/panels/browser_debugger/CategorizedBreakpointsSidebarPane.ts +0 -5
- package/front_end/panels/browser_debugger/EventListenerBreakpointsSidebarPane.ts +6 -12
- package/front_end/panels/browser_debugger/browser_debugger-meta.ts +5 -3
- package/front_end/panels/console/ConsoleFormat.ts +2 -62
- package/front_end/panels/console/ConsoleViewMessage.ts +14 -7
- package/front_end/panels/elements/ElementsTreeElement.ts +1 -2
- package/front_end/panels/emulation/AdvancedApp.ts +1 -2
- package/front_end/panels/emulation/DeviceModeToolbar.ts +83 -69
- package/front_end/panels/emulation/DeviceModeView.ts +4 -134
- package/front_end/panels/emulation/DeviceModeWrapper.ts +52 -69
- package/front_end/panels/emulation/MediaQueryInspector.ts +2 -2
- package/front_end/panels/emulation/emulation-meta.ts +12 -12
- package/front_end/panels/issues/IssuesPane.ts +3 -1
- package/front_end/panels/lighthouse/LighthouseController.ts +6 -0
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +17 -21
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryNavigator.ts +206 -126
- package/front_end/panels/linear_memory_inspector/components/linearMemoryInspector.css +1 -1
- package/front_end/panels/mobile_throttling/CalibrationController.ts +1 -1
- package/front_end/panels/mobile_throttling/MobileThrottlingSelector.ts +3 -3
- package/front_end/panels/mobile_throttling/NetworkPanelIndicator.ts +6 -6
- package/front_end/panels/mobile_throttling/NetworkThrottlingSelector.ts +14 -12
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +13 -13
- package/front_end/panels/mobile_throttling/ThrottlingPresets.ts +10 -10
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +28 -28
- package/front_end/panels/mobile_throttling/mobile_throttling-meta.ts +6 -6
- package/front_end/panels/network/RequestHeadersView.ts +1 -1
- package/front_end/panels/network/ResourceChunkView.ts +243 -144
- package/front_end/panels/network/ResourceDirectSocketChunkView.ts +52 -29
- package/front_end/panels/network/ResourceWebSocketFrameView.ts +21 -35
- package/front_end/panels/network/resourceChunkView.css +41 -36
- package/front_end/panels/profiler/HeapDetachedElementsDataGrid.ts +21 -12
- package/front_end/panels/profiler/profiler.ts +4 -0
- package/front_end/panels/recorder/RecorderPanel.ts +6 -14
- package/front_end/panels/sensors/LocationsSettingsTab.ts +7 -7
- package/front_end/panels/settings/AISettingsTab.ts +75 -31
- package/front_end/panels/settings/SettingsScreen.ts +8 -13
- package/front_end/panels/settings/components/SyncSection.ts +3 -4
- package/front_end/panels/settings/emulation/DevicesSettingsTab.ts +650 -18
- package/front_end/panels/settings/emulation/devicesSettingsTab.css +18 -0
- package/front_end/panels/settings/settings-meta.ts +0 -1
- package/front_end/panels/sources/CategorizedBreakpointL10n.ts +0 -2
- package/front_end/panels/sources/DebuggerPausedMessage.ts +11 -5
- package/front_end/panels/sources/DebuggerPlugin.ts +1 -1
- package/front_end/panels/sources/EditingLocationHistoryManager.ts +12 -9
- package/front_end/panels/sources/SourcesPanel.ts +19 -17
- package/front_end/panels/sources/SourcesView.ts +191 -96
- package/front_end/panels/sources/TabbedEditorContainer.ts +3 -4
- package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +2 -5
- package/front_end/panels/timeline/TimelinePanel.ts +2 -0
- package/front_end/panels/timeline/TimelineUIUtils.ts +15 -0
- package/front_end/panels/timeline/components/CWVMetrics.ts +16 -3
- package/front_end/panels/timeline/components/cwvMetrics.css +4 -0
- package/front_end/panels/timeline/components/liveMetricsView.css +0 -17
- package/front_end/panels/timeline/components/metricValueStyles.css +17 -0
- package/front_end/panels/timeline/timeline-meta.ts +3 -5
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/codemirror.next/chunk/angular.js +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/chunk/cpp.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.d.ts +1332 -193
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/rebuild.sh +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 +64 -15
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +65 -16
- package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +50 -7
- 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.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts +2 -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 +5 -5
- 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/Connection.d.ts +2 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js +8 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Connection.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js +3 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Dialog.js.map +1 -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 +16 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts +5 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js +11 -6
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Connection.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js +5 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Dialog.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/NetworkManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js +4 -3
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts +27 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js +12 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/Debug.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/puppeteer/common/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js +2 -0
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +2 -1
- 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 +5 -4
- 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/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 +64 -15
- package/front_end/third_party/puppeteer/package/package.json +2 -2
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +50 -7
- package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +9 -7
- package/front_end/third_party/puppeteer/package/src/bidi/Connection.ts +9 -6
- package/front_end/third_party/puppeteer/package/src/bidi/Dialog.ts +4 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +24 -1
- package/front_end/third_party/puppeteer/package/src/cdp/Connection.ts +11 -6
- package/front_end/third_party/puppeteer/package/src/cdp/Dialog.ts +7 -0
- package/front_end/third_party/puppeteer/package/src/cdp/NetworkManager.ts +11 -0
- package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +7 -3
- package/front_end/third_party/puppeteer/package/src/common/Debug.ts +30 -5
- package/front_end/third_party/puppeteer/package/src/common/util.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +2 -0
- package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +6 -4
- package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
- package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
- package/front_end/tsconfig.compatibility.json +2 -1
- package/front_end/tsconfig.json +1 -1
- package/front_end/ui/components/icon_button/IconButton.ts +1 -1
- package/front_end/ui/components/issue_counter/IssueCounter.ts +1 -1
- package/front_end/ui/components/settings/SettingCheckbox.ts +4 -7
- package/front_end/ui/components/settings/settings.ts +1 -2
- package/front_end/ui/legacy/Treeoutline.ts +52 -30
- package/front_end/ui/legacy/components/object_ui/CSSStyleSanitizer.ts +74 -0
- package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +6 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +47 -54
- package/front_end/ui/legacy/components/object_ui/object_ui.ts +2 -0
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +5 -27
- package/front_end/ui/legacy/components/settings_ui/SettingsUI.ts +10 -12
- package/front_end/ui/settings/SettingUIRegistration.ts +0 -8
- package/front_end/ui/visual_logging/KnownContextValues.ts +37 -0
- package/inspector_overlay/tsconfig.json +8 -2
- package/package.json +3 -2
- package/.agents/skills/gerrit-cli/scripts/gerrit_client_wrapper.py +0 -47
- package/front_end/core/sdk/CSSModel.test.api.ts +0 -102
- package/front_end/core/sdk/DOMModel.test.api.ts +0 -104
- package/front_end/foundation/Universe.test.api.ts +0 -73
- package/front_end/panels/application/SharedStorageEventsView.ts +0 -128
- package/front_end/panels/application/SharedStorageItemsView.ts +0 -179
- package/front_end/panels/application/SharedStorageListTreeElement.ts +0 -65
- package/front_end/panels/application/SharedStorageModel.ts +0 -249
- package/front_end/panels/application/SharedStorageTreeElement.ts +0 -40
- package/front_end/panels/application/components/SharedStorageAccessGrid.ts +0 -191
- package/front_end/panels/application/components/SharedStorageMetadataView.ts +0 -133
- package/front_end/panels/application/components/sharedStorageAccessGrid.css +0 -29
- package/front_end/panels/application/components/sharedStorageMetadataView.css +0 -29
- package/front_end/panels/application/sharedStorageEventsView.css +0 -9
- package/front_end/panels/network/OriginalResourceChunkView.ts +0 -340
- package/front_end/panels/network/originalResourceChunkView.css +0 -49
- package/front_end/ui/components/settings/SettingDeprecationWarning.ts +0 -47
- package/front_end/ui/components/settings/settingDeprecationWarning.css +0 -14
- /package/front_end/generated/{ARIAProperties.js → ARIAProperties.ts} +0 -0
|
@@ -173,6 +173,7 @@ export function isIssueCodeSupported(code: Protocol.Audits.InspectorIssueCode):
|
|
|
173
173
|
*/
|
|
174
174
|
export function createIssuesFromProtocolIssue(
|
|
175
175
|
issuesModel: SDK.IssuesModel.IssuesModel|null, inspectorIssue: Protocol.Audits.InspectorIssue,
|
|
176
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
176
177
|
frameManager: SDK.FrameManager.FrameManager = SDK.FrameManager.FrameManager.instance()): Issue[] {
|
|
177
178
|
const handler = issueCodeHandlers.get(inspectorIssue.code);
|
|
178
179
|
if (handler) {
|
|
@@ -203,6 +204,7 @@ export function defaultHideIssueByCodeSetting(): HideIssueMenuSetting {
|
|
|
203
204
|
return setting;
|
|
204
205
|
}
|
|
205
206
|
|
|
207
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
206
208
|
export function getHideIssueByCodeSetting(settings: Common.Settings.Settings = Common.Settings.Settings.instance()):
|
|
207
209
|
Common.Settings.Setting<HideIssueMenuSetting> {
|
|
208
210
|
return settings.createSetting('hide-issue-by-code-setting-experiment-2021', defaultHideIssueByCodeSetting());
|
|
@@ -235,13 +237,18 @@ export class IssuesManager extends Common.ObjectWrapper.ObjectWrapper<EventTypes
|
|
|
235
237
|
constructor(
|
|
236
238
|
private readonly showThirdPartyIssuesSetting?: Common.Settings.Setting<boolean>,
|
|
237
239
|
private readonly hideIssueSetting?: Common.Settings.Setting<HideIssueMenuSetting>,
|
|
240
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
238
241
|
frameManager: SDK.FrameManager.FrameManager = SDK.FrameManager.FrameManager.instance(),
|
|
242
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
239
243
|
targetManager: SDK.TargetManager.TargetManager = SDK.TargetManager.TargetManager.instance(),
|
|
244
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
240
245
|
workspace: Workspace.Workspace.WorkspaceImpl = Workspace.Workspace.WorkspaceImpl.instance(),
|
|
241
246
|
debuggerWorkspaceBinding: Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding =
|
|
242
|
-
|
|
247
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
248
|
+
Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance(),
|
|
243
249
|
cssWorkspaceBinding: Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding =
|
|
244
|
-
|
|
250
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
251
|
+
Bindings.CSSWorkspaceBinding.CSSWorkspaceBinding.instance(),
|
|
245
252
|
) {
|
|
246
253
|
super();
|
|
247
254
|
this.#frameManager = frameManager;
|
|
@@ -523,6 +530,7 @@ export interface EventTypes {
|
|
|
523
530
|
|
|
524
531
|
// @ts-expect-error
|
|
525
532
|
globalThis.addIssueForTest = (issue: Protocol.Audits.InspectorIssue) => {
|
|
533
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
526
534
|
const mainTarget = SDK.TargetManager.TargetManager.instance().primaryPageTarget();
|
|
527
535
|
const issuesModel = mainTarget?.model(SDK.IssuesModel.IssuesModel);
|
|
528
536
|
issuesModel?.issueAdded({issue});
|
|
@@ -14,6 +14,13 @@ import * as CrUXManager from '../crux-manager/crux-manager.js';
|
|
|
14
14
|
|
|
15
15
|
import * as Spec from './web-vitals-injected/spec/spec.js';
|
|
16
16
|
|
|
17
|
+
export const timelineEnableSoftNavigationsSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
|
|
18
|
+
name: 'timeline-enable-soft-navigations',
|
|
19
|
+
type: Common.Settings.SettingType.BOOLEAN,
|
|
20
|
+
storageType: Common.Settings.SettingStorageType.SYNCED,
|
|
21
|
+
defaultValue: true,
|
|
22
|
+
};
|
|
23
|
+
|
|
17
24
|
const UIStrings = {
|
|
18
25
|
/**
|
|
19
26
|
* @description Warning text indicating that the Largest Contentful Paint (LCP) performance metric was affected by the user changing the simulated device.
|
|
@@ -61,18 +68,19 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
61
68
|
#mutex = new Common.Mutex.Mutex();
|
|
62
69
|
readonly #targetManager: SDK.TargetManager.TargetManager;
|
|
63
70
|
readonly #deviceModeModel: EmulationModel.DeviceModeModel.DeviceModeModel|null;
|
|
71
|
+
readonly #settings: Common.Settings.Settings;
|
|
64
72
|
|
|
65
|
-
constructor(targetManager: SDK.TargetManager.TargetManager,
|
|
73
|
+
constructor(targetManager: SDK.TargetManager.TargetManager, settings: Common.Settings.Settings,
|
|
66
74
|
deviceModeModel: EmulationModel.DeviceModeModel.DeviceModeModel|null) {
|
|
67
75
|
super();
|
|
68
76
|
this.#targetManager = targetManager;
|
|
77
|
+
this.#settings = settings;
|
|
69
78
|
this.#deviceModeModel = deviceModeModel;
|
|
70
79
|
this.#targetManager.observeTargets(this, {scoped: true});
|
|
71
80
|
this.#targetManager.addModelListener(SDK.ResourceTreeModel.ResourceTreeModel,
|
|
72
81
|
SDK.ResourceTreeModel.Events.PrimaryPageChanged, this.#onPrimaryPageChanged,
|
|
73
82
|
this);
|
|
74
|
-
|
|
75
|
-
.moduleSetting('timeline-enable-soft-navigations')
|
|
83
|
+
this.#settings.resolve(timelineEnableSoftNavigationsSettingDescriptor)
|
|
76
84
|
.addChangeListener(this.#onSettingChanged, this);
|
|
77
85
|
}
|
|
78
86
|
|
|
@@ -104,7 +112,8 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
104
112
|
if (!Root.DevToolsContext.globalInstance().has(LiveMetrics) || forceNew) {
|
|
105
113
|
Root.DevToolsContext.globalInstance().set(
|
|
106
114
|
LiveMetrics,
|
|
107
|
-
|
|
115
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
116
|
+
new LiveMetrics(SDK.TargetManager.TargetManager.instance(), Common.Settings.Settings.instance(),
|
|
108
117
|
EmulationModel.DeviceModeModel.DeviceModeModel.tryInstance()));
|
|
109
118
|
}
|
|
110
119
|
|
|
@@ -149,6 +158,19 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
149
158
|
return false;
|
|
150
159
|
}
|
|
151
160
|
|
|
161
|
+
// Validate duration at runtime to prevent code injection via interpolation.
|
|
162
|
+
const duration = Number(interaction.duration);
|
|
163
|
+
if (!Number.isFinite(duration)) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// JSON.stringify escapes quotes. We concatenate safeInteractionType (which is
|
|
168
|
+
// wrapped in double quotes) instead of interpolating it directly inside the
|
|
169
|
+
// single-quoted template below. This avoids syntax errors if the value contains
|
|
170
|
+
// single quotes (e.g. "pointer'"), which would otherwise terminate the
|
|
171
|
+
// single-quoted template string.
|
|
172
|
+
const safeInteractionType = JSON.stringify(interaction.interactionType ?? 'unknown');
|
|
173
|
+
|
|
152
174
|
const scriptsTable = [];
|
|
153
175
|
for (const loaf of interaction.longAnimationFrameTimings) {
|
|
154
176
|
for (const script of loaf.scripts) {
|
|
@@ -179,8 +201,8 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
179
201
|
'';
|
|
180
202
|
await this.#target.runtimeAgent().invoke_evaluate({
|
|
181
203
|
expression: `
|
|
182
|
-
console.group('[DevTools] Long animation frames for ${
|
|
183
|
-
|
|
204
|
+
console.group('[DevTools] Long animation frames for ${duration}ms ' + ${
|
|
205
|
+
safeInteractionType} + ' interaction');
|
|
184
206
|
console.log('Scripts${scriptLimitText}:');
|
|
185
207
|
console.table(${JSON.stringify(scriptsTable)});
|
|
186
208
|
console.log('Intersecting long animation frame events${loafLimitText}:', ${
|
|
@@ -206,6 +228,12 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
206
228
|
*/
|
|
207
229
|
async #resolveNodeRef(index: number, executionContextId: Protocol.Runtime.ExecutionContextId):
|
|
208
230
|
Promise<SDK.DOMModel.DOMNode|null> {
|
|
231
|
+
// Validate index at runtime because the payload comes from an untrusted binding
|
|
232
|
+
// and could contain malicious strings if type casted.
|
|
233
|
+
if (!Number.isInteger(index)) {
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
|
|
209
237
|
if (!this.#target) {
|
|
210
238
|
return null;
|
|
211
239
|
}
|
|
@@ -412,7 +440,9 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
412
440
|
this.#clearMetrics();
|
|
413
441
|
this.#navigationType = webVitalsEvent.navigationType;
|
|
414
442
|
if (webVitalsEvent.url) {
|
|
443
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
415
444
|
CrUXManager.CrUXManager.instance().setMainDocumentURL(webVitalsEvent.url);
|
|
445
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
416
446
|
void CrUXManager.CrUXManager.instance().refresh();
|
|
417
447
|
}
|
|
418
448
|
break;
|
|
@@ -445,7 +475,10 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
445
475
|
|
|
446
476
|
const resourceTreeModel = this.#target.model(SDK.ResourceTreeModel.ResourceTreeModel);
|
|
447
477
|
const primaryFrameId = resourceTreeModel?.mainFrame?.id;
|
|
448
|
-
|
|
478
|
+
// Ensure the context belongs to our isolated world and is not the default
|
|
479
|
+
// page context, to prevent the page from spoofing events.
|
|
480
|
+
return Boolean(primaryFrameId && executionContext.frameId === primaryFrameId &&
|
|
481
|
+
executionContext.name === LIVE_METRICS_WORLD_NAME && !executionContext.isDefault);
|
|
449
482
|
}
|
|
450
483
|
|
|
451
484
|
async #onBindingCalled(event: {data: Protocol.Runtime.BindingCalledEvent}): Promise<void> {
|
|
@@ -546,8 +579,7 @@ export class LiveMetrics extends Common.ObjectWrapper.ObjectWrapper<EventTypes>
|
|
|
546
579
|
});
|
|
547
580
|
}
|
|
548
581
|
|
|
549
|
-
const softNavsSettingValue =
|
|
550
|
-
Common.Settings.Settings.instance().moduleSetting('timeline-enable-soft-navigations').get();
|
|
582
|
+
const softNavsSettingValue = this.#settings.resolve(timelineEnableSoftNavigationsSettingDescriptor).get();
|
|
551
583
|
const source = `window.devToolsReportSoftNavs = ${softNavsSettingValue};\n` + await InjectedScript.get();
|
|
552
584
|
|
|
553
585
|
// Inject the script
|
|
@@ -27,11 +27,14 @@ export class LogManager implements SDK.TargetManager.SDKModelObserver<SDK.LogMod
|
|
|
27
27
|
|
|
28
28
|
static instance({forceNew}: {forceNew: boolean} = {forceNew: false}): LogManager {
|
|
29
29
|
if (!Root.DevToolsContext.globalInstance().has(LogManager) || forceNew) {
|
|
30
|
-
Root.DevToolsContext.globalInstance().set(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
Root.DevToolsContext.globalInstance().set(
|
|
31
|
+
LogManager,
|
|
32
|
+
new LogManager(
|
|
33
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
34
|
+
SDK.TargetManager.TargetManager.instance(),
|
|
35
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
36
|
+
NetworkLog.instance(),
|
|
37
|
+
));
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
return Root.DevToolsContext.globalInstance().get(LogManager);
|
|
@@ -56,6 +56,7 @@ export class NetworkLog extends Common.ObjectWrapper.ObjectWrapper<EventTypes> i
|
|
|
56
56
|
static instance(): NetworkLog {
|
|
57
57
|
if (!Root.DevToolsContext.globalInstance().has(NetworkLog)) {
|
|
58
58
|
Root.DevToolsContext.globalInstance().set(
|
|
59
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
59
60
|
NetworkLog, new NetworkLog(SDK.TargetManager.TargetManager.instance(), Common.Settings.Settings.instance()));
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -47,9 +47,7 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
47
47
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
|
|
48
48
|
Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, this.onFileSystemRemoved, this);
|
|
49
49
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
|
|
50
|
-
Host.InspectorFrontendHostAPI.Events.FileSystemAdded,
|
|
51
|
-
this.onFileSystemAdded(event);
|
|
52
|
-
}, this);
|
|
50
|
+
Host.InspectorFrontendHostAPI.Events.FileSystemAdded, this.onFileSystemAdded, this);
|
|
53
51
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
|
|
54
52
|
Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, this.onFileSystemFilesChanged, this);
|
|
55
53
|
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
|
|
@@ -101,13 +99,33 @@ export class IsolatedFileSystemManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
101
99
|
this.fileSystemsLoadedPromise = this.requestFileSystems();
|
|
102
100
|
}
|
|
103
101
|
|
|
102
|
+
// TODO(crbug.com/542394587): Should be `Symbol.dispsoe`
|
|
103
|
+
dispose(): void {
|
|
104
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
105
|
+
Host.InspectorFrontendHostAPI.Events.FileSystemRemoved, this.onFileSystemRemoved, this);
|
|
106
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
107
|
+
Host.InspectorFrontendHostAPI.Events.FileSystemAdded, this.onFileSystemAdded, this);
|
|
108
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
109
|
+
Host.InspectorFrontendHostAPI.Events.FileSystemFilesChangedAddedRemoved, this.onFileSystemFilesChanged, this);
|
|
110
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
111
|
+
Host.InspectorFrontendHostAPI.Events.IndexingTotalWorkCalculated, this.onIndexingTotalWorkCalculated, this);
|
|
112
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
113
|
+
Host.InspectorFrontendHostAPI.Events.IndexingWorked, this.onIndexingWorked, this);
|
|
114
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
115
|
+
Host.InspectorFrontendHostAPI.Events.IndexingDone, this.onIndexingDone, this);
|
|
116
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.removeEventListener(
|
|
117
|
+
Host.InspectorFrontendHostAPI.Events.SearchCompleted, this.onSearchCompleted, this);
|
|
118
|
+
}
|
|
119
|
+
|
|
104
120
|
static instance(opts: {
|
|
105
121
|
forceNew?: boolean|null,
|
|
106
122
|
settings?: Common.Settings.Settings|null,
|
|
107
123
|
console?: Common.Console.Console|null,
|
|
108
124
|
} = {}): IsolatedFileSystemManager {
|
|
109
125
|
const forceNew = opts.forceNew ?? null;
|
|
126
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
110
127
|
const settings = opts.settings ?? Common.Settings.Settings.instance();
|
|
128
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
111
129
|
const console = opts.console ?? Common.Console.Console.instance();
|
|
112
130
|
if (!Root.DevToolsContext.globalInstance().has(IsolatedFileSystemManager) || forceNew) {
|
|
113
131
|
const instance = new IsolatedFileSystemManager(settings, console);
|
|
@@ -103,11 +103,17 @@ export class NetworkPersistenceManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
103
103
|
NetworkPersistenceManager,
|
|
104
104
|
new NetworkPersistenceManager(
|
|
105
105
|
workspace,
|
|
106
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
106
107
|
PersistenceImpl.instance(),
|
|
108
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
107
109
|
Breakpoints.BreakpointManager.BreakpointManager.instance(),
|
|
110
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
108
111
|
SDK.TargetManager.TargetManager.instance(),
|
|
112
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
109
113
|
Common.Settings.Settings.instance(),
|
|
114
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
110
115
|
IsolatedFileSystemManager.instance(),
|
|
116
|
+
// eslint-disable-next-line @devtools/no-instance-of-migrated-singletons
|
|
111
117
|
SDK.NetworkManager.MultitargetNetworkManager.instance(),
|
|
112
118
|
),
|
|
113
119
|
);
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Common from '../../core/common/common.js';
|
|
6
6
|
import * as Platform from '../../core/platform/platform.js';
|
|
7
|
-
import type * as Root from '../../core/root/root.js';
|
|
8
7
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
9
8
|
|
|
10
9
|
/** The security origin for all DevTools (front-end) resources. */
|
|
@@ -107,23 +106,20 @@ export class ProjectSettingsModel extends Common.ObjectWrapper.ObjectWrapper<Eve
|
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
constructor(
|
|
110
|
-
hostConfig: Root.Runtime.HostConfig,
|
|
111
109
|
pageResourceLoader: SDK.PageResourceLoader.PageResourceLoader,
|
|
112
110
|
targetManager: SDK.TargetManager.TargetManager,
|
|
113
111
|
) {
|
|
114
112
|
super();
|
|
115
113
|
this.#pageResourceLoader = pageResourceLoader;
|
|
116
114
|
this.#targetManager = targetManager;
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.#inspectedURLChanged({data: target});
|
|
126
|
-
}
|
|
115
|
+
this.#targetManager.addEventListener(
|
|
116
|
+
SDK.TargetManager.Events.INSPECTED_URL_CHANGED,
|
|
117
|
+
this.#inspectedURLChanged,
|
|
118
|
+
this,
|
|
119
|
+
);
|
|
120
|
+
const target = this.#targetManager.primaryPageTarget();
|
|
121
|
+
if (target !== null) {
|
|
122
|
+
this.#inspectedURLChanged({data: target});
|
|
127
123
|
}
|
|
128
124
|
}
|
|
129
125
|
|
|
@@ -440,7 +440,12 @@ export class TraceProcessor extends EventTarget {
|
|
|
440
440
|
let id, urlString, navigation;
|
|
441
441
|
if (context.navigation) {
|
|
442
442
|
id = `NAVIGATION_${this.#insights.size}`;
|
|
443
|
-
|
|
443
|
+
if (Types.Events.isSoftNavigationStart(context.navigation)) {
|
|
444
|
+
urlString = context.navigation.args.context.URL;
|
|
445
|
+
} else {
|
|
446
|
+
urlString = data.Meta.finalDisplayUrlByNavigationId.get(context.navigation.args.data?.navigationId ?? '') ??
|
|
447
|
+
data.Meta.mainFrameURL;
|
|
448
|
+
}
|
|
444
449
|
navigation = context.navigation;
|
|
445
450
|
} else {
|
|
446
451
|
id = Types.Events.NO_NAVIGATION;
|
|
@@ -523,17 +528,28 @@ export class TraceProcessor extends EventTarget {
|
|
|
523
528
|
|
|
524
529
|
// Filter main frame navigations to those that have the necessary data (frameId and navigationId).
|
|
525
530
|
// TODO(cjamcl): Does this filtering makes the "use the next nav as the end time" logic potentially broken? Are navs without nav id or frame even real?
|
|
526
|
-
const
|
|
527
|
-
|
|
531
|
+
const hardNavigations = data.Meta.mainFrameNavigations.filter(navigation => navigation.args.frame &&
|
|
532
|
+
navigation.args.data?.navigationId);
|
|
533
|
+
|
|
534
|
+
const softNavigations =
|
|
535
|
+
this.#modelConfiguration.enableSoftNavigation ? Array.from(data.Meta.softNavigationsById.values()) : [];
|
|
536
|
+
const navigations = [...hardNavigations, ...softNavigations].sort((a, b) => a.ts - b.ts);
|
|
528
537
|
|
|
529
538
|
this.#computeInsightsForInitialTracePeriod(data, navigations, options);
|
|
530
539
|
|
|
531
540
|
for (const [index, navigation] of navigations.entries()) {
|
|
532
541
|
const min = navigation.ts;
|
|
533
|
-
// Use trace end for the last navigation, otherwise use the start of the next navigation.
|
|
534
|
-
|
|
542
|
+
// Use trace end for the last navigation, otherwise use the start of the next navigation (minus 1 to avoid overlap).
|
|
543
|
+
let max = index + 1 < navigations.length ? navigations[index + 1].ts : data.Meta.traceBounds.max;
|
|
544
|
+
if (index + 1 < navigations.length) {
|
|
545
|
+
max = Types.Timing.Micro(max - 1);
|
|
546
|
+
}
|
|
535
547
|
const bounds = Helpers.Timing.traceWindowFromMicroSeconds(min, max);
|
|
536
|
-
|
|
548
|
+
if (Types.Events.isSoftNavigationStart(navigation)) {
|
|
549
|
+
this.#computeInsightsForSoftNavigation(navigation, bounds, data, options);
|
|
550
|
+
} else {
|
|
551
|
+
this.#computeInsightsForNavigation(navigation, bounds, data, traceEvents, options);
|
|
552
|
+
}
|
|
537
553
|
}
|
|
538
554
|
}
|
|
539
555
|
|
|
@@ -541,12 +557,13 @@ export class TraceProcessor extends EventTarget {
|
|
|
541
557
|
* Computes insights for the period before the first navigation, or for the entire trace if no navigations exist.
|
|
542
558
|
*/
|
|
543
559
|
#computeInsightsForInitialTracePeriod(
|
|
544
|
-
data: Handlers.Types.HandlerData,
|
|
560
|
+
data: Handlers.Types.HandlerData,
|
|
561
|
+
navigations: ReadonlyArray<Types.Events.NavigationStart|Types.Events.SoftNavigationStart>,
|
|
545
562
|
options: Types.Configuration.ParseOptions): void {
|
|
546
563
|
// Determine bounds: Use the period before the first navigation if navigations exist, otherwise use the entire trace bounds.
|
|
547
|
-
const bounds = navigations.length > 0 ?
|
|
548
|
-
|
|
549
|
-
|
|
564
|
+
const bounds = navigations.length > 0 ? Helpers.Timing.traceWindowFromMicroSeconds(
|
|
565
|
+
data.Meta.traceBounds.min, Types.Timing.Micro(navigations[0].ts - 1)) :
|
|
566
|
+
data.Meta.traceBounds;
|
|
550
567
|
|
|
551
568
|
const context: Insights.Types.InsightSetContext = {
|
|
552
569
|
options,
|
|
@@ -609,6 +626,21 @@ export class TraceProcessor extends EventTarget {
|
|
|
609
626
|
};
|
|
610
627
|
this.#computeInsightSet(data, context);
|
|
611
628
|
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Computes insights for a specific soft navigation event.
|
|
632
|
+
*/
|
|
633
|
+
#computeInsightsForSoftNavigation(navigation: Types.Events.SoftNavigationStart, bounds: Types.Timing.TraceWindowMicro,
|
|
634
|
+
data: Handlers.Types.HandlerData, options: Types.Configuration.ParseOptions): void {
|
|
635
|
+
const frameId = navigation.args.frame;
|
|
636
|
+
const context: Insights.Types.InsightSetContextWithSoftNavigation = {
|
|
637
|
+
options,
|
|
638
|
+
bounds,
|
|
639
|
+
frameId,
|
|
640
|
+
navigation,
|
|
641
|
+
};
|
|
642
|
+
this.#computeInsightSet(data, context);
|
|
643
|
+
}
|
|
612
644
|
}
|
|
613
645
|
|
|
614
646
|
/**
|
|
@@ -39,7 +39,6 @@ import type {HandlerName} from './types.js';
|
|
|
39
39
|
|
|
40
40
|
interface LayoutShiftsData {
|
|
41
41
|
clusters: readonly Types.Events.SyntheticLayoutShiftCluster[];
|
|
42
|
-
clustersByNavigationId: Map<Types.Events.NavigationId, Types.Events.SyntheticLayoutShiftCluster[]>;
|
|
43
42
|
sessionMaxScore: number;
|
|
44
43
|
// The session window which contains the SessionMaxScore
|
|
45
44
|
clsWindowID: number;
|
|
@@ -110,7 +109,6 @@ let sessionMaxScore = 0;
|
|
|
110
109
|
let clsWindowID = -1;
|
|
111
110
|
|
|
112
111
|
let clusters: Types.Events.SyntheticLayoutShiftCluster[] = [];
|
|
113
|
-
let clustersByNavigationId = new Map<Types.Events.NavigationId, Types.Events.SyntheticLayoutShiftCluster[]>();
|
|
114
112
|
|
|
115
113
|
/**
|
|
116
114
|
* Represents a point in time in which a LS score change
|
|
@@ -141,7 +139,6 @@ export function reset(): void {
|
|
|
141
139
|
sessionMaxScore = 0;
|
|
142
140
|
scoreRecords = [];
|
|
143
141
|
clsWindowID = -1;
|
|
144
|
-
clustersByNavigationId = new Map();
|
|
145
142
|
}
|
|
146
143
|
|
|
147
144
|
export function handleEvent(event: Types.Events.Event): void {
|
|
@@ -292,8 +289,9 @@ export async function finalize(): Promise<void> {
|
|
|
292
289
|
}
|
|
293
290
|
|
|
294
291
|
async function buildLayoutShiftsClusters(): Promise<void> {
|
|
295
|
-
const {navigationsByFrameId, mainFrameId, traceBounds} = metaHandlerData();
|
|
296
|
-
const navigations
|
|
292
|
+
const {navigationsByFrameId, mainFrameId, traceBounds, softNavigationsById} = metaHandlerData();
|
|
293
|
+
const navigations: Types.Events.Event[] =
|
|
294
|
+
[...(navigationsByFrameId.get(mainFrameId) || []), ...softNavigationsById.values()].sort((a, b) => a.ts - b.ts);
|
|
297
295
|
if (layoutShiftEvents.length === 0) {
|
|
298
296
|
return;
|
|
299
297
|
}
|
|
@@ -348,13 +346,15 @@ async function buildLayoutShiftsClusters(): Promise<void> {
|
|
|
348
346
|
// If this cluster happened after a navigation, set the navigationId to
|
|
349
347
|
// the current navigation. This lets us easily group clusters by
|
|
350
348
|
// navigation.
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
349
|
+
let navigationId: string|undefined = undefined;
|
|
350
|
+
if (currentShiftNavigation !== null) {
|
|
351
|
+
const nav = navigations[currentShiftNavigation];
|
|
352
|
+
if (Types.Events.isNavigationStart(nav)) {
|
|
353
|
+
navigationId = nav.args.data?.navigationId;
|
|
354
|
+
}
|
|
355
|
+
} else {
|
|
356
|
+
navigationId = Types.Events.NO_NAVIGATION;
|
|
357
|
+
}
|
|
358
358
|
|
|
359
359
|
clusters.push(Helpers.SyntheticEvents.SyntheticEventsManager
|
|
360
360
|
.registerSyntheticEvent<Types.Events.SyntheticLayoutShiftCluster>({
|
|
@@ -519,12 +519,6 @@ async function buildLayoutShiftsClusters(): Promise<void> {
|
|
|
519
519
|
sessionMaxScore = weightedScore;
|
|
520
520
|
}
|
|
521
521
|
|
|
522
|
-
if (cluster.navigationId) {
|
|
523
|
-
const clustersForId = Platform.MapUtilities.getWithDefault(clustersByNavigationId, cluster.navigationId, () => {
|
|
524
|
-
return [];
|
|
525
|
-
});
|
|
526
|
-
clustersForId.push(cluster);
|
|
527
|
-
}
|
|
528
522
|
}
|
|
529
523
|
}
|
|
530
524
|
|
|
@@ -543,7 +537,6 @@ export function data(): LayoutShiftsData {
|
|
|
543
537
|
remoteFonts,
|
|
544
538
|
scoreRecords,
|
|
545
539
|
backendNodeIds,
|
|
546
|
-
clustersByNavigationId,
|
|
547
540
|
paintImageEvents,
|
|
548
541
|
};
|
|
549
542
|
}
|
|
@@ -62,6 +62,7 @@ let navigationsByNavigationId = new Map<string, Types.Events.NavigationStart>();
|
|
|
62
62
|
let softNavigationsById = new Map<number, Types.Events.SoftNavigationStart>();
|
|
63
63
|
let finalDisplayUrlByNavigationId = new Map<string, string>();
|
|
64
64
|
let mainFrameNavigations: Types.Events.NavigationStart[] = [];
|
|
65
|
+
let sameDocumentNavigations: Types.Events.DidCommitSameDocumentNavigation[] = [];
|
|
65
66
|
|
|
66
67
|
// Represents all the threads in the trace, organized by process. This is mostly for internal
|
|
67
68
|
// bookkeeping so that during the finalize pass we can obtain the main and browser thread IDs.
|
|
@@ -97,6 +98,7 @@ export function reset(): void {
|
|
|
97
98
|
finalDisplayUrlByNavigationId = new Map();
|
|
98
99
|
processNames = new Map();
|
|
99
100
|
mainFrameNavigations = [];
|
|
101
|
+
sameDocumentNavigations = [];
|
|
100
102
|
|
|
101
103
|
browserProcessId = Types.Events.ProcessID(-1);
|
|
102
104
|
browserThreadId = Types.Events.ThreadID(-1);
|
|
@@ -346,15 +348,12 @@ export function handleEvent(event: Types.Events.Event): void {
|
|
|
346
348
|
return;
|
|
347
349
|
}
|
|
348
350
|
|
|
349
|
-
//
|
|
351
|
+
// Track history API navigations to compute final display URLs in finalize.
|
|
350
352
|
if (Types.Events.isDidCommitSameDocumentNavigation(event)) {
|
|
351
353
|
if (event.args.render_frame_host.frame_type !== 'PRIMARY_MAIN_FRAME') {
|
|
352
354
|
return;
|
|
353
355
|
}
|
|
354
|
-
|
|
355
|
-
const navigation = mainFrameNavigations.at(-1);
|
|
356
|
-
const key = navigation?.args.data?.navigationId ?? '';
|
|
357
|
-
finalDisplayUrlByNavigationId.set(key, event.args.url);
|
|
356
|
+
sameDocumentNavigations.push(event);
|
|
358
357
|
return;
|
|
359
358
|
}
|
|
360
359
|
}
|
|
@@ -440,6 +439,40 @@ export async function finalize(options?: FinalizeOptions): Promise<void> {
|
|
|
440
439
|
mainFrameURL = firstMainFrameNav.args.data.documentLoaderURL;
|
|
441
440
|
}
|
|
442
441
|
}
|
|
442
|
+
|
|
443
|
+
// Compute final display URLs for each hard navigation.
|
|
444
|
+
// A hard navigation's final URL is updated by history API navigations (e.g. pushState).
|
|
445
|
+
// However, if a soft navigation occurs, subsequent history API navigations belong to the
|
|
446
|
+
// soft navigation and should not update the hard navigation's URL.
|
|
447
|
+
const softNavs = Array.from(softNavigationsById.values()).sort((a, b) => a.ts - b.ts);
|
|
448
|
+
|
|
449
|
+
// Create an array of intervals for each hard navigation.
|
|
450
|
+
const hardNavs = [...mainFrameNavigations];
|
|
451
|
+
|
|
452
|
+
// Add a faux navigation to cover the time before the first hard navigation, or the whole trace if there are none.
|
|
453
|
+
const intervals = [
|
|
454
|
+
{minTs: 0, maxTs: hardNavs.length > 0 ? hardNavs[0].ts : Infinity, key: ''},
|
|
455
|
+
...hardNavs.map((nav, i) => ({
|
|
456
|
+
minTs: nav.ts,
|
|
457
|
+
maxTs: i + 1 < hardNavs.length ? hardNavs[i + 1].ts : Infinity,
|
|
458
|
+
key: nav.args.data?.navigationId ?? '',
|
|
459
|
+
})),
|
|
460
|
+
];
|
|
461
|
+
|
|
462
|
+
for (const {minTs, maxTs, key} of intervals) {
|
|
463
|
+
// Find the first soft navigation within this hard navigation's time window.
|
|
464
|
+
const firstSoftNav = softNavs.find(sn => sn.ts >= minTs && sn.ts < maxTs);
|
|
465
|
+
// If a soft navigation occurred, we only consider history events before it.
|
|
466
|
+
const effectiveMaxTs = firstSoftNav ? firstSoftNav.ts : maxTs;
|
|
467
|
+
|
|
468
|
+
// Find the last history API navigation in the effective window.
|
|
469
|
+
const historyEvents = sameDocumentNavigations.filter(hn => hn.ts >= minTs && hn.ts < effectiveMaxTs);
|
|
470
|
+
|
|
471
|
+
const lastHistoryEvent = historyEvents.at(-1);
|
|
472
|
+
if (lastHistoryEvent) {
|
|
473
|
+
finalDisplayUrlByNavigationId.set(key, lastHistoryEvent.args.url);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
443
476
|
}
|
|
444
477
|
|
|
445
478
|
export interface MetaHandlerData {
|
|
@@ -599,8 +599,7 @@ export function generateInsight(data: Handlers.Types.HandlerData, context: Insig
|
|
|
599
599
|
const domLoadingEvents = data.LayoutShifts.domLoadingEvents.filter(isWithinContext);
|
|
600
600
|
const unsizedImageEvents = data.LayoutShifts.layoutImageUnsizedEvents.filter(isWithinContext);
|
|
601
601
|
|
|
602
|
-
const
|
|
603
|
-
const clusters = data.LayoutShifts.clustersByNavigationId.get(clusterKey) ?? [];
|
|
602
|
+
const clusters = data.LayoutShifts.clusters.filter(isWithinContext);
|
|
604
603
|
const clustersByScore = clusters.toSorted((a, b) => b.clusterCumulativeScore - a.clusterCumulativeScore);
|
|
605
604
|
const worstCluster = clustersByScore.at(0);
|
|
606
605
|
const layoutShifts = clusters.flatMap(cluster => cluster.events);
|
|
@@ -127,7 +127,7 @@ function metaCharsetLabel(disposition: Types.Events.MetaCharsetDisposition|undef
|
|
|
127
127
|
|
|
128
128
|
export function generateInsight(
|
|
129
129
|
data: Handlers.Types.HandlerData, context: InsightSetContext): CharacterSetInsightModel {
|
|
130
|
-
if (!context.navigation) {
|
|
130
|
+
if (!context.navigation || !('navigationId' in context)) {
|
|
131
131
|
return finalize({});
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -160,7 +160,26 @@ export function getFieldMetricsForInsightSet(
|
|
|
160
160
|
return null;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
let pageResult = getPageResult(cruxFieldData, insightSet.url.href, insightSet.url.origin, scope);
|
|
164
|
+
|
|
165
|
+
if (!pageResult && insightSet.navigation && Types.Events.isSoftNavigationStart(insightSet.navigation)) {
|
|
166
|
+
pageResult = cruxFieldData.find(result => {
|
|
167
|
+
const key = scope ? result[`${scope.pageScope}-${scope.deviceScope}`]?.record.key :
|
|
168
|
+
(result['url-ALL'] || result['origin-ALL'])?.record.key;
|
|
169
|
+
if (!key) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
if (key.url) {
|
|
173
|
+
try {
|
|
174
|
+
return new URL(key.url).origin === insightSet.url.origin;
|
|
175
|
+
} catch {
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return key.origin === insightSet.url.origin;
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
164
183
|
if (!pageResult) {
|
|
165
184
|
return null;
|
|
166
185
|
}
|
|
@@ -266,7 +285,7 @@ function estimateSavingsWithGraphs(
|
|
|
266
285
|
*/
|
|
267
286
|
export function metricSavingsForWastedBytes(
|
|
268
287
|
wastedBytesByRequestId: Map<string, number>, context: InsightSetContext): MetricSavings|undefined {
|
|
269
|
-
if (!context.navigation || !context.lantern) {
|
|
288
|
+
if (!context.navigation || !('lantern' in context) || !context.lantern) {
|
|
270
289
|
return;
|
|
271
290
|
}
|
|
272
291
|
|
|
@@ -191,7 +191,7 @@ function finalize(partialModel: PartialInsightModel<DocumentLatencyInsightModel>
|
|
|
191
191
|
|
|
192
192
|
export function generateInsight(
|
|
193
193
|
data: Handlers.Types.HandlerData, context: InsightSetContext): DocumentLatencyInsightModel {
|
|
194
|
-
if (!context.navigation) {
|
|
194
|
+
if (!context.navigation || !('navigationId' in context)) {
|
|
195
195
|
return finalize({});
|
|
196
196
|
}
|
|
197
197
|
|
|
@@ -110,10 +110,10 @@ function anyValuesNaN(...values: number[]): boolean {
|
|
|
110
110
|
* them to be missing on newer traces, but old trace files may lack some of the
|
|
111
111
|
* data we rely on, so we want to handle that case.
|
|
112
112
|
*/
|
|
113
|
-
function determineSubparts(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
function determineSubparts(nav: Types.Events.NavigationStart|Types.Events.SoftNavigationStart,
|
|
114
|
+
docRequest: Types.Events.SyntheticNetworkRequest,
|
|
115
|
+
lcpEvent: Types.Events.AnyLargestContentfulPaintCandidate,
|
|
116
|
+
lcpRequest: Types.Events.SyntheticNetworkRequest|undefined): LCPSubparts|null {
|
|
117
117
|
const firstDocByteTs = calculateDocFirstByteTs(docRequest);
|
|
118
118
|
if (firstDocByteTs === null) {
|
|
119
119
|
return null;
|
|
@@ -232,9 +232,10 @@ export function generateInsight(
|
|
|
232
232
|
const lcpMs = Helpers.Timing.microToMilli(metricScore.timing);
|
|
233
233
|
// This helps position things on the timeline's UI accurately for a trace.
|
|
234
234
|
const lcpTs = metricScore.event?.ts ? Helpers.Timing.microToMilli(metricScore.event?.ts) : undefined;
|
|
235
|
-
const lcpRequest =
|
|
235
|
+
const lcpRequest =
|
|
236
|
+
'navigationId' in context ? data.LargestImagePaint.lcpRequestByNavigationId.get(context.navigationId) : undefined;
|
|
236
237
|
|
|
237
|
-
const docRequest = networkRequests.byId.get(context.navigationId);
|
|
238
|
+
const docRequest = 'navigationId' in context ? networkRequests.byId.get(context.navigationId) : undefined;
|
|
238
239
|
if (!docRequest) {
|
|
239
240
|
return finalize({lcpMs, lcpTs, lcpEvent, lcpRequest, warnings: [InsightWarning.NO_DOCUMENT_REQUEST]});
|
|
240
241
|
}
|
|
@@ -101,7 +101,7 @@ function finalize(partialModel: PartialInsightModel<LCPDiscoveryInsightModel>):
|
|
|
101
101
|
|
|
102
102
|
export function generateInsight(
|
|
103
103
|
data: Handlers.Types.HandlerData, context: InsightSetContext): LCPDiscoveryInsightModel {
|
|
104
|
-
if (!context.navigation) {
|
|
104
|
+
if (!context.navigation || !('navigationId' in context)) {
|
|
105
105
|
return finalize({});
|
|
106
106
|
}
|
|
107
107
|
|