chrome-devtools-frontend 1.0.1549484 → 1.0.1553956
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/styleguide/ux/components.md +84 -17
- package/docs/styleguide/ux/images/cards.png +0 -0
- package/docs/ui_engineering.md +2 -2
- package/eslint.config.mjs +7 -0
- package/front_end/Images/generate-css-vars.js +8 -4
- package/front_end/core/common/Settings.ts +20 -8
- package/front_end/core/host/UserMetrics.ts +3 -1
- package/front_end/core/i18n/collect-ui-strings.js +19 -10
- package/front_end/core/i18n/generate-locales-js.js +4 -4
- package/front_end/core/protocol_client/CDPConnection.ts +1 -0
- package/front_end/core/protocol_client/InspectorBackend.ts +5 -1
- package/front_end/core/root/Runtime.ts +0 -12
- package/front_end/core/sdk/DOMModel.ts +38 -3
- package/front_end/core/sdk/DebuggerModel.ts +9 -4
- package/front_end/core/sdk/IsolateManager.ts +7 -0
- package/front_end/core/sdk/NetworkManager.ts +12 -10
- package/front_end/core/sdk/PageResourceLoader.ts +11 -4
- package/front_end/core/sdk/RehydratingConnection.ts +5 -2
- package/front_end/core/sdk/SourceMapManager.ts +12 -6
- package/front_end/entrypoints/main/MainImpl.ts +28 -19
- package/front_end/foundation/Universe.ts +7 -0
- package/front_end/generated/InspectorBackendCommands.ts +5 -2
- package/front_end/generated/SupportedCSSProperties.js +14 -0
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +6 -0
- package/front_end/generated/protocol.ts +76 -0
- package/front_end/models/ai_assistance/AiConversation.ts +94 -4
- package/front_end/models/ai_assistance/BuiltInAi.ts +79 -5
- package/front_end/models/ai_assistance/agents/AiAgent.ts +30 -15
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +179 -41
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +5 -0
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +62 -0
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +2 -1
- package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +1 -7
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +124 -12
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +125 -30
- package/front_end/models/ai_assistance/performance/AICallTree.ts +42 -0
- package/front_end/models/ai_code_generation/AiCodeGeneration.ts +12 -0
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +6 -8
- package/front_end/models/issues_manager/BounceTrackingIssue.ts +4 -14
- package/front_end/models/issues_manager/ClientHintIssue.ts +5 -12
- package/front_end/models/issues_manager/ContentSecurityPolicyIssue.ts +5 -12
- package/front_end/models/issues_manager/CookieDeprecationMetadataIssue.ts +7 -14
- package/front_end/models/issues_manager/CookieIssue.ts +27 -30
- package/front_end/models/issues_manager/CorsIssue.ts +8 -17
- package/front_end/models/issues_manager/CrossOriginEmbedderPolicyIssue.ts +5 -8
- package/front_end/models/issues_manager/DeprecationIssue.ts +7 -14
- package/front_end/models/issues_manager/ElementAccessibilityIssue.ts +7 -14
- package/front_end/models/issues_manager/FederatedAuthRequestIssue.ts +4 -11
- package/front_end/models/issues_manager/FederatedAuthUserInfoRequestIssue.ts +4 -11
- package/front_end/models/issues_manager/GenericIssue.ts +11 -16
- package/front_end/models/issues_manager/HeavyAdIssue.ts +4 -11
- package/front_end/models/issues_manager/Issue.ts +13 -4
- package/front_end/models/issues_manager/IssueAggregator.ts +17 -2
- package/front_end/models/issues_manager/IssuesManager.ts +5 -0
- package/front_end/models/issues_manager/LowTextContrastIssue.ts +3 -10
- package/front_end/models/issues_manager/MixedContentIssue.ts +7 -13
- package/front_end/models/issues_manager/PartitioningBlobURLIssue.ts +4 -11
- package/front_end/models/issues_manager/PermissionElementIssue.ts +262 -0
- package/front_end/models/issues_manager/PropertyRuleIssue.ts +6 -12
- package/front_end/models/issues_manager/QuirksModeIssue.ts +3 -10
- package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +7 -13
- package/front_end/models/issues_manager/SharedArrayBufferIssue.ts +4 -11
- package/front_end/models/issues_manager/SharedDictionaryIssue.ts +6 -13
- package/front_end/models/issues_manager/StylesheetLoadingIssue.ts +8 -13
- package/front_end/models/issues_manager/UnencodedDigestIssue.ts +2 -9
- package/front_end/models/issues_manager/descriptions/permissionElementActivationDisabled.md +7 -0
- package/front_end/models/issues_manager/descriptions/permissionElementActivationDisabledWithOccluder.md +9 -0
- package/front_end/models/issues_manager/descriptions/permissionElementActivationDisabledWithOccluderParent.md +9 -0
- package/front_end/models/issues_manager/descriptions/permissionElementCspFrameAncestorsMissing.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementFencedFrameDisallowed.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementFontSizeTooLarge.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementFontSizeTooSmall.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementGeolocationDeprecated.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementInsetBoxShadowUnsupported.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementInvalidDisplayStyle.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementInvalidSizeValue.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementInvalidType.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementInvalidTypeActivation.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementLowContrast.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementNonOpaqueColor.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementPaddingBottomUnsupported.md +6 -0
- package/front_end/models/issues_manager/descriptions/permissionElementPaddingRightUnsupported.md +6 -0
- package/front_end/models/issues_manager/descriptions/permissionElementPermissionsPolicyBlocked.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementRegistrationFailed.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementRequestInProgress.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementSecurityChecksFailed.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementTypeNotSupported.md +5 -0
- package/front_end/models/issues_manager/descriptions/permissionElementUntrustedEvent.md +7 -0
- package/front_end/models/issues_manager/issues_manager.ts +2 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +8 -13
- package/front_end/models/stack_trace/StackTraceModel.ts +37 -18
- package/front_end/models/trace/Processor.ts +14 -15
- package/front_end/models/trace/insights/Common.ts +2 -8
- package/front_end/models/trace/insights/types.ts +12 -2
- package/front_end/models/trace/types/TraceEvents.ts +4 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +28 -6
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +9 -23
- package/front_end/panels/ai_assistance/ai_assistance.ts +1 -0
- package/front_end/panels/ai_assistance/components/ChatView.ts +78 -2
- package/front_end/panels/ai_assistance/components/CollapsibleAssistanceContentWidget.ts +71 -0
- package/front_end/panels/ai_assistance/components/PerformanceAgentFlameChart.ts +126 -0
- package/front_end/panels/ai_assistance/components/PerformanceAgentMarkdownRenderer.ts +131 -2
- package/front_end/panels/ai_assistance/components/chatView.css +28 -0
- package/front_end/panels/ai_assistance/components/collapsibleAssistanceContentWidget.css +33 -0
- package/front_end/panels/application/AppManifestView.ts +1007 -521
- package/front_end/panels/application/ApplicationPanelSidebar.ts +22 -38
- package/front_end/panels/application/BackForwardCacheTreeElement.ts +2 -2
- package/front_end/panels/application/BounceTrackingMitigationsTreeElement.ts +2 -2
- package/front_end/panels/application/ExtensionStorageItemsView.ts +3 -5
- package/front_end/panels/application/InterestGroupTreeElement.ts +2 -2
- package/front_end/panels/application/KeyValueStorageItemsView.ts +3 -2
- package/front_end/panels/application/OpenedWindowDetailsView.ts +2 -2
- package/front_end/panels/application/OriginTrialTreeView.ts +1 -1
- package/front_end/panels/application/PreloadingTreeElement.ts +3 -3
- package/front_end/panels/application/ReportingApiTreeElement.ts +2 -2
- package/front_end/panels/application/ServiceWorkerCacheTreeElement.ts +3 -3
- package/front_end/panels/application/SharedStorageListTreeElement.ts +2 -2
- package/front_end/panels/application/StorageBucketsTreeElement.ts +3 -3
- package/front_end/panels/application/StorageView.ts +2 -2
- package/front_end/panels/application/TrustTokensTreeElement.ts +2 -2
- package/front_end/panels/application/components/BackForwardCacheView.ts +2 -2
- package/front_end/panels/application/components/PermissionsPolicySection.ts +1 -1
- package/front_end/panels/application/components/ProtocolHandlersView.ts +1 -1
- package/front_end/panels/application/components/SharedStorageMetadataView.ts +1 -1
- package/front_end/panels/application/components/TrustTokensView.ts +1 -1
- package/front_end/panels/application/preloading/PreloadingView.ts +46 -45
- package/front_end/panels/application/preloading/components/MismatchedPreloadingGrid.ts +80 -75
- package/front_end/panels/application/preloading/components/PreloadingDisabledInfobar.ts +169 -133
- package/front_end/panels/application/preloading/components/PreloadingGrid.ts +1 -1
- package/front_end/panels/application/preloading/components/RuleSetDetailsView.ts +74 -93
- package/front_end/panels/application/preloading/components/RuleSetGrid.ts +143 -118
- package/front_end/panels/application/preloading/components/UsedPreloadingView.ts +52 -12
- package/front_end/panels/application/preloading/components/components.ts +0 -2
- package/front_end/panels/changes/ChangesSidebar.ts +2 -0
- package/front_end/panels/changes/CombinedDiffView.ts +2 -0
- package/front_end/panels/common/Annotation.ts +184 -0
- package/front_end/panels/common/AnnotationManager.ts +208 -0
- package/front_end/panels/common/ExtensionView.ts +47 -0
- package/front_end/panels/common/PersistenceUtils.ts +22 -26
- package/front_end/panels/common/annotation.css +40 -0
- package/front_end/panels/common/common.ts +2 -0
- package/front_end/panels/console/ConsoleInsightTeaser.ts +187 -5
- package/front_end/panels/console/ConsolePinPane.ts +437 -217
- package/front_end/panels/console/ConsolePrompt.ts +36 -227
- package/front_end/panels/console/ConsoleView.ts +69 -68
- package/front_end/panels/console/ConsoleViewMessage.ts +18 -14
- package/front_end/panels/console/consoleInsightTeaser.css +23 -0
- package/front_end/panels/console/consoleView.css +1 -1
- package/front_end/panels/console_counters/WarningErrorCounter.ts +2 -0
- package/front_end/panels/css_overview/CSSOverviewCompletedView.ts +1 -1
- package/front_end/panels/elements/AdoptedStyleSheetTreeElement.ts +89 -0
- package/front_end/panels/elements/ColorSwatchPopoverIcon.ts +5 -5
- package/front_end/panels/elements/ComputedStyleWidget.ts +16 -5
- package/front_end/panels/elements/ElementsPanel.ts +75 -0
- package/front_end/panels/elements/ElementsSidebarPane.ts +1 -3
- package/front_end/panels/elements/ElementsTreeElement.ts +459 -451
- package/front_end/panels/elements/ElementsTreeOutline.ts +48 -15
- package/front_end/panels/elements/ShortcutTreeElement.ts +2 -2
- package/front_end/panels/elements/StyleEditorWidget.ts +2 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +21 -20
- package/front_end/panels/elements/StylesSidebarPane.ts +5 -6
- package/front_end/panels/elements/TopLayerContainer.ts +2 -2
- package/front_end/panels/elements/components/ElementsBreadcrumbs.ts +1 -1
- package/front_end/panels/elements/components/ElementsTreeExpandButton.ts +1 -1
- package/front_end/panels/elements/components/QueryContainer.ts +1 -1
- package/front_end/panels/elements/components/StylePropertyEditor.ts +1 -1
- package/front_end/panels/emulation/DeviceModeWrapper.ts +48 -3
- package/front_end/panels/emulation/MediaQueryInspector.ts +171 -125
- package/front_end/panels/explain/components/ConsoleInsight.ts +181 -154
- package/front_end/panels/explain/components/consoleInsight.css +348 -347
- package/front_end/panels/issues/AffectedPermissionElementsView.ts +46 -0
- package/front_end/panels/issues/AffectedResourcesView.ts +2 -2
- package/front_end/panels/issues/AttributionReportingIssueDetailsView.ts +2 -2
- package/front_end/panels/issues/IssueKindView.ts +2 -2
- package/front_end/panels/issues/IssueView.ts +6 -4
- package/front_end/panels/issues/IssuesPane.ts +6 -0
- package/front_end/panels/js_timeline/js_timeline-meta.ts +4 -2
- package/front_end/panels/layer_viewer/LayerDetailsView.ts +165 -149
- package/front_end/panels/layer_viewer/Layers3DView.ts +131 -78
- package/front_end/panels/lighthouse/LighthouseStatusView.ts +149 -100
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryHighlightChipList.ts +91 -65
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryInspector.ts +25 -34
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryNavigator.ts +1 -1
- package/front_end/panels/linear_memory_inspector/components/LinearMemoryValueInterpreter.ts +61 -45
- package/front_end/panels/linear_memory_inspector/components/ValueInterpreterDisplay.ts +171 -152
- package/front_end/panels/linear_memory_inspector/components/ValueInterpreterSettings.ts +50 -51
- package/front_end/panels/linear_memory_inspector/components/valueInterpreterDisplay.css +0 -13
- package/front_end/panels/linear_memory_inspector/components/valueInterpreterSettings.css +20 -18
- package/front_end/panels/media/PlayerListView.ts +1 -1
- package/front_end/panels/mobile_throttling/CalibrationController.ts +3 -1
- package/front_end/panels/mobile_throttling/ThrottlingManager.ts +2 -2
- package/front_end/panels/mobile_throttling/ThrottlingSettingsTab.ts +2 -3
- package/front_end/panels/network/NetworkDataGridNode.ts +17 -9
- package/front_end/panels/network/NetworkFrameGrouper.ts +2 -2
- package/front_end/panels/network/NetworkItemView.ts +46 -7
- package/front_end/panels/network/NetworkLogView.ts +10 -11
- package/front_end/panels/network/NetworkLogViewColumns.ts +3 -3
- package/front_end/panels/network/NetworkPanel.ts +63 -1
- package/front_end/panels/network/RequestCookiesView.ts +2 -2
- package/front_end/panels/network/RequestInitiatorView.ts +146 -113
- package/front_end/panels/network/SignedExchangeInfoView.ts +2 -2
- package/front_end/panels/network/components/RequestHeaderSection.css +51 -50
- package/front_end/panels/network/components/RequestHeaderSection.ts +81 -71
- package/front_end/panels/network/components/RequestHeadersView.css +1 -1
- package/front_end/panels/network/components/RequestHeadersView.ts +26 -11
- package/front_end/panels/network/components/RequestTrustTokensView.css +24 -14
- package/front_end/panels/network/components/RequestTrustTokensView.ts +145 -142
- package/front_end/panels/profiler/HeapSnapshotGridNodes.ts +3 -3
- package/front_end/panels/profiler/IsolateSelector.ts +2 -1
- package/front_end/panels/profiler/ProfileDataGrid.ts +2 -2
- package/front_end/panels/profiler/ProfilesPanel.ts +2 -2
- package/front_end/panels/protocol_monitor/JSONEditor.ts +1 -1
- package/front_end/panels/protocol_monitor/ProtocolMonitor.ts +49 -33
- package/front_end/panels/recorder/RecorderController.ts +2 -3
- package/front_end/panels/recorder/components/ControlButton.ts +68 -34
- package/front_end/panels/recorder/components/CreateRecordingView.ts +10 -7
- package/front_end/panels/recorder/components/ExtensionView.ts +1 -1
- package/front_end/panels/recorder/components/RecordingListView.ts +1 -1
- package/front_end/panels/recorder/components/RecordingView.ts +82 -89
- package/front_end/panels/recorder/components/ReplaySection.ts +226 -145
- package/front_end/panels/recorder/{controllers → components}/SelectorPicker.ts +129 -52
- package/front_end/panels/recorder/components/StepEditor.ts +21 -67
- package/front_end/panels/recorder/components/StepView.ts +223 -181
- package/front_end/panels/recorder/components/TimelineSection.ts +69 -48
- package/front_end/panels/recorder/components/components.ts +2 -2
- package/front_end/panels/recorder/components/selectorPicker.css +14 -0
- package/front_end/panels/recorder/components/stepEditor.css +0 -5
- package/front_end/panels/recorder/components/stepView.css +196 -198
- package/front_end/panels/recorder/extensions/ExtensionManager.ts +4 -48
- package/front_end/panels/recorder/models/ScreenshotUtils.ts +17 -11
- package/front_end/panels/screencast/ScreencastView.ts +8 -8
- package/front_end/panels/search/SearchView.ts +1 -1
- package/front_end/panels/security/CookieControlsTreeElement.ts +2 -2
- package/front_end/panels/security/CookieControlsView.ts +9 -16
- package/front_end/panels/security/CookieReportTreeElement.ts +2 -2
- package/front_end/panels/security/SecurityPanel.ts +5 -5
- package/front_end/panels/security/SecurityPanelSidebar.ts +3 -4
- package/front_end/panels/settings/KeybindsSettingsTab.ts +4 -4
- package/front_end/panels/settings/SettingsScreen.ts +2 -3
- package/front_end/panels/settings/components/SyncSection.ts +0 -1
- package/front_end/panels/snippets/SnippetsQuickOpen.ts +16 -8
- package/front_end/panels/sources/BreakpointEditDialog.ts +3 -3
- package/front_end/panels/sources/BreakpointsView.ts +1 -1
- package/front_end/panels/sources/CSSPlugin.ts +6 -6
- package/front_end/panels/sources/CallStackSidebarPane.ts +63 -78
- package/front_end/panels/sources/DebuggerPausedMessage.ts +3 -3
- package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +39 -30
- package/front_end/panels/sources/GoToLineQuickOpen.ts +11 -7
- package/front_end/panels/sources/NavigatorView.ts +2 -2
- package/front_end/panels/sources/OpenFileQuickOpen.ts +11 -15
- package/front_end/panels/sources/OutlineQuickOpen.ts +23 -26
- package/front_end/panels/sources/SourcesPanel.ts +1 -11
- package/front_end/panels/sources/SourcesView.ts +2 -2
- package/front_end/panels/sources/TabbedEditorContainer.ts +13 -11
- package/front_end/panels/sources/ThreadsSidebarPane.ts +96 -101
- package/front_end/panels/sources/UISourceCodeFrame.ts +5 -5
- package/front_end/panels/sources/threadsSidebarPane.css +6 -5
- package/front_end/panels/timeline/InteractionsTrackAppender.ts +2 -3
- package/front_end/panels/timeline/TimelineFlameChartDataProvider.ts +23 -33
- package/front_end/panels/timeline/TimelineFlameChartNetworkDataProvider.ts +4 -3
- package/front_end/panels/timeline/TimelineFlameChartView.ts +12 -0
- package/front_end/panels/timeline/TimelineHistoryManager.ts +2 -2
- package/front_end/panels/timeline/TimelinePanel.ts +17 -14
- package/front_end/panels/timeline/components/CPUThrottlingSelector.ts +1 -1
- package/front_end/panels/timeline/components/IgnoreListSetting.ts +164 -142
- package/front_end/panels/timeline/components/InteractionBreakdown.ts +48 -28
- package/front_end/panels/timeline/components/LayoutShiftDetails.ts +18 -23
- package/front_end/panels/timeline/components/LiveMetricsView.ts +1 -1
- package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +99 -74
- package/front_end/panels/timeline/components/NetworkThrottlingSelector.ts +1 -1
- package/front_end/panels/timeline/components/OriginMap.ts +1 -1
- package/front_end/panels/timeline/components/SidebarInsightsTab.ts +9 -12
- package/front_end/panels/timeline/components/SidebarSingleInsightSet.ts +262 -291
- package/front_end/panels/timeline/components/Utils.ts +25 -0
- package/front_end/panels/timeline/components/insights/BaseInsightComponent.ts +210 -146
- package/front_end/panels/timeline/components/insights/CLSCulprits.ts +8 -20
- package/front_end/panels/timeline/components/insights/Cache.ts +0 -9
- package/front_end/panels/timeline/components/insights/Checklist.ts +1 -1
- package/front_end/panels/timeline/components/insights/DOMSize.ts +12 -34
- package/front_end/panels/timeline/components/insights/DocumentLatency.ts +0 -9
- package/front_end/panels/timeline/components/insights/DuplicatedJavaScript.ts +0 -9
- package/front_end/panels/timeline/components/insights/EventRef.ts +47 -109
- package/front_end/panels/timeline/components/insights/FontDisplay.ts +0 -9
- package/front_end/panels/timeline/components/insights/ForcedReflow.ts +0 -9
- package/front_end/panels/timeline/components/insights/INPBreakdown.ts +0 -9
- package/front_end/panels/timeline/components/insights/ImageDelivery.ts +2 -11
- package/front_end/panels/timeline/components/insights/ImageRef.ts +112 -0
- package/front_end/panels/timeline/components/insights/InsightRenderer.ts +91 -0
- package/front_end/panels/timeline/components/insights/LCPBreakdown.ts +0 -9
- package/front_end/panels/timeline/components/insights/LCPDiscovery.ts +4 -11
- package/front_end/panels/timeline/components/insights/LegacyJavaScript.ts +0 -9
- package/front_end/panels/timeline/components/insights/ModernHTTP.ts +0 -9
- package/front_end/panels/timeline/components/insights/NetworkDependencyTree.ts +7 -22
- package/front_end/panels/timeline/components/insights/NodeLink.ts +68 -43
- package/front_end/panels/timeline/components/insights/README.md +2 -3
- package/front_end/panels/timeline/components/insights/RenderBlocking.ts +0 -9
- package/front_end/panels/timeline/components/insights/SlowCSSSelector.ts +0 -9
- package/front_end/panels/timeline/components/insights/ThirdParties.ts +0 -9
- package/front_end/panels/timeline/components/insights/Viewport.ts +7 -19
- package/front_end/panels/timeline/components/insights/baseInsightComponent.css +5 -0
- package/front_end/panels/timeline/components/insights/insights.ts +2 -0
- package/front_end/panels/timeline/components/interactionBreakdown.css +15 -13
- package/front_end/panels/timeline/enable-easter-egg.js +7 -3
- package/front_end/panels/timeline/overlays/components/EntriesLinkOverlay.ts +1 -1
- package/front_end/panels/timeline/overlays/components/EntryLabelOverlay.ts +1 -1
- package/front_end/panels/timeline/timeline-meta.ts +3 -2
- package/front_end/panels/utils/utils.ts +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/puppeteer/README.chromium +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BluetoothEmulation.d.ts +96 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BluetoothEmulation.js +8 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts +87 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts +2 -6
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js +5 -24
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/DeviceRequestPrompt.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts +5 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/api/api.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BluetoothEmulation.d.ts +18 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BluetoothEmulation.js +42 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts +4 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/DeviceRequestPrompt.d.ts +27 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/DeviceRequestPrompt.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/DeviceRequestPrompt.js +90 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/DeviceRequestPrompt.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Frame.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Frame.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Frame.js +3 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts +4 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js +5 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js +14 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/bidi/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BluetoothEmulation.d.ts +18 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BluetoothEmulation.js +30 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts +5 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js +22 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/CdpSession.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/CdpSession.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts +2 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js +4 -6
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/FrameManager.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/FrameManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/FrameManager.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/FrameManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js +8 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebWorker.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebWorker.js +8 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/WebWorker.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/cdp.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/cdp.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/cdp.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/cdp/cdp.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js +30 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts +15 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/injected/injected.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js +2 -13
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/LaunchOptions.d.ts +5 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/LaunchOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/LaunchOptions.js +17 -0
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/node/LaunchOptions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/Mutex.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/cjs/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +221 -4
- package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +182 -95
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BluetoothEmulation.d.ts +96 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BluetoothEmulation.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts +87 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts +2 -6
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js +4 -22
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/DeviceRequestPrompt.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts +5 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/api/api.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BluetoothEmulation.d.ts +18 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BluetoothEmulation.js +38 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts +4 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js +10 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/DeviceRequestPrompt.d.ts +27 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/DeviceRequestPrompt.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/DeviceRequestPrompt.js +85 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/DeviceRequestPrompt.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Frame.d.ts +3 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Frame.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Frame.js +3 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Frame.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts +4 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js +5 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts +4 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js +14 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/core/BrowsingContext.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js +7 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/bidi/util.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Accessibility.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BluetoothEmulation.d.ts +18 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BluetoothEmulation.d.ts.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BluetoothEmulation.js +26 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/BluetoothEmulation.js.map +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts +5 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js +22 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Browser.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/CdpSession.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/CdpSession.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts +2 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js +2 -4
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/DeviceRequestPrompt.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/FrameManager.d.ts +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/FrameManager.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/FrameManager.js +2 -2
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/FrameManager.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts +2 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js +8 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/Page.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebWorker.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebWorker.js +8 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/WebWorker.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/cdp.d.ts +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/cdp.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/cdp.js +1 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/cdp/cdp.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/BrowserConnector.js +31 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/BrowserConnector.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts +15 -0
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/common/ConnectOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js +2 -13
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/ChromeLauncher.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/LaunchOptions.d.ts +5 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/LaunchOptions.d.ts.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/LaunchOptions.js +16 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/node/LaunchOptions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.d.ts +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js +3 -3
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/revisions.js.map +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.d.ts +1 -1
- package/front_end/third_party/puppeteer/package/lib/esm/puppeteer/util/version.js +1 -1
- package/front_end/third_party/puppeteer/package/lib/types.d.ts +221 -4
- package/front_end/third_party/puppeteer/package/package.json +4 -4
- package/front_end/third_party/puppeteer/package/src/api/BluetoothEmulation.ts +103 -0
- package/front_end/third_party/puppeteer/package/src/api/Browser.ts +96 -1
- package/front_end/third_party/puppeteer/package/src/api/DeviceRequestPrompt.ts +2 -10
- package/front_end/third_party/puppeteer/package/src/api/Page.ts +6 -0
- package/front_end/third_party/puppeteer/package/src/api/api.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/bidi/BluetoothEmulation.ts +52 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +15 -0
- package/front_end/third_party/puppeteer/package/src/bidi/DeviceRequestPrompt.ts +138 -0
- package/front_end/third_party/puppeteer/package/src/bidi/Frame.ts +7 -3
- package/front_end/third_party/puppeteer/package/src/bidi/Page.ts +10 -2
- package/front_end/third_party/puppeteer/package/src/bidi/core/BrowsingContext.ts +30 -2
- package/front_end/third_party/puppeteer/package/src/bidi/util.ts +8 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Accessibility.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/BluetoothEmulation.ts +47 -0
- package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +33 -3
- package/front_end/third_party/puppeteer/package/src/cdp/CdpSession.ts +1 -1
- package/front_end/third_party/puppeteer/package/src/cdp/DeviceRequestPrompt.ts +3 -8
- package/front_end/third_party/puppeteer/package/src/cdp/Frame.ts +2 -2
- package/front_end/third_party/puppeteer/package/src/cdp/FrameManager.ts +9 -4
- package/front_end/third_party/puppeteer/package/src/cdp/Page.ts +13 -0
- package/front_end/third_party/puppeteer/package/src/cdp/WebWorker.ts +8 -3
- package/front_end/third_party/puppeteer/package/src/cdp/cdp.ts +1 -0
- package/front_end/third_party/puppeteer/package/src/common/BrowserConnector.ts +45 -1
- package/front_end/third_party/puppeteer/package/src/common/ConnectOptions.ts +20 -0
- package/front_end/third_party/puppeteer/package/src/node/ChromeLauncher.ts +5 -17
- package/front_end/third_party/puppeteer/package/src/node/LaunchOptions.ts +23 -7
- 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/third_party/puppeteer/puppeteer-tsconfig.json +4 -0
- package/front_end/ui/components/adorners/Adorner.ts +20 -0
- package/front_end/ui/components/annotations/AnnotationRepository.ts +154 -14
- package/front_end/ui/components/buttons/Button.ts +1 -1
- package/front_end/ui/components/buttons/FloatingButton.ts +1 -1
- package/front_end/ui/components/highlighting/HighlightElement.ts +15 -2
- package/front_end/ui/components/icon_button/FileSourceIcon.ts +1 -1
- package/front_end/ui/components/icon_button/IconButton.ts +1 -1
- package/front_end/ui/components/icon_button/icon_button.ts +0 -2
- package/front_end/ui/components/issue_counter/IssueCounter.ts +1 -1
- package/front_end/ui/components/issue_counter/IssueLinkIcon.ts +1 -1
- package/front_end/ui/components/markdown_view/MarkdownImage.ts +3 -3
- package/front_end/ui/components/request_link_icon/RequestLinkIcon.ts +1 -1
- package/front_end/ui/components/settings/SettingDeprecationWarning.ts +1 -1
- package/front_end/ui/components/snackbars/Snackbars.docs.ts +0 -1
- package/front_end/ui/components/survey_link/SurveyLink.ts +1 -1
- package/front_end/ui/components/text_editor/AiCodeCompletionTeaserPlaceholder.ts +12 -3
- package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +182 -0
- package/front_end/ui/components/text_editor/config.ts +2 -2
- package/front_end/ui/components/text_editor/text_editor.ts +1 -0
- package/front_end/ui/helpers/OpenInNewTab.ts +5 -1
- package/front_end/ui/i18n/i18n.ts +9 -9
- package/front_end/ui/kit/cards/Card.docs.ts +43 -0
- package/front_end/ui/kit/icons/Icon.docs.ts +34 -0
- package/front_end/ui/{components/icon_button → kit/icons}/Icon.ts +4 -4
- package/front_end/ui/kit/kit.ts +2 -0
- package/front_end/ui/kit/link/Link.docs.ts +15 -0
- package/front_end/ui/kit/link/Link.ts +151 -0
- package/front_end/ui/kit/link/link.css +27 -0
- package/front_end/ui/legacy/EmptyWidget.ts +6 -0
- package/front_end/ui/legacy/Floaty.ts +442 -0
- package/front_end/ui/legacy/Infobar.ts +3 -3
- package/front_end/ui/legacy/InspectorView.ts +15 -3
- package/front_end/ui/legacy/ReportView.ts +1 -1
- package/front_end/ui/legacy/SearchableView.ts +2 -2
- package/front_end/ui/legacy/SelectMenu.docs.ts +0 -1
- package/front_end/ui/legacy/SoftContextMenu.ts +5 -5
- package/front_end/ui/legacy/SoftDropDown.ts +2 -2
- package/front_end/ui/legacy/TabbedPane.ts +139 -61
- package/front_end/ui/legacy/Toolbar.ts +3 -3
- package/front_end/ui/legacy/Treeoutline.ts +2 -2
- package/front_end/ui/legacy/UIUtils.ts +4 -4
- package/front_end/ui/legacy/ViewManager.ts +4 -4
- package/front_end/ui/legacy/components/color_picker/ContrastDetails.ts +8 -8
- package/front_end/ui/legacy/components/color_picker/Spectrum.ts +4 -4
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +5 -5
- package/front_end/ui/legacy/components/inline_editor/ColorSwatch.ts +36 -36
- package/front_end/ui/legacy/components/inline_editor/FontEditor.ts +2 -2
- package/front_end/ui/legacy/components/inline_editor/Swatches.ts +5 -5
- package/front_end/ui/legacy/components/object_ui/CustomPreviewComponent.ts +3 -3
- package/front_end/ui/legacy/components/object_ui/JavaScriptREPL.ts +22 -37
- package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +31 -1
- package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +2 -2
- package/front_end/ui/legacy/components/perf_ui/OverviewGrid.ts +3 -3
- package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +22 -29
- package/front_end/ui/legacy/components/quick_open/FilteredListWidget.ts +8 -15
- package/front_end/ui/legacy/components/quick_open/HelpQuickOpen.ts +11 -14
- package/front_end/ui/legacy/components/utils/Linkifier.ts +7 -11
- package/front_end/ui/legacy/floaty.css +77 -0
- package/front_end/ui/legacy/legacy.ts +2 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +6 -0
- package/inspector_overlay/loadCSS.rollup.js +5 -4
- package/mcp/mcp.ts +1 -0
- package/package.json +2 -2
- package/front_end/panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts +0 -99
- package/front_end/panels/recorder/components/SelectButton.ts +0 -304
- package/front_end/panels/recorder/controllers/controllers.ts +0 -7
- package/front_end/ui/components/chrome_link/ChromeLink.ts +0 -76
- package/front_end/ui/components/chrome_link/chromeLink.css +0 -12
- package/front_end/ui/components/chrome_link/chrome_link.ts +0 -9
- package/front_end/ui/components/icon_button/Icon.docs.ts +0 -78
- /package/front_end/panels/recorder/components/{selectButton.css → replaySection.css} +0 -0
- /package/front_end/ui/{components/icon_button → kit/icons}/icon.css +0 -0
|
@@ -1,26 +1,40 @@
|
|
|
1
1
|
// Copyright 2016 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
-
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
4
|
+
/* eslint-disable @devtools/no-imperative-dom-api, @devtools/no-lit-render-outside-of-view */
|
|
5
|
+
|
|
6
|
+
import '../../ui/kit/kit.js';
|
|
7
|
+
import '../../ui/legacy/components/inline_editor/inline_editor.js';
|
|
5
8
|
|
|
6
9
|
import * as Common from '../../core/common/common.js';
|
|
7
10
|
import * as Host from '../../core/host/host.js';
|
|
8
11
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
9
|
-
import
|
|
12
|
+
import * as Platform from '../../core/platform/platform.js';
|
|
10
13
|
import * as SDK from '../../core/sdk/sdk.js';
|
|
11
14
|
import type * as Protocol from '../../generated/protocol.js';
|
|
12
15
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
13
|
-
import * as IconButton from '../../ui/components/icon_button/icon_button.js';
|
|
14
|
-
import * as uiI18n from '../../ui/i18n/i18n.js';
|
|
15
|
-
import * as InlineEditor from '../../ui/legacy/components/inline_editor/inline_editor.js';
|
|
16
16
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
17
17
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
18
|
+
import {html, i18nTemplate, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
|
|
18
19
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
19
20
|
|
|
20
21
|
import appManifestViewStyles from './appManifestView.css.js';
|
|
21
22
|
import * as ApplicationComponents from './components/components.js';
|
|
22
23
|
|
|
23
24
|
const UIStrings = {
|
|
25
|
+
/**
|
|
26
|
+
* @description Text in App Manifest View of the Application panel
|
|
27
|
+
*/
|
|
28
|
+
noManifestDetected: 'No manifest detected',
|
|
29
|
+
/**
|
|
30
|
+
* @description Description text on manifests in App Manifest View of the Application panel which describes the app manifest view tab
|
|
31
|
+
*/
|
|
32
|
+
manifestDescription:
|
|
33
|
+
'A manifest defines how your app appears on phone’s home screens and what the app looks like on launch.',
|
|
34
|
+
/**
|
|
35
|
+
* @description Text in App Manifest View of the Application panel
|
|
36
|
+
*/
|
|
37
|
+
appManifest: 'Manifest',
|
|
24
38
|
/**
|
|
25
39
|
* @description Text in App Manifest View of the Application panel
|
|
26
40
|
*/
|
|
@@ -454,6 +468,655 @@ interface Screenshot {
|
|
|
454
468
|
platform?: string;
|
|
455
469
|
}
|
|
456
470
|
|
|
471
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
472
|
+
interface Manifest {
|
|
473
|
+
background_color?: string;
|
|
474
|
+
description?: string;
|
|
475
|
+
display?: string;
|
|
476
|
+
display_override?: string[];
|
|
477
|
+
icons?: Array<{
|
|
478
|
+
src: string,
|
|
479
|
+
sizes?: string,
|
|
480
|
+
type?: string,
|
|
481
|
+
purpose?: string,
|
|
482
|
+
}>;
|
|
483
|
+
id?: string;
|
|
484
|
+
name?: string;
|
|
485
|
+
note_taking?: {
|
|
486
|
+
new_note_url?: string,
|
|
487
|
+
};
|
|
488
|
+
orientation?: string;
|
|
489
|
+
protocol_handlers?: Protocol.Page.ProtocolHandler[];
|
|
490
|
+
screenshots?: Screenshot[];
|
|
491
|
+
short_name?: string;
|
|
492
|
+
shortcuts?: Array<{
|
|
493
|
+
name: string,
|
|
494
|
+
url: string,
|
|
495
|
+
description?: string,
|
|
496
|
+
short_name?: string,
|
|
497
|
+
icons?: Array<{
|
|
498
|
+
src: string,
|
|
499
|
+
sizes?: string,
|
|
500
|
+
type?: string,
|
|
501
|
+
purpose?: string,
|
|
502
|
+
}>,
|
|
503
|
+
}>;
|
|
504
|
+
start_url?: string;
|
|
505
|
+
theme_color?: string;
|
|
506
|
+
}
|
|
507
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
508
|
+
|
|
509
|
+
interface ReportSectionItem {
|
|
510
|
+
content: LitTemplate|LitTemplate[]|string|HTMLElement;
|
|
511
|
+
title?: string;
|
|
512
|
+
label?: string;
|
|
513
|
+
flexed?: boolean;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
interface IdentitySectionData {
|
|
517
|
+
name: string;
|
|
518
|
+
shortName: string;
|
|
519
|
+
description: string;
|
|
520
|
+
appId: string|null;
|
|
521
|
+
recommendedId: string|null;
|
|
522
|
+
hasId: boolean;
|
|
523
|
+
warnings: Platform.UIString.LocalizedString[];
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
interface PresentationSectionData {
|
|
527
|
+
startUrl: string;
|
|
528
|
+
completeStartUrl: Platform.DevToolsPath.UrlString|null;
|
|
529
|
+
themeColor: Common.Color.Color|null;
|
|
530
|
+
backgroundColor: Common.Color.Color|null;
|
|
531
|
+
orientation: string;
|
|
532
|
+
display: string;
|
|
533
|
+
newNoteUrl?: string;
|
|
534
|
+
hasNewNoteUrl: boolean;
|
|
535
|
+
completeNewNoteUrl: Platform.DevToolsPath.UrlString|null;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
interface ProtocolHandlersSectionData {
|
|
539
|
+
protocolHandlers: Protocol.Page.ProtocolHandler[];
|
|
540
|
+
manifestLink: Platform.DevToolsPath.UrlString;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
interface IconsSectionData {
|
|
544
|
+
icons: Map<string, ProcessedImageResource[]>;
|
|
545
|
+
imageResourceErrors: Platform.UIString.LocalizedString[];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
interface ProcessedShortcut {
|
|
549
|
+
name: string;
|
|
550
|
+
shortName?: string;
|
|
551
|
+
description?: string;
|
|
552
|
+
url: string;
|
|
553
|
+
shortcutUrl: Platform.DevToolsPath.UrlString;
|
|
554
|
+
icons: Map<string, ProcessedImageResource[]>;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
interface ShortcutsSectionData {
|
|
558
|
+
shortcuts: ProcessedShortcut[];
|
|
559
|
+
warnings: Platform.UIString.LocalizedString[];
|
|
560
|
+
imageResourceErrors: Platform.UIString.LocalizedString[];
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
interface ProcessedScreenshot {
|
|
564
|
+
screenshot: Screenshot;
|
|
565
|
+
processedImage: ProcessedImageResource;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
interface ScreenshotsSectionData {
|
|
569
|
+
screenshots: ProcessedScreenshot[];
|
|
570
|
+
warnings: Platform.UIString.LocalizedString[];
|
|
571
|
+
imageResourceErrors: Platform.UIString.LocalizedString[];
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
interface WindowControlsSectionData {
|
|
575
|
+
hasWco: boolean;
|
|
576
|
+
themeColor: string;
|
|
577
|
+
wcoStyleSheetText: boolean;
|
|
578
|
+
url: Platform.DevToolsPath.UrlString;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
type ProcessedImageResource = {
|
|
582
|
+
imageResourceErrors: Platform.UIString.LocalizedString[],
|
|
583
|
+
imageUrl?: string,
|
|
584
|
+
squareSizedIconAvailable?: boolean,
|
|
585
|
+
}|{
|
|
586
|
+
imageResourceErrors: Platform.UIString.LocalizedString[],
|
|
587
|
+
imageUrl: string,
|
|
588
|
+
squareSizedIconAvailable: boolean,
|
|
589
|
+
title: string,
|
|
590
|
+
naturalWidth: number,
|
|
591
|
+
naturalHeight: number,
|
|
592
|
+
imageSrc: string,
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
function renderErrors(
|
|
596
|
+
errorsSection: UI.ReportView.Section, warnings?: Platform.UIString.LocalizedString[],
|
|
597
|
+
manifestErrors?: Protocol.Page.AppManifestError[], imageErrors?: Platform.UIString.LocalizedString[]): void {
|
|
598
|
+
errorsSection.clearContent();
|
|
599
|
+
errorsSection.element.classList.toggle(
|
|
600
|
+
'hidden', !manifestErrors?.length && !warnings?.length && !imageErrors?.length);
|
|
601
|
+
|
|
602
|
+
for (const error of manifestErrors ?? []) {
|
|
603
|
+
const icon = UI.UIUtils.createIconLabel({
|
|
604
|
+
title: error.message,
|
|
605
|
+
iconName: error.critical ? 'cross-circle-filled' : 'warning-filled',
|
|
606
|
+
color: error.critical ? 'var(--icon-error)' : 'var(--icon-warning)',
|
|
607
|
+
});
|
|
608
|
+
errorsSection.appendRow().appendChild(icon);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
for (const warning of warnings ?? []) {
|
|
612
|
+
const msgElement = document.createTextNode(warning);
|
|
613
|
+
errorsSection.appendRow().appendChild(msgElement);
|
|
614
|
+
}
|
|
615
|
+
for (const error of imageErrors ?? []) {
|
|
616
|
+
const msgElement = document.createTextNode(error);
|
|
617
|
+
errorsSection.appendRow().appendChild(msgElement);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function renderIdentity(identitySection: UI.ReportView.Section, identityData: IdentitySectionData): void {
|
|
622
|
+
const {name, shortName, description, appId, recommendedId, hasId} = identityData;
|
|
623
|
+
const fields: ReportSectionItem[] = [];
|
|
624
|
+
fields.push({title: i18nString(UIStrings.name), content: name});
|
|
625
|
+
fields.push({title: i18nString(UIStrings.shortName), content: shortName});
|
|
626
|
+
fields.push({title: i18nString(UIStrings.description), content: description});
|
|
627
|
+
|
|
628
|
+
if (appId && recommendedId) {
|
|
629
|
+
const onCopy = (): void => {
|
|
630
|
+
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.copiedToClipboard, {PH1: recommendedId}));
|
|
631
|
+
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(recommendedId);
|
|
632
|
+
};
|
|
633
|
+
// clang-format off
|
|
634
|
+
fields.push({title: i18nString(UIStrings.computedAppId), label: 'App Id', content: html`
|
|
635
|
+
${appId}
|
|
636
|
+
<devtools-icon class="inline-icon" name="help" title=${i18nString(UIStrings.appIdExplainer)}
|
|
637
|
+
jslog=${VisualLogging.action('help').track({hover: true})}>
|
|
638
|
+
</devtools-icon>
|
|
639
|
+
<devtools-link href="https://developer.chrome.com/blog/pwa-manifest-id/"
|
|
640
|
+
.jslogContext=${'learn-more'}>
|
|
641
|
+
${i18nString(UIStrings.learnMore)}
|
|
642
|
+
</devtools-link>
|
|
643
|
+
${!hasId ? html`
|
|
644
|
+
<div class="multiline-value">
|
|
645
|
+
${i18nTemplate(str_, UIStrings.appIdNote, {
|
|
646
|
+
PH1: html`<code>${recommendedId}</code>`,
|
|
647
|
+
PH2: html`<devtools-button class="inline-button" @click=${onCopy}
|
|
648
|
+
.iconName=${'copy'}
|
|
649
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
650
|
+
.size=${Buttons.Button.Size.SMALL}
|
|
651
|
+
.jslogContext=${'manifest.copy-id'}
|
|
652
|
+
.title=${i18nString(UIStrings.copyToClipboard)}>
|
|
653
|
+
</devtools-button>`,
|
|
654
|
+
})}
|
|
655
|
+
</div>` : nothing}`});
|
|
656
|
+
// clang-format on
|
|
657
|
+
} else {
|
|
658
|
+
identitySection.removeField(i18nString(UIStrings.computedAppId));
|
|
659
|
+
}
|
|
660
|
+
setSectionContents(fields, identitySection);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function renderPresentation(
|
|
664
|
+
presentationSection: UI.ReportView.Section, presentationData: PresentationSectionData): void {
|
|
665
|
+
const {
|
|
666
|
+
startUrl,
|
|
667
|
+
completeStartUrl,
|
|
668
|
+
themeColor,
|
|
669
|
+
backgroundColor,
|
|
670
|
+
orientation,
|
|
671
|
+
display,
|
|
672
|
+
newNoteUrl,
|
|
673
|
+
hasNewNoteUrl,
|
|
674
|
+
completeNewNoteUrl,
|
|
675
|
+
} = presentationData;
|
|
676
|
+
const fields: ReportSectionItem[] = [
|
|
677
|
+
{
|
|
678
|
+
title: i18nString(UIStrings.startUrl),
|
|
679
|
+
label: i18nString(UIStrings.startUrl),
|
|
680
|
+
content: completeStartUrl ? Components.Linkifier.Linkifier.linkifyURL(
|
|
681
|
+
completeStartUrl, ({text: startUrl, tabStop: true, jslogContext: 'start-url'})) :
|
|
682
|
+
nothing,
|
|
683
|
+
},
|
|
684
|
+
{
|
|
685
|
+
title: i18nString(UIStrings.themeColor),
|
|
686
|
+
content: themeColor ? html`<devtools-color-swatch .color=${themeColor}></devtools-color-swatch>` : nothing,
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
title: i18nString(UIStrings.backgroundColor),
|
|
690
|
+
content: backgroundColor ? html`<devtools-color-swatch .color=${backgroundColor}></devtools-color-swatch>` :
|
|
691
|
+
nothing,
|
|
692
|
+
},
|
|
693
|
+
{title: i18nString(UIStrings.orientation), content: orientation},
|
|
694
|
+
{title: i18nString(UIStrings.display), content: display},
|
|
695
|
+
];
|
|
696
|
+
if (completeNewNoteUrl) {
|
|
697
|
+
fields.push({
|
|
698
|
+
title: i18nString(UIStrings.newNoteUrl),
|
|
699
|
+
content: hasNewNoteUrl ?
|
|
700
|
+
Components.Linkifier.Linkifier.linkifyURL(completeNewNoteUrl, ({text: newNoteUrl, tabStop: true})) :
|
|
701
|
+
nothing,
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
setSectionContents(fields, presentationSection);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
function renderProtocolHandlers(
|
|
708
|
+
protocolHandlersView: ApplicationComponents.ProtocolHandlersView.ProtocolHandlersView,
|
|
709
|
+
data: ProtocolHandlersSectionData): void {
|
|
710
|
+
protocolHandlersView.protocolHandlers = data.protocolHandlers;
|
|
711
|
+
protocolHandlersView.manifestLink = data.manifestLink;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
function renderImage(imageSrc: string, imageUrl: string, naturalWidth: number): LitTemplate {
|
|
715
|
+
// clang-format off
|
|
716
|
+
return html`
|
|
717
|
+
<div class="image-wrapper">
|
|
718
|
+
<img src=${imageSrc} alt=${i18nString(UIStrings.imageFromS, {PH1: imageUrl})}
|
|
719
|
+
width=${naturalWidth}>
|
|
720
|
+
</div>`;
|
|
721
|
+
// clang-format on
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
function renderIcons(iconsSection: UI.ReportView.Section, data: IconsSectionData): void {
|
|
725
|
+
iconsSection.clearContent();
|
|
726
|
+
|
|
727
|
+
const contents: ReportSectionItem[] = [
|
|
728
|
+
// clang-format off
|
|
729
|
+
{
|
|
730
|
+
content: html`<devtools-checkbox class="mask-checkbox"
|
|
731
|
+
jslog=${VisualLogging.toggle('show-minimal-safe-area-for-maskable-icons')
|
|
732
|
+
.track({change: true})}
|
|
733
|
+
@click=${(event: Event) => {
|
|
734
|
+
iconsSection.setIconMasked((event.target as HTMLInputElement).checked);
|
|
735
|
+
}}>
|
|
736
|
+
${i18nString(UIStrings.showOnlyTheMinimumSafeAreaFor)}
|
|
737
|
+
</devtools-checkbox>`},
|
|
738
|
+
// clang-format on
|
|
739
|
+
{
|
|
740
|
+
content: i18nTemplate(str_, UIStrings.needHelpReadOurS, {
|
|
741
|
+
PH1: html`
|
|
742
|
+
<devtools-link href="https://web.dev/maskable-icon/" .jslogContext=${'learn-more'}>
|
|
743
|
+
${i18nString(UIStrings.documentationOnMaskableIcons)}
|
|
744
|
+
</devtools-link>`,
|
|
745
|
+
}),
|
|
746
|
+
},
|
|
747
|
+
];
|
|
748
|
+
for (const [title, images] of data.icons) {
|
|
749
|
+
const content = images.filter(icon => 'imageSrc' in icon)
|
|
750
|
+
.map(icon => renderImage(icon.imageSrc, icon.imageUrl, icon.naturalWidth));
|
|
751
|
+
contents.push({title, content, flexed: true});
|
|
752
|
+
}
|
|
753
|
+
setSectionContents(contents, iconsSection);
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
function renderShortcuts(
|
|
757
|
+
reportView: UI.ReportView.ReportView, shortcutSections: UI.ReportView.Section[], data: ShortcutsSectionData): void {
|
|
758
|
+
for (const shortcutsSection of shortcutSections) {
|
|
759
|
+
shortcutsSection.detach(/** overrideHideOnDetach= */ true);
|
|
760
|
+
}
|
|
761
|
+
shortcutSections.length = 0;
|
|
762
|
+
|
|
763
|
+
let shortcutIndex = 1;
|
|
764
|
+
for (const shortcut of data.shortcuts) {
|
|
765
|
+
const shortcutSection = reportView.appendSection(i18nString(UIStrings.shortcutS, {PH1: shortcutIndex}));
|
|
766
|
+
shortcutSection.element.setAttribute('jslog', `${VisualLogging.section('shortcuts')}`);
|
|
767
|
+
shortcutSections.push(shortcutSection);
|
|
768
|
+
|
|
769
|
+
const fields: ReportSectionItem[] = [
|
|
770
|
+
{title: i18nString(UIStrings.name), flexed: true, content: shortcut.name},
|
|
771
|
+
];
|
|
772
|
+
if (shortcut.shortName) {
|
|
773
|
+
fields.push({title: i18nString(UIStrings.shortName), flexed: true, content: shortcut.shortName});
|
|
774
|
+
}
|
|
775
|
+
if (shortcut.description) {
|
|
776
|
+
fields.push({title: i18nString(UIStrings.description), flexed: true, content: shortcut.description});
|
|
777
|
+
}
|
|
778
|
+
fields.push({
|
|
779
|
+
title: i18nString(UIStrings.url),
|
|
780
|
+
flexed: true,
|
|
781
|
+
content: Components.Linkifier.Linkifier.linkifyURL(
|
|
782
|
+
shortcut.shortcutUrl, ({text: shortcut.url, tabStop: true, jslogContext: 'shortcut'})),
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
for (const [title, images] of shortcut.icons) {
|
|
786
|
+
const content = images.filter(icon => 'imageSrc' in icon)
|
|
787
|
+
.map(icon => renderImage(icon.imageSrc, icon.imageUrl, icon.naturalWidth));
|
|
788
|
+
fields.push({title, content, flexed: true});
|
|
789
|
+
}
|
|
790
|
+
setSectionContents(fields, shortcutSection);
|
|
791
|
+
shortcutIndex++;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
function renderScreenshots(
|
|
796
|
+
reportView: UI.ReportView.ReportView, screenshotsSections: UI.ReportView.Section[],
|
|
797
|
+
data: ScreenshotsSectionData): void {
|
|
798
|
+
for (const screenshotSection of screenshotsSections) {
|
|
799
|
+
screenshotSection.detach(/** overrideHideOnDetach= */ true);
|
|
800
|
+
}
|
|
801
|
+
screenshotsSections.length = 0;
|
|
802
|
+
|
|
803
|
+
let screenshotIndex = 1;
|
|
804
|
+
for (const processedScreenshot of data.screenshots) {
|
|
805
|
+
const {screenshot, processedImage} = processedScreenshot;
|
|
806
|
+
const screenshotSection = reportView.appendSection(i18nString(UIStrings.screenshotS, {PH1: screenshotIndex}));
|
|
807
|
+
screenshotsSections.push(screenshotSection);
|
|
808
|
+
const fields: ReportSectionItem[] = [];
|
|
809
|
+
|
|
810
|
+
if (screenshot.form_factor) {
|
|
811
|
+
fields.push({title: i18nString(UIStrings.formFactor), flexed: true, content: screenshot.form_factor});
|
|
812
|
+
}
|
|
813
|
+
if (screenshot.label) {
|
|
814
|
+
fields.push({title: i18nString(UIStrings.label), flexed: true, content: screenshot.label});
|
|
815
|
+
}
|
|
816
|
+
if (screenshot.platform) {
|
|
817
|
+
fields.push({title: i18nString(UIStrings.platform), flexed: true, content: screenshot.platform});
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
if ('imageSrc' in processedImage) {
|
|
821
|
+
const content = renderImage(processedImage.imageSrc, processedImage.imageUrl, processedImage.naturalWidth);
|
|
822
|
+
fields.push({title: processedImage.title, content, flexed: true});
|
|
823
|
+
}
|
|
824
|
+
setSectionContents(fields, screenshotSection);
|
|
825
|
+
screenshotIndex++;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
function renderInstallability(
|
|
830
|
+
installabilitySection: UI.ReportView.Section, installabilityErrors: Protocol.Page.InstallabilityError[]): void {
|
|
831
|
+
installabilitySection.clearContent();
|
|
832
|
+
installabilitySection.element.classList.toggle('hidden', !installabilityErrors.length);
|
|
833
|
+
const errorMessages = getInstallabilityErrorMessages(installabilityErrors);
|
|
834
|
+
setSectionContents(errorMessages.map(content => ({content})), installabilitySection);
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
function renderWindowControlsSection(
|
|
838
|
+
windowControlsSection: UI.ReportView.Section, data: WindowControlsSectionData, selectedPlatform?: string,
|
|
839
|
+
onSelectOs?: (selectedOS: SDK.OverlayModel.EmulatedOSType) => Promise<void>,
|
|
840
|
+
onToggleWcoToolbar?: (enabled: boolean) => Promise<void>): void {
|
|
841
|
+
const {hasWco, url} = data;
|
|
842
|
+
const contents: ReportSectionItem[] = [];
|
|
843
|
+
if (hasWco) {
|
|
844
|
+
// clang-format off
|
|
845
|
+
contents.push({content: html`
|
|
846
|
+
<devtools-icon class="inline-icon" name="check-circle"></devtools-icon>
|
|
847
|
+
${i18nTemplate(str_, UIStrings.wcoFound, {
|
|
848
|
+
PH1: html`<code class="wco">window-controls-overlay</code>`,
|
|
849
|
+
PH2: html`<code>
|
|
850
|
+
<devtools-link href="https://developer.mozilla.org/en-US/docs/Web/Manifest/display_override"
|
|
851
|
+
.jslogContext=${'display-override'}>
|
|
852
|
+
display-override
|
|
853
|
+
</devtools-link>
|
|
854
|
+
</code>`,
|
|
855
|
+
PH3: html`${Components.Linkifier.Linkifier.linkifyURL(url)}`,
|
|
856
|
+
})}`});
|
|
857
|
+
// clang-format on
|
|
858
|
+
if (selectedPlatform && onSelectOs && onToggleWcoToolbar) {
|
|
859
|
+
const controls = renderWindowControls(selectedPlatform, onSelectOs, onToggleWcoToolbar);
|
|
860
|
+
contents.push(controls);
|
|
861
|
+
}
|
|
862
|
+
} else {
|
|
863
|
+
// clang-format off
|
|
864
|
+
contents.push({content: html`
|
|
865
|
+
<devtools-icon class="inline-icon" name="info"></devtools-icon>
|
|
866
|
+
${i18nTemplate(str_, UIStrings.wcoNotFound, {
|
|
867
|
+
PH1: html`<code>
|
|
868
|
+
<devtools-link href="https://developer.mozilla.org/en-US/docs/Web/Manifest/display_override"
|
|
869
|
+
.jslogContext=${'display-override'}>
|
|
870
|
+
display-override
|
|
871
|
+
</devtools-link>
|
|
872
|
+
</code>`})}`});
|
|
873
|
+
// clang-format on
|
|
874
|
+
}
|
|
875
|
+
// clang-format off
|
|
876
|
+
contents.push({content: i18nTemplate(str_, UIStrings.wcoNeedHelpReadMore, { PH1: html`<devtools-link
|
|
877
|
+
href="https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/how-to/window-controls-overlay"
|
|
878
|
+
.jslogContext=${'customize-pwa-tittle-bar'}>
|
|
879
|
+
${i18nString(UIStrings.customizePwaTitleBar)}
|
|
880
|
+
</devtools-link>`})});
|
|
881
|
+
// clang-format on
|
|
882
|
+
windowControlsSection.clearContent();
|
|
883
|
+
setSectionContents(contents, windowControlsSection);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
function getInstallabilityErrorMessages(installabilityErrors: Protocol.Page.InstallabilityError[]): string[] {
|
|
887
|
+
const errorMessages = [];
|
|
888
|
+
for (const installabilityError of installabilityErrors) {
|
|
889
|
+
let errorMessage;
|
|
890
|
+
switch (installabilityError.errorId) {
|
|
891
|
+
case 'not-in-main-frame':
|
|
892
|
+
errorMessage = i18nString(UIStrings.pageIsNotLoadedInTheMainFrame);
|
|
893
|
+
break;
|
|
894
|
+
case 'not-from-secure-origin':
|
|
895
|
+
errorMessage = i18nString(UIStrings.pageIsNotServedFromASecureOrigin);
|
|
896
|
+
break;
|
|
897
|
+
case 'no-manifest':
|
|
898
|
+
errorMessage = i18nString(UIStrings.pageHasNoManifestLinkUrl);
|
|
899
|
+
break;
|
|
900
|
+
case 'manifest-empty':
|
|
901
|
+
errorMessage = i18nString(UIStrings.manifestCouldNotBeFetchedIsEmpty);
|
|
902
|
+
break;
|
|
903
|
+
case 'start-url-not-valid':
|
|
904
|
+
errorMessage = i18nString(UIStrings.manifestStartUrlIsNotValid);
|
|
905
|
+
break;
|
|
906
|
+
case 'manifest-missing-name-or-short-name':
|
|
907
|
+
errorMessage = i18nString(UIStrings.manifestDoesNotContainANameOr);
|
|
908
|
+
break;
|
|
909
|
+
case 'manifest-display-not-supported':
|
|
910
|
+
errorMessage = i18nString(UIStrings.manifestDisplayPropertyMustBeOne);
|
|
911
|
+
break;
|
|
912
|
+
case 'manifest-missing-suitable-icon':
|
|
913
|
+
if (installabilityError.errorArguments.length !== 1 ||
|
|
914
|
+
installabilityError.errorArguments[0].name !== 'minimum-icon-size-in-pixels') {
|
|
915
|
+
console.error('Installability error does not have the correct errorArguments');
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
errorMessage =
|
|
919
|
+
i18nString(UIStrings.manifestDoesNotContainASuitable, {PH1: installabilityError.errorArguments[0].value});
|
|
920
|
+
break;
|
|
921
|
+
case 'no-acceptable-icon':
|
|
922
|
+
if (installabilityError.errorArguments.length !== 1 ||
|
|
923
|
+
installabilityError.errorArguments[0].name !== 'minimum-icon-size-in-pixels') {
|
|
924
|
+
console.error('Installability error does not have the correct errorArguments');
|
|
925
|
+
break;
|
|
926
|
+
}
|
|
927
|
+
errorMessage =
|
|
928
|
+
i18nString(UIStrings.noSuppliedIconIsAtLeastSpxSquare, {PH1: installabilityError.errorArguments[0].value});
|
|
929
|
+
break;
|
|
930
|
+
case 'cannot-download-icon':
|
|
931
|
+
errorMessage = i18nString(UIStrings.couldNotDownloadARequiredIcon);
|
|
932
|
+
break;
|
|
933
|
+
case 'no-icon-available':
|
|
934
|
+
errorMessage = i18nString(UIStrings.downloadedIconWasEmptyOr);
|
|
935
|
+
break;
|
|
936
|
+
case 'platform-not-supported-on-android':
|
|
937
|
+
errorMessage = i18nString(UIStrings.theSpecifiedApplicationPlatform);
|
|
938
|
+
break;
|
|
939
|
+
case 'no-id-specified':
|
|
940
|
+
errorMessage = i18nString(UIStrings.noPlayStoreIdProvided);
|
|
941
|
+
break;
|
|
942
|
+
case 'ids-do-not-match':
|
|
943
|
+
errorMessage = i18nString(UIStrings.thePlayStoreAppUrlAndPlayStoreId);
|
|
944
|
+
break;
|
|
945
|
+
case 'already-installed':
|
|
946
|
+
errorMessage = i18nString(UIStrings.theAppIsAlreadyInstalled);
|
|
947
|
+
break;
|
|
948
|
+
case 'url-not-supported-for-webapk':
|
|
949
|
+
errorMessage = i18nString(UIStrings.aUrlInTheManifestContainsA);
|
|
950
|
+
break;
|
|
951
|
+
case 'in-incognito':
|
|
952
|
+
errorMessage = i18nString(UIStrings.pageIsLoadedInAnIncognitoWindow);
|
|
953
|
+
break;
|
|
954
|
+
case 'not-offline-capable':
|
|
955
|
+
errorMessage = i18nString(UIStrings.pageDoesNotWorkOffline);
|
|
956
|
+
break;
|
|
957
|
+
case 'no-url-for-service-worker':
|
|
958
|
+
errorMessage = i18nString(UIStrings.couldNotCheckServiceWorker);
|
|
959
|
+
break;
|
|
960
|
+
case 'prefer-related-applications':
|
|
961
|
+
errorMessage = i18nString(UIStrings.manifestSpecifies);
|
|
962
|
+
break;
|
|
963
|
+
case 'prefer-related-applications-only-beta-stable':
|
|
964
|
+
errorMessage = i18nString(UIStrings.preferrelatedapplicationsIsOnly);
|
|
965
|
+
break;
|
|
966
|
+
case 'manifest-display-override-not-supported':
|
|
967
|
+
errorMessage = i18nString(UIStrings.manifestContainsDisplayoverride);
|
|
968
|
+
break;
|
|
969
|
+
case 'warn-not-offline-capable':
|
|
970
|
+
errorMessage = i18nString(
|
|
971
|
+
UIStrings.pageDoesNotWorkOfflineThePage,
|
|
972
|
+
{PH1: 'https://developer.chrome.com/blog/improved-pwa-offline-detection/'});
|
|
973
|
+
break;
|
|
974
|
+
default:
|
|
975
|
+
console.error(`Installability error id '${installabilityError.errorId}' is not recognized`);
|
|
976
|
+
break;
|
|
977
|
+
}
|
|
978
|
+
if (errorMessage) {
|
|
979
|
+
errorMessages.push(errorMessage);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
return errorMessages;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
function renderWindowControls(
|
|
986
|
+
selectedPlatform: string, onSelectOs: (selectedOS: SDK.OverlayModel.EmulatedOSType) => Promise<void>,
|
|
987
|
+
onToggleWcoToolbar: (enabled: boolean) => Promise<void>): ReportSectionItem {
|
|
988
|
+
// clang-format off
|
|
989
|
+
return {content: html`
|
|
990
|
+
<devtools-checkbox @click=${(event: Event) => onToggleWcoToolbar((event.target as HTMLInputElement).checked)}
|
|
991
|
+
title=${i18nString(UIStrings.selectWindowControlsOverlayEmulationOs)}>
|
|
992
|
+
${i18nString(UIStrings.selectWindowControlsOverlayEmulationOs)}
|
|
993
|
+
</devtools-checkbox>
|
|
994
|
+
<select value=${selectedPlatform}
|
|
995
|
+
@change=${(event: Event): void => {
|
|
996
|
+
const target = event.target as HTMLSelectElement;
|
|
997
|
+
const selectedOS = target.options[target.selectedIndex].value;
|
|
998
|
+
void onSelectOs(selectedOS as SDK.OverlayModel.EmulatedOSType);
|
|
999
|
+
}}
|
|
1000
|
+
.selectedIndex=${0}>
|
|
1001
|
+
<option value=${SDK.OverlayModel.EmulatedOSType.WINDOWS}
|
|
1002
|
+
jslog=${VisualLogging.item('windows').track({click: true})}>
|
|
1003
|
+
Windows
|
|
1004
|
+
</option>
|
|
1005
|
+
<option value=${SDK.OverlayModel.EmulatedOSType.MAC}
|
|
1006
|
+
jslog=${VisualLogging.item('macos').track({click: true })}>
|
|
1007
|
+
macOS
|
|
1008
|
+
</option>
|
|
1009
|
+
<option value=${SDK.OverlayModel.EmulatedOSType.LINUX}
|
|
1010
|
+
jslog=${VisualLogging.item('linux').track({click: true})}>
|
|
1011
|
+
Linux
|
|
1012
|
+
</option>
|
|
1013
|
+
</select>`};
|
|
1014
|
+
// clang-format on
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
function setSectionContents(items: ReportSectionItem[], section: UI.ReportView.Section): void {
|
|
1018
|
+
for (const item of items) {
|
|
1019
|
+
if (!item.title) {
|
|
1020
|
+
render(item.content, section.appendRow());
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
const element = item.flexed ? section.appendFlexedField(item.title) : section.appendField(item.title);
|
|
1024
|
+
if (item.label) {
|
|
1025
|
+
UI.ARIAUtils.setLabel(element, item.label);
|
|
1026
|
+
}
|
|
1027
|
+
render(item.content, element);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
interface ViewInput {
|
|
1032
|
+
emptyView: UI.EmptyWidget.EmptyWidget;
|
|
1033
|
+
reportView: UI.ReportView.ReportView;
|
|
1034
|
+
errorsSection?: UI.ReportView.Section;
|
|
1035
|
+
installabilitySection?: UI.ReportView.Section;
|
|
1036
|
+
identitySection?: UI.ReportView.Section;
|
|
1037
|
+
presentationSection?: UI.ReportView.Section;
|
|
1038
|
+
protocolHandlersView?: ApplicationComponents.ProtocolHandlersView.ProtocolHandlersView;
|
|
1039
|
+
iconsSection?: UI.ReportView.Section;
|
|
1040
|
+
windowControlsSection?: UI.ReportView.Section;
|
|
1041
|
+
shortcutSections?: UI.ReportView.Section[];
|
|
1042
|
+
screenshotsSections?: UI.ReportView.Section[];
|
|
1043
|
+
parsedManifest?: Manifest;
|
|
1044
|
+
url?: Platform.DevToolsPath.UrlString;
|
|
1045
|
+
identityData?: IdentitySectionData;
|
|
1046
|
+
presentationData?: PresentationSectionData;
|
|
1047
|
+
protocolHandlersData?: ProtocolHandlersSectionData;
|
|
1048
|
+
iconsData?: IconsSectionData;
|
|
1049
|
+
shortcutsData?: ShortcutsSectionData;
|
|
1050
|
+
screenshotsData?: ScreenshotsSectionData;
|
|
1051
|
+
installabilityErrors?: Protocol.Page.InstallabilityError[];
|
|
1052
|
+
warnings?: Platform.UIString.LocalizedString[];
|
|
1053
|
+
errors?: Protocol.Page.AppManifestError[];
|
|
1054
|
+
imageErrors?: Platform.UIString.LocalizedString[];
|
|
1055
|
+
windowControlsData?: WindowControlsSectionData;
|
|
1056
|
+
selectedPlatform?: string;
|
|
1057
|
+
onSelectOs?: (selectedOS: SDK.OverlayModel.EmulatedOSType) => Promise<void>;
|
|
1058
|
+
onToggleWcoToolbar?: (enabled: boolean) => Promise<void>;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
type View = (input: ViewInput, output: undefined, target: HTMLElement) => void;
|
|
1062
|
+
|
|
1063
|
+
export const DEFAULT_VIEW: View = (input, _output, _target) => {
|
|
1064
|
+
const {
|
|
1065
|
+
reportView,
|
|
1066
|
+
errorsSection,
|
|
1067
|
+
installabilitySection,
|
|
1068
|
+
identitySection,
|
|
1069
|
+
presentationSection,
|
|
1070
|
+
protocolHandlersView,
|
|
1071
|
+
iconsSection,
|
|
1072
|
+
windowControlsSection,
|
|
1073
|
+
shortcutSections,
|
|
1074
|
+
screenshotsSections,
|
|
1075
|
+
identityData,
|
|
1076
|
+
presentationData,
|
|
1077
|
+
protocolHandlersData,
|
|
1078
|
+
iconsData,
|
|
1079
|
+
shortcutsData,
|
|
1080
|
+
screenshotsData,
|
|
1081
|
+
installabilityErrors,
|
|
1082
|
+
warnings,
|
|
1083
|
+
errors,
|
|
1084
|
+
imageErrors,
|
|
1085
|
+
windowControlsData,
|
|
1086
|
+
selectedPlatform,
|
|
1087
|
+
onSelectOs,
|
|
1088
|
+
onToggleWcoToolbar,
|
|
1089
|
+
} = input;
|
|
1090
|
+
if (identitySection && identityData) {
|
|
1091
|
+
renderIdentity(identitySection, identityData);
|
|
1092
|
+
}
|
|
1093
|
+
if (presentationSection && presentationData) {
|
|
1094
|
+
renderPresentation(presentationSection, presentationData);
|
|
1095
|
+
}
|
|
1096
|
+
if (protocolHandlersView && protocolHandlersData) {
|
|
1097
|
+
renderProtocolHandlers(protocolHandlersView, protocolHandlersData);
|
|
1098
|
+
}
|
|
1099
|
+
if (iconsSection && iconsData) {
|
|
1100
|
+
renderIcons(iconsSection, iconsData);
|
|
1101
|
+
}
|
|
1102
|
+
if (shortcutSections && shortcutsData) {
|
|
1103
|
+
renderShortcuts(reportView, shortcutSections, shortcutsData);
|
|
1104
|
+
}
|
|
1105
|
+
if (screenshotsSections && screenshotsData) {
|
|
1106
|
+
renderScreenshots(reportView, screenshotsSections, screenshotsData);
|
|
1107
|
+
}
|
|
1108
|
+
if (installabilitySection && installabilityErrors) {
|
|
1109
|
+
renderInstallability(installabilitySection, installabilityErrors);
|
|
1110
|
+
}
|
|
1111
|
+
if (windowControlsSection && windowControlsData) {
|
|
1112
|
+
renderWindowControlsSection(
|
|
1113
|
+
windowControlsSection, windowControlsData, selectedPlatform, onSelectOs, onToggleWcoToolbar);
|
|
1114
|
+
}
|
|
1115
|
+
if (errorsSection) {
|
|
1116
|
+
renderErrors(errorsSection, warnings, errors, imageErrors);
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
|
|
457
1120
|
export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.Widget.VBox>(UI.Widget.VBox)
|
|
458
1121
|
implements SDK.TargetManager.Observer {
|
|
459
1122
|
private readonly emptyView: UI.EmptyWidget.EmptyWidget;
|
|
@@ -467,41 +1130,38 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
467
1130
|
private readonly protocolHandlersSection: UI.ReportView.Section;
|
|
468
1131
|
private readonly shortcutSections: UI.ReportView.Section[];
|
|
469
1132
|
private readonly screenshotsSections: UI.ReportView.Section[];
|
|
470
|
-
private nameField: HTMLElement;
|
|
471
|
-
private shortNameField: HTMLElement;
|
|
472
|
-
private descriptionField: Element;
|
|
473
|
-
private readonly startURLField: HTMLElement;
|
|
474
|
-
private readonly themeColorSwatch: InlineEditor.ColorSwatch.ColorSwatch;
|
|
475
|
-
private readonly backgroundColorSwatch: InlineEditor.ColorSwatch.ColorSwatch;
|
|
476
|
-
private orientationField: HTMLElement;
|
|
477
|
-
private displayField: HTMLElement;
|
|
478
|
-
private readonly newNoteUrlField: HTMLElement;
|
|
479
|
-
private readonly throttler: Common.Throttler.Throttler;
|
|
480
1133
|
private registeredListeners: Common.EventTarget.EventDescriptor[];
|
|
481
1134
|
private target?: SDK.Target.Target;
|
|
482
1135
|
private resourceTreeModel?: SDK.ResourceTreeModel.ResourceTreeModel|null;
|
|
483
1136
|
private serviceWorkerManager?: SDK.ServiceWorkerManager.ServiceWorkerManager|null;
|
|
484
1137
|
private overlayModel?: SDK.OverlayModel.OverlayModel|null;
|
|
485
1138
|
private protocolHandlersView: ApplicationComponents.ProtocolHandlersView.ProtocolHandlersView;
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
1139
|
+
private manifestUrl: Platform.DevToolsPath.UrlString;
|
|
1140
|
+
private manifestData: string|null;
|
|
1141
|
+
private manifestErrors: Protocol.Page.AppManifestError[];
|
|
1142
|
+
private installabilityErrors: Protocol.Page.InstallabilityError[];
|
|
1143
|
+
private appIdResponse: Protocol.Page.GetAppIdResponse|null;
|
|
1144
|
+
private wcoToolbarEnabled = false;
|
|
1145
|
+
private readonly view: View;
|
|
1146
|
+
|
|
1147
|
+
constructor(view: View = DEFAULT_VIEW) {
|
|
490
1148
|
super({
|
|
491
1149
|
jslog: `${VisualLogging.pane('manifest')}`,
|
|
492
1150
|
useShadowDom: true,
|
|
493
1151
|
});
|
|
1152
|
+
this.view = view;
|
|
494
1153
|
this.registerRequiredCSS(appManifestViewStyles);
|
|
495
1154
|
|
|
496
1155
|
this.contentElement.classList.add('manifest-container');
|
|
497
1156
|
|
|
498
|
-
this.emptyView =
|
|
1157
|
+
this.emptyView = new UI.EmptyWidget.EmptyWidget(
|
|
1158
|
+
i18nString(UIStrings.noManifestDetected), i18nString(UIStrings.manifestDescription));
|
|
499
1159
|
this.emptyView.link = 'https://web.dev/add-manifest/' as Platform.DevToolsPath.UrlString;
|
|
500
1160
|
|
|
501
1161
|
this.emptyView.show(this.contentElement);
|
|
502
1162
|
this.emptyView.hideWidget();
|
|
503
1163
|
|
|
504
|
-
this.reportView =
|
|
1164
|
+
this.reportView = new UI.ReportView.ReportView(i18nString(UIStrings.appManifest));
|
|
505
1165
|
this.reportView.registerRequiredCSS(appManifestViewStyles);
|
|
506
1166
|
this.reportView.element.classList.add('manifest-view-header');
|
|
507
1167
|
this.reportView.show(this.contentElement);
|
|
@@ -524,29 +1184,14 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
524
1184
|
this.shortcutSections = [];
|
|
525
1185
|
this.screenshotsSections = [];
|
|
526
1186
|
|
|
527
|
-
this.nameField = this.identitySection.appendField(i18nString(UIStrings.name));
|
|
528
|
-
this.shortNameField = this.identitySection.appendField(i18nString(UIStrings.shortName));
|
|
529
|
-
this.descriptionField = this.identitySection.appendFlexedField(i18nString(UIStrings.description));
|
|
530
|
-
|
|
531
|
-
this.startURLField = this.presentationSection.appendField(i18nString(UIStrings.startUrl));
|
|
532
|
-
UI.ARIAUtils.setLabel(this.startURLField, i18nString(UIStrings.startUrl));
|
|
533
|
-
|
|
534
|
-
const themeColorField = this.presentationSection.appendField(i18nString(UIStrings.themeColor));
|
|
535
|
-
this.themeColorSwatch = new InlineEditor.ColorSwatch.ColorSwatch();
|
|
536
|
-
themeColorField.appendChild(this.themeColorSwatch);
|
|
537
|
-
|
|
538
|
-
const backgroundColorField = this.presentationSection.appendField(i18nString(UIStrings.backgroundColor));
|
|
539
|
-
this.backgroundColorSwatch = new InlineEditor.ColorSwatch.ColorSwatch();
|
|
540
|
-
backgroundColorField.appendChild(this.backgroundColorSwatch);
|
|
541
|
-
|
|
542
|
-
this.orientationField = this.presentationSection.appendField(i18nString(UIStrings.orientation));
|
|
543
|
-
this.displayField = this.presentationSection.appendField(i18nString(UIStrings.display));
|
|
544
|
-
|
|
545
|
-
this.newNoteUrlField = this.presentationSection.appendField(i18nString(UIStrings.newNoteUrl));
|
|
546
|
-
|
|
547
|
-
this.throttler = throttler;
|
|
548
1187
|
SDK.TargetManager.TargetManager.instance().observeTargets(this);
|
|
549
1188
|
this.registeredListeners = [];
|
|
1189
|
+
|
|
1190
|
+
this.manifestUrl = Platform.DevToolsPath.EmptyUrlString;
|
|
1191
|
+
this.manifestData = null;
|
|
1192
|
+
this.manifestErrors = [];
|
|
1193
|
+
this.installabilityErrors = [];
|
|
1194
|
+
this.appIdResponse = null;
|
|
550
1195
|
}
|
|
551
1196
|
|
|
552
1197
|
getStaticSections(): UI.ReportView.Section[] {
|
|
@@ -614,20 +1259,32 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
614
1259
|
this.resourceTreeModel.getAppId(),
|
|
615
1260
|
]);
|
|
616
1261
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
1262
|
+
this.manifestUrl = url;
|
|
1263
|
+
this.manifestData = data;
|
|
1264
|
+
this.manifestErrors = errors;
|
|
1265
|
+
this.installabilityErrors = installabilityErrors;
|
|
1266
|
+
this.appIdResponse = appId;
|
|
1267
|
+
|
|
1268
|
+
if (immediately) {
|
|
1269
|
+
await this.performUpdate();
|
|
1270
|
+
} else {
|
|
1271
|
+
await this.requestUpdate();
|
|
1272
|
+
}
|
|
620
1273
|
}
|
|
621
1274
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
1275
|
+
override async performUpdate(): Promise<void> {
|
|
1276
|
+
const url = this.manifestUrl;
|
|
1277
|
+
let data = this.manifestData;
|
|
1278
|
+
const errors = this.manifestErrors;
|
|
1279
|
+
const installabilityErrors = this.installabilityErrors;
|
|
1280
|
+
const appIdResponse = this.appIdResponse;
|
|
1281
|
+
|
|
626
1282
|
const appId = appIdResponse?.appId || null;
|
|
627
1283
|
const recommendedId = appIdResponse?.recommendedId || null;
|
|
628
1284
|
if ((!data || data === '{}') && !errors.length) {
|
|
629
1285
|
this.emptyView.showWidget();
|
|
630
1286
|
this.reportView.hideWidget();
|
|
1287
|
+
this.view({emptyView: this.emptyView, reportView: this.reportView}, undefined, this.contentElement);
|
|
631
1288
|
this.dispatchEventToListeners(Events.MANIFEST_DETECTED, false);
|
|
632
1289
|
return;
|
|
633
1290
|
}
|
|
@@ -635,21 +1292,13 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
635
1292
|
this.reportView.showWidget();
|
|
636
1293
|
this.dispatchEventToListeners(Events.MANIFEST_DETECTED, true);
|
|
637
1294
|
|
|
638
|
-
const link = Components.Linkifier.Linkifier.linkifyURL(url);
|
|
639
|
-
link.tabIndex = 0;
|
|
1295
|
+
const link = Components.Linkifier.Linkifier.linkifyURL(url, {tabStop: true});
|
|
640
1296
|
this.reportView.setURL(link);
|
|
641
|
-
this.errorsSection.clearContent();
|
|
642
|
-
this.errorsSection.element.classList.toggle('hidden', !errors.length);
|
|
643
|
-
for (const error of errors) {
|
|
644
|
-
const icon = UI.UIUtils.createIconLabel({
|
|
645
|
-
title: error.message,
|
|
646
|
-
iconName: error.critical ? 'cross-circle-filled' : 'warning-filled',
|
|
647
|
-
color: error.critical ? 'var(--icon-error)' : 'var(--icon-warning)',
|
|
648
|
-
});
|
|
649
|
-
this.errorsSection.appendRow().appendChild(icon);
|
|
650
|
-
}
|
|
651
1297
|
|
|
652
1298
|
if (!data) {
|
|
1299
|
+
this.view(
|
|
1300
|
+
{emptyView: this.emptyView, reportView: this.reportView, errorsSection: this.errorsSection, errors},
|
|
1301
|
+
undefined, this.contentElement);
|
|
653
1302
|
return;
|
|
654
1303
|
}
|
|
655
1304
|
|
|
@@ -658,414 +1307,80 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
658
1307
|
} // Trim the BOM as per https://tools.ietf.org/html/rfc7159#section-8.1.
|
|
659
1308
|
|
|
660
1309
|
const parsedManifest = JSON.parse(data);
|
|
661
|
-
this.nameField.textContent = stringProperty('name');
|
|
662
|
-
this.shortNameField.textContent = stringProperty('short_name');
|
|
663
|
-
|
|
664
|
-
const warnings = [];
|
|
665
|
-
|
|
666
|
-
const description = stringProperty('description');
|
|
667
|
-
this.descriptionField.textContent = description;
|
|
668
|
-
// See https://crbug.com/1354304 for details.
|
|
669
|
-
if (description.length > 300) {
|
|
670
|
-
warnings.push(i18nString(UIStrings.descriptionMayBeTruncated));
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
const startURL = stringProperty('start_url');
|
|
674
|
-
if (appId && recommendedId) {
|
|
675
|
-
const appIdField = this.identitySection.appendField(i18nString(UIStrings.computedAppId));
|
|
676
|
-
UI.ARIAUtils.setLabel(appIdField, 'App Id');
|
|
677
|
-
appIdField.textContent = appId;
|
|
678
|
-
|
|
679
|
-
const helpIcon = IconButton.Icon.create('help', 'inline-icon');
|
|
680
|
-
helpIcon.title = i18nString(UIStrings.appIdExplainer);
|
|
681
|
-
helpIcon.setAttribute('jslog', `${VisualLogging.action('help').track({hover: true})}`);
|
|
682
|
-
appIdField.appendChild(helpIcon);
|
|
683
|
-
|
|
684
|
-
const learnMoreLink = UI.XLink.XLink.create(
|
|
685
|
-
'https://developer.chrome.com/blog/pwa-manifest-id/', i18nString(UIStrings.learnMore), undefined, undefined,
|
|
686
|
-
'learn-more');
|
|
687
|
-
appIdField.appendChild(learnMoreLink);
|
|
688
|
-
|
|
689
|
-
if (!stringProperty('id')) {
|
|
690
|
-
const suggestedIdNote = appIdField.createChild('div', 'multiline-value');
|
|
691
|
-
const suggestedIdSpan = document.createElement('code');
|
|
692
|
-
suggestedIdSpan.textContent = recommendedId;
|
|
693
|
-
|
|
694
|
-
const copyButton = new Buttons.Button.Button();
|
|
695
|
-
copyButton.data = {
|
|
696
|
-
variant: Buttons.Button.Variant.ICON,
|
|
697
|
-
iconName: 'copy',
|
|
698
|
-
size: Buttons.Button.Size.SMALL,
|
|
699
|
-
jslogContext: 'manifest.copy-id',
|
|
700
|
-
title: i18nString(UIStrings.copyToClipboard),
|
|
701
|
-
};
|
|
702
|
-
copyButton.className = 'inline-button';
|
|
703
|
-
copyButton.addEventListener('click', () => {
|
|
704
|
-
UI.ARIAUtils.LiveAnnouncer.alert(i18nString(UIStrings.copiedToClipboard, {PH1: recommendedId}));
|
|
705
|
-
Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(recommendedId);
|
|
706
|
-
});
|
|
707
|
-
suggestedIdNote.appendChild(
|
|
708
|
-
uiI18n.getFormatLocalizedString(str_, UIStrings.appIdNote, {PH1: suggestedIdSpan, PH2: copyButton}));
|
|
709
|
-
}
|
|
710
|
-
} else {
|
|
711
|
-
this.identitySection.removeField(i18nString(UIStrings.computedAppId));
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
this.startURLField.removeChildren();
|
|
715
|
-
if (startURL) {
|
|
716
|
-
const completeURL = Common.ParsedURL.ParsedURL.completeURL(url, startURL);
|
|
717
|
-
if (completeURL) {
|
|
718
|
-
const link = Components.Linkifier.Linkifier.linkifyURL(
|
|
719
|
-
completeURL, ({text: startURL} as Components.Linkifier.LinkifyURLOptions));
|
|
720
|
-
link.tabIndex = 0;
|
|
721
|
-
link.setAttribute('jslog', `${VisualLogging.link('start-url').track({click: true})}`);
|
|
722
|
-
this.startURLField.appendChild(link);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
this.themeColorSwatch.classList.toggle('hidden', !stringProperty('theme_color'));
|
|
727
|
-
const themeColor = Common.Color.parse(stringProperty('theme_color') || 'white') || Common.Color.parse('white');
|
|
728
|
-
if (themeColor) {
|
|
729
|
-
this.themeColorSwatch.renderColor(themeColor);
|
|
730
|
-
}
|
|
731
|
-
this.backgroundColorSwatch.classList.toggle('hidden', !stringProperty('background_color'));
|
|
732
|
-
const backgroundColor =
|
|
733
|
-
Common.Color.parse(stringProperty('background_color') || 'white') || Common.Color.parse('white');
|
|
734
|
-
if (backgroundColor) {
|
|
735
|
-
this.backgroundColorSwatch.renderColor(backgroundColor);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
this.orientationField.textContent = stringProperty('orientation');
|
|
739
|
-
const displayType = stringProperty('display');
|
|
740
|
-
this.displayField.textContent = displayType;
|
|
741
|
-
|
|
742
|
-
const noteTaking = parsedManifest['note_taking'] || {};
|
|
743
|
-
const newNoteUrl = noteTaking['new_note_url'];
|
|
744
|
-
const hasNewNoteUrl = typeof newNoteUrl === 'string';
|
|
745
|
-
this.newNoteUrlField.parentElement?.classList.toggle('hidden', !hasNewNoteUrl);
|
|
746
|
-
this.newNoteUrlField.removeChildren();
|
|
747
|
-
if (hasNewNoteUrl) {
|
|
748
|
-
const completeURL = (Common.ParsedURL.ParsedURL.completeURL(url, newNoteUrl) as Platform.DevToolsPath.UrlString);
|
|
749
|
-
const link = Components.Linkifier.Linkifier.linkifyURL(
|
|
750
|
-
completeURL, ({text: newNoteUrl} as Components.Linkifier.LinkifyURLOptions));
|
|
751
|
-
link.tabIndex = 0;
|
|
752
|
-
this.newNoteUrlField.appendChild(link);
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
const protocolHandlers = parsedManifest['protocol_handlers'] || [];
|
|
756
|
-
this.protocolHandlersView.protocolHandlers = protocolHandlers;
|
|
757
|
-
this.protocolHandlersView.manifestLink = url;
|
|
758
|
-
|
|
759
|
-
const icons = parsedManifest['icons'] || [];
|
|
760
|
-
this.iconsSection.clearContent();
|
|
761
|
-
|
|
762
|
-
const shortcuts = parsedManifest['shortcuts'] || [];
|
|
763
|
-
for (const shortcutsSection of this.shortcutSections) {
|
|
764
|
-
shortcutsSection.detach(/** overrideHideOnDetach= */ true);
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
const screenshots: Screenshot[] = parsedManifest['screenshots'] || [];
|
|
768
|
-
for (const screenshotSection of this.screenshotsSections) {
|
|
769
|
-
screenshotSection.detach(/** overrideHideOnDetach= */ true);
|
|
770
|
-
}
|
|
771
|
-
|
|
772
|
-
const imageErrors: Platform.UIString.LocalizedString[] = [];
|
|
773
|
-
|
|
774
|
-
const setIconMaskedCheckbox = UI.UIUtils.CheckboxLabel.create(i18nString(UIStrings.showOnlyTheMinimumSafeAreaFor));
|
|
775
|
-
setIconMaskedCheckbox.classList.add('mask-checkbox');
|
|
776
|
-
setIconMaskedCheckbox.setAttribute(
|
|
777
|
-
'jslog', `${VisualLogging.toggle('show-minimal-safe-area-for-maskable-icons').track({change: true})}`);
|
|
778
|
-
setIconMaskedCheckbox.addEventListener('click', () => {
|
|
779
|
-
this.iconsSection.setIconMasked(setIconMaskedCheckbox.checked);
|
|
780
|
-
});
|
|
781
|
-
this.iconsSection.appendRow().appendChild(setIconMaskedCheckbox);
|
|
782
|
-
const documentationLink = UI.XLink.XLink.create(
|
|
783
|
-
'https://web.dev/maskable-icon/', i18nString(UIStrings.documentationOnMaskableIcons), undefined, undefined,
|
|
784
|
-
'learn-more');
|
|
785
|
-
this.iconsSection.appendRow().appendChild(
|
|
786
|
-
uiI18n.getFormatLocalizedString(str_, UIStrings.needHelpReadOurS, {PH1: documentationLink}));
|
|
787
|
-
|
|
788
|
-
let squareSizedIconAvailable = false;
|
|
789
|
-
for (const icon of icons) {
|
|
790
|
-
const result = await this.appendImageResourceToSection(url, icon, this.iconsSection, /** isScreenshot= */ false);
|
|
791
|
-
imageErrors.push(...result.imageResourceErrors);
|
|
792
|
-
squareSizedIconAvailable = result.squareSizedIconAvailable || squareSizedIconAvailable;
|
|
793
|
-
}
|
|
794
|
-
if (!squareSizedIconAvailable) {
|
|
795
|
-
imageErrors.push(i18nString(UIStrings.sSShouldHaveSquareIcon));
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
if (shortcuts.length > 4) {
|
|
799
|
-
warnings.push(i18nString(UIStrings.shortcutsMayBeNotAvailable));
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
let shortcutIndex = 1;
|
|
803
|
-
for (const shortcut of shortcuts) {
|
|
804
|
-
const shortcutSection = this.reportView.appendSection(i18nString(UIStrings.shortcutS, {PH1: shortcutIndex}));
|
|
805
|
-
shortcutSection.element.setAttribute('jslog', `${VisualLogging.section('shortcuts')}`);
|
|
806
|
-
this.shortcutSections.push(shortcutSection);
|
|
807
|
-
|
|
808
|
-
shortcutSection.appendFlexedField(i18nString(UIStrings.name), shortcut.name);
|
|
809
|
-
if (shortcut.short_name) {
|
|
810
|
-
shortcutSection.appendFlexedField(i18nString(UIStrings.shortName), shortcut.short_name);
|
|
811
|
-
}
|
|
812
|
-
if (shortcut.description) {
|
|
813
|
-
shortcutSection.appendFlexedField(i18nString(UIStrings.description), shortcut.description);
|
|
814
|
-
}
|
|
815
|
-
const urlField = shortcutSection.appendFlexedField(i18nString(UIStrings.url));
|
|
816
|
-
const shortcutUrl = Common.ParsedURL.ParsedURL.completeURL(url, shortcut.url) as Platform.DevToolsPath.UrlString;
|
|
817
|
-
const link = Components.Linkifier.Linkifier.linkifyURL(
|
|
818
|
-
shortcutUrl, ({text: shortcut.url} as Components.Linkifier.LinkifyURLOptions));
|
|
819
|
-
link.setAttribute('jslog', `${VisualLogging.link('shortcut').track({click: true})}`);
|
|
820
|
-
link.tabIndex = 0;
|
|
821
|
-
urlField.appendChild(link);
|
|
822
|
-
|
|
823
|
-
const shortcutIcons = shortcut.icons || [];
|
|
824
|
-
let hasShortcutIconLargeEnough = false;
|
|
825
|
-
for (const shortcutIcon of shortcutIcons) {
|
|
826
|
-
const {imageResourceErrors: shortcutIconErrors} =
|
|
827
|
-
await this.appendImageResourceToSection(url, shortcutIcon, shortcutSection, /** isScreenshot= */ false);
|
|
828
|
-
imageErrors.push(...shortcutIconErrors);
|
|
829
|
-
if (!hasShortcutIconLargeEnough && shortcutIcon.sizes) {
|
|
830
|
-
const shortcutIconSize = shortcutIcon.sizes.match(/^(\d+)x(\d+)$/);
|
|
831
|
-
if (shortcutIconSize && shortcutIconSize[1] >= 96 && shortcutIconSize[2] >= 96) {
|
|
832
|
-
hasShortcutIconLargeEnough = true;
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
if (!hasShortcutIconLargeEnough) {
|
|
837
|
-
imageErrors.push(i18nString(UIStrings.shortcutSShouldIncludeAXPixel, {PH1: shortcutIndex}));
|
|
838
|
-
}
|
|
839
|
-
shortcutIndex++;
|
|
840
|
-
}
|
|
841
1310
|
|
|
842
|
-
|
|
843
|
-
const formFactorScreenshotDimensions = new Map<string, {width: number, height: number}>();
|
|
844
|
-
let haveScreenshotsDifferentAspectRatio = false;
|
|
845
|
-
for (const screenshot of screenshots) {
|
|
846
|
-
const screenshotSection =
|
|
847
|
-
this.reportView.appendSection(i18nString(UIStrings.screenshotS, {PH1: screenshotIndex}));
|
|
848
|
-
this.screenshotsSections.push(screenshotSection);
|
|
849
|
-
|
|
850
|
-
if (screenshot.form_factor) {
|
|
851
|
-
screenshotSection.appendFlexedField(i18nString(UIStrings.formFactor), screenshot.form_factor);
|
|
852
|
-
}
|
|
853
|
-
if (screenshot.label) {
|
|
854
|
-
screenshotSection.appendFlexedField(i18nString(UIStrings.label), screenshot.label);
|
|
855
|
-
}
|
|
856
|
-
if (screenshot.platform) {
|
|
857
|
-
screenshotSection.appendFlexedField(i18nString(UIStrings.platform), screenshot.platform);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
const {imageResourceErrors: screenshotErrors, naturalWidth: width, naturalHeight: height} =
|
|
861
|
-
await this.appendImageResourceToSection(url, screenshot, screenshotSection, /** isScreenshot= */ true);
|
|
862
|
-
imageErrors.push(...screenshotErrors);
|
|
863
|
-
|
|
864
|
-
if (screenshot.form_factor && width && height) {
|
|
865
|
-
formFactorScreenshotDimensions.has(screenshot.form_factor) ||
|
|
866
|
-
formFactorScreenshotDimensions.set(screenshot.form_factor, {width, height});
|
|
867
|
-
const formFactorFirstScreenshotDimensions = formFactorScreenshotDimensions.get(screenshot.form_factor);
|
|
868
|
-
if (formFactorFirstScreenshotDimensions) {
|
|
869
|
-
haveScreenshotsDifferentAspectRatio = haveScreenshotsDifferentAspectRatio ||
|
|
870
|
-
(width * formFactorFirstScreenshotDimensions.height !==
|
|
871
|
-
height * formFactorFirstScreenshotDimensions.width);
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
screenshotIndex++;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
if (haveScreenshotsDifferentAspectRatio) {
|
|
879
|
-
warnings.push(i18nString(UIStrings.screenshotsMustHaveSameAspectRatio));
|
|
880
|
-
}
|
|
881
|
-
|
|
882
|
-
const screenshotsForDesktop = screenshots.filter(screenshot => screenshot.form_factor === 'wide');
|
|
883
|
-
const screenshotsForMobile = screenshots.filter(screenshot => screenshot.form_factor !== 'wide');
|
|
1311
|
+
const identityData = this.processIdentity(parsedManifest, appId, recommendedId);
|
|
884
1312
|
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
}
|
|
888
|
-
if (screenshotsForMobile.length < 1) {
|
|
889
|
-
warnings.push(i18nString(UIStrings.noScreenshotsForRicherPWAInstallOnMobile));
|
|
890
|
-
}
|
|
891
|
-
if (screenshotsForDesktop.length > 8) {
|
|
892
|
-
warnings.push(i18nString(UIStrings.tooManyScreenshotsForDesktop));
|
|
893
|
-
}
|
|
894
|
-
if (screenshotsForMobile.length > 5) {
|
|
895
|
-
warnings.push(i18nString(UIStrings.tooManyScreenshotsForMobile));
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
this.installabilitySection.clearContent();
|
|
899
|
-
this.installabilitySection.element.classList.toggle('hidden', !installabilityErrors.length);
|
|
900
|
-
const errorMessages = this.getInstallabilityErrorMessages(installabilityErrors);
|
|
901
|
-
for (const error of errorMessages) {
|
|
902
|
-
const msgElement = document.createTextNode(error);
|
|
903
|
-
this.installabilitySection.appendRow().appendChild(msgElement);
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
this.errorsSection.element.classList.toggle('hidden', !errors.length && !imageErrors.length && !warnings.length);
|
|
907
|
-
for (const warning of warnings) {
|
|
908
|
-
const msgElement = document.createTextNode(warning);
|
|
909
|
-
this.errorsSection.appendRow().appendChild(msgElement);
|
|
910
|
-
}
|
|
911
|
-
for (const error of imageErrors) {
|
|
912
|
-
const msgElement = document.createTextNode(error);
|
|
913
|
-
this.errorsSection.appendRow().appendChild(msgElement);
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
function stringProperty(name: string): string {
|
|
917
|
-
const value = parsedManifest[name];
|
|
918
|
-
if (typeof value !== 'string') {
|
|
919
|
-
return '';
|
|
920
|
-
}
|
|
921
|
-
return value;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
this.windowControlsSection.clearContent();
|
|
925
|
-
const displayOverride = parsedManifest['display_override'] || [];
|
|
926
|
-
const hasWco = displayOverride.includes('window-controls-overlay');
|
|
1313
|
+
const presentationData = this.processPresentation(parsedManifest, url);
|
|
1314
|
+
const protocolHandlersData = this.processProtocolHandlers(parsedManifest, url);
|
|
927
1315
|
|
|
928
|
-
const
|
|
929
|
-
|
|
930
|
-
undefined, 'display-override');
|
|
931
|
-
const displayOverrideText = document.createElement('code');
|
|
932
|
-
displayOverrideText.appendChild(displayOverrideLink);
|
|
1316
|
+
const iconsData = await this.processIcons(parsedManifest, url);
|
|
1317
|
+
const shortcutsData = await this.processShortcuts(parsedManifest, url);
|
|
933
1318
|
|
|
934
|
-
const
|
|
1319
|
+
const screenshotsData = await this.processScreenshots(parsedManifest, url);
|
|
935
1320
|
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
wco.classList.add('wco');
|
|
942
|
-
wco.textContent = 'window-controls-overlay';
|
|
943
|
-
wcoStatusMessage.appendChild(
|
|
944
|
-
uiI18n.getFormatLocalizedString(str_, UIStrings.wcoFound, {PH1: wco, PH2: displayOverrideText, PH3: link}));
|
|
945
|
-
|
|
946
|
-
if (this.overlayModel) {
|
|
947
|
-
await this.appendWindowControlsToSection(this.overlayModel, url, stringProperty('theme_color'));
|
|
948
|
-
}
|
|
949
|
-
} else {
|
|
950
|
-
const infoIcon = IconButton.Icon.create('info', 'inline-icon');
|
|
951
|
-
|
|
952
|
-
wcoStatusMessage.appendChild(infoIcon);
|
|
953
|
-
|
|
954
|
-
wcoStatusMessage.appendChild(
|
|
955
|
-
uiI18n.getFormatLocalizedString(str_, UIStrings.wcoNotFound, {PH1: displayOverrideText}));
|
|
956
|
-
}
|
|
1321
|
+
const warnings = [
|
|
1322
|
+
...identityData.warnings,
|
|
1323
|
+
...shortcutsData.warnings,
|
|
1324
|
+
...screenshotsData.warnings,
|
|
1325
|
+
];
|
|
957
1326
|
|
|
958
|
-
const
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1327
|
+
const imageErrors = [
|
|
1328
|
+
...iconsData.imageResourceErrors,
|
|
1329
|
+
...shortcutsData.imageResourceErrors,
|
|
1330
|
+
...screenshotsData.imageResourceErrors,
|
|
1331
|
+
];
|
|
963
1332
|
|
|
964
|
-
this.
|
|
1333
|
+
const windowControlsData = await this.processWindowControls(parsedManifest, url);
|
|
1334
|
+
const selectedPlatform = this.overlayModel?.getWindowControlsConfig().selectedPlatform;
|
|
1335
|
+
const onSelectOs = this.overlayModel ?
|
|
1336
|
+
(selectedOS: SDK.OverlayModel.EmulatedOSType) => this.onSelectOs(selectedOS, windowControlsData.themeColor) :
|
|
1337
|
+
undefined;
|
|
1338
|
+
const onToggleWcoToolbar = this.overlayModel ? (enabled: boolean) => this.onToggleWcoToolbar(enabled) : undefined;
|
|
1339
|
+
this.view(
|
|
1340
|
+
{
|
|
1341
|
+
emptyView: this.emptyView,
|
|
1342
|
+
reportView: this.reportView,
|
|
1343
|
+
errorsSection: this.errorsSection,
|
|
1344
|
+
installabilitySection: this.installabilitySection,
|
|
1345
|
+
identitySection: this.identitySection,
|
|
1346
|
+
presentationSection: this.presentationSection,
|
|
1347
|
+
protocolHandlersView: this.protocolHandlersView,
|
|
1348
|
+
iconsSection: this.iconsSection,
|
|
1349
|
+
windowControlsSection: this.windowControlsSection,
|
|
1350
|
+
shortcutSections: this.shortcutSections,
|
|
1351
|
+
screenshotsSections: this.screenshotsSections,
|
|
1352
|
+
parsedManifest,
|
|
1353
|
+
url,
|
|
1354
|
+
identityData,
|
|
1355
|
+
presentationData,
|
|
1356
|
+
protocolHandlersData,
|
|
1357
|
+
iconsData,
|
|
1358
|
+
shortcutsData,
|
|
1359
|
+
screenshotsData,
|
|
1360
|
+
installabilityErrors,
|
|
1361
|
+
warnings,
|
|
1362
|
+
errors,
|
|
1363
|
+
imageErrors,
|
|
1364
|
+
windowControlsData,
|
|
1365
|
+
selectedPlatform,
|
|
1366
|
+
onSelectOs,
|
|
1367
|
+
onToggleWcoToolbar,
|
|
1368
|
+
},
|
|
1369
|
+
undefined, this.contentElement);
|
|
965
1370
|
}
|
|
966
1371
|
|
|
967
|
-
|
|
968
|
-
const
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
switch (installabilityError.errorId) {
|
|
972
|
-
case 'not-in-main-frame':
|
|
973
|
-
errorMessage = i18nString(UIStrings.pageIsNotLoadedInTheMainFrame);
|
|
974
|
-
break;
|
|
975
|
-
case 'not-from-secure-origin':
|
|
976
|
-
errorMessage = i18nString(UIStrings.pageIsNotServedFromASecureOrigin);
|
|
977
|
-
break;
|
|
978
|
-
case 'no-manifest':
|
|
979
|
-
errorMessage = i18nString(UIStrings.pageHasNoManifestLinkUrl);
|
|
980
|
-
break;
|
|
981
|
-
case 'manifest-empty':
|
|
982
|
-
errorMessage = i18nString(UIStrings.manifestCouldNotBeFetchedIsEmpty);
|
|
983
|
-
break;
|
|
984
|
-
case 'start-url-not-valid':
|
|
985
|
-
errorMessage = i18nString(UIStrings.manifestStartUrlIsNotValid);
|
|
986
|
-
break;
|
|
987
|
-
case 'manifest-missing-name-or-short-name':
|
|
988
|
-
errorMessage = i18nString(UIStrings.manifestDoesNotContainANameOr);
|
|
989
|
-
break;
|
|
990
|
-
case 'manifest-display-not-supported':
|
|
991
|
-
errorMessage = i18nString(UIStrings.manifestDisplayPropertyMustBeOne);
|
|
992
|
-
break;
|
|
993
|
-
case 'manifest-missing-suitable-icon':
|
|
994
|
-
if (installabilityError.errorArguments.length !== 1 ||
|
|
995
|
-
installabilityError.errorArguments[0].name !== 'minimum-icon-size-in-pixels') {
|
|
996
|
-
console.error('Installability error does not have the correct errorArguments');
|
|
997
|
-
break;
|
|
998
|
-
}
|
|
999
|
-
errorMessage =
|
|
1000
|
-
i18nString(UIStrings.manifestDoesNotContainASuitable, {PH1: installabilityError.errorArguments[0].value});
|
|
1001
|
-
break;
|
|
1002
|
-
case 'no-acceptable-icon':
|
|
1003
|
-
if (installabilityError.errorArguments.length !== 1 ||
|
|
1004
|
-
installabilityError.errorArguments[0].name !== 'minimum-icon-size-in-pixels') {
|
|
1005
|
-
console.error('Installability error does not have the correct errorArguments');
|
|
1006
|
-
break;
|
|
1007
|
-
}
|
|
1008
|
-
errorMessage = i18nString(
|
|
1009
|
-
UIStrings.noSuppliedIconIsAtLeastSpxSquare, {PH1: installabilityError.errorArguments[0].value});
|
|
1010
|
-
break;
|
|
1011
|
-
case 'cannot-download-icon':
|
|
1012
|
-
errorMessage = i18nString(UIStrings.couldNotDownloadARequiredIcon);
|
|
1013
|
-
break;
|
|
1014
|
-
case 'no-icon-available':
|
|
1015
|
-
errorMessage = i18nString(UIStrings.downloadedIconWasEmptyOr);
|
|
1016
|
-
break;
|
|
1017
|
-
case 'platform-not-supported-on-android':
|
|
1018
|
-
errorMessage = i18nString(UIStrings.theSpecifiedApplicationPlatform);
|
|
1019
|
-
break;
|
|
1020
|
-
case 'no-id-specified':
|
|
1021
|
-
errorMessage = i18nString(UIStrings.noPlayStoreIdProvided);
|
|
1022
|
-
break;
|
|
1023
|
-
case 'ids-do-not-match':
|
|
1024
|
-
errorMessage = i18nString(UIStrings.thePlayStoreAppUrlAndPlayStoreId);
|
|
1025
|
-
break;
|
|
1026
|
-
case 'already-installed':
|
|
1027
|
-
errorMessage = i18nString(UIStrings.theAppIsAlreadyInstalled);
|
|
1028
|
-
break;
|
|
1029
|
-
case 'url-not-supported-for-webapk':
|
|
1030
|
-
errorMessage = i18nString(UIStrings.aUrlInTheManifestContainsA);
|
|
1031
|
-
break;
|
|
1032
|
-
case 'in-incognito':
|
|
1033
|
-
errorMessage = i18nString(UIStrings.pageIsLoadedInAnIncognitoWindow);
|
|
1034
|
-
break;
|
|
1035
|
-
case 'not-offline-capable':
|
|
1036
|
-
errorMessage = i18nString(UIStrings.pageDoesNotWorkOffline);
|
|
1037
|
-
break;
|
|
1038
|
-
case 'no-url-for-service-worker':
|
|
1039
|
-
errorMessage = i18nString(UIStrings.couldNotCheckServiceWorker);
|
|
1040
|
-
break;
|
|
1041
|
-
case 'prefer-related-applications':
|
|
1042
|
-
errorMessage = i18nString(UIStrings.manifestSpecifies);
|
|
1043
|
-
break;
|
|
1044
|
-
case 'prefer-related-applications-only-beta-stable':
|
|
1045
|
-
errorMessage = i18nString(UIStrings.preferrelatedapplicationsIsOnly);
|
|
1046
|
-
break;
|
|
1047
|
-
case 'manifest-display-override-not-supported':
|
|
1048
|
-
errorMessage = i18nString(UIStrings.manifestContainsDisplayoverride);
|
|
1049
|
-
break;
|
|
1050
|
-
case 'warn-not-offline-capable':
|
|
1051
|
-
errorMessage = i18nString(
|
|
1052
|
-
UIStrings.pageDoesNotWorkOfflineThePage,
|
|
1053
|
-
{PH1: 'https://developer.chrome.com/blog/improved-pwa-offline-detection/'});
|
|
1054
|
-
break;
|
|
1055
|
-
default:
|
|
1056
|
-
console.error(`Installability error id '${installabilityError.errorId}' is not recognized`);
|
|
1057
|
-
break;
|
|
1058
|
-
}
|
|
1059
|
-
if (errorMessage) {
|
|
1060
|
-
errorMessages.push(errorMessage);
|
|
1061
|
-
}
|
|
1372
|
+
private stringProperty(parsedManifest: Manifest, name: keyof Manifest): string {
|
|
1373
|
+
const value = parsedManifest[name];
|
|
1374
|
+
if (typeof value !== 'string') {
|
|
1375
|
+
return '';
|
|
1062
1376
|
}
|
|
1063
|
-
return
|
|
1377
|
+
return value;
|
|
1064
1378
|
}
|
|
1065
1379
|
|
|
1066
1380
|
private async loadImage(url: Platform.DevToolsPath.UrlString): Promise<{
|
|
1067
|
-
|
|
1068
|
-
|
|
1381
|
+
naturalWidth: number,
|
|
1382
|
+
naturalHeight: number,
|
|
1383
|
+
src: string,
|
|
1069
1384
|
}|null> {
|
|
1070
1385
|
const frameId = this.resourceTreeModel?.mainFrame?.id;
|
|
1071
1386
|
if (!this.target) {
|
|
@@ -1081,8 +1396,6 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1081
1396
|
initiatorUrl: this.target.inspectedURL(),
|
|
1082
1397
|
},
|
|
1083
1398
|
/* isBinary=*/ true);
|
|
1084
|
-
const wrapper = document.createElement('div');
|
|
1085
|
-
wrapper.classList.add('image-wrapper');
|
|
1086
1399
|
const image = document.createElement('img');
|
|
1087
1400
|
const result = new Promise((resolve, reject) => {
|
|
1088
1401
|
image.onload = resolve;
|
|
@@ -1092,11 +1405,9 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1092
1405
|
// does not work, we can parse mimeType out of the response headers
|
|
1093
1406
|
// using front_end/core/platform/MimeType.ts.
|
|
1094
1407
|
image.src = 'data:application/octet-stream;base64,' + await Common.Base64.encode(content);
|
|
1095
|
-
image.alt = i18nString(UIStrings.imageFromS, {PH1: url});
|
|
1096
|
-
wrapper.appendChild(image);
|
|
1097
1408
|
try {
|
|
1098
1409
|
await result;
|
|
1099
|
-
return {
|
|
1410
|
+
return {naturalWidth: image.naturalWidth, naturalHeight: image.naturalHeight, src: image.src};
|
|
1100
1411
|
} catch {
|
|
1101
1412
|
}
|
|
1102
1413
|
return null;
|
|
@@ -1128,17 +1439,17 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1128
1439
|
}
|
|
1129
1440
|
|
|
1130
1441
|
checkSizeProblem(
|
|
1131
|
-
size: ParsedSize,
|
|
1442
|
+
size: ParsedSize, naturalWidth: number, naturalHeight: number, resourceName: Platform.UIString.LocalizedString,
|
|
1132
1443
|
imageUrl: string): {hasSquareSize: boolean, error?: Platform.UIString.LocalizedString} {
|
|
1133
1444
|
if ('any' in size) {
|
|
1134
|
-
return {hasSquareSize:
|
|
1445
|
+
return {hasSquareSize: naturalWidth === naturalHeight};
|
|
1135
1446
|
}
|
|
1136
1447
|
const hasSquareSize = size.width === size.height;
|
|
1137
|
-
if (
|
|
1448
|
+
if (naturalWidth !== size.width && naturalHeight !== size.height) {
|
|
1138
1449
|
return {
|
|
1139
1450
|
error: i18nString(UIStrings.actualSizeSspxOfSSDoesNotMatch, {
|
|
1140
|
-
PH1:
|
|
1141
|
-
PH2:
|
|
1451
|
+
PH1: naturalWidth,
|
|
1452
|
+
PH2: naturalHeight,
|
|
1142
1453
|
PH3: resourceName,
|
|
1143
1454
|
PH4: imageUrl,
|
|
1144
1455
|
PH5: size.width,
|
|
@@ -1147,35 +1458,29 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1147
1458
|
hasSquareSize,
|
|
1148
1459
|
};
|
|
1149
1460
|
}
|
|
1150
|
-
if (
|
|
1461
|
+
if (naturalWidth !== size.width) {
|
|
1151
1462
|
return {
|
|
1152
1463
|
error: i18nString(
|
|
1153
1464
|
UIStrings.actualWidthSpxOfSSDoesNotMatch,
|
|
1154
|
-
{PH1:
|
|
1465
|
+
{PH1: naturalWidth, PH2: resourceName, PH3: imageUrl, PH4: size.width}),
|
|
1155
1466
|
hasSquareSize,
|
|
1156
1467
|
};
|
|
1157
1468
|
}
|
|
1158
|
-
if (
|
|
1469
|
+
if (naturalHeight !== size.height) {
|
|
1159
1470
|
return {
|
|
1160
1471
|
error: i18nString(
|
|
1161
1472
|
UIStrings.actualHeightSpxOfSSDoesNotMatch,
|
|
1162
|
-
{PH1:
|
|
1473
|
+
{PH1: naturalHeight, PH2: resourceName, PH3: imageUrl, PH4: size.height}),
|
|
1163
1474
|
hasSquareSize,
|
|
1164
1475
|
};
|
|
1165
1476
|
}
|
|
1166
1477
|
return {hasSquareSize};
|
|
1167
1478
|
}
|
|
1168
1479
|
|
|
1169
|
-
private async
|
|
1170
|
-
|
|
1171
|
-
// eslint-disable-
|
|
1172
|
-
|
|
1173
|
-
isScreenshot: boolean): Promise<{
|
|
1174
|
-
imageResourceErrors: Platform.UIString.LocalizedString[],
|
|
1175
|
-
squareSizedIconAvailable?: boolean,
|
|
1176
|
-
naturalWidth?: number,
|
|
1177
|
-
naturalHeight?: number,
|
|
1178
|
-
}> {
|
|
1480
|
+
private async processImageResource(
|
|
1481
|
+
baseUrl: Platform.DevToolsPath.UrlString,
|
|
1482
|
+
imageResource: any, // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
1483
|
+
isScreenshot: boolean): Promise<ProcessedImageResource> {
|
|
1179
1484
|
const imageResourceErrors: Platform.UIString.LocalizedString[] = [];
|
|
1180
1485
|
const resourceName = isScreenshot ? i18nString(UIStrings.screenshot) : i18nString(UIStrings.icon);
|
|
1181
1486
|
if (!imageResource.src) {
|
|
@@ -1186,18 +1491,16 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1186
1491
|
if (!imageUrl) {
|
|
1187
1492
|
imageResourceErrors.push(
|
|
1188
1493
|
i18nString(UIStrings.sUrlSFailedToParse, {PH1: resourceName, PH2: imageResource['src']}));
|
|
1189
|
-
return {imageResourceErrors};
|
|
1494
|
+
return {imageResourceErrors, imageUrl: imageResource['src']};
|
|
1190
1495
|
}
|
|
1191
1496
|
const result = await this.loadImage(imageUrl);
|
|
1192
1497
|
if (!result) {
|
|
1193
1498
|
imageResourceErrors.push(i18nString(UIStrings.sSFailedToLoad, {PH1: resourceName, PH2: imageUrl}));
|
|
1194
|
-
return {imageResourceErrors};
|
|
1499
|
+
return {imageResourceErrors, imageUrl};
|
|
1195
1500
|
}
|
|
1196
|
-
const {
|
|
1197
|
-
const {naturalWidth, naturalHeight} = image;
|
|
1501
|
+
const {src, naturalWidth, naturalHeight} = result;
|
|
1198
1502
|
const sizes = this.parseSizes(imageResource['sizes'], resourceName, imageUrl, imageResourceErrors);
|
|
1199
1503
|
const title = sizes.map(x => x.formatted).join(' ') + '\n' + (imageResource['type'] || '');
|
|
1200
|
-
const field = section.appendFlexedField(title);
|
|
1201
1504
|
let squareSizedIconAvailable = false;
|
|
1202
1505
|
if (!imageResource.sizes) {
|
|
1203
1506
|
imageResourceErrors.push(i18nString(UIStrings.sSDoesNotSpecifyItsSizeInThe, {PH1: resourceName, PH2: imageUrl}));
|
|
@@ -1206,13 +1509,13 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1206
1509
|
imageResourceErrors.push(i18nString(UIStrings.screenshotPixelSize, {url: imageUrl}));
|
|
1207
1510
|
}
|
|
1208
1511
|
for (const size of sizes) {
|
|
1209
|
-
const {error, hasSquareSize} = this.checkSizeProblem(size,
|
|
1512
|
+
const {error, hasSquareSize} = this.checkSizeProblem(size, naturalWidth, naturalHeight, resourceName, imageUrl);
|
|
1210
1513
|
squareSizedIconAvailable = squareSizedIconAvailable || hasSquareSize;
|
|
1211
1514
|
if (error) {
|
|
1212
1515
|
imageResourceErrors.push(error);
|
|
1213
1516
|
} else if (isScreenshot) {
|
|
1214
|
-
const width = 'any' in size ?
|
|
1215
|
-
const height = 'any' in size ?
|
|
1517
|
+
const width = 'any' in size ? naturalWidth : size.width;
|
|
1518
|
+
const height = 'any' in size ? naturalHeight : size.height;
|
|
1216
1519
|
if (width < 320 || height < 320) {
|
|
1217
1520
|
imageResourceErrors.push(
|
|
1218
1521
|
i18nString(UIStrings.sSSizeShouldBeAtLeast320, {PH1: resourceName, PH2: imageUrl}));
|
|
@@ -1229,66 +1532,249 @@ export class AppManifestView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1229
1532
|
}
|
|
1230
1533
|
}
|
|
1231
1534
|
}
|
|
1232
|
-
image.width = image.naturalWidth;
|
|
1233
1535
|
|
|
1234
1536
|
const purpose = typeof imageResource['purpose'] === 'string' ? imageResource['purpose'].toLowerCase() : '';
|
|
1235
1537
|
if (purpose.includes('any') && purpose.includes('maskable')) {
|
|
1236
1538
|
imageResourceErrors.push(i18nString(UIStrings.avoidPurposeAnyAndMaskable));
|
|
1237
1539
|
}
|
|
1238
1540
|
|
|
1239
|
-
|
|
1240
|
-
|
|
1541
|
+
return {
|
|
1542
|
+
imageResourceErrors,
|
|
1543
|
+
squareSizedIconAvailable,
|
|
1544
|
+
naturalWidth,
|
|
1545
|
+
naturalHeight,
|
|
1546
|
+
title,
|
|
1547
|
+
imageSrc: src,
|
|
1548
|
+
imageUrl,
|
|
1549
|
+
};
|
|
1550
|
+
}
|
|
1551
|
+
|
|
1552
|
+
private async onToggleWcoToolbar(enabled: boolean): Promise<void> {
|
|
1553
|
+
this.wcoToolbarEnabled = enabled;
|
|
1554
|
+
if (this.overlayModel) {
|
|
1555
|
+
await this.overlayModel.toggleWindowControlsToolbar(this.wcoToolbarEnabled);
|
|
1556
|
+
}
|
|
1241
1557
|
}
|
|
1242
1558
|
|
|
1243
|
-
private async
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1559
|
+
private async onSelectOs(selectedOS: SDK.OverlayModel.EmulatedOSType, themeColor: string): Promise<void> {
|
|
1560
|
+
if (this.overlayModel) {
|
|
1561
|
+
this.overlayModel.setWindowControlsPlatform(selectedOS);
|
|
1562
|
+
this.overlayModel.setWindowControlsThemeColor(themeColor);
|
|
1563
|
+
await this.overlayModel.toggleWindowControlsToolbar(this.wcoToolbarEnabled);
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1247
1566
|
|
|
1248
|
-
|
|
1249
|
-
|
|
1567
|
+
private processIdentity(parsedManifest: Manifest, appId: string|null, recommendedId: string|null):
|
|
1568
|
+
IdentitySectionData {
|
|
1569
|
+
const description = this.stringProperty(parsedManifest, 'description');
|
|
1570
|
+
const warnings: Platform.UIString.LocalizedString[] = [];
|
|
1571
|
+
// See https://crbug.com/1354304 for details.
|
|
1572
|
+
if (description.length > 300) {
|
|
1573
|
+
warnings.push(i18nString(UIStrings.descriptionMayBeTruncated));
|
|
1250
1574
|
}
|
|
1575
|
+
return {
|
|
1576
|
+
name: this.stringProperty(parsedManifest, 'name'),
|
|
1577
|
+
shortName: this.stringProperty(parsedManifest, 'short_name'),
|
|
1578
|
+
description: this.stringProperty(parsedManifest, 'description'),
|
|
1579
|
+
appId,
|
|
1580
|
+
recommendedId,
|
|
1581
|
+
hasId: Boolean(this.stringProperty(parsedManifest, 'id')),
|
|
1582
|
+
warnings,
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
1251
1585
|
|
|
1252
|
-
|
|
1586
|
+
private async processIcons(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString):
|
|
1587
|
+
Promise<IconsSectionData> {
|
|
1588
|
+
const icons = parsedManifest['icons'] || [];
|
|
1589
|
+
const imageErrors: Platform.UIString.LocalizedString[] = [];
|
|
1590
|
+
const processedIcons: ProcessedImageResource[] = [];
|
|
1591
|
+
let squareSizedIconAvailable = false;
|
|
1253
1592
|
|
|
1254
|
-
const
|
|
1255
|
-
|
|
1593
|
+
for (const icon of icons) {
|
|
1594
|
+
const result = await this.processImageResource(url, icon, /** isScreenshot= */ false);
|
|
1595
|
+
processedIcons.push(result);
|
|
1596
|
+
imageErrors.push(...result.imageResourceErrors);
|
|
1256
1597
|
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1598
|
+
if (result.squareSizedIconAvailable) {
|
|
1599
|
+
squareSizedIconAvailable = true;
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1260
1602
|
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
osSelectElement.selectedIndex = 0;
|
|
1603
|
+
const processedIconsByTitle = Map.groupBy(
|
|
1604
|
+
processedIcons.filter((icon): icon is ProcessedImageResource&{title: string} => 'title' in icon),
|
|
1605
|
+
img => img.title,
|
|
1606
|
+
);
|
|
1266
1607
|
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1608
|
+
if (!squareSizedIconAvailable) {
|
|
1609
|
+
imageErrors.push(i18nString(UIStrings.sSShouldHaveSquareIcon));
|
|
1610
|
+
}
|
|
1611
|
+
return {icons: processedIconsByTitle, imageResourceErrors: imageErrors};
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
private async processShortcuts(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString):
|
|
1615
|
+
Promise<ShortcutsSectionData> {
|
|
1616
|
+
const shortcuts = parsedManifest['shortcuts'] || [];
|
|
1617
|
+
const processedShortcuts: ProcessedShortcut[] = [];
|
|
1618
|
+
|
|
1619
|
+
const warnings: Platform.UIString.LocalizedString[] = [];
|
|
1620
|
+
const imageErrors: Platform.UIString.LocalizedString[] = [];
|
|
1621
|
+
|
|
1622
|
+
if (shortcuts.length > 4) {
|
|
1623
|
+
warnings.push(i18nString(UIStrings.shortcutsMayBeNotAvailable));
|
|
1269
1624
|
}
|
|
1270
1625
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1626
|
+
let shortcutIndex = 1;
|
|
1627
|
+
for (const shortcut of shortcuts) {
|
|
1628
|
+
const shortcutUrl = Common.ParsedURL.ParsedURL.completeURL(url, shortcut.url) as Platform.DevToolsPath.UrlString;
|
|
1629
|
+
const shortcutIcons = shortcut.icons || [];
|
|
1630
|
+
const processedIcons: ProcessedImageResource[] = [];
|
|
1631
|
+
let hasShortcutIconLargeEnough = false;
|
|
1632
|
+
|
|
1633
|
+
for (const shortcutIcon of shortcutIcons) {
|
|
1634
|
+
const result = await this.processImageResource(url, shortcutIcon, /** isScreenshot= */ false);
|
|
1635
|
+
processedIcons.push(result);
|
|
1636
|
+
imageErrors.push(...result.imageResourceErrors);
|
|
1637
|
+
|
|
1638
|
+
if (!hasShortcutIconLargeEnough && shortcutIcon.sizes) {
|
|
1639
|
+
const shortcutIconSize = shortcutIcon.sizes.match(/^(\d+)x(\d+)$/);
|
|
1640
|
+
if (shortcutIconSize && Number(shortcutIconSize[1]) >= 96 && Number(shortcutIconSize[2]) >= 96) {
|
|
1641
|
+
hasShortcutIconLargeEnough = true;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1277
1644
|
}
|
|
1278
|
-
});
|
|
1279
1645
|
|
|
1280
|
-
|
|
1646
|
+
const iconsByTitle = Map.groupBy(
|
|
1647
|
+
processedIcons.filter(icon => 'title' in icon),
|
|
1648
|
+
img => img.title,
|
|
1649
|
+
);
|
|
1650
|
+
|
|
1651
|
+
processedShortcuts.push({
|
|
1652
|
+
name: shortcut.name,
|
|
1653
|
+
shortName: shortcut.short_name,
|
|
1654
|
+
description: shortcut.description,
|
|
1655
|
+
url: shortcut.url,
|
|
1656
|
+
shortcutUrl,
|
|
1657
|
+
icons: iconsByTitle,
|
|
1658
|
+
});
|
|
1659
|
+
|
|
1660
|
+
if (!hasShortcutIconLargeEnough) {
|
|
1661
|
+
imageErrors.push(i18nString(UIStrings.shortcutSShouldIncludeAXPixel, {PH1: shortcutIndex}));
|
|
1662
|
+
}
|
|
1663
|
+
shortcutIndex++;
|
|
1664
|
+
}
|
|
1665
|
+
return {shortcuts: processedShortcuts, warnings, imageResourceErrors: imageErrors};
|
|
1666
|
+
}
|
|
1667
|
+
|
|
1668
|
+
private async processScreenshots(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString):
|
|
1669
|
+
Promise<ScreenshotsSectionData> {
|
|
1670
|
+
const screenshots: Screenshot[] = parsedManifest['screenshots'] || [];
|
|
1671
|
+
const processedScreenshots: ProcessedScreenshot[] = [];
|
|
1672
|
+
|
|
1673
|
+
const warnings: Platform.UIString.LocalizedString[] = [];
|
|
1674
|
+
const imageErrors: Platform.UIString.LocalizedString[] = [];
|
|
1675
|
+
|
|
1676
|
+
let haveScreenshotsDifferentAspectRatio = false;
|
|
1677
|
+
const formFactorScreenshotDimensions = new Map<string, {width: number, height: number}>();
|
|
1678
|
+
for (const screenshot of screenshots) {
|
|
1679
|
+
const result = await this.processImageResource(url, screenshot, /** isScreenshot= */ true);
|
|
1680
|
+
processedScreenshots.push({screenshot, processedImage: result});
|
|
1681
|
+
imageErrors.push(...result.imageResourceErrors);
|
|
1682
|
+
|
|
1683
|
+
if (screenshot.form_factor && 'naturalWidth' in result) {
|
|
1684
|
+
const width = result.naturalWidth;
|
|
1685
|
+
const height = result.naturalHeight;
|
|
1686
|
+
formFactorScreenshotDimensions.has(screenshot.form_factor) ||
|
|
1687
|
+
formFactorScreenshotDimensions.set(screenshot.form_factor, {width, height});
|
|
1688
|
+
const formFactorFirstScreenshotDimensions = formFactorScreenshotDimensions.get(screenshot.form_factor);
|
|
1689
|
+
if (formFactorFirstScreenshotDimensions) {
|
|
1690
|
+
haveScreenshotsDifferentAspectRatio = haveScreenshotsDifferentAspectRatio ||
|
|
1691
|
+
(width * formFactorFirstScreenshotDimensions.height !==
|
|
1692
|
+
height * formFactorFirstScreenshotDimensions.width);
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
if (haveScreenshotsDifferentAspectRatio) {
|
|
1698
|
+
warnings.push(i18nString(UIStrings.screenshotsMustHaveSameAspectRatio));
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
const screenshotsForDesktop = screenshots.filter(screenshot => screenshot.form_factor === 'wide');
|
|
1702
|
+
const screenshotsForMobile = screenshots.filter(screenshot => screenshot.form_factor !== 'wide');
|
|
1703
|
+
|
|
1704
|
+
if (screenshotsForDesktop.length < 1) {
|
|
1705
|
+
warnings.push(i18nString(UIStrings.noScreenshotsForRicherPWAInstallOnDesktop));
|
|
1706
|
+
}
|
|
1707
|
+
if (screenshotsForMobile.length < 1) {
|
|
1708
|
+
warnings.push(i18nString(UIStrings.noScreenshotsForRicherPWAInstallOnMobile));
|
|
1709
|
+
}
|
|
1710
|
+
if (screenshotsForDesktop.length > 8) {
|
|
1711
|
+
warnings.push(i18nString(UIStrings.tooManyScreenshotsForDesktop));
|
|
1712
|
+
}
|
|
1713
|
+
if (screenshotsForMobile.length > 5) {
|
|
1714
|
+
warnings.push(i18nString(UIStrings.tooManyScreenshotsForMobile));
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
return {screenshots: processedScreenshots, warnings, imageResourceErrors: imageErrors};
|
|
1718
|
+
}
|
|
1719
|
+
|
|
1720
|
+
private async processWindowControls(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString):
|
|
1721
|
+
Promise<WindowControlsSectionData> {
|
|
1722
|
+
const displayOverride = parsedManifest['display_override'] || [];
|
|
1723
|
+
const hasWco = displayOverride.includes('window-controls-overlay');
|
|
1724
|
+
const themeColor = this.stringProperty(parsedManifest, 'theme_color');
|
|
1725
|
+
let wcoStyleSheetText = false;
|
|
1726
|
+
if (this.overlayModel) {
|
|
1727
|
+
wcoStyleSheetText = await this.overlayModel.hasStyleSheetText(url);
|
|
1728
|
+
}
|
|
1729
|
+
return {
|
|
1730
|
+
hasWco,
|
|
1731
|
+
themeColor,
|
|
1732
|
+
wcoStyleSheetText,
|
|
1733
|
+
url,
|
|
1734
|
+
};
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1737
|
+
private processPresentation(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString): PresentationSectionData {
|
|
1738
|
+
const startURL = this.stringProperty(parsedManifest, 'start_url');
|
|
1739
|
+
const completeURL = startURL ? Common.ParsedURL.ParsedURL.completeURL(url, startURL) : null;
|
|
1740
|
+
const themeColorString = this.stringProperty(parsedManifest, 'theme_color');
|
|
1741
|
+
const themeColor = themeColorString ? Common.Color.parse(themeColorString) ?? Common.Color.parse('white') : null;
|
|
1742
|
+
const backgroundColorString = this.stringProperty(parsedManifest, 'background_color');
|
|
1743
|
+
const backgroundColor =
|
|
1744
|
+
backgroundColorString ? Common.Color.parse(backgroundColorString) ?? Common.Color.parse('white') : null;
|
|
1745
|
+
const noteTaking = parsedManifest['note_taking'] || {};
|
|
1746
|
+
const newNoteUrl = noteTaking['new_note_url'];
|
|
1747
|
+
const hasNewNoteUrl = typeof newNoteUrl === 'string';
|
|
1748
|
+
const completeNewNoteUrl = hasNewNoteUrl ?
|
|
1749
|
+
(Common.ParsedURL.ParsedURL.completeURL(url, newNoteUrl) as Platform.DevToolsPath.UrlString) :
|
|
1750
|
+
null;
|
|
1751
|
+
|
|
1752
|
+
return {
|
|
1753
|
+
startUrl: startURL,
|
|
1754
|
+
completeStartUrl: completeURL,
|
|
1755
|
+
themeColor,
|
|
1756
|
+
backgroundColor,
|
|
1757
|
+
orientation: this.stringProperty(parsedManifest, 'orientation'),
|
|
1758
|
+
display: this.stringProperty(parsedManifest, 'display'),
|
|
1759
|
+
newNoteUrl,
|
|
1760
|
+
hasNewNoteUrl,
|
|
1761
|
+
completeNewNoteUrl,
|
|
1762
|
+
};
|
|
1763
|
+
}
|
|
1281
1764
|
|
|
1282
|
-
|
|
1765
|
+
private processProtocolHandlers(parsedManifest: Manifest, url: Platform.DevToolsPath.UrlString):
|
|
1766
|
+
ProtocolHandlersSectionData {
|
|
1767
|
+
return {
|
|
1768
|
+
protocolHandlers: parsedManifest['protocol_handlers'] || [],
|
|
1769
|
+
manifestLink: url,
|
|
1770
|
+
};
|
|
1283
1771
|
}
|
|
1284
1772
|
}
|
|
1285
1773
|
|
|
1286
1774
|
export const enum Events {
|
|
1287
1775
|
MANIFEST_DETECTED = 'ManifestDetected',
|
|
1288
|
-
MANIFEST_RENDERED = 'ManifestRendered',
|
|
1289
1776
|
}
|
|
1290
1777
|
|
|
1291
1778
|
export interface EventTypes {
|
|
1292
1779
|
[Events.MANIFEST_DETECTED]: boolean;
|
|
1293
|
-
[Events.MANIFEST_RENDERED]: void;
|
|
1294
1780
|
}
|