| File: | Source/WebKit/WebProcess/WebPage/WebPage.cpp |
| Warning: | line 9340, column 15 Local variable 'cachedImage' is uncounted and unsafe |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* |
| 2 | * Copyright (C) 2010-2025 Apple Inc. All rights reserved. |
| 3 | * Copyright (C) 2012 Intel Corporation. All rights reserved. |
| 4 | * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: |
| 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer. |
| 11 | * 2. Redistributions in binary form must reproduce the above copyright |
| 12 | * notice, this list of conditions and the following disclaimer in the |
| 13 | * documentation and/or other materials provided with the distribution. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| 16 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 17 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 18 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 19 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 20 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 21 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 22 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 23 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 24 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 25 | * THE POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | |
| 28 | #include "config.h" |
| 29 | #include "WebPage.h" |
| 30 | |
| 31 | #include "APIArray.h" |
| 32 | #include "APIGeometry.h" |
| 33 | #include "APIInjectedBundleEditorClient.h" |
| 34 | #include "APIInjectedBundleFormClient.h" |
| 35 | #include "APIInjectedBundlePageContextMenuClient.h" |
| 36 | #include "APIInjectedBundlePageLoaderClient.h" |
| 37 | #include "APIInjectedBundlePageResourceLoadClient.h" |
| 38 | #include "APIInjectedBundlePageUIClient.h" |
| 39 | #include "Connection.h" |
| 40 | #include "ContentAsStringIncludesChildFrames.h" |
| 41 | #include "DragControllerAction.h" |
| 42 | #include "DragEventForwardingData.h" |
| 43 | #include "DrawingArea.h" |
| 44 | #include "DrawingAreaMessages.h" |
| 45 | #include "EditorState.h" |
| 46 | #include "EventDispatcher.h" |
| 47 | #include "FindController.h" |
| 48 | #include "FocusedElementInformation.h" |
| 49 | #include "FormDataReference.h" |
| 50 | #include "FrameTreeNodeData.h" |
| 51 | #include "GeolocationPermissionRequestManager.h" |
| 52 | #include "GoToBackForwardItemParameters.h" |
| 53 | #include "ImageOptions.h" |
| 54 | #include "InjectUserScriptImmediately.h" |
| 55 | #include "InjectedBundle.h" |
| 56 | #include "InjectedBundleHitTestResult.h" |
| 57 | #include "InjectedBundleScriptWorld.h" |
| 58 | #include "JavaScriptEvaluationResult.h" |
| 59 | #include "LibWebRTCCodecs.h" |
| 60 | #include "LibWebRTCProvider.h" |
| 61 | #include "LoadParameters.h" |
| 62 | #include "Logging.h" |
| 63 | #include "MediaKeySystemPermissionRequestManager.h" |
| 64 | #include "MediaPlaybackState.h" |
| 65 | #include "MessageSenderInlines.h" |
| 66 | #include "NetworkConnectionToWebProcessMessages.h" |
| 67 | #include "NetworkProcessConnection.h" |
| 68 | #include "NodeHitTestResult.h" |
| 69 | #include "NotificationPermissionRequestManager.h" |
| 70 | #include "PageBanner.h" |
| 71 | #include "PageInspectorTarget.h" |
| 72 | #include "PlaybackSessionContextIdentifier.h" |
| 73 | #include "PluginView.h" |
| 74 | #include "PolicyDecision.h" |
| 75 | #include "PrintInfo.h" |
| 76 | #include "ProvisionalFrameCreationParameters.h" |
| 77 | #include "RemoteRenderingBackendProxy.h" |
| 78 | #include "RemoteScrollingCoordinator.h" |
| 79 | #include "RemoteSnapshotRecorderProxy.h" |
| 80 | #include "RemoteWebInspectorUI.h" |
| 81 | #include "RemoteWebInspectorUIMessages.h" |
| 82 | #include "RunJavaScriptParameters.h" |
| 83 | #include "SessionState.h" |
| 84 | #include "SessionStateConversion.h" |
| 85 | #include "ShareableBitmapUtilities.h" |
| 86 | #include "SharedBufferReference.h" |
| 87 | #include "TextRecognitionUpdateResult.h" |
| 88 | #include "UserMediaPermissionRequestManager.h" |
| 89 | #include "ViewGestureGeometryCollector.h" |
| 90 | #include "VisitedLinkTableController.h" |
| 91 | #include "WKBundleAPICast.h" |
| 92 | #include "WKRetainPtr.h" |
| 93 | #include "WKSharedAPICast.h" |
| 94 | #include "WebAlternativeTextClient.h" |
| 95 | #include "WebAttachmentElementClient.h" |
| 96 | #include "WebBackForwardListItem.h" |
| 97 | #include "WebBackForwardListProxy.h" |
| 98 | #include "WebBadgeClient.h" |
| 99 | #include "WebBroadcastChannelRegistry.h" |
| 100 | #include "WebCacheStorageProvider.h" |
| 101 | #include "WebChromeClient.h" |
| 102 | #include "WebColorChooser.h" |
| 103 | #include "WebContextMenu.h" |
| 104 | #include "WebContextMenuClient.h" |
| 105 | #include "WebCookieJar.h" |
| 106 | #include "WebCryptoClient.h" |
| 107 | #include "WebDataListSuggestionPicker.h" |
| 108 | #include "WebDatabaseProvider.h" |
| 109 | #include "WebDateTimeChooser.h" |
| 110 | #include "WebDiagnosticLoggingClient.h" |
| 111 | #include "WebDocumentSyncClient.h" |
| 112 | #include "WebDragClient.h" |
| 113 | #include "WebEditorClient.h" |
| 114 | #include "WebErrors.h" |
| 115 | #include "WebEventConversion.h" |
| 116 | #include "WebEventFactory.h" |
| 117 | #include "WebFoundTextRange.h" |
| 118 | #include "WebFoundTextRangeController.h" |
| 119 | #include "WebFrame.h" |
| 120 | #include "WebFrameMetrics.h" |
| 121 | #include "WebFullScreenManager.h" |
| 122 | #include "WebFullScreenManagerMessages.h" |
| 123 | #include "WebFullScreenManagerProxyMessages.h" |
| 124 | #include "WebGamepadProvider.h" |
| 125 | #include "WebGeolocationClient.h" |
| 126 | #include "WebHistoryItemClient.h" |
| 127 | #include "WebHitTestResultData.h" |
| 128 | #include "WebImage.h" |
| 129 | #include "WebInspectorBackend.h" |
| 130 | #include "WebInspectorBackendClient.h" |
| 131 | #include "WebInspectorBackendMessages.h" |
| 132 | #include "WebInspectorUI.h" |
| 133 | #include "WebInspectorUIMessages.h" |
| 134 | #include "WebKeyboardEvent.h" |
| 135 | #include "WebLoaderStrategy.h" |
| 136 | #include "WebLocalFrameLoaderClient.h" |
| 137 | #include "WebMediaKeyStorageManager.h" |
| 138 | #include "WebMediaKeySystemClient.h" |
| 139 | #include "WebMediaStrategy.h" |
| 140 | #include "WebModelPlayerProvider.h" |
| 141 | #include "WebMouseEvent.h" |
| 142 | #include "WebNotificationClient.h" |
| 143 | #include "WebOpenPanelResultListener.h" |
| 144 | #include "WebPageCreationParameters.h" |
| 145 | #include "WebPageGroupProxy.h" |
| 146 | #include "WebPageInlines.h" |
| 147 | #include "WebPageInternals.h" |
| 148 | #include "WebPageMessages.h" |
| 149 | #include "WebPageOverlay.h" |
| 150 | #include "WebPageProxyMessages.h" |
| 151 | #include "WebPageTesting.h" |
| 152 | #include "WebPaymentCoordinator.h" |
| 153 | #include "WebPerformanceLoggingClient.h" |
| 154 | #include "WebPluginInfoProvider.h" |
| 155 | #include "WebPopupMenu.h" |
| 156 | #include "WebPreferencesDefinitions.h" |
| 157 | #include "WebPreferencesKeys.h" |
| 158 | #include "WebPreferencesStore.h" |
| 159 | #include "WebProcess.h" |
| 160 | #include "WebProcessPoolMessages.h" |
| 161 | #include "WebProcessProxyMessages.h" |
| 162 | #include "WebProgressTrackerClient.h" |
| 163 | #include "WebRemoteFrameClient.h" |
| 164 | #include "WebScreenOrientationManager.h" |
| 165 | #include "WebServiceWorkerProvider.h" |
| 166 | #include "WebSocketProvider.h" |
| 167 | #include "WebSpeechRecognitionProvider.h" |
| 168 | #include "WebSpeechSynthesisClient.h" |
| 169 | #include "WebStorageNamespaceProvider.h" |
| 170 | #include "WebStorageProvider.h" |
| 171 | #include "WebTouchEvent.h" |
| 172 | #include "WebURLSchemeHandlerProxy.h" |
| 173 | #include "WebUndoStep.h" |
| 174 | #include "WebUserContentController.h" |
| 175 | #include "WebUserMediaClient.h" |
| 176 | #include "WebValidationMessageClient.h" |
| 177 | #include "WebWheelEvent.h" |
| 178 | #include "WebsiteDataStoreParameters.h" |
| 179 | #include "WebsitePoliciesData.h" |
| 180 | #include <JavaScriptCore/APICast.h> |
| 181 | #include <JavaScriptCore/JSCInlines.h> |
| 182 | #include <JavaScriptCore/JSCJSValue.h> |
| 183 | #include <JavaScriptCore/JSLock.h> |
| 184 | #include <JavaScriptCore/ProfilerDatabase.h> |
| 185 | #include <JavaScriptCore/SamplingProfiler.h> |
| 186 | #include <WebCore/AXObjectCache.h> |
| 187 | #include <WebCore/AnimationTimelinesController.h> |
| 188 | #include <WebCore/AppHighlight.h> |
| 189 | #include <WebCore/ArchiveResource.h> |
| 190 | #include <WebCore/BackForwardCache.h> |
| 191 | #include <WebCore/BackForwardController.h> |
| 192 | #include <WebCore/BitmapImage.h> |
| 193 | #include <WebCore/CachedPage.h> |
| 194 | #include <WebCore/CaptionUserPreferences.h> |
| 195 | #include <WebCore/Chrome.h> |
| 196 | #include <WebCore/CommonVM.h> |
| 197 | #include <WebCore/ContactsRequestData.h> |
| 198 | #include <WebCore/ContainerNodeInlines.h> |
| 199 | #include <WebCore/ContextMenuController.h> |
| 200 | #include <WebCore/CrossOriginEmbedderPolicy.h> |
| 201 | #include <WebCore/CrossOriginOpenerPolicy.h> |
| 202 | #include <WebCore/DOMPasteAccess.h> |
| 203 | #include <WebCore/DataTransfer.h> |
| 204 | #include <WebCore/DatabaseManager.h> |
| 205 | #include <WebCore/DeprecatedGlobalSettings.h> |
| 206 | #include <WebCore/DisplayListRecorderImpl.h> |
| 207 | #include <WebCore/Document.h> |
| 208 | #include <WebCore/DocumentFragment.h> |
| 209 | #include <WebCore/DocumentFullscreen.h> |
| 210 | #include <WebCore/DocumentImmersive.h> |
| 211 | #include <WebCore/DocumentInlines.h> |
| 212 | #include <WebCore/DocumentLoader.h> |
| 213 | #include <WebCore/DocumentMarkerController.h> |
| 214 | #include <WebCore/DocumentMarkers.h> |
| 215 | #include <WebCore/DocumentPage.h> |
| 216 | #include <WebCore/DocumentQuirks.h> |
| 217 | #include <WebCore/DocumentStorageAccess.h> |
| 218 | #include <WebCore/DocumentView.h> |
| 219 | #include <WebCore/DragController.h> |
| 220 | #include <WebCore/DragData.h> |
| 221 | #include <WebCore/DragEventTargetData.h> |
| 222 | #include <WebCore/Editing.h> |
| 223 | #include <WebCore/Editor.h> |
| 224 | #include <WebCore/ElementAncestorIteratorInlines.h> |
| 225 | #include <WebCore/ElementTargetingController.h> |
| 226 | #include <WebCore/EventHandler.h> |
| 227 | #include <WebCore/EventNames.h> |
| 228 | #include <WebCore/ExceptionCode.h> |
| 229 | #include <WebCore/File.h> |
| 230 | #include <WebCore/FocusController.h> |
| 231 | #include <WebCore/FocusControllerTypes.h> |
| 232 | #include <WebCore/FocusOptions.h> |
| 233 | #include <WebCore/FontAttributeChanges.h> |
| 234 | #include <WebCore/FontAttributes.h> |
| 235 | #include <WebCore/FormState.h> |
| 236 | #include <WebCore/FragmentDirectiveParser.h> |
| 237 | #include <WebCore/FragmentDirectiveRangeFinder.h> |
| 238 | #include <WebCore/FragmentDirectiveUtilities.h> |
| 239 | #include <WebCore/FrameDestructionObserverInlines.h> |
| 240 | #include <WebCore/FrameInlines.h> |
| 241 | #include <WebCore/FrameInspectorController.h> |
| 242 | #include <WebCore/FrameLoadRequest.h> |
| 243 | #include <WebCore/FrameLoaderTypes.h> |
| 244 | #include <WebCore/GeometryUtilities.h> |
| 245 | #include <WebCore/HTMLAttachmentElement.h> |
| 246 | #include <WebCore/HTMLBodyElement.h> |
| 247 | #include <WebCore/HTMLFormElement.h> |
| 248 | #include <WebCore/HTMLImageElement.h> |
| 249 | #include <WebCore/HTMLInputElement.h> |
| 250 | #include <WebCore/HTMLModelElement.h> |
| 251 | #include <WebCore/HTMLPlugInElement.h> |
| 252 | #include <WebCore/HTMLSelectElement.h> |
| 253 | #include <WebCore/HTMLTextAreaElement.h> |
| 254 | #include <WebCore/HTMLTextFormControlElement.h> |
| 255 | #include <WebCore/HTTPParsers.h> |
| 256 | #include <WebCore/HTTPStatusCodes.h> |
| 257 | #include <WebCore/HandleUserInputEventResult.h> |
| 258 | #include <WebCore/Highlight.h> |
| 259 | #include <WebCore/HighlightRegistry.h> |
| 260 | #include <WebCore/HistoryController.h> |
| 261 | #include <WebCore/HistoryItem.h> |
| 262 | #include <WebCore/HitTestResult.h> |
| 263 | #include <WebCore/ImageAnalysisQueue.h> |
| 264 | #include <WebCore/ImageOverlay.h> |
| 265 | #include <WebCore/ImageUtilities.h> |
| 266 | #include <WebCore/JSDOMExceptionHandling.h> |
| 267 | #include <WebCore/JSNode.h> |
| 268 | #include <WebCore/KeyboardEvent.h> |
| 269 | #include <WebCore/LegacySchemeRegistry.h> |
| 270 | #include <WebCore/LocalFrameInlines.h> |
| 271 | #include <WebCore/LocalFrameView.h> |
| 272 | #include <WebCore/LocalizedStrings.h> |
| 273 | #include <WebCore/LoginStatus.h> |
| 274 | #include <WebCore/MIMETypeRegistry.h> |
| 275 | #include <WebCore/MediaDocument.h> |
| 276 | #include <WebCore/MediaPlayer.h> |
| 277 | #include <WebCore/MouseEvent.h> |
| 278 | #include <WebCore/NavigationScheduler.h> |
| 279 | #include <WebCore/NotImplemented.h> |
| 280 | #include <WebCore/NotificationController.h> |
| 281 | #include <WebCore/OriginAccessPatterns.h> |
| 282 | #include <WebCore/Page.h> |
| 283 | #include <WebCore/PageConfiguration.h> |
| 284 | #include <WebCore/PageGroup.h> |
| 285 | #include <WebCore/PageInspectorController.h> |
| 286 | #include <WebCore/PingLoader.h> |
| 287 | #include <WebCore/PlatformKeyboardEvent.h> |
| 288 | #include <WebCore/PlatformMediaSessionManager.h> |
| 289 | #include <WebCore/PlatformMouseEvent.h> |
| 290 | #include <WebCore/PlatformStrategies.h> |
| 291 | #include <WebCore/PluginDocument.h> |
| 292 | #include <WebCore/PointerCaptureController.h> |
| 293 | #include <WebCore/PopupMenuClient.h> |
| 294 | #include <WebCore/PrintContext.h> |
| 295 | #include <WebCore/ProcessCapabilities.h> |
| 296 | #include <WebCore/PromisedAttachmentInfo.h> |
| 297 | #include <WebCore/Quirks.h> |
| 298 | #include <WebCore/Range.h> |
| 299 | #include <WebCore/RegistrableDomain.h> |
| 300 | #include <WebCore/RemoteDOMWindow.h> |
| 301 | #include <WebCore/RemoteFrame.h> |
| 302 | #include <WebCore/RemoteFrameClient.h> |
| 303 | #include <WebCore/RemoteFrameGeometryTransformer.h> |
| 304 | #include <WebCore/RemoteFrameView.h> |
| 305 | #include <WebCore/RemoteUserInputEventData.h> |
| 306 | #include <WebCore/RenderImage.h> |
| 307 | #include <WebCore/RenderLayer.h> |
| 308 | #include <WebCore/RenderLayerCompositor.h> |
| 309 | #include <WebCore/RenderTheme.h> |
| 310 | #include <WebCore/RenderTreeAsText.h> |
| 311 | #include <WebCore/RenderVideoInlines.h> |
| 312 | #include <WebCore/RenderView.h> |
| 313 | #include <WebCore/Report.h> |
| 314 | #include <WebCore/ReportingScope.h> |
| 315 | #include <WebCore/ResourceLoadStatistics.h> |
| 316 | #include <WebCore/ResourceRequest.h> |
| 317 | #include <WebCore/ResourceResponse.h> |
| 318 | #include <WebCore/RunJavaScriptParameters.h> |
| 319 | #include <WebCore/SWClientConnection.h> |
| 320 | #include <WebCore/ScriptController.h> |
| 321 | #include <WebCore/ScriptDisallowedScope.h> |
| 322 | #include <WebCore/SecurityPolicy.h> |
| 323 | #include <WebCore/SelectionRestorationMode.h> |
| 324 | #include <WebCore/SerializedScriptValue.h> |
| 325 | #include <WebCore/Settings.h> |
| 326 | #include <WebCore/ShadowRoot.h> |
| 327 | #include <WebCore/ShareableBitmap.h> |
| 328 | #include <WebCore/SharedBuffer.h> |
| 329 | #include <WebCore/StaticRange.h> |
| 330 | #include <WebCore/StyleProperties.h> |
| 331 | #include <WebCore/SubframeLoader.h> |
| 332 | #include <WebCore/SubresourceLoader.h> |
| 333 | #include <WebCore/SubstituteData.h> |
| 334 | #include <WebCore/SystemPreviewInfo.h> |
| 335 | #include <WebCore/TextExtraction.h> |
| 336 | #include <WebCore/TextIterator.h> |
| 337 | #include <WebCore/TextManipulationController.h> |
| 338 | #include <WebCore/TextRecognitionOptions.h> |
| 339 | #include <WebCore/TranslationContextMenuInfo.h> |
| 340 | #include <WebCore/UserContentURLPattern.h> |
| 341 | #include <WebCore/UserGestureIndicator.h> |
| 342 | #include <WebCore/UserScript.h> |
| 343 | #include <WebCore/UserStyleSheet.h> |
| 344 | #include <WebCore/UserTypingGestureIndicator.h> |
| 345 | #include <WebCore/ViolationReportType.h> |
| 346 | #include <WebCore/VisiblePosition.h> |
| 347 | #include <WebCore/VisibleUnits.h> |
| 348 | #include <WebCore/WebKitJSHandle.h> |
| 349 | #include <WebCore/WritingDirection.h> |
| 350 | #include <WebCore/markup.h> |
| 351 | #include <algorithm> |
| 352 | #include <pal/SessionID.h> |
| 353 | #include <ranges> |
| 354 | #include <wtf/CoroutineUtilities.h> |
| 355 | #include <wtf/ProcessID.h> |
| 356 | #include <wtf/RunLoop.h> |
| 357 | #include <wtf/Scope.h> |
| 358 | #include <wtf/SetForScope.h> |
| 359 | #include <wtf/SystemTracing.h> |
| 360 | #include <wtf/text/MakeString.h> |
| 361 | #include <wtf/text/TextStream.h> |
| 362 | |
| 363 | #if ENABLE(APP_HIGHLIGHTS)(defined 1 && 1) |
| 364 | #include <WebCore/AppHighlightStorage.h> |
| 365 | #endif |
| 366 | |
| 367 | #if ENABLE(DATA_DETECTION)(defined 1 && 1) |
| 368 | #include "DataDetectionResult.h" |
| 369 | #endif |
| 370 | |
| 371 | #if ENABLE(MHTML)(defined 0 && 0) |
| 372 | #include <WebCore/MHTMLArchive.h> |
| 373 | #endif |
| 374 | |
| 375 | #if ENABLE(POINTER_LOCK)(defined 1 && 1) |
| 376 | #include <WebCore/PointerLockController.h> |
| 377 | #endif |
| 378 | |
| 379 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 380 | #include "DefaultWebBrowserChecks.h" |
| 381 | #include "InsertTextOptions.h" |
| 382 | #include "PlaybackSessionManager.h" |
| 383 | #include "RemoteLayerTreeDrawingArea.h" |
| 384 | #include "RemoteObjectRegistryMessages.h" |
| 385 | #include "TextAnimationController.h" |
| 386 | #include "TextCheckingControllerProxy.h" |
| 387 | #include "VideoPresentationManager.h" |
| 388 | #include "WKStringCF.h" |
| 389 | #include "WebRemoteObjectRegistry.h" |
| 390 | #include <WebCore/LegacyWebArchive.h> |
| 391 | #include <WebCore/VP9UtilitiesCocoa.h> |
| 392 | #include <pal/spi/cg/ImageIOSPI.h> |
| 393 | #include <wtf/MachSendRight.h> |
| 394 | #include <wtf/cocoa/RuntimeApplicationChecksCocoa.h> |
| 395 | #include <wtf/spi/darwin/SandboxSPI.h> |
| 396 | #endif |
| 397 | |
| 398 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 399 | #include "WebPrintOperationGtk.h" |
| 400 | #include <WebCore/SelectionData.h> |
| 401 | #include <gtk/gtk.h> |
| 402 | #endif |
| 403 | |
| 404 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 405 | #include "InteractionInformationAtPosition.h" |
| 406 | #include "InteractionInformationRequest.h" |
| 407 | #include "WebAutocorrectionContext.h" |
| 408 | #include <CoreGraphics/CoreGraphics.h> |
| 409 | #include <WebCore/Icon.h> |
| 410 | #include <pal/spi/cf/CoreTextSPI.h> |
| 411 | #endif |
| 412 | |
| 413 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 414 | #include <WebCore/LocalDefaultSystemAppearance.h> |
| 415 | #include <pal/spi/cf/CFUtilitiesSPI.h> |
| 416 | #endif |
| 417 | |
| 418 | #if ENABLE(DATA_DETECTION)(defined 1 && 1) |
| 419 | #include <WebCore/DataDetection.h> |
| 420 | #include <WebCore/DataDetectionResultsStorage.h> |
| 421 | #endif |
| 422 | |
| 423 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) && USE(GSTREAMER)(defined USE_GSTREAMER && USE_GSTREAMER) |
| 424 | #include <WebCore/MockRealtimeMediaSourceCenter.h> |
| 425 | #endif |
| 426 | |
| 427 | #if ENABLE(WEB_AUTHN)(defined 1 && 1) |
| 428 | #include "DigitalCredentialsCoordinator.h" |
| 429 | #include "WebAuthenticatorCoordinator.h" |
| 430 | #include <WebCore/AuthenticatorCoordinator.h> |
| 431 | #include <WebCore/DigitalCredentialsRequestData.h> |
| 432 | #include <WebCore/DigitalCredentialsResponseData.h> |
| 433 | #include <WebCore/ExceptionData.h> |
| 434 | #endif // ENABLE(WEB_AUTHN) |
| 435 | |
| 436 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) && ENABLE(DEVICE_ORIENTATION)(defined 1 && 1) |
| 437 | #include "WebDeviceOrientationUpdateProvider.h" |
| 438 | #endif |
| 439 | |
| 440 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 441 | #include "RemoteMediaPlayerManager.h" |
| 442 | #if ENABLE(ENCRYPTED_MEDIA)(defined 1 && 1) |
| 443 | #include "RemoteCDMFactory.h" |
| 444 | #endif |
| 445 | #if ENABLE(LEGACY_ENCRYPTED_MEDIA)(defined 1 && 1) |
| 446 | #include "RemoteLegacyCDMFactory.h" |
| 447 | #endif |
| 448 | #if HAVE(AVASSETREADER)(defined 1 && 1) |
| 449 | #include "RemoteImageDecoderAVFManager.h" |
| 450 | #endif |
| 451 | #endif |
| 452 | |
| 453 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) |
| 454 | #include <WebCore/TextRecognitionResult.h> |
| 455 | #endif |
| 456 | |
| 457 | #if ENABLE(MEDIA_SESSION_COORDINATOR)(defined ENABLE_MEDIA_SESSION_COORDINATOR && ENABLE_MEDIA_SESSION_COORDINATOR ) |
| 458 | #include "RemoteMediaSessionCoordinator.h" |
| 459 | #include <WebCore/MediaSessionCoordinator.h> |
| 460 | #include <WebCore/NavigatorMediaSession.h> |
| 461 | #endif |
| 462 | |
| 463 | #if ENABLE(ARKIT_INLINE_PREVIEW_IOS)(defined 0 && 0) |
| 464 | #include "ARKitInlinePreviewModelPlayerIOS.h" |
| 465 | #endif |
| 466 | |
| 467 | #if PLATFORM(IOS)(defined 1 && 1) || PLATFORM(VISION)(defined WTF_PLATFORM_VISION && WTF_PLATFORM_VISION) |
| 468 | #include "WebPreferencesDefaultValuesIOS.h" |
| 469 | #endif |
| 470 | |
| 471 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 472 | #include "ModelProcessConnection.h" |
| 473 | #endif |
| 474 | |
| 475 | #if USE(SKIA)(defined USE_SKIA && USE_SKIA) |
| 476 | #include <WebCore/FontRenderOptions.h> |
| 477 | #endif |
| 478 | |
| 479 | #if USE(CG)(defined 1 && 1) |
| 480 | // FIXME: Move the CG-specific PDF painting code out of WebPage.cpp. |
| 481 | #include <WebCore/GraphicsContextCG.h> |
| 482 | #endif |
| 483 | |
| 484 | #if ENABLE(LOCKDOWN_MODE_API)(defined 1 && 1) |
| 485 | #import <pal/spi/cg/CoreGraphicsSPI.h> |
| 486 | #endif |
| 487 | |
| 488 | #if ENABLE(WK_WEB_EXTENSIONS)(defined 1 && 1) && PLATFORM(COCOA)(defined 1 && 1) |
| 489 | #include "WebExtensionControllerProxy.h" |
| 490 | #endif |
| 491 | |
| 492 | #if ENABLE(WEBXR)(defined 0 && 0) |
| 493 | #include "PlatformXRSystemProxy.h" |
| 494 | #endif |
| 495 | |
| 496 | #if ENABLE(PDF_HUD)(defined ENABLE_PDF_HUD && ENABLE_PDF_HUD) |
| 497 | #include "PDFPluginBase.h" |
| 498 | #endif |
| 499 | |
| 500 | #if HAVE(AUDIT_TOKEN)(defined 1 && 1) |
| 501 | #include "CoreIPCAuditToken.h" |
| 502 | #endif |
| 503 | |
| 504 | #if ENABLE(VIDEO)(defined 1 && 1) || ENABLE(WEB_AUDIO)(defined 1 && 1) |
| 505 | #include "RemoteMediaSessionManager.h" |
| 506 | #endif |
| 507 | |
| 508 | #if __has_include(<WebKitAdditions/WebPreferencesDefaultValuesAdditions.h>) |
| 509 | #include <WebKitAdditions/WebPreferencesDefaultValuesAdditions.h> |
| 510 | #endif |
| 511 | |
| 512 | namespace WebKit { |
| 513 | using namespace JSC; |
| 514 | using namespace WebCore; |
| 515 | |
| 516 | static const Seconds pageScrollHysteresisDuration { 300_ms }; |
| 517 | static const Seconds initialLayerVolatilityTimerInterval { 20_ms }; |
| 518 | static const Seconds maximumLayerVolatilityTimerInterval { 2_s }; |
| 519 | |
| 520 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 521 | static constexpr Seconds updateFocusedElementInformationDebounceInterval { 100_ms }; |
| 522 | static constexpr Seconds updateLayoutViewportHeightExpansionTimerInterval { 200_ms }; |
| 523 | #endif |
| 524 | |
| 525 | #define WEBPAGE_RELEASE_LOG(channel, fmt, ...) RELEASE_LOG(channel, "%p - [webPageID=%" PRIu64 "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__)clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2Logchannel .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("%p - [webPageID=%" "ll" "u" "] WebPage::" fmt), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG67" ) = "%p - [webPageID=%" "ll" "u" "] WebPage::" fmt; uint8_t _Alignas (16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("%p - [webPageID=%" "ll" "u" "] WebPage::" fmt, this, m_identifier .toUInt64(), ##__VA_ARGS__)]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format (_os_fmt_buf, "%p - [webPageID=%" "ll" "u" "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__), (uint32_t)sizeof (_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop |
| 526 | #define WEBPAGE_RELEASE_LOG_FORWARDABLE(channel, fmt, ...)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->fmt(m_identifier.toUInt64(), ...); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2Logchannel .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p (MESSAGE_fmt), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG68" ) = MESSAGE_fmt; uint8_t _Alignas(16) __attribute__((uninitialized )) _os_fmt_buf[__builtin_os_log_format_buffer_size(MESSAGE_fmt , m_identifier.toUInt64(), ...)]; _os_log_impl(&__dso_handle , _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format (_os_fmt_buf, MESSAGE_fmt, m_identifier.toUInt64(), ...), (uint32_t )sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0) RELEASE_LOG_FORWARDABLE(channel, fmt, m_identifier.toUInt64(), ##__VA_ARGS__)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->fmt(m_identifier.toUInt64(), ##__VA_ARGS__ ); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2Logchannel .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p (MESSAGE_fmt), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG69" ) = MESSAGE_fmt; uint8_t _Alignas(16) __attribute__((uninitialized )) _os_fmt_buf[__builtin_os_log_format_buffer_size(MESSAGE_fmt , m_identifier.toUInt64(), ##__VA_ARGS__)]; _os_log_impl(& __dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format (_os_fmt_buf, MESSAGE_fmt, m_identifier.toUInt64(), ##__VA_ARGS__ ), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0) |
| 527 | #define WEBPAGE_RELEASE_LOG_ERROR(channel, fmt, ...) RELEASE_LOG_ERROR(channel, "%p - [webPageID=%" PRIu64 "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__)clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2Logchannel .osLogChannel); os_log_type_t _type_tmp = OS_LOG_TYPE_ERROR; if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("%p - [webPageID=%" "ll" "u" "] WebPage::" fmt), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG70" ) = "%p - [webPageID=%" "ll" "u" "] WebPage::" fmt; uint8_t _Alignas (16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("%p - [webPageID=%" "ll" "u" "] WebPage::" fmt, this, m_identifier .toUInt64(), ##__VA_ARGS__)]; _os_log_error_impl(&__dso_handle , _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format (_os_fmt_buf, "%p - [webPageID=%" "ll" "u" "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__), (uint32_t)sizeof (_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop |
| 528 | |
| 529 | class SendStopResponsivenessTimer { |
| 530 | public: |
| 531 | ~SendStopResponsivenessTimer() |
| 532 | { |
| 533 | protect(WebProcess::singleton().parentProcessConnection())->send(Messages::WebProcessProxy::StopResponsivenessTimer(), 0); |
| 534 | } |
| 535 | }; |
| 536 | |
| 537 | Ref<WebPage> WebPage::create(PageIdentifier pageID, WebPageCreationParameters&& parameters) |
| 538 | { |
| 539 | String openedMainFrameName = parameters.openedMainFrameName; |
| 540 | auto page = adoptRef(*new WebPage(pageID, WTF::move(parameters))); |
| 541 | |
| 542 | if (RefPtr injectedBundle = WebProcess::singleton().injectedBundle()) |
| 543 | injectedBundle->didCreatePage(page); |
| 544 | |
| 545 | page->corePage()->mainFrame().tree().setSpecifiedName(AtomString(openedMainFrameName)); |
| 546 | |
| 547 | #if HAVE(SANDBOX_STATE_FLAGS)(defined 1 && 1) |
| 548 | setHasLaunchedWebContentProcess(); |
| 549 | #endif |
| 550 | |
| 551 | return page; |
| 552 | } |
| 553 | |
| 554 | void WebPage::ref() const |
| 555 | { |
| 556 | API::ObjectImpl<API::Object::Type::BundlePage>::ref(); |
| 557 | } |
| 558 | |
| 559 | void WebPage::deref() const |
| 560 | { |
| 561 | API::ObjectImpl<API::Object::Type::BundlePage>::deref(); |
| 562 | } |
| 563 | |
| 564 | static Vector<UserContentURLPattern> parseAndAllowAccessToCORSDisablingPatterns(const Vector<String>& input) |
| 565 | { |
| 566 | return WTF::compactMap(input, [](auto& pattern) -> std::optional<UserContentURLPattern> { |
| 567 | UserContentURLPattern parsedPattern(pattern); |
| 568 | if (!parsedPattern.isValid()) |
| 569 | return std::nullopt; |
| 570 | WebCore::OriginAccessPatternsForWebProcess::singleton().allowAccessTo(parsedPattern); |
| 571 | return parsedPattern; |
| 572 | }); |
| 573 | } |
| 574 | |
| 575 | static PageConfiguration::MainFrameCreationParameters mainFrameCreationParameters(Ref<WebFrame>&& mainFrame, auto frameType, auto initialSandboxFlags, auto initialReferrerPolicy) |
| 576 | { |
| 577 | auto invalidator = mainFrame->makeInvalidator(); |
| 578 | switch (frameType) { |
| 579 | case Frame::FrameType::Local: |
| 580 | return PageConfiguration::LocalMainFrameCreationParameters { |
| 581 | { [mainFrame = WTF::move(mainFrame), invalidator = WTF::move(invalidator)] (auto& localFrame, auto& frameLoader) mutable { |
| 582 | return makeUniqueRefWithoutRefCountedCheck<WebLocalFrameLoaderClient>(localFrame, frameLoader, WTF::move(mainFrame), WTF::move(invalidator)); |
| 583 | } }, |
| 584 | initialSandboxFlags, |
| 585 | initialReferrerPolicy |
| 586 | }; |
| 587 | case Frame::FrameType::Remote: |
| 588 | return CompletionHandler<UniqueRef<RemoteFrameClient>(RemoteFrame&)> { [mainFrame = WTF::move(mainFrame), invalidator = WTF::move(invalidator)] (auto&) mutable { |
| 589 | return makeUniqueRef<WebRemoteFrameClient>(WTF::move(mainFrame), WTF::move(invalidator)); |
| 590 | } }; |
| 591 | } |
| 592 | RELEASE_ASSERT_NOT_REACHED()do { WTF::isIntegralOrPointerType(); compilerFenceForCrash(); WTFCrashWithInfo(592, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); |
| 593 | } |
| 594 | |
| 595 | static RefPtr<Frame> frameFromIdentifier(std::optional<FrameIdentifier> identifier) |
| 596 | { |
| 597 | if (!identifier) |
| 598 | return nullptr; |
| 599 | RefPtr webFrame = WebProcess::singleton().webFrame(*identifier); |
| 600 | if (!webFrame) |
| 601 | return nullptr; |
| 602 | return webFrame->coreFrame(); |
| 603 | } |
| 604 | |
| 605 | WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters) |
| 606 | : m_internals(makeUniqueRef<Internals>()) |
| 607 | , m_identifier(pageID) |
| 608 | , m_viewSize(parameters.viewSize) |
| 609 | , m_drawingArea(DrawingArea::create(*this, parameters)) |
| 610 | , m_webPageTesting(WebPageTesting::create(*this)) |
| 611 | , m_mainFrame(WebFrame::create(*this, parameters.mainFrameIdentifier)) |
| 612 | , m_pageGroup(WebProcess::singleton().webPageGroup(WTF::move(parameters.pageGroupData))) |
| 613 | #if ENABLE(TILED_CA_DRAWING_AREA)(defined ENABLE_TILED_CA_DRAWING_AREA && ENABLE_TILED_CA_DRAWING_AREA ) |
| 614 | , m_drawingAreaType(parameters.drawingAreaType) |
| 615 | #endif |
| 616 | , m_alwaysShowsHorizontalScroller { parameters.alwaysShowsHorizontalScroller } |
| 617 | , m_alwaysShowsVerticalScroller { parameters.alwaysShowsVerticalScroller } |
| 618 | , m_shouldRenderCanvasInGPUProcess { parameters.shouldRenderCanvasInGPUProcess } |
| 619 | , m_shouldRenderDOMInGPUProcess { parameters.shouldRenderDOMInGPUProcess } |
| 620 | , m_shouldPlayMediaInGPUProcess { parameters.shouldPlayMediaInGPUProcess } |
| 621 | #if ENABLE(WEBGL)(defined 1 && 1) |
| 622 | , m_shouldRenderWebGLInGPUProcess { parameters.shouldRenderWebGLInGPUProcess } |
| 623 | #endif |
| 624 | , m_shouldSendConsoleLogsToUIProcessForTesting(parameters.shouldSendConsoleLogsToUIProcessForTesting) |
| 625 | #if HAVE(NSVIEW_CORNER_CONFIGURATION)(defined HAVE_NSVIEW_CORNER_CONFIGURATION && HAVE_NSVIEW_CORNER_CONFIGURATION ) |
| 626 | , m_scrollbarAvoidanceCornerRadii(parameters.scrollbarAvoidanceCornerRadii) |
| 627 | #endif |
| 628 | #if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)(defined 0 && 0) |
| 629 | , m_textCheckingControllerProxy(makeUniqueRefWithoutRefCountedCheck<TextCheckingControllerProxy>(*this)) |
| 630 | #endif |
| 631 | #if PLATFORM(COCOA)(defined 1 && 1) || PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 632 | , m_viewGestureGeometryCollector(ViewGestureGeometryCollector::create(*this)) |
| 633 | #elif PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 634 | , m_accessibilityObject(nullptr) |
| 635 | #endif |
| 636 | #if USE(GRAPHICS_LAYER_TEXTURE_MAPPER)(defined USE_GRAPHICS_LAYER_TEXTURE_MAPPER && USE_GRAPHICS_LAYER_TEXTURE_MAPPER ) || USE(GRAPHICS_LAYER_WC)(defined USE_GRAPHICS_LAYER_WC && USE_GRAPHICS_LAYER_WC ) |
| 637 | , m_nativeWindowHandle(parameters.nativeWindowHandle) |
| 638 | #endif |
| 639 | , m_setCanStartMediaTimer(RunLoop::mainSingleton(), "WebPage::SetCanStartMediaTimer"_s, this, &WebPage::setCanStartMediaTimerFired) |
| 640 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 641 | , m_contextMenuClient(makeUnique<API::InjectedBundle::PageContextMenuClient>()) |
| 642 | #endif |
| 643 | , m_editorClient { makeUnique<API::InjectedBundle::EditorClient>() } |
| 644 | , m_formClient(makeUnique<API::InjectedBundle::FormClient>()) |
| 645 | , m_loaderClient(makeUnique<API::InjectedBundle::PageLoaderClient>()) |
| 646 | , m_resourceLoadClient(makeUnique<API::InjectedBundle::ResourceLoadClient>()) |
| 647 | , m_uiClient(makeUnique<API::InjectedBundle::PageUIClient>()) |
| 648 | , m_findController(makeUniqueRef<FindController>(this)) |
| 649 | , m_foundTextRangeController(makeUniqueRef<WebFoundTextRangeController>(*this)) |
| 650 | , m_userContentController(WebUserContentController::getOrCreate(WTF::move(parameters.userContentControllerParameters))) |
| 651 | , m_screenOrientationManager(makeUniqueRefWithoutRefCountedCheck<WebScreenOrientationManager>(*this)) |
| 652 | #if ENABLE(GEOLOCATION)(defined 1 && 1) |
| 653 | , m_geolocationPermissionRequestManager(makeUniqueRefWithoutRefCountedCheck<GeolocationPermissionRequestManager>(*this)) |
| 654 | #endif |
| 655 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) |
| 656 | , m_userMediaPermissionRequestManager { makeUniqueRefWithoutRefCountedCheck<UserMediaPermissionRequestManager>(*this) } |
| 657 | #endif |
| 658 | #if ENABLE(ENCRYPTED_MEDIA)(defined 1 && 1) |
| 659 | , m_mediaKeySystemPermissionRequestManager { makeUniqueRefWithoutRefCountedCheck<MediaKeySystemPermissionRequestManager>(*this) } |
| 660 | #endif |
| 661 | , m_pageScrolledHysteresis([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) pageStoppedScrolling(); }, pageScrollHysteresisDuration) |
| 662 | , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel) |
| 663 | , m_canRunModal(parameters.canRunModal) |
| 664 | #if HAVE(TOUCH_BAR)(defined HAVE_TOUCH_BAR && HAVE_TOUCH_BAR) |
| 665 | , m_requiresUserActionForEditingControlsManager(parameters.requiresUserActionForEditingControlsManager) |
| 666 | #endif |
| 667 | #if HAVE(UIKIT_RESIZABLE_WINDOWS)(defined 1 && 1) |
| 668 | , m_isWindowResizingEnabled(parameters.hasResizableWindows) |
| 669 | #endif |
| 670 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 671 | , m_overflowHeightForTopScrollEdgeEffect(parameters.overflowHeightForTopScrollEdgeEffect) |
| 672 | #endif |
| 673 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 674 | , m_forceAlwaysUserScalable(parameters.ignoresViewportScaleLimits) |
| 675 | #endif |
| 676 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 677 | , m_screenIsBeingCaptured(parameters.isCapturingScreen) |
| 678 | , m_screenSize(parameters.screenSize) |
| 679 | , m_availableScreenSize(parameters.availableScreenSize) |
| 680 | , m_overrideScreenSize(parameters.overrideScreenSize) |
| 681 | , m_overrideAvailableScreenSize(parameters.overrideAvailableScreenSize) |
| 682 | , m_deviceOrientation(parameters.deviceOrientation) |
| 683 | , m_keyboardIsAttached(parameters.hardwareKeyboardState.isAttached) |
| 684 | , m_updateFocusedElementInformationTimer(*this, &WebPage::updateFocusedElementInformation, updateFocusedElementInformationDebounceInterval) |
| 685 | #endif |
| 686 | , m_layerVolatilityTimer(*this, &WebPage::layerVolatilityTimerFired) |
| 687 | , m_activityState(parameters.activityState) |
| 688 | , m_userInterfaceLayoutDirection(parameters.userInterfaceLayoutDirection) |
| 689 | , m_overrideContentSecurityPolicy { WTF::move(parameters.overrideContentSecurityPolicy) } |
| 690 | , m_cpuLimit(parameters.cpuLimit) |
| 691 | #if USE(WPE_RENDERER)(defined USE_WPE_RENDERER && USE_WPE_RENDERER) |
| 692 | , m_hostFileDescriptor(WTF::move(parameters.hostFileDescriptor)) |
| 693 | #endif |
| 694 | , m_webPageProxyIdentifier(parameters.webPageProxyIdentifier) |
| 695 | #if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1) |
| 696 | , m_textAutoSizingAdjustmentTimer(*this, &WebPage::textAutoSizingAdjustmentTimerFired) |
| 697 | #endif |
| 698 | , m_overriddenMediaType { WTF::move(parameters.overriddenMediaType) } |
| 699 | , m_processDisplayName { WTF::move(parameters.processDisplayName) } |
| 700 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) || PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) |
| 701 | #if USE(GBM)(defined USE_GBM && USE_GBM) || OS(ANDROID)(defined WTF_OS_ANDROID && WTF_OS_ANDROID) |
| 702 | , m_preferredBufferFormats(WTF::move(parameters.preferredBufferFormats)) |
| 703 | #endif |
| 704 | #endif |
| 705 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 706 | , m_limitsNavigationsToAppBoundDomains(parameters.limitsNavigationsToAppBoundDomains) |
| 707 | #endif |
| 708 | , m_lastNavigationWasAppInitiated(parameters.lastNavigationWasAppInitiated) |
| 709 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 710 | , m_updateLayoutViewportHeightExpansionTimer(*this, &WebPage::updateLayoutViewportHeightExpansionTimerFired, updateLayoutViewportHeightExpansionTimerInterval) |
| 711 | #endif |
| 712 | #if ENABLE(IPC_TESTING_API)(defined ENABLE_IPC_TESTING_API && ENABLE_IPC_TESTING_API ) |
| 713 | , m_visitedLinkTableID(parameters.visitedLinkTableID) |
| 714 | #endif |
| 715 | #if ENABLE(APP_HIGHLIGHTS)(defined 1 && 1) |
| 716 | , m_appHighlightsVisible(parameters.appHighlightsVisible) |
| 717 | #endif |
| 718 | , m_historyItemClient(WebHistoryItemClient::create(*this)) |
| 719 | #if ENABLE(WRITING_TOOLS)(defined 1 && 1) |
| 720 | , m_textAnimationController(makeUniqueRef<TextAnimationController>(*this)) |
| 721 | #endif |
| 722 | , m_backgroundTextExtractionEnabled(parameters.backgroundTextExtractionEnabled) |
| 723 | , m_isPopup(parameters.isPopup) |
| 724 | #if ENABLE(MODEL_ELEMENT_IMMERSIVE)(defined ENABLE_MODEL_ELEMENT_IMMERSIVE && ENABLE_MODEL_ELEMENT_IMMERSIVE ) |
| 725 | , m_allowsImmersiveEnvironments(parameters.allowsImmersiveEnvironments) |
| 726 | #endif |
| 727 | { |
| 728 | WEBPAGE_RELEASE_LOG(Loading, "constructor:"); |
| 729 | |
| 730 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 731 | #if HAVE(SANDBOX_STATE_FLAGS)(defined 1 && 1) |
| 732 | auto auditToken = WebProcess::singleton().auditTokenForSelf(); |
| 733 | auto shouldBlockWebInspector = parameters.store.getBoolValueForKey(WebPreferencesKey::blockWebInspectorInWebContentSandboxKey()); |
| 734 | if (shouldBlockWebInspector) |
| 735 | sandbox_enable_state_flag("BlockWebInspectorInWebContentSandbox", *auditToken); |
| 736 | #if PLATFORM(IOS)(defined 1 && 1) |
| 737 | auto shouldBlockMobileGestalt = parameters.store.getBoolValueForKey(WebPreferencesKey::blockMobileGestaltInWebContentSandboxKey()); |
| 738 | if (shouldBlockMobileGestalt) |
| 739 | sandbox_enable_state_flag("BlockMobileGestaltInWebContentSandbox", *auditToken); |
| 740 | #endif |
| 741 | auto shouldBlockMobileAsset = parameters.store.getBoolValueForKey(WebPreferencesKey::blockMobileAssetInWebContentSandboxKey()); |
| 742 | if (shouldBlockMobileAsset) |
| 743 | sandbox_enable_state_flag("BlockMobileAssetInWebContentSandbox", *auditToken); |
| 744 | auto unifiedPDFEnabled = parameters.store.getBoolValueForKey(WebPreferencesKey::unifiedPDFEnabledKey()); |
| 745 | if (unifiedPDFEnabled) |
| 746 | sandbox_enable_state_flag("UnifiedPDFEnabled", *auditToken); |
| 747 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 748 | auto shouldAllowInstalledFonts = parameters.store.getBoolValueForKey(WebPreferencesKey::shouldAllowUserInstalledFontsKey()); |
| 749 | if (!shouldAllowInstalledFonts || !WTF::MacApplication::isAppleMail()) |
| 750 | sandbox_enable_state_flag("BlockUserInstalledFonts", *auditToken); |
| 751 | auto shouldBlockFontService = parameters.store.getBoolValueForKey(WebPreferencesKey::blockFontServiceInWebContentSandboxKey()); |
| 752 | if (shouldBlockFontService) |
| 753 | sandbox_enable_state_flag("BlockFontServiceInWebContentSandbox", *auditToken); |
| 754 | auto shouldBlockIconServices = parameters.store.getBoolValueForKey(WebPreferencesKey::blockIconServicesInWebContentSandboxKey()); |
| 755 | if (shouldBlockIconServices) |
| 756 | sandbox_enable_state_flag("BlockIconServicesInWebContentSandbox", *auditToken); |
| 757 | auto shouldBlockOpenDirectory = parameters.store.getBoolValueForKey(WebPreferencesKey::blockOpenDirectoryInWebContentSandboxKey()); |
| 758 | if (shouldBlockOpenDirectory) |
| 759 | sandbox_enable_state_flag("BlockOpenDirectoryInWebContentSandbox", *auditToken); |
| 760 | #endif // PLATFORM(MAC) |
| 761 | #endif // HAVE(SANDBOX_STATE_FLAGS) |
| 762 | auto shouldBlockIOKit = parameters.store.getBoolValueForKey(WebPreferencesKey::blockIOKitInWebContentSandboxKey()) |
| 763 | #if ENABLE(WEBGL)(defined 1 && 1) |
| 764 | && m_shouldRenderWebGLInGPUProcess |
| 765 | #if ENABLE(TILED_CA_DRAWING_AREA)(defined ENABLE_TILED_CA_DRAWING_AREA && ENABLE_TILED_CA_DRAWING_AREA ) |
| 766 | && m_drawingAreaType == DrawingAreaType::RemoteLayerTree |
| 767 | #endif |
| 768 | #endif |
| 769 | && m_shouldRenderCanvasInGPUProcess |
| 770 | && m_shouldRenderDOMInGPUProcess |
| 771 | && m_shouldPlayMediaInGPUProcess; |
| 772 | |
| 773 | if (shouldBlockIOKit) { |
| 774 | #if HAVE(SANDBOX_STATE_FLAGS)(defined 1 && 1) && !ENABLE(WEBCONTENT_GPU_SANDBOX_EXTENSIONS_BLOCKING)(defined 1 && 1) |
| 775 | sandbox_enable_state_flag("BlockIOKitInWebContentSandbox", *auditToken); |
| 776 | #endif |
| 777 | ProcessCapabilities::setHardwareAcceleratedDecodingDisabled(true); |
| 778 | ProcessCapabilities::setCanUseAcceleratedBuffers(false); |
| 779 | static bool disabled { false }; |
| 780 | if (!std::exchange(disabled, true)) { |
| 781 | OSStatus ok = CGImageSourceDisableHardwareDecoding(); |
| 782 | ASSERT_UNUSED(ok, ok == noErr)((void)ok); |
| 783 | } |
| 784 | } |
| 785 | #endif |
| 786 | |
| 787 | auto frameType = parameters.remotePageParameters ? Frame::FrameType::Remote : Frame::FrameType::Local; |
| 788 | ASSERT(!parameters.remotePageParameters || parameters.remotePageParameters->frameTreeParameters.frameID == parameters.mainFrameIdentifier)((void)0); |
| 789 | |
| 790 | PageConfiguration pageConfiguration( |
| 791 | pageID, |
| 792 | WebProcess::singleton().sessionID(), |
| 793 | makeUniqueRef<WebEditorClient>(*this), |
| 794 | WebSocketProvider::create(parameters.webPageProxyIdentifier), |
| 795 | createLibWebRTCProvider(*this), |
| 796 | WebProcess::singleton().cacheStorageProvider(), |
| 797 | m_userContentController, |
| 798 | WebBackForwardListProxy::create(*this), |
| 799 | WebProcess::singleton().cookieJar(), |
| 800 | makeUniqueRef<WebProgressTrackerClient>(*this), |
| 801 | mainFrameCreationParameters(m_mainFrame.copyRef(), frameType, parameters.initialSandboxFlags, parameters.initialReferrerPolicy), |
| 802 | m_mainFrame->frameID(), |
| 803 | frameFromIdentifier(parameters.mainFrameOpenerIdentifier), |
| 804 | makeUniqueRef<WebSpeechRecognitionProvider>(pageID), |
| 805 | WebProcess::singleton().broadcastChannelRegistry(), |
| 806 | makeUniqueRef<WebStorageProvider>(WebProcess::singleton().mediaKeysStorageDirectory(), WebProcess::singleton().mediaKeysStorageSalt()), |
| 807 | WebModelPlayerProvider::create(*this), |
| 808 | WebProcess::singleton().badgeClient(), |
| 809 | m_historyItemClient.copyRef(), |
| 810 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 811 | makeUniqueRef<WebContextMenuClient>(this), |
| 812 | #endif |
| 813 | #if ENABLE(APPLE_PAY)(defined 1 && 1) |
| 814 | WebPaymentCoordinator::create(*this), |
| 815 | #endif |
| 816 | makeUniqueRef<WebChromeClient>(*this), |
| 817 | makeUniqueRef<WebCryptoClient>(this->identifier()), |
| 818 | makeUniqueRef<WebDocumentSyncClient>(*this) |
| 819 | #if ENABLE(WEB_AUTHN)(defined 1 && 1) |
| 820 | , DigitalCredentialsCoordinator::create(*this) |
| 821 | #endif |
| 822 | ); |
| 823 | |
| 824 | #if ENABLE(DRAG_SUPPORT)(defined 1 && 1) |
| 825 | pageConfiguration.dragClient = makeUnique<WebDragClient>(this); |
| 826 | #endif |
| 827 | pageConfiguration.inspectorBackendClient = makeUnique<WebInspectorBackendClient>(this); |
| 828 | #if USE(AUTOCORRECTION_PANEL)(defined USE_AUTOCORRECTION_PANEL && USE_AUTOCORRECTION_PANEL ) |
| 829 | pageConfiguration.alternativeTextClient = makeUnique<WebAlternativeTextClient>(this); |
| 830 | #endif |
| 831 | |
| 832 | pageConfiguration.diagnosticLoggingClient = makeUnique<WebDiagnosticLoggingClient>(*this); |
| 833 | pageConfiguration.performanceLoggingClient = makeUnique<WebPerformanceLoggingClient>(*this); |
| 834 | pageConfiguration.screenOrientationManager = m_screenOrientationManager.get(); |
| 835 | |
| 836 | #if ENABLE(SPEECH_SYNTHESIS)(defined 1 && 1) && !USE(GSTREAMER)(defined USE_GSTREAMER && USE_GSTREAMER) |
| 837 | pageConfiguration.speechSynthesisClient = WebSpeechSynthesisClient::create(*this); |
| 838 | #endif |
| 839 | |
| 840 | #if PLATFORM(COCOA)(defined 1 && 1) || PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 841 | pageConfiguration.validationMessageClient = makeUnique<WebValidationMessageClient>(*this); |
| 842 | #endif |
| 843 | |
| 844 | pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID()); |
| 845 | pageConfiguration.pluginInfoProvider = WebPluginInfoProvider::singleton(); |
| 846 | pageConfiguration.storageNamespaceProvider = WebStorageNamespaceProvider::getOrCreate(); |
| 847 | pageConfiguration.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID); |
| 848 | |
| 849 | #if ENABLE(WEB_AUTHN)(defined 1 && 1) |
| 850 | pageConfiguration.authenticatorCoordinatorClient = makeUnique<WebAuthenticatorCoordinator>(*this); |
| 851 | #endif |
| 852 | |
| 853 | #if ENABLE(APPLICATION_MANIFEST)(defined 1 && 1) |
| 854 | pageConfiguration.applicationManifest = WTF::move(parameters.applicationManifest); |
| 855 | #endif |
| 856 | |
| 857 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) && ENABLE(DEVICE_ORIENTATION)(defined 1 && 1) |
| 858 | pageConfiguration.deviceOrientationUpdateProvider = WebDeviceOrientationUpdateProvider::create(*this); |
| 859 | #endif |
| 860 | |
| 861 | #if ENABLE(WK_WEB_EXTENSIONS)(defined 1 && 1) && PLATFORM(COCOA)(defined 1 && 1) |
| 862 | if (parameters.webExtensionControllerParameters) |
| 863 | m_webExtensionController = WebExtensionControllerProxy::getOrCreate(parameters.webExtensionControllerParameters.value(), this); |
| 864 | #endif |
| 865 | |
| 866 | m_corsDisablingPatterns = WTF::move(parameters.corsDisablingPatterns); |
| 867 | if (!m_corsDisablingPatterns.isEmpty()) |
| 868 | synchronizeCORSDisablingPatternsWithNetworkProcess(); |
| 869 | pageConfiguration.corsDisablingPatterns = parseAndAllowAccessToCORSDisablingPatterns(m_corsDisablingPatterns); |
| 870 | |
| 871 | pageConfiguration.maskedURLSchemes = WTF::move(parameters.maskedURLSchemes); |
| 872 | pageConfiguration.loadsSubresources = parameters.loadsSubresources; |
| 873 | pageConfiguration.allowedNetworkHosts = WTF::move(parameters.allowedNetworkHosts); |
| 874 | pageConfiguration.shouldRelaxThirdPartyCookieBlocking = parameters.shouldRelaxThirdPartyCookieBlocking; |
| 875 | pageConfiguration.httpsUpgradeEnabled = parameters.httpsUpgradeEnabled; |
| 876 | pageConfiguration.portsForUpgradingInsecureSchemeForTesting = parameters.portsForUpgradingInsecureSchemeForTesting; |
| 877 | |
| 878 | if (!parameters.crossOriginAccessControlCheckEnabled) |
| 879 | CrossOriginAccessControlCheckDisabler::singleton().setCrossOriginAccessControlCheckEnabled(false); |
| 880 | |
| 881 | #if ENABLE(ATTACHMENT_ELEMENT)(defined 1 && 1) |
| 882 | pageConfiguration.attachmentElementClient = makeUnique<WebAttachmentElementClient>(*this); |
| 883 | #endif |
| 884 | |
| 885 | pageConfiguration.contentSecurityPolicyModeForExtension = parameters.contentSecurityPolicyModeForExtension; |
| 886 | |
| 887 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 888 | static bool hasConsumedGPUExtensionHandles = false; |
| 889 | if (!hasConsumedGPUExtensionHandles) { |
| 890 | SandboxExtension::consumePermanently(parameters.gpuIOKitExtensionHandles); |
| 891 | SandboxExtension::consumePermanently(parameters.gpuMachExtensionHandles); |
| 892 | hasConsumedGPUExtensionHandles = true; |
| 893 | } |
| 894 | #endif |
| 895 | |
| 896 | #if HAVE(STATIC_FONT_REGISTRY)(defined HAVE_STATIC_FONT_REGISTRY && HAVE_STATIC_FONT_REGISTRY ) |
| 897 | if (parameters.fontMachExtensionHandles.size()) |
| 898 | WebProcess::singleton().switchFromStaticFontRegistryToUserFontRegistry(WTF::move(parameters.fontMachExtensionHandles)); |
| 899 | #endif |
| 900 | |
| 901 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 902 | pageConfiguration.canShowWhileLocked = parameters.canShowWhileLocked; |
| 903 | #endif |
| 904 | |
| 905 | #if PLATFORM(VISION)(defined WTF_PLATFORM_VISION && WTF_PLATFORM_VISION) && ENABLE(GAMEPAD)(defined 1 && 1) |
| 906 | pageConfiguration.gamepadAccessRequiresExplicitConsent = parameters.gamepadAccessRequiresExplicitConsent; |
| 907 | #endif |
| 908 | |
| 909 | #if HAVE(AUDIT_TOKEN)(defined 1 && 1) |
| 910 | pageConfiguration.presentingApplicationAuditToken = parameters.presentingApplicationAuditToken ? std::optional(parameters.presentingApplicationAuditToken->auditToken()) : std::nullopt; |
| 911 | #endif |
| 912 | |
| 913 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 914 | pageConfiguration.presentingApplicationBundleIdentifier = WTF::move(parameters.presentingApplicationBundleIdentifier); |
| 915 | #endif |
| 916 | |
| 917 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) |
| 918 | pageConfiguration.imageTranslationLanguageIdentifiers = WTF::move(parameters.imageTranslationLanguageIdentifiers); |
| 919 | #endif |
| 920 | |
| 921 | if (parameters.textManipulationParameters) { |
| 922 | m_textManipulationIncludesSubframes = parameters.textManipulationParameters->includeSubframes; |
| 923 | m_internals->textManipulationExclusionRules = WTF::move(parameters.textManipulationParameters->exclusionRules); |
| 924 | } |
| 925 | |
| 926 | #if ENABLE(VIDEO)(defined 1 && 1) || ENABLE(WEB_AUDIO)(defined 1 && 1) |
| 927 | if (parameters.store.getBoolValueForKey(WebPreferencesKey::remoteMediaSessionManagerEnabledKey()) || parameters.store.getBoolValueForKey(WebPreferencesKey::siteIsolationSharedProcessEnabledKey())) { |
| 928 | pageConfiguration.mediaSessionManagerFactory = [weakThis = WeakPtr { *this }](PageIdentifier) -> RefPtr<MediaSessionManagerInterface> { |
| 929 | |
| 930 | RefPtr protectedThis = weakThis.get(); |
| 931 | if (!protectedThis) |
| 932 | return nullptr; |
| 933 | |
| 934 | // FIXME: This is often null with site isolation enabled. It seems like this is not what was intended. |
| 935 | RefPtr topDocument = protectedThis->localTopDocument(); |
| 936 | if (!topDocument) |
| 937 | return nullptr; |
| 938 | |
| 939 | RefPtr topCorePage = topDocument->page(); |
| 940 | if (!topCorePage) |
| 941 | return nullptr; |
| 942 | |
| 943 | RefPtr topWebPage = WebPage::fromCorePage(*topCorePage); |
| 944 | if (!topWebPage) |
| 945 | return nullptr; |
| 946 | |
| 947 | RefPtr<PlatformMediaSessionManager> manager = RemoteMediaSessionManager::create(*topWebPage, *protectedThis); |
| 948 | manager->resetRestrictions(); |
| 949 | |
| 950 | return manager; |
| 951 | }; |
| 952 | } |
| 953 | #endif |
| 954 | |
| 955 | Ref page = Page::create(WTF::move(pageConfiguration)); |
| 956 | m_page = page.copyRef(); |
| 957 | |
| 958 | updateAfterDrawingAreaCreation(parameters); |
| 959 | |
| 960 | if (parameters.displayID) |
| 961 | windowScreenDidChange(*parameters.displayID, parameters.nominalFramesPerSecond); |
| 962 | |
| 963 | WebStorageNamespaceProvider::incrementUseCount(sessionStorageNamespaceIdentifier()); |
| 964 | |
| 965 | if (parameters.shouldForceSiteIsolationAlwaysOnForTesting) |
| 966 | WebPreferences::forceSiteIsolationAlwaysOnForTesting(); |
| 967 | |
| 968 | updatePreferences(parameters.store); |
| 969 | if (page->settings().siteIsolationEnabled()) { |
| 970 | if (RefPtr frame = page->localMainFrame()) |
| 971 | frame->inspectorController().siteIsolationFirstEnabled(); |
| 972 | } |
| 973 | |
| 974 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) || ENABLE(ROUTING_ARBITRATION)(defined ENABLE_ROUTING_ARBITRATION && ENABLE_ROUTING_ARBITRATION ) |
| 975 | DeprecatedGlobalSettings::setShouldManageAudioSessionCategory(true); |
| 976 | #endif |
| 977 | |
| 978 | m_backgroundColor = parameters.backgroundColor; |
| 979 | |
| 980 | // We need to set the device scale factor before creating the drawing area |
| 981 | // to ensure it's created with the right size. |
| 982 | page->setDeviceScaleFactor(parameters.deviceScaleFactor); |
| 983 | |
| 984 | #if USE(GRAPHICS_LAYER_WC)(defined USE_GRAPHICS_LAYER_WC && USE_GRAPHICS_LAYER_WC ) || USE(GRAPHICS_LAYER_TEXTURE_MAPPER)(defined USE_GRAPHICS_LAYER_TEXTURE_MAPPER && USE_GRAPHICS_LAYER_TEXTURE_MAPPER ) |
| 985 | setIntrinsicDeviceScaleFactor(parameters.intrinsicDeviceScaleFactor); |
| 986 | #endif |
| 987 | |
| 988 | #if USE(SKIA)(defined USE_SKIA && USE_SKIA) |
| 989 | FontRenderOptions::singleton().setUseSubpixelPositioning(parameters.deviceScaleFactor >= 2.); |
| 990 | #endif |
| 991 | |
| 992 | RefPtr drawingArea = m_drawingArea; |
| 993 | #if USE(COORDINATED_GRAPHICS)(defined USE_COORDINATED_GRAPHICS && USE_COORDINATED_GRAPHICS ) || USE(TEXTURE_MAPPER)(defined USE_TEXTURE_MAPPER && USE_TEXTURE_MAPPER) |
| 994 | if (drawingArea->enterAcceleratedCompositingModeIfNeeded() && !parameters.isProcessSwap) |
| 995 | drawingArea->sendEnterAcceleratedCompositingModeIfNeeded(); |
| 996 | #endif |
| 997 | drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument); |
| 998 | |
| 999 | if (parameters.isProcessSwap) |
| 1000 | freezeLayerTree(LayerTreeFreezeReason::ProcessSwap); |
| 1001 | |
| 1002 | #if ENABLE(ASYNC_SCROLLING)(defined 1 && 1) |
| 1003 | m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey()); |
| 1004 | if (!drawingArea->supportsAsyncScrolling()) |
| 1005 | m_useAsyncScrolling = false; |
| 1006 | page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling); |
| 1007 | #endif |
| 1008 | |
| 1009 | // Disable Back/Forward cache expiration in the WebContent process since management happens in the UIProcess |
| 1010 | // in modern WebKit. |
| 1011 | page->settings().setBackForwardCacheExpirationInterval(Seconds::infinity()); |
| 1012 | |
| 1013 | m_mainFrame->initWithCoreMainFrame(*this, protect(page->mainFrame())); |
| 1014 | |
| 1015 | if (auto& remotePageParameters = parameters.remotePageParameters) { |
| 1016 | Ref frameTreeSyncData = remotePageParameters->frameTreeParameters.frameTreeSyncData; |
| 1017 | protect(page->mainFrame())->updateFrameTreeSyncData(WTF::move(frameTreeSyncData)); |
| 1018 | for (auto& childParameters : remotePageParameters->frameTreeParameters.children) |
| 1019 | constructFrameTree(m_mainFrame.get(), childParameters); |
| 1020 | page->setMainFrameURLAndOrigin(remotePageParameters->initialMainDocumentURL, nullptr); |
| 1021 | if (auto websitePolicies = remotePageParameters->websitePoliciesData) { |
| 1022 | if (auto* remoteMainFrameClient = m_mainFrame->remoteFrameClient()) |
| 1023 | remoteMainFrameClient->applyWebsitePolicies(WTF::move(*remotePageParameters->websitePoliciesData)); |
| 1024 | } |
| 1025 | } |
| 1026 | if (auto&& provisionalFrameCreationParameters = parameters.provisionalFrameCreationParameters) { |
| 1027 | ASSERT(page->settings().siteIsolationEnabled())((void)0); |
| 1028 | createProvisionalFrame(WTF::move(*provisionalFrameCreationParameters)); |
| 1029 | } |
| 1030 | |
| 1031 | drawingArea->updatePreferences(parameters.store); |
| 1032 | |
| 1033 | setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage); |
| 1034 | didSetPageZoomFactor(parameters.pageZoomFactor); |
| 1035 | didSetTextZoomFactor(parameters.textZoomFactor); |
| 1036 | |
| 1037 | #if ENABLE(GEOLOCATION)(defined 1 && 1) |
| 1038 | WebCore::provideGeolocationTo(page.ptr(), WebGeolocationClient::create(*this)); |
| 1039 | #endif |
| 1040 | // FIXME: These should use makeUnique and makeUniqueRef instead of new. |
| 1041 | #if ENABLE(NOTIFICATIONS)(defined 1 && 1) |
| 1042 | WebCore::provideNotification(page.ptr(), new WebNotificationClient(this)); |
| 1043 | #endif |
| 1044 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) |
| 1045 | WebCore::provideUserMediaTo(page.ptr(), WebUserMediaClient::create(*this)); |
| 1046 | #endif |
| 1047 | #if ENABLE(ENCRYPTED_MEDIA)(defined 1 && 1) |
| 1048 | WebCore::provideMediaKeySystemTo(page, WebMediaKeySystemClient::create(*this)); |
| 1049 | #endif |
| 1050 | |
| 1051 | page->setControlledByAutomation(parameters.controlledByAutomation); |
| 1052 | page->setHasResourceLoadClient(parameters.hasResourceLoadClient); |
| 1053 | |
| 1054 | page->setCanStartMedia(false); |
| 1055 | m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow; |
| 1056 | if (parameters.mediaPlaybackIsSuspended) |
| 1057 | page->suspendAllMediaPlayback(); |
| 1058 | |
| 1059 | if (parameters.openedByDOM) |
| 1060 | page->setOpenedByDOM(); |
| 1061 | |
| 1062 | page->setGroupName(m_pageGroup->identifier()); |
| 1063 | page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection); |
| 1064 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 1065 | // Set hardware keyboard attached status |
| 1066 | page->didUpdateHardwareKeyboardAttachment(m_keyboardIsAttached); |
| 1067 | |
| 1068 | page->setTextAutosizingWidth(parameters.textAutosizingWidth); |
| 1069 | setOverrideViewportArguments(parameters.overrideViewportArguments); |
| 1070 | #endif |
| 1071 | |
| 1072 | platformInitialize(parameters); |
| 1073 | |
| 1074 | setUseFixedLayout(parameters.useFixedLayout); |
| 1075 | |
| 1076 | setDefaultUnobscuredSize(parameters.defaultUnobscuredSize); |
| 1077 | setMinimumUnobscuredSize(parameters.minimumUnobscuredSize); |
| 1078 | setMaximumUnobscuredSize(parameters.maximumUnobscuredSize); |
| 1079 | |
| 1080 | setUnderlayColor(parameters.underlayColor); |
| 1081 | |
| 1082 | setPaginationMode(parameters.paginationMode); |
| 1083 | setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns); |
| 1084 | setPageLength(parameters.pageLength); |
| 1085 | setGapBetweenPages(parameters.gapBetweenPages); |
| 1086 | |
| 1087 | setUseColorAppearance(parameters.useDarkAppearance, parameters.useElevatedUserInterfaceLevel); |
| 1088 | |
| 1089 | if (parameters.isEditable) |
| 1090 | setEditable(true); |
| 1091 | |
| 1092 | if (parameters.accessibilityEnabled) |
| 1093 | enableAccessibility(); |
| 1094 | |
| 1095 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 1096 | setUseFormSemanticContext(parameters.useFormSemanticContext); |
| 1097 | setHeaderBannerHeight(parameters.headerBannerHeight); |
| 1098 | setFooterBannerHeight(parameters.footerBannerHeight); |
| 1099 | if (parameters.viewWindowCoordinates) |
| 1100 | windowAndViewFramesChanged(*parameters.viewWindowCoordinates); |
| 1101 | #endif |
| 1102 | |
| 1103 | // If the page is created off-screen, its visibilityState should be prerender. |
| 1104 | page->setActivityState(m_activityState); |
| 1105 | if (!isVisible()) |
| 1106 | page->setIsPrerender(); |
| 1107 | |
| 1108 | updateIsInWindow(true); |
| 1109 | |
| 1110 | setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout); |
| 1111 | setSizeToContentAutoSizeMaximumSize(parameters.sizeToContentAutoSizeMaximumSize); |
| 1112 | setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight); |
| 1113 | setViewportSizeForCSSViewportUnits(parameters.viewportSizeForCSSViewportUnits); |
| 1114 | |
| 1115 | setScrollPinningBehavior(parameters.scrollPinningBehavior); |
| 1116 | if (parameters.scrollbarOverlayStyle) |
| 1117 | m_scrollbarOverlayStyle = static_cast<ScrollbarOverlayStyle>(parameters.scrollbarOverlayStyle.value()); |
| 1118 | else |
| 1119 | m_scrollbarOverlayStyle = std::optional<ScrollbarOverlayStyle>(); |
| 1120 | |
| 1121 | setObscuredContentInsets(parameters.obscuredContentInsets); |
| 1122 | |
| 1123 | #if ENABLE(BANNER_VIEW_OVERLAYS)(defined ENABLE_BANNER_VIEW_OVERLAYS && ENABLE_BANNER_VIEW_OVERLAYS ) |
| 1124 | setHasBannerViewOverlay(parameters.hasBannerViewOverlay); |
| 1125 | #endif |
| 1126 | |
| 1127 | m_userAgent = WTF::move(parameters.userAgent); |
| 1128 | |
| 1129 | setMediaVolume(parameters.mediaVolume); |
| 1130 | |
| 1131 | setMuted(parameters.muted, [] { }); |
| 1132 | |
| 1133 | // We use the DidFirstVisuallyNonEmptyLayout milestone to determine when to unfreeze the layer tree. |
| 1134 | // We use LayoutMilestone::DidFirstMeaningfulPaint to generte WKPageLoadTiming. |
| 1135 | page->addLayoutMilestones({ WebCore::LayoutMilestone::DidFirstLayout, WebCore::LayoutMilestone::DidFirstVisuallyNonEmptyLayout, LayoutMilestone::DidFirstMeaningfulPaint }); |
| 1136 | |
| 1137 | auto& webProcess = WebProcess::singleton(); |
| 1138 | webProcess.addMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier, *this); |
| 1139 | |
| 1140 | // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers. |
| 1141 | webProcess.addMessageReceiver(Messages::WebInspectorBackend::messageReceiverName(), m_identifier, *this); |
| 1142 | webProcess.addMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier, *this); |
| 1143 | webProcess.addMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier, *this); |
| 1144 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 1145 | webProcess.addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier, *this); |
| 1146 | #endif |
| 1147 | |
| 1148 | #if ENABLE(SCROLLING_THREAD)(defined 0 && 0) |
| 1149 | if (m_useAsyncScrolling) |
| 1150 | drawingArea->registerScrollingTree(); |
| 1151 | #endif |
| 1152 | |
| 1153 | for (auto& mimeType : parameters.mimeTypesWithCustomContentProviders) |
| 1154 | m_mimeTypesWithCustomContentProviders.add(mimeType); |
| 1155 | |
| 1156 | if (parameters.viewScaleFactor != 1) |
| 1157 | scaleView(parameters.viewScaleFactor); |
| 1158 | |
| 1159 | page->addLayoutMilestones(parameters.observedLayoutMilestones); |
| 1160 | |
| 1161 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 1162 | setSmartInsertDeleteEnabled(parameters.smartInsertDeleteEnabled); |
| 1163 | #endif |
| 1164 | |
| 1165 | #if HAVE(APP_ACCENT_COLORS)(defined HAVE_APP_ACCENT_COLORS && HAVE_APP_ACCENT_COLORS ) |
| 1166 | setAccentColor(parameters.accentColor); |
| 1167 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 1168 | setAppUsesCustomAccentColor(parameters.appUsesCustomAccentColor); |
| 1169 | #endif |
| 1170 | #endif |
| 1171 | |
| 1172 | m_needsFontAttributes = parameters.needsFontAttributes; |
| 1173 | |
| 1174 | setNeedsScrollGeometryUpdates(parameters.needsScrollGeometryUpdates); |
| 1175 | |
| 1176 | #if ENABLE(WEB_RTC)(defined 1 && 1) |
| 1177 | if (!parameters.iceCandidateFilteringEnabled) |
| 1178 | page->disableICECandidateFiltering(); |
| 1179 | #if USE(LIBWEBRTC)(defined 1 && 1) |
| 1180 | if (parameters.enumeratingAllNetworkInterfacesEnabled) |
| 1181 | downcast<LibWebRTCProvider>(page->webRTCProvider()).enableEnumeratingAllNetworkInterfaces(); |
| 1182 | if (parameters.store.getBoolValueForKey(WebPreferencesKey::enumeratingVisibleNetworkInterfacesEnabledKey())) |
| 1183 | downcast<LibWebRTCProvider>(page->webRTCProvider()).enableEnumeratingVisibleNetworkInterfaces(); |
| 1184 | #endif |
| 1185 | #endif |
| 1186 | |
| 1187 | for (const auto& iterator : parameters.urlSchemeHandlers) |
| 1188 | registerURLSchemeHandler(iterator.value, iterator.key); |
| 1189 | for (auto& scheme : parameters.urlSchemesWithLegacyCustomProtocolHandlers) |
| 1190 | LegacySchemeRegistry::registerURLSchemeAsHandledBySchemeHandler({ scheme }); |
| 1191 | |
| 1192 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 1193 | setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize, parameters.viewportConfigurationLayoutSizeScaleFactorFromClient, parameters.viewportConfigurationMinimumEffectiveDeviceWidth); |
| 1194 | #endif |
| 1195 | |
| 1196 | #if HAVE(VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1197 | LayerHostingContextID contextID = 0; |
| 1198 | #if !HAVE(NON_HOSTING_VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1199 | m_contextForVisibilityPropagation = LayerHostingContext::create({ |
| 1200 | canShowWhileLocked() |
| 1201 | }); |
| 1202 | WEBPAGE_RELEASE_LOG(Process, "WebPage: Created context with ID %u for visibility propagation from UIProcess", m_contextForVisibilityPropagation->contextID()); |
| 1203 | contextID = m_contextForVisibilityPropagation->cachedContextID(); |
| 1204 | #endif // !HAVE(NON_HOSTING_VISIBILITY_PROPAGATION_VIEW) |
| 1205 | send(Messages::WebPageProxy::DidCreateContextInWebProcessForVisibilityPropagation(contextID)); |
| 1206 | #endif // HAVE(VISIBILITY_PROPAGATION_VIEW) && !HAVE(NON_HOSTING_VISIBILITY_PROPAGATION_VIEW) |
| 1207 | |
| 1208 | #if ENABLE(VP9)(defined 1 && 1) && PLATFORM(COCOA)(defined 1 && 1) |
| 1209 | VP9TestingOverrides::singleton().setShouldEnableVP9Decoder(parameters.shouldEnableVP9Decoder); |
| 1210 | #endif |
| 1211 | |
| 1212 | page->setCanUseCredentialStorage(parameters.canUseCredentialStorage); |
| 1213 | |
| 1214 | #if HAVE(SANDBOX_STATE_FLAGS)(defined 1 && 1) |
| 1215 | auto experimentalSandbox = parameters.store.getBoolValueForKey(WebPreferencesKey::experimentalSandboxEnabledKey()); |
| 1216 | if (experimentalSandbox) |
| 1217 | sandbox_enable_state_flag("EnableExperimentalSandbox", *auditToken); |
| 1218 | |
| 1219 | #if HAVE(MACH_BOOTSTRAP_EXTENSION)(defined 1 && 1) |
| 1220 | SandboxExtension::consumePermanently(parameters.machBootstrapHandle); |
| 1221 | #endif |
| 1222 | #endif // HAVE(SANDBOX_STATE_FLAGS) |
| 1223 | |
| 1224 | updateThrottleState(); |
| 1225 | #if ENABLE(ACCESSIBILITY_ANIMATION_CONTROL)(defined 1 && 1) |
| 1226 | updateImageAnimationEnabled(); |
| 1227 | #endif |
| 1228 | #if ENABLE(ACCESSIBILITY_NON_BLINKING_CURSOR)(defined 0 && 0) |
| 1229 | updatePrefersNonBlinkingCursor(); |
| 1230 | #endif |
| 1231 | #if ENABLE(ADVANCED_PRIVACY_PROTECTIONS)(defined 1 && 1) |
| 1232 | setLinkDecorationFilteringData(WTF::move(parameters.linkDecorationFilteringData)); |
| 1233 | setAllowedQueryParametersForAdvancedPrivacyProtections(WTF::move(parameters.allowedQueryParametersForAdvancedPrivacyProtections)); |
| 1234 | #endif |
| 1235 | if (parameters.windowFeatures) { |
| 1236 | page->applyWindowFeatures(*parameters.windowFeatures); |
| 1237 | page->chrome().show(); |
| 1238 | page->setOpenedByDOM(); |
| 1239 | } |
| 1240 | |
| 1241 | if (parameters.allowPostingLegacySynchronousMessages) |
| 1242 | InjectedBundleScriptWorld::normalWorldSingleton().setAllowPostingLegacySynchronousMessages(); |
| 1243 | |
| 1244 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 1245 | RELEASE_ASSERT_IMPLIES(m_backgroundTextExtractionEnabled, isParentProcessAWebBrowser())do { if (__builtin_expect(!!((m_backgroundTextExtractionEnabled ) && !(isParentProcessAWebBrowser())), 0)) { do { __asm__ volatile ("brk #0xc471"); __builtin_unreachable(); } while ( 0); } } while (0); |
| 1246 | #endif |
| 1247 | } |
| 1248 | |
| 1249 | void WebPage::updateAfterDrawingAreaCreation(const WebPageCreationParameters& parameters) |
| 1250 | { |
| 1251 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 1252 | m_page->settings().setForceCompositingMode(true); |
| 1253 | #endif |
| 1254 | #if ENABLE(TILED_CA_DRAWING_AREA)(defined ENABLE_TILED_CA_DRAWING_AREA && ENABLE_TILED_CA_DRAWING_AREA ) |
| 1255 | if (parameters.drawingAreaType == DrawingAreaType::TiledCoreAnimation) { |
| 1256 | if (auto viewExposedRect = parameters.viewExposedRect) |
| 1257 | protect(drawingArea())->setViewExposedRect(viewExposedRect); |
| 1258 | } |
| 1259 | #endif |
| 1260 | } |
| 1261 | |
| 1262 | void WebPage::constructFrameTree(WebFrame& parent, const FrameTreeCreationParameters& treeCreationParameters) |
| 1263 | { |
| 1264 | auto frame = WebFrame::createRemoteSubframe(*this, parent, treeCreationParameters.frameID, treeCreationParameters.frameName, treeCreationParameters.openerFrameID, Ref { treeCreationParameters.frameTreeSyncData }); |
| 1265 | for (auto& parameters : treeCreationParameters.children) |
| 1266 | constructFrameTree(frame, parameters); |
| 1267 | } |
| 1268 | |
| 1269 | void WebPage::createRemoteSubframe(WebCore::FrameIdentifier parentID, WebCore::FrameIdentifier newChildID, const String& newChildFrameName, Ref<WebCore::FrameTreeSyncData>&& frameTreeSyncData) |
| 1270 | { |
| 1271 | RefPtr parentFrame = WebProcess::singleton().webFrame(parentID); |
| 1272 | if (!parentFrame) { |
| 1273 | ASSERT_NOT_REACHED()((void)0); |
| 1274 | return; |
| 1275 | } |
| 1276 | WebFrame::createRemoteSubframe(*this, *parentFrame, newChildID, newChildFrameName, std::nullopt, WTF::move(frameTreeSyncData)); |
| 1277 | } |
| 1278 | |
| 1279 | Awaitable<std::optional<FrameTreeNodeData>> WebPage::getFrameTree() |
| 1280 | { |
| 1281 | co_return m_mainFrame->frameTreeData(); |
| 1282 | } |
| 1283 | |
| 1284 | void WebPage::didFinishLoadInAnotherProcess(WebCore::FrameIdentifier frameID) |
| 1285 | { |
| 1286 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1287 | if (!frame) |
| 1288 | return; |
| 1289 | ASSERT(frame->page() == this)((void)0); |
| 1290 | frame->didFinishLoadInAnotherProcess(); |
| 1291 | } |
| 1292 | |
| 1293 | void WebPage::frameWasRemovedInAnotherProcess(WebCore::FrameIdentifier frameID) |
| 1294 | { |
| 1295 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1296 | if (!frame) { |
| 1297 | ASSERT_NOT_REACHED()((void)0); |
| 1298 | return; |
| 1299 | } |
| 1300 | ASSERT(frame->page() == this)((void)0); |
| 1301 | frame->markAsRemovedInAnotherProcess(); |
| 1302 | frame->removeFromTree(); |
| 1303 | } |
| 1304 | |
| 1305 | void WebPage::topDocumentSyncDataChangedInAnotherProcess(const WebCore::DocumentSyncSerializationData& data) |
| 1306 | { |
| 1307 | if (RefPtr page = corePage()) |
| 1308 | page->updateTopDocumentSyncData(data); |
| 1309 | } |
| 1310 | |
| 1311 | void WebPage::allTopDocumentSyncDataChangedInAnotherProcess(Ref<WebCore::DocumentSyncData>&& data) |
| 1312 | { |
| 1313 | if (RefPtr page = corePage()) |
| 1314 | page->updateTopDocumentSyncData(WTF::move(data)); |
| 1315 | } |
| 1316 | |
| 1317 | void WebPage::frameTreeSyncDataChangedInAnotherProcess(FrameIdentifier frameID, const WebCore::FrameTreeSyncSerializationData& data) |
| 1318 | { |
| 1319 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 1320 | |
| 1321 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1322 | if (!frame) |
| 1323 | return; |
| 1324 | |
| 1325 | ASSERT(frame->page() == this)((void)0); |
| 1326 | |
| 1327 | RefPtr coreFrame = frame->coreFrame(); |
| 1328 | if (coreFrame) { |
| 1329 | coreFrame->updateFrameTreeSyncData(data); |
| 1330 | |
| 1331 | if (data.type == FrameTreeSyncDataType::FrameRect) |
| 1332 | frame->updateFrameRectFromRemote(coreFrame->frameTreeSyncData().frameRect); |
| 1333 | } |
| 1334 | } |
| 1335 | |
| 1336 | void WebPage::allFrameTreeSyncDataChangedInAnotherProcess(FrameIdentifier frameID, Ref<WebCore::FrameTreeSyncData>&& data) |
| 1337 | { |
| 1338 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 1339 | |
| 1340 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1341 | if (!frame) |
| 1342 | return; |
| 1343 | |
| 1344 | ASSERT(frame->page() == this)((void)0); |
| 1345 | |
| 1346 | RefPtr coreFrame = frame->coreFrame(); |
| 1347 | if (coreFrame) |
| 1348 | coreFrame->updateFrameTreeSyncData(WTF::move(data)); |
| 1349 | } |
| 1350 | |
| 1351 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 1352 | void WebPage::gpuProcessConnectionDidBecomeAvailable(GPUProcessConnection& gpuProcessConnection) |
| 1353 | { |
| 1354 | UNUSED_PARAM(gpuProcessConnection)(void)gpuProcessConnection; |
| 1355 | |
| 1356 | #if HAVE(VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1357 | gpuProcessConnection.createVisibilityPropagationContextForPage(*this); |
| 1358 | #endif |
| 1359 | |
| 1360 | #if ENABLE(EXTENSION_CAPABILITIES)(defined 1 && 1) |
| 1361 | if (!mediaPlaybackEnvironment().isEmpty()) |
| 1362 | gpuProcessConnection.setMediaPlaybackEnvironment(identifier(), mediaPlaybackEnvironment()); |
| 1363 | |
| 1364 | if (!displayCaptureEnvironment().isEmpty()) |
| 1365 | gpuProcessConnection.setDisplayCaptureEnvironment(identifier(), displayCaptureEnvironment()); |
| 1366 | #endif |
| 1367 | } |
| 1368 | |
| 1369 | void WebPage::gpuProcessConnectionWasDestroyed() |
| 1370 | { |
| 1371 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 1372 | if (RefPtr remoteLayerTreeDrawingArea = dynamicDowncast<RemoteLayerTreeDrawingArea>(protect(drawingArea()))) |
| 1373 | remoteLayerTreeDrawingArea->gpuProcessConnectionWasDestroyed(); |
| 1374 | #endif |
| 1375 | } |
| 1376 | |
| 1377 | #endif |
| 1378 | |
| 1379 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 1380 | void WebPage::modelProcessConnectionDidBecomeAvailable(ModelProcessConnection& modelProcessConnection) |
| 1381 | { |
| 1382 | #if HAVE(VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1383 | modelProcessConnection.createVisibilityPropagationContextForPage(*this); |
| 1384 | #else |
| 1385 | UNUSED_PARAM(modelProcessConnection)(void)modelProcessConnection; |
| 1386 | #endif |
| 1387 | } |
| 1388 | #endif |
| 1389 | |
| 1390 | void WebPage::requestMediaPlaybackState(CompletionHandler<void(WebKit::MediaPlaybackState)>&& completionHandler) |
| 1391 | { |
| 1392 | RefPtr page = m_page; |
| 1393 | if (!page->mediaPlaybackExists()) |
| 1394 | return completionHandler(MediaPlaybackState::NoMediaPlayback); |
| 1395 | if (page->mediaPlaybackIsPaused()) |
| 1396 | return completionHandler(MediaPlaybackState::MediaPlaybackPaused); |
| 1397 | if (page->mediaPlaybackIsSuspended()) |
| 1398 | return completionHandler(MediaPlaybackState::MediaPlaybackSuspended); |
| 1399 | |
| 1400 | completionHandler(MediaPlaybackState::MediaPlaybackPlaying); |
| 1401 | } |
| 1402 | |
| 1403 | void WebPage::pauseAllMediaPlayback(CompletionHandler<void()>&& completionHandler) |
| 1404 | { |
| 1405 | protect(corePage())->pauseAllMediaPlayback(); |
| 1406 | completionHandler(); |
| 1407 | } |
| 1408 | |
| 1409 | void WebPage::suspendAllMediaPlayback(CompletionHandler<void()>&& completionHandler) |
| 1410 | { |
| 1411 | protect(corePage())->suspendAllMediaPlayback(); |
| 1412 | completionHandler(); |
| 1413 | } |
| 1414 | |
| 1415 | void WebPage::resumeAllMediaPlayback(CompletionHandler<void()>&& completionHandler) |
| 1416 | { |
| 1417 | protect(corePage())->resumeAllMediaPlayback(); |
| 1418 | completionHandler(); |
| 1419 | } |
| 1420 | |
| 1421 | void WebPage::suspendAllMediaBuffering() |
| 1422 | { |
| 1423 | protect(corePage())->suspendAllMediaBuffering(); |
| 1424 | } |
| 1425 | |
| 1426 | void WebPage::resumeAllMediaBuffering() |
| 1427 | { |
| 1428 | protect(corePage())->resumeAllMediaBuffering(); |
| 1429 | } |
| 1430 | |
| 1431 | static void addRootFramesToNewDrawingArea(WebFrame& frame, DrawingArea& drawingArea) |
| 1432 | { |
| 1433 | if (frame.isRootFrame() || (frame.provisionalFrame() && protect(frame.provisionalFrame())->isRootFrame())) |
| 1434 | drawingArea.addRootFrame(frame.frameID()); |
| 1435 | if (!frame.coreFrame()) |
| 1436 | return; |
| 1437 | for (RefPtr child = frame.coreFrame()->tree().firstChild(); child; child = child->tree().nextSibling()) { |
| 1438 | if (RefPtr childWebFrame = WebFrame::fromCoreFrame(*child)) |
| 1439 | addRootFramesToNewDrawingArea(*childWebFrame, drawingArea); |
| 1440 | } |
| 1441 | } |
| 1442 | |
| 1443 | void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters) |
| 1444 | { |
| 1445 | ASSERT(m_drawingArea)((void)0); |
| 1446 | |
| 1447 | setSize(parameters.viewSize); |
| 1448 | |
| 1449 | // If the UIProcess created a new DrawingArea, then we need to do the same. |
| 1450 | if (m_drawingArea->identifier() != parameters.drawingAreaIdentifier) { |
| 1451 | RefPtr oldDrawingArea = std::exchange(m_drawingArea, nullptr); |
| 1452 | oldDrawingArea->removeMessageReceiverIfNeeded(); |
| 1453 | |
| 1454 | m_drawingArea = DrawingArea::create(*this, parameters); |
| 1455 | RefPtr drawingArea = m_drawingArea; |
| 1456 | updateAfterDrawingAreaCreation(parameters); |
| 1457 | addRootFramesToNewDrawingArea(m_mainFrame.get(), *drawingArea); |
| 1458 | |
| 1459 | drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument); |
| 1460 | drawingArea->updatePreferences(parameters.store); |
| 1461 | |
| 1462 | #if USE(COORDINATED_GRAPHICS)(defined USE_COORDINATED_GRAPHICS && USE_COORDINATED_GRAPHICS ) || USE(TEXTURE_MAPPER)(defined USE_TEXTURE_MAPPER && USE_TEXTURE_MAPPER) |
| 1463 | if (drawingArea->enterAcceleratedCompositingModeIfNeeded() && !parameters.isProcessSwap) |
| 1464 | drawingArea->sendEnterAcceleratedCompositingModeIfNeeded(); |
| 1465 | #endif |
| 1466 | |
| 1467 | drawingArea->adoptLayersFromDrawingArea(*oldDrawingArea); |
| 1468 | drawingArea->adoptDisplayRefreshMonitorsFromDrawingArea(*oldDrawingArea); |
| 1469 | |
| 1470 | unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended); |
| 1471 | } |
| 1472 | |
| 1473 | setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout); |
| 1474 | setSizeToContentAutoSizeMaximumSize(parameters.sizeToContentAutoSizeMaximumSize); |
| 1475 | |
| 1476 | if (m_activityState != parameters.activityState) |
| 1477 | setActivityState(parameters.activityState, ActivityStateChangeAsynchronous, [] { }); |
| 1478 | |
| 1479 | #if HAVE(APP_ACCENT_COLORS)(defined HAVE_APP_ACCENT_COLORS && HAVE_APP_ACCENT_COLORS ) |
| 1480 | setAccentColor(parameters.accentColor); |
| 1481 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 1482 | setAppUsesCustomAccentColor(parameters.appUsesCustomAccentColor); |
| 1483 | #endif |
| 1484 | #endif |
| 1485 | |
| 1486 | setUseColorAppearance(parameters.useDarkAppearance, parameters.useElevatedUserInterfaceLevel); |
| 1487 | |
| 1488 | if (auto&& provisionalFrameCreationParameters = parameters.provisionalFrameCreationParameters) { |
| 1489 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 1490 | createProvisionalFrame(WTF::move(*provisionalFrameCreationParameters)); |
| 1491 | } |
| 1492 | |
| 1493 | platformReinitializeAccessibilityToken(); |
| 1494 | } |
| 1495 | |
| 1496 | void WebPage::updateThrottleState() |
| 1497 | { |
| 1498 | bool isThrottleable = this->isThrottleable(); |
| 1499 | |
| 1500 | // The UserActivity prevents App Nap. So if we want to allow App Nap of the page, stop the activity. |
| 1501 | // If the page should not be app nap'd, start it. |
| 1502 | if (isThrottleable) |
| 1503 | m_internals->userActivity.stop(); |
| 1504 | else |
| 1505 | m_internals->userActivity.start(); |
| 1506 | |
| 1507 | if (m_page && m_page->settings().serviceWorkersEnabled()) { |
| 1508 | RunLoop::mainSingleton().dispatch([isThrottleable] { |
| 1509 | WebServiceWorkerProvider::singleton().updateThrottleState(isThrottleable); |
| 1510 | }); |
| 1511 | } |
| 1512 | } |
| 1513 | |
| 1514 | bool WebPage::isThrottleable() const |
| 1515 | { |
| 1516 | bool isActive = m_activityState.containsAny({ ActivityState::IsLoading, ActivityState::IsAudible, ActivityState::IsCapturingMedia, ActivityState::WindowIsActive }); |
| 1517 | bool isVisuallyIdle = m_activityState.contains(ActivityState::IsVisuallyIdle); |
| 1518 | |
| 1519 | return m_isAppNapEnabled && !isActive && isVisuallyIdle; |
| 1520 | } |
| 1521 | |
| 1522 | WebPage::~WebPage() |
| 1523 | { |
| 1524 | ASSERT(!m_page)((void)0); |
| 1525 | WEBPAGE_RELEASE_LOG(Loading, "destructor:"); |
| 1526 | |
| 1527 | if (!m_corsDisablingPatterns.isEmpty()) { |
| 1528 | m_corsDisablingPatterns.clear(); |
| 1529 | synchronizeCORSDisablingPatternsWithNetworkProcess(); |
| 1530 | } |
| 1531 | |
| 1532 | platformDetach(); |
| 1533 | |
| 1534 | m_sandboxExtensionTracker.invalidate(); |
| 1535 | |
| 1536 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 1537 | for (Ref pluginView : m_pluginViews) |
| 1538 | pluginView->webPageDestroyed(); |
| 1539 | #endif |
| 1540 | |
| 1541 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 1542 | if (RefPtr headerBanner = m_headerBanner) |
| 1543 | headerBanner->detachFromPage(); |
| 1544 | if (RefPtr footerBanner = m_footerBanner) |
| 1545 | footerBanner->detachFromPage(); |
| 1546 | #endif |
| 1547 | |
| 1548 | WebStorageNamespaceProvider::decrementUseCount(sessionStorageNamespaceIdentifier()); |
| 1549 | |
| 1550 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) && HAVE(VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1551 | if (RefPtr gpuProcessConnection = WebProcess::singleton().existingGPUProcessConnection()) |
| 1552 | gpuProcessConnection->destroyVisibilityPropagationContextForPage(*this); |
| 1553 | #endif // ENABLE(GPU_PROCESS) |
| 1554 | |
| 1555 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) && HAVE(VISIBILITY_PROPAGATION_VIEW)(defined 1 && 1) |
| 1556 | if (RefPtr modelProcessConnection = WebProcess::singleton().existingModelProcessConnection()) |
| 1557 | modelProcessConnection->destroyVisibilityPropagationContextForPage(*this); |
| 1558 | #endif // ENABLE(MODEL_PROCESS) && HAVE(VISIBILITY_PROPAGATION_VIEW) |
| 1559 | |
| 1560 | #if ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1) |
| 1561 | if (RefPtr playbackSessionManager = m_playbackSessionManager) |
| 1562 | playbackSessionManager->invalidate(); |
| 1563 | |
| 1564 | if (RefPtr videoPresentationManager = m_videoPresentationManager) |
| 1565 | videoPresentationManager->invalidate(); |
| 1566 | #endif |
| 1567 | |
| 1568 | for (auto& completionHandler : std::exchange(m_markLayersAsVolatileCompletionHandlers, { })) |
| 1569 | completionHandler(false); |
| 1570 | |
| 1571 | #if ENABLE(EXTENSION_CAPABILITIES)(defined 1 && 1) |
| 1572 | setMediaPlaybackEnvironment({ }); |
| 1573 | setDisplayCaptureEnvironment({ }); |
| 1574 | #endif |
| 1575 | } |
| 1576 | |
| 1577 | IPC::Connection* WebPage::messageSenderConnection() const |
| 1578 | { |
| 1579 | return WebProcess::singleton().parentProcessConnection(); |
| 1580 | } |
| 1581 | |
| 1582 | uint64_t WebPage::messageSenderDestinationID() const |
| 1583 | { |
| 1584 | return identifier().toUInt64(); |
| 1585 | } |
| 1586 | |
| 1587 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 1588 | void WebPage::setInjectedBundleContextMenuClient(std::unique_ptr<API::InjectedBundle::PageContextMenuClient>&& contextMenuClient) |
| 1589 | { |
| 1590 | if (!contextMenuClient) { |
| 1591 | m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>(); |
| 1592 | return; |
| 1593 | } |
| 1594 | |
| 1595 | m_contextMenuClient = WTF::move(contextMenuClient); |
| 1596 | } |
| 1597 | #endif |
| 1598 | |
| 1599 | void WebPage::setInjectedBundleEditorClient(std::unique_ptr<API::InjectedBundle::EditorClient>&& editorClient) |
| 1600 | { |
| 1601 | if (!editorClient) { |
| 1602 | m_editorClient = makeUnique<API::InjectedBundle::EditorClient>(); |
| 1603 | return; |
| 1604 | } |
| 1605 | |
| 1606 | m_editorClient = WTF::move(editorClient); |
| 1607 | } |
| 1608 | |
| 1609 | void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient>&& formClient) |
| 1610 | { |
| 1611 | if (!formClient) { |
| 1612 | m_formClient = makeUnique<API::InjectedBundle::FormClient>(); |
| 1613 | return; |
| 1614 | } |
| 1615 | |
| 1616 | m_formClient = WTF::move(formClient); |
| 1617 | } |
| 1618 | |
| 1619 | void WebPage::setInjectedBundlePageLoaderClient(std::unique_ptr<API::InjectedBundle::PageLoaderClient>&& loaderClient) |
| 1620 | { |
| 1621 | if (!loaderClient) { |
| 1622 | m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>(); |
| 1623 | return; |
| 1624 | } |
| 1625 | |
| 1626 | m_loaderClient = WTF::move(loaderClient); |
| 1627 | |
| 1628 | // It would be nice to get rid of this code and transition all clients to using didLayout instead of |
| 1629 | // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required |
| 1630 | // for backwards compatibility. |
| 1631 | if (auto milestones = m_loaderClient->layoutMilestones()) |
| 1632 | listenForLayoutMilestones(milestones); |
| 1633 | } |
| 1634 | |
| 1635 | void WebPage::setInjectedBundleResourceLoadClient(std::unique_ptr<API::InjectedBundle::ResourceLoadClient>&& client) |
| 1636 | { |
| 1637 | if (!m_resourceLoadClient) |
| 1638 | m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>(); |
| 1639 | else |
| 1640 | m_resourceLoadClient = WTF::move(client); |
| 1641 | } |
| 1642 | |
| 1643 | void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient>&& uiClient) |
| 1644 | { |
| 1645 | if (!uiClient) { |
| 1646 | m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>(); |
| 1647 | return; |
| 1648 | } |
| 1649 | |
| 1650 | m_uiClient = WTF::move(uiClient); |
| 1651 | } |
| 1652 | |
| 1653 | bool WebPage::hasPendingEditorStateUpdate() const |
| 1654 | { |
| 1655 | return m_pendingEditorStateUpdateStatus != PendingEditorStateUpdateStatus::NotScheduled; |
| 1656 | } |
| 1657 | |
| 1658 | EditorState WebPage::editorState(ShouldPerformLayout shouldPerformLayout) const |
| 1659 | { |
| 1660 | // Always return an EditorState with a valid identifier or it will fail to decode and this process will be terminated. |
| 1661 | EditorState result; |
| 1662 | result.identifier = m_internals->lastEditorStateIdentifier.increment(); |
| 1663 | |
| 1664 | // Ref the frame because this function may perform layout, which may cause frame destruction. |
| 1665 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1666 | if (!frame) |
| 1667 | return result; |
| 1668 | |
| 1669 | auto sanitizeEditorStateOnceCreated = makeScopeExit([&result] { |
| 1670 | result.clipOwnedRectExtentsToNumericLimits(); |
| 1671 | }); |
| 1672 | |
| 1673 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 1674 | if (RefPtr pluginView = focusedPluginViewForFrame(*frame); pluginView && pluginView->populateEditorStateIfNeeded(result)) |
| 1675 | return result; |
| 1676 | #endif |
| 1677 | |
| 1678 | const VisibleSelection& selection = frame->selection().selection(); |
| 1679 | Ref editor = frame->editor(); |
| 1680 | |
| 1681 | result.selectionType = selection.type(); |
| 1682 | result.isContentEditable = selection.hasEditableStyle(); |
| 1683 | result.isContentRichlyEditable = selection.isContentRichlyEditable(); |
| 1684 | result.isInPasswordField = selection.isInPasswordField(); |
| 1685 | result.hasComposition = editor->hasComposition(); |
| 1686 | result.shouldIgnoreSelectionChanges = editor->ignoreSelectionChanges() || (editor->client() && !protect(editor->client())->shouldRevealCurrentSelectionAfterInsertion()); |
| 1687 | result.triggeredByAccessibilitySelectionChange = m_pendingEditorStateUpdateStatus == PendingEditorStateUpdateStatus::ScheduledDuringAccessibilitySelectionChange || m_isChangingSelectionForAccessibility; |
| 1688 | |
| 1689 | Ref<Document> document = *frame->document(); |
| 1690 | |
| 1691 | if (result.selectionType == WebCore::SelectionType::Range) { |
| 1692 | auto selectionRange = selection.range(); |
| 1693 | result.selectionIsRangeInsideImageOverlay = selectionRange && ImageOverlay::isInsideOverlay(*selectionRange); |
| 1694 | result.selectionIsRangeInAutoFilledAndViewableField = selection.isInAutoFilledAndViewableField(); |
| 1695 | } |
| 1696 | |
| 1697 | m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No; |
| 1698 | |
| 1699 | if (shouldAvoidComputingPostLayoutDataForEditorState()) { |
| 1700 | getPlatformEditorState(*frame, result); |
| 1701 | return result; |
| 1702 | } |
| 1703 | |
| 1704 | if (shouldPerformLayout == ShouldPerformLayout::Yes || requiresPostLayoutDataForEditorState(*frame)) |
| 1705 | document->updateLayout(); // May cause document destruction |
| 1706 | |
| 1707 | if (RefPtr frameView = document->view(); frameView && !frameView->needsLayout() && !document->hasNodesWithMissingStyle()) { |
| 1708 | if (!result.postLayoutData) |
| 1709 | result.postLayoutData = std::optional<EditorState::PostLayoutData> { EditorState::PostLayoutData { } }; |
| 1710 | result.postLayoutData->canCut = editor->canCut(); |
| 1711 | result.postLayoutData->canCopy = editor->canCopy(); |
| 1712 | result.postLayoutData->canPaste = editor->canEdit(); |
| 1713 | |
| 1714 | if (!result.visualData) |
| 1715 | result.visualData = std::optional<EditorState::VisualData> { EditorState::VisualData { } }; |
| 1716 | } |
| 1717 | |
| 1718 | getPlatformEditorState(*frame, result); |
| 1719 | |
| 1720 | return result; |
| 1721 | } |
| 1722 | |
| 1723 | void WebPage::changeFontAttributes(WebCore::FontAttributeChanges&& changes) |
| 1724 | { |
| 1725 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1726 | if (!frame) |
| 1727 | return; |
| 1728 | |
| 1729 | if (frame->selection().selection().isContentEditable()) |
| 1730 | protect(frame->editor())->applyStyleToSelection(changes.createEditingStyle(), changes.editAction(), Editor::ColorFilterMode::InvertColor); |
| 1731 | } |
| 1732 | |
| 1733 | void WebPage::changeFont(WebCore::FontChanges&& changes) |
| 1734 | { |
| 1735 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1736 | if (!frame) |
| 1737 | return; |
| 1738 | |
| 1739 | if (frame->selection().selection().isContentEditable()) |
| 1740 | protect(frame->editor())->applyStyleToSelection(changes.createEditingStyle(), EditAction::SetFont, Editor::ColorFilterMode::InvertColor); |
| 1741 | } |
| 1742 | |
| 1743 | void WebPage::executeEditCommandWithCallback(const String& commandName, const String& argument, CompletionHandler<void()>&& completionHandler) |
| 1744 | { |
| 1745 | executeEditCommand(commandName, argument); |
| 1746 | completionHandler(); |
| 1747 | } |
| 1748 | |
| 1749 | void WebPage::selectAll() |
| 1750 | { |
| 1751 | executeEditingCommand("SelectAll"_s, { }); |
| 1752 | platformDidSelectAll(); |
| 1753 | } |
| 1754 | |
| 1755 | bool WebPage::shouldDispatchSyntheticMouseEventsWhenModifyingSelection() const |
| 1756 | { |
| 1757 | RefPtr localTopDocument = protect(corePage())->localTopDocument(); |
| 1758 | return localTopDocument && localTopDocument->quirks().shouldDispatchSyntheticMouseEventsWhenModifyingSelection(); |
| 1759 | } |
| 1760 | |
| 1761 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 1762 | |
| 1763 | void WebPage::platformDidSelectAll() |
| 1764 | { |
| 1765 | } |
| 1766 | |
| 1767 | #endif // !PLATFORM(IOS_FAMILY) |
| 1768 | |
| 1769 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 1770 | std::pair<URL, WebCore::DidFilterLinkDecoration> WebPage::applyLinkDecorationFilteringWithResult(const URL& url, WebCore::LinkDecorationFilteringTrigger) |
| 1771 | { |
| 1772 | return { url, WebCore::DidFilterLinkDecoration::No }; |
| 1773 | } |
| 1774 | |
| 1775 | void WebPage::bindRemoteAccessibilityFrames(int, WebCore::FrameIdentifier, WebCore::AccessibilityRemoteToken, CompletionHandler<void(WebCore::AccessibilityRemoteToken, int)>&& completionHandler) |
| 1776 | { |
| 1777 | completionHandler({ }, { }); |
| 1778 | } |
| 1779 | |
| 1780 | void WebPage::resolveAccessibilityHitTestForTesting(WebCore::FrameIdentifier, const WebCore::IntPoint&, CompletionHandler<void(String)>&& completionHandler) |
| 1781 | { |
| 1782 | completionHandler({ }); |
| 1783 | } |
| 1784 | |
| 1785 | void WebPage::updateRemotePageAccessibilityOffset(WebCore::FrameIdentifier, WebCore::IntPoint) |
| 1786 | { |
| 1787 | } |
| 1788 | |
| 1789 | #endif |
| 1790 | |
| 1791 | #if ENABLE(ACCESSIBILITY_LOCAL_FRAME)(defined 1 && 1) |
| 1792 | void WebPage::updateRemotePageAccessibilityInheritedState(WebCore::FrameIdentifier frameID, const WebCore::InheritedFrameState& state) |
| 1793 | { |
| 1794 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1795 | if (!frame) |
| 1796 | return; |
| 1797 | |
| 1798 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 1799 | if (!coreFrame) |
| 1800 | return; |
| 1801 | |
| 1802 | RefPtr document = coreFrame->document(); |
| 1803 | if (!document) |
| 1804 | return; |
| 1805 | |
| 1806 | WeakPtr cache = document->axObjectCache(); |
| 1807 | if (!cache) |
| 1808 | return; |
| 1809 | |
| 1810 | cache->setFrameInheritedState(*coreFrame, state); |
| 1811 | } |
| 1812 | |
| 1813 | void WebPage::updateRemotePageAccessibilityScreenPosition(WebCore::FrameIdentifier frameID, const WebCore::FrameGeometry& geometry) |
| 1814 | { |
| 1815 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 1816 | RefPtr coreFrame = frame ? frame->coreLocalFrame() : nullptr; |
| 1817 | RefPtr document = coreFrame ? coreFrame->document() : nullptr; |
| 1818 | if (WeakPtr cache = document ? document->axObjectCache() : nullptr) |
| 1819 | cache->setFrameGeometry(*coreFrame, geometry); |
| 1820 | } |
| 1821 | #endif // ENABLE(ACCESSIBILITY_LOCAL_FRAME) |
| 1822 | |
| 1823 | void WebPage::updateEditorStateAfterLayoutIfEditabilityChanged() |
| 1824 | { |
| 1825 | // FIXME: We should update EditorStateIsContentEditable to track whether the state is richly |
| 1826 | // editable or plainttext-only. |
| 1827 | if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset) |
| 1828 | return; |
| 1829 | |
| 1830 | if (hasPendingEditorStateUpdate()) |
| 1831 | return; |
| 1832 | |
| 1833 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1834 | if (!frame) |
| 1835 | return; |
| 1836 | |
| 1837 | auto isEditable = frame->selection().selection().hasEditableStyle() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No; |
| 1838 | if (m_lastEditorStateWasContentEditable != isEditable) |
| 1839 | scheduleFullEditorStateUpdate(); |
| 1840 | } |
| 1841 | |
| 1842 | static OptionSet<RenderAsTextFlag> toRenderAsTextFlags(unsigned options) |
| 1843 | { |
| 1844 | OptionSet<RenderAsTextFlag> flags; |
| 1845 | |
| 1846 | if (options & RenderTreeShowAllLayers) |
| 1847 | flags.add(RenderAsTextFlag::ShowAllLayers); |
| 1848 | if (options & RenderTreeShowLayerNesting) |
| 1849 | flags.add(RenderAsTextFlag::ShowLayerNesting); |
| 1850 | if (options & RenderTreeShowCompositedLayers) |
| 1851 | flags.add(RenderAsTextFlag::ShowCompositedLayers); |
| 1852 | if (options & RenderTreeShowOverflow) |
| 1853 | flags.add(RenderAsTextFlag::ShowOverflow); |
| 1854 | if (options & RenderTreeShowSVGGeometry) |
| 1855 | flags.add(RenderAsTextFlag::ShowSVGGeometry); |
| 1856 | if (options & RenderTreeShowLayerFragments) |
| 1857 | flags.add(RenderAsTextFlag::ShowLayerFragments); |
| 1858 | |
| 1859 | return flags; |
| 1860 | } |
| 1861 | |
| 1862 | String WebPage::renderTreeExternalRepresentation(unsigned options) const |
| 1863 | { |
| 1864 | return externalRepresentation(protect(m_mainFrame->coreLocalFrame()).get(), toRenderAsTextFlags(options)); |
| 1865 | } |
| 1866 | |
| 1867 | String WebPage::renderTreeExternalRepresentationForPrinting() const |
| 1868 | { |
| 1869 | return externalRepresentation(protect(m_mainFrame->coreLocalFrame()).get(), { RenderAsTextFlag::PrintingMode }); |
| 1870 | } |
| 1871 | |
| 1872 | uint64_t WebPage::renderTreeSize() const |
| 1873 | { |
| 1874 | if (RefPtr page = m_page) |
| 1875 | return page->renderTreeSize(); |
| 1876 | return 0; |
| 1877 | } |
| 1878 | |
| 1879 | void WebPage::setHasResourceLoadClient(bool has) |
| 1880 | { |
| 1881 | if (m_page) |
| 1882 | m_page->setHasResourceLoadClient(has); |
| 1883 | } |
| 1884 | |
| 1885 | void WebPage::setCanUseCredentialStorage(bool has) |
| 1886 | { |
| 1887 | if (m_page) |
| 1888 | m_page->setCanUseCredentialStorage(has); |
| 1889 | } |
| 1890 | |
| 1891 | bool WebPage::isTrackingRepaints() const |
| 1892 | { |
| 1893 | if (RefPtr view = localMainFrameView()) |
| 1894 | return view->isTrackingRepaints(); |
| 1895 | |
| 1896 | return false; |
| 1897 | } |
| 1898 | |
| 1899 | Ref<API::Array> WebPage::trackedRepaintRects() |
| 1900 | { |
| 1901 | RefPtr view = localMainFrameView(); |
| 1902 | if (!view) |
| 1903 | return API::Array::create(); |
| 1904 | |
| 1905 | auto repaintRects = view->trackedRepaintRects().map([](auto& repaintRect) -> RefPtr<API::Object> { |
| 1906 | return API::Rect::create(toAPI(repaintRect)); |
| 1907 | }); |
| 1908 | return API::Array::create(WTF::move(repaintRects)); |
| 1909 | } |
| 1910 | |
| 1911 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 1912 | |
| 1913 | PluginView* WebPage::focusedPluginViewForFrame(LocalFrame& frame) |
| 1914 | { |
| 1915 | RefPtr pluginDocument = dynamicDowncast<PluginDocument>(frame.document()); |
| 1916 | if (!pluginDocument) |
| 1917 | return nullptr; |
| 1918 | |
| 1919 | if (pluginDocument->focusedElement() != pluginDocument->pluginElement()) |
| 1920 | return nullptr; |
| 1921 | |
| 1922 | return pluginViewForFrame(&frame); |
| 1923 | } |
| 1924 | |
| 1925 | PluginView* WebPage::pluginViewForFrame(LocalFrame* frame) |
| 1926 | { |
| 1927 | if (!frame) |
| 1928 | return nullptr; |
| 1929 | RefPtr document = dynamicDowncast<PluginDocument>(frame->document()); |
| 1930 | if (!document) |
| 1931 | return nullptr; |
| 1932 | return downcast<PluginView>(document->pluginWidget()); |
| 1933 | } |
| 1934 | |
| 1935 | PluginView* WebPage::mainFramePlugIn() const |
| 1936 | { |
| 1937 | RefPtr localMainFrame = this->localMainFrame(); |
| 1938 | return pluginViewForFrame(localMainFrame.get()); |
| 1939 | } |
| 1940 | |
| 1941 | #endif |
| 1942 | |
| 1943 | void WebPage::executeEditingCommand(const String& commandName, const String& argument) |
| 1944 | { |
| 1945 | platformWillPerformEditingCommand(); |
| 1946 | |
| 1947 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1948 | if (!frame) |
| 1949 | return; |
| 1950 | |
| 1951 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 1952 | if (RefPtr pluginView = focusedPluginViewForFrame(*frame)) { |
| 1953 | pluginView->handleEditingCommand(commandName, argument); |
| 1954 | return; |
| 1955 | } |
| 1956 | #endif |
| 1957 | |
| 1958 | protect(frame->editor())->command(commandName).execute(argument); |
| 1959 | } |
| 1960 | |
| 1961 | void WebPage::setEditable(bool editable) |
| 1962 | { |
| 1963 | protect(corePage())->setEditable(editable); |
| 1964 | protect(corePage())->setTabKeyCyclesThroughElements(!editable); |
| 1965 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1966 | if (!frame) |
| 1967 | return; |
| 1968 | |
| 1969 | if (editable) { |
| 1970 | protect(frame->editor())->applyEditingStyleToBodyElement(); |
| 1971 | // If the page is made editable and the selection is empty, set it to something. |
| 1972 | if (frame->selection().isNone()) |
| 1973 | protect(frame->selection())->setSelectionFromNone(); |
| 1974 | } |
| 1975 | } |
| 1976 | |
| 1977 | void WebPage::increaseListLevel() |
| 1978 | { |
| 1979 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1980 | if (!frame) |
| 1981 | return; |
| 1982 | |
| 1983 | protect(frame->editor())->increaseSelectionListLevel(); |
| 1984 | } |
| 1985 | |
| 1986 | void WebPage::decreaseListLevel() |
| 1987 | { |
| 1988 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1989 | if (!frame) |
| 1990 | return; |
| 1991 | |
| 1992 | protect(frame->editor())->decreaseSelectionListLevel(); |
| 1993 | } |
| 1994 | |
| 1995 | void WebPage::changeListType() |
| 1996 | { |
| 1997 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 1998 | if (!frame) |
| 1999 | return; |
| 2000 | |
| 2001 | protect(frame->editor())->changeSelectionListType(); |
| 2002 | } |
| 2003 | |
| 2004 | void WebPage::setBaseWritingDirection(WritingDirection direction) |
| 2005 | { |
| 2006 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 2007 | if (!frame) |
| 2008 | return; |
| 2009 | |
| 2010 | protect(frame->editor())->setBaseWritingDirection(direction); |
| 2011 | } |
| 2012 | |
| 2013 | void WebPage::enterAcceleratedCompositingMode(WebCore::Frame& frame, GraphicsLayer* layer) |
| 2014 | { |
| 2015 | protect(drawingArea())->setRootCompositingLayer(frame, layer); |
| 2016 | } |
| 2017 | |
| 2018 | void WebPage::exitAcceleratedCompositingMode(WebCore::Frame& frame) |
| 2019 | { |
| 2020 | protect(drawingArea())->setRootCompositingLayer(frame, nullptr); |
| 2021 | } |
| 2022 | |
| 2023 | void WebPage::close() |
| 2024 | { |
| 2025 | if (m_isClosed) |
| 2026 | return; |
| 2027 | |
| 2028 | flushDeferredDidReceiveMouseEvent(); |
| 2029 | |
| 2030 | WEBPAGE_RELEASE_LOG_FORWARDABLE(Loading, WEBPAGE_CLOSE)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_CLOSE(m_identifier.toUInt64()); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogLoading .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::close"), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG71" ) = "[webPageID=%" "ll" "u" "] WebPage::close"; uint8_t _Alignas (16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("[webPageID=%" "ll" "u" "] WebPage::close", m_identifier.toUInt64 ())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "[webPageID=%" "ll" "u" "] WebPage::close", m_identifier.toUInt64()), (uint32_t )sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0); |
| 2031 | |
| 2032 | if (RefPtr networkProcessConnection = WebProcess::singleton().existingNetworkProcessConnection()) |
| 2033 | networkProcessConnection->connection().send(Messages::NetworkConnectionToWebProcess::ClearPageSpecificData(m_identifier), 0); |
| 2034 | |
| 2035 | m_isClosed = true; |
| 2036 | |
| 2037 | // If there is still no URL, then we never loaded anything in this page, so nothing to report. |
| 2038 | if (!m_mainFrame->url().isEmpty()) |
| 2039 | reportUsedFeatures(); |
| 2040 | |
| 2041 | if (WebProcess::singleton().injectedBundle()) |
| 2042 | WebProcess::singleton().injectedBundle()->willDestroyPage(Ref { *this }); |
| 2043 | |
| 2044 | if (RefPtr inspector = std::exchange(m_inspector, nullptr)) |
| 2045 | inspector->disconnectFromPage(); |
| 2046 | |
| 2047 | m_page->inspectorController().disconnectAllFrontends(); |
| 2048 | |
| 2049 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 2050 | if (auto manager = std::exchange(m_fullScreenManager, { })) |
| 2051 | manager->invalidate(); |
| 2052 | #endif |
| 2053 | |
| 2054 | if (RefPtr activePopupMenu = std::exchange(m_activePopupMenu, nullptr)) |
| 2055 | activePopupMenu->disconnectFromPage(); |
| 2056 | |
| 2057 | if (RefPtr activeOpenPanelResultListener = std::exchange(m_activeOpenPanelResultListener, nullptr)) |
| 2058 | activeOpenPanelResultListener->disconnectFromPage(); |
| 2059 | |
| 2060 | if (RefPtr activeColorChooser = m_activeColorChooser.get()) { |
| 2061 | activeColorChooser->disconnectFromPage(); |
| 2062 | m_activeColorChooser = nullptr; |
| 2063 | } |
| 2064 | |
| 2065 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 2066 | m_printOperation = nullptr; |
| 2067 | #endif |
| 2068 | |
| 2069 | m_sandboxExtensionTracker.invalidate(); |
| 2070 | |
| 2071 | #if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1) |
| 2072 | m_textAutoSizingAdjustmentTimer.stop(); |
| 2073 | #endif |
| 2074 | |
| 2075 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2076 | invokePendingSyntheticClickCallback(SyntheticClickResult::PageInvalid); |
| 2077 | m_updateFocusedElementInformationTimer.stop(); |
| 2078 | #endif |
| 2079 | |
| 2080 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 2081 | m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>(); |
| 2082 | #endif |
| 2083 | m_editorClient = makeUnique<API::InjectedBundle::EditorClient>(); |
| 2084 | m_formClient = makeUnique<API::InjectedBundle::FormClient>(); |
| 2085 | m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>(); |
| 2086 | m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>(); |
| 2087 | m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>(); |
| 2088 | |
| 2089 | m_printContext = nullptr; |
| 2090 | if (RefPtr localFrame = m_mainFrame->coreLocalFrame()) |
| 2091 | localFrame->loader().detachFromParent(); |
| 2092 | |
| 2093 | if (RefPtr provisionalFrame = m_mainFrame->provisionalFrame()) |
| 2094 | provisionalFrame->loader().detachFromParent(); |
| 2095 | |
| 2096 | #if ENABLE(SCROLLING_THREAD)(defined 0 && 0) |
| 2097 | if (m_useAsyncScrolling) |
| 2098 | protect(drawingArea())->unregisterScrollingTree(); |
| 2099 | #endif |
| 2100 | |
| 2101 | protect(corePage())->destroyRenderTrees(); |
| 2102 | |
| 2103 | m_drawingArea = nullptr; |
| 2104 | m_webPageTesting = nullptr; |
| 2105 | m_page = nullptr; |
| 2106 | |
| 2107 | bool isRunningModal = m_isRunningModal; |
| 2108 | m_isRunningModal = false; |
| 2109 | |
| 2110 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 2111 | if (RefPtr remoteObjectRegistry = m_remoteObjectRegistry.get()) |
| 2112 | remoteObjectRegistry->close(); |
| 2113 | ASSERT(!m_remoteObjectRegistry)((void)0); |
| 2114 | #endif |
| 2115 | |
| 2116 | auto& webProcess = WebProcess::singleton(); |
| 2117 | webProcess.removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier); |
| 2118 | // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers. |
| 2119 | webProcess.removeMessageReceiver(Messages::WebInspectorBackend::messageReceiverName(), m_identifier); |
| 2120 | webProcess.removeMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier); |
| 2121 | webProcess.removeMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier); |
| 2122 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 2123 | webProcess.removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier); |
| 2124 | #endif |
| 2125 | #if PLATFORM(COCOA)(defined 1 && 1) || PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 2126 | m_viewGestureGeometryCollector = nullptr; |
| 2127 | #endif |
| 2128 | |
| 2129 | stopObservingNowPlayingMetadata(); |
| 2130 | |
| 2131 | String processDisplayName = m_processDisplayName; |
| 2132 | |
| 2133 | // The WebPage can be destroyed by this call. |
| 2134 | WebProcess::singleton().removeWebPage(m_identifier); |
| 2135 | |
| 2136 | WebProcess::singleton().updateActivePages(processDisplayName); |
| 2137 | |
| 2138 | if (isRunningModal) |
| 2139 | RunLoop::mainSingleton().stop(); |
| 2140 | } |
| 2141 | |
| 2142 | void WebPage::tryClose(CompletionHandler<void(bool)>&& completionHandler) |
| 2143 | { |
| 2144 | RefPtr coreFrame = m_mainFrame->coreLocalFrame(); |
| 2145 | if (!coreFrame) { |
| 2146 | completionHandler(false); |
| 2147 | return; |
| 2148 | } |
| 2149 | completionHandler(coreFrame->loader().shouldClose()); |
| 2150 | } |
| 2151 | |
| 2152 | void WebPage::sendClose() |
| 2153 | { |
| 2154 | send(Messages::WebPageProxy::ClosePage()); |
| 2155 | } |
| 2156 | |
| 2157 | void WebPage::suspendForProcessSwap(CompletionHandler<void(std::optional<bool>)>&& completionHandler) |
| 2158 | { |
| 2159 | flushDeferredDidReceiveMouseEvent(); |
| 2160 | |
| 2161 | // FIXME: Make this work if the main frame is not a LocalFrame. |
| 2162 | RefPtr currentHistoryItem = m_mainFrame->coreLocalFrame()->loader().history().currentItem(); |
| 2163 | if (!currentHistoryItem) |
| 2164 | return completionHandler(false); |
| 2165 | |
| 2166 | if (!BackForwardCache::singleton().addIfCacheable(*currentHistoryItem, protect(corePage()).get())) |
| 2167 | return completionHandler(false); |
| 2168 | |
| 2169 | // Back/forward cache does not break the opener link for the main frame (only does so for the subframes) because the |
| 2170 | // main frame is normally re-used for the navigation. However, in the case of process-swapping, the main frame |
| 2171 | // is now hosted in another process and the one in this process is in the cache. |
| 2172 | if (RefPtr frame = m_mainFrame->coreLocalFrame()) |
| 2173 | frame->detachFromAllOpenedFrames(); |
| 2174 | |
| 2175 | completionHandler(true); |
| 2176 | } |
| 2177 | |
| 2178 | void WebPage::loadURLInFrame(URL&& url, const String& referrer, FrameIdentifier frameID) |
| 2179 | { |
| 2180 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 2181 | if (!frame) |
| 2182 | return; |
| 2183 | |
| 2184 | RefPtr coreLocalFrame = frame->coreLocalFrame(); |
| 2185 | coreLocalFrame->loader().load(FrameLoadRequest(*coreLocalFrame, ResourceRequest(URL { url }, referrer))); |
| 2186 | } |
| 2187 | |
| 2188 | void WebPage::loadDataInFrame(std::span<const uint8_t> data, String&& type, String&& encodingName, URL&& baseURL, FrameIdentifier frameID) |
| 2189 | { |
| 2190 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 2191 | if (!frame) |
| 2192 | return; |
| 2193 | ASSERT(&mainWebFrame() != frame)((void)0); |
| 2194 | |
| 2195 | Ref sharedBuffer = SharedBuffer::create(data); |
| 2196 | ResourceResponse response(URL { baseURL }, WTF::move(type), sharedBuffer->size(), WTF::move(encodingName)); |
| 2197 | SubstituteData substituteData(WTF::move(sharedBuffer), URL { baseURL }, WTF::move(response), SubstituteData::SessionHistoryVisibility::Hidden); |
| 2198 | frame->coreLocalFrame()->loader().load(FrameLoadRequest(*frame->coreLocalFrame(), ResourceRequest(WTF::move(baseURL)), WTF::move(substituteData))); |
| 2199 | } |
| 2200 | |
| 2201 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 2202 | void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters) |
| 2203 | { |
| 2204 | } |
| 2205 | #endif |
| 2206 | |
| 2207 | void WebPage::createProvisionalFrame(ProvisionalFrameCreationParameters&& parameters) |
| 2208 | { |
| 2209 | RefPtr frame = WebProcess::singleton().webFrame(parameters.frameID); |
| 2210 | if (!frame) |
| 2211 | return; |
| 2212 | ASSERT(frame->page() == this)((void)0); |
| 2213 | frame->createProvisionalFrame(WTF::move(parameters)); |
| 2214 | } |
| 2215 | |
| 2216 | void WebPage::loadDidCommitInAnotherProcess(WebCore::FrameIdentifier frameID, std::optional<WebCore::LayerHostingContextIdentifier> layerHostingContextIdentifier) |
| 2217 | { |
| 2218 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 2219 | if (!frame) |
| 2220 | return; |
| 2221 | ASSERT(frame->page() == this)((void)0); |
| 2222 | frame->loadDidCommitInAnotherProcess(layerHostingContextIdentifier); |
| 2223 | } |
| 2224 | |
| 2225 | void WebPage::loadRequest(LoadParameters&& loadParameters) |
| 2226 | { |
| 2227 | WEBPAGE_RELEASE_LOG_FORWARDABLE(Loading, WEBPAGE_LOADREQUEST, loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume->toUInt64() : 0)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_LOADREQUEST(m_identifier.toUInt64 (), loadParameters.navigationID ? loadParameters.navigationID ->toUInt64() : 0, static_cast<unsigned>(loadParameters .shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated (), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume ->toUInt64() : 0); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogLoading .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::loadRequest: navigationID=%" "ll" "u" ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" "ll" "u"), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG72" ) = "[webPageID=%" "ll" "u" "] WebPage::loadRequest: navigationID=%" "ll" "u" ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" "ll" "u"; uint8_t _Alignas(16) __attribute__((uninitialized) ) _os_fmt_buf[__builtin_os_log_format_buffer_size("[webPageID=%" "ll" "u" "] WebPage::loadRequest: navigationID=%" "ll" "u" ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" "ll" "u", m_identifier.toUInt64(), loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast <unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume ->toUInt64() : 0)]; _os_log_impl(&__dso_handle, _log_tmp , _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format( _os_fmt_buf, "[webPageID=%" "ll" "u" "] WebPage::loadRequest: navigationID=%" "ll" "u" ", shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" "ll" "u", m_identifier.toUInt64(), loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast <unsigned>(loadParameters.shouldTreatAsContinuingLoad), loadParameters.request.isAppInitiated(), loadParameters.existingNetworkResourceLoadIdentifierToResume ? loadParameters.existingNetworkResourceLoadIdentifierToResume ->toUInt64() : 0), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0); |
| 2228 | |
| 2229 | RefPtr frame = loadParameters.frameIdentifier ? WebProcess::singleton().webFrame(*loadParameters.frameIdentifier) : m_mainFrame.ptr(); |
| 2230 | if (!frame) { |
| 2231 | ASSERT_NOT_REACHED()((void)0); |
| 2232 | return; |
| 2233 | } |
| 2234 | RefPtr localFrame = frame->coreLocalFrame() ? frame->coreLocalFrame() : frame->provisionalFrame(); |
| 2235 | if (!localFrame) { |
| 2236 | ASSERT_NOT_REACHED()((void)0); |
| 2237 | return; |
| 2238 | } |
| 2239 | |
| 2240 | setLastNavigationWasAppInitiated(loadParameters.request.isAppInitiated()); |
| 2241 | |
| 2242 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 2243 | setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain, *frame); |
| 2244 | #endif |
| 2245 | |
| 2246 | WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(loadParameters.existingNetworkResourceLoadIdentifierToResume); |
| 2247 | auto resumingLoadScope = makeScopeExit([] { |
| 2248 | WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(std::nullopt); |
| 2249 | }); |
| 2250 | |
| 2251 | SendStopResponsivenessTimer stopper; |
| 2252 | |
| 2253 | m_pendingNavigationID = loadParameters.navigationID; |
| 2254 | m_internals->pendingWebsitePolicies = WTF::move(loadParameters.websitePolicies); |
| 2255 | |
| 2256 | m_sandboxExtensionTracker.beginLoad(WTF::move(loadParameters.sandboxExtensionHandle)); |
| 2257 | |
| 2258 | // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess |
| 2259 | // to all the client to set up any needed state. |
| 2260 | m_loaderClient->willLoadURLRequest(*this, loadParameters.request, WebProcess::singleton().transformHandlesToObjects(protect(loadParameters.userData.object()).get()).get()); |
| 2261 | |
| 2262 | platformDidReceiveLoadParameters(loadParameters); |
| 2263 | |
| 2264 | if (loadParameters.originatingFrame && !loadParameters.frameIdentifier) |
| 2265 | m_mainFrameNavigationInitiator = makeUnique<FrameInfoData>(*loadParameters.originatingFrame); |
| 2266 | |
| 2267 | // Initate the load in WebCore. |
| 2268 | ASSERT(localFrame->document())((void)0); |
| 2269 | FrameLoadRequest frameLoadRequest { *localFrame, WTF::move(loadParameters.request) }; |
| 2270 | frameLoadRequest.setShouldOpenExternalURLsPolicy(loadParameters.shouldOpenExternalURLsPolicy); |
| 2271 | frameLoadRequest.setShouldTreatAsContinuingLoad(loadParameters.shouldTreatAsContinuingLoad); |
| 2272 | frameLoadRequest.setLockHistory(loadParameters.lockHistory); |
| 2273 | frameLoadRequest.setLockBackForwardList(loadParameters.lockBackForwardList); |
| 2274 | frameLoadRequest.setClientRedirectSourceForHistory(WTF::move(loadParameters.clientRedirectSourceForHistory)); |
| 2275 | frameLoadRequest.setIsHandledByAboutSchemeHandler(loadParameters.isHandledByAboutSchemeHandler); |
| 2276 | if (loadParameters.isRequestFromClientOrUserInput) |
| 2277 | frameLoadRequest.setIsRequestFromClientOrUserInput(); |
| 2278 | if (loadParameters.advancedPrivacyProtections) |
| 2279 | frameLoadRequest.setAdvancedPrivacyProtections(*loadParameters.advancedPrivacyProtections); |
| 2280 | if (loadParameters.originalRequest) |
| 2281 | frameLoadRequest.setOriginalResourceRequest(*loadParameters.originalRequest); |
| 2282 | |
| 2283 | if (loadParameters.effectiveSandboxFlags) |
| 2284 | localFrame->updateSandboxFlags(loadParameters.effectiveSandboxFlags, Frame::NotifyUIProcess::No); |
| 2285 | |
| 2286 | if (auto ownerPermissionsPolicy = std::exchange(loadParameters.ownerPermissionsPolicy, { })) |
| 2287 | localFrame->setOwnerPermissionsPolicy(WTF::move(*ownerPermissionsPolicy)); |
| 2288 | |
| 2289 | localFrame->loader().setNavigationUpgradeToHTTPSBehavior(loadParameters.navigationUpgradeToHTTPSBehavior); |
| 2290 | localFrame->loader().setRequiredCookiesVersion(loadParameters.requiredCookiesVersion); |
| 2291 | localFrame->loader().load(WTF::move(frameLoadRequest), WTF::move(loadParameters.requester)); |
| 2292 | |
| 2293 | ASSERT(!m_pendingNavigationID)((void)0); |
| 2294 | ASSERT(!m_internals->pendingWebsitePolicies)((void)0); |
| 2295 | } |
| 2296 | |
| 2297 | // LoadRequestWaitingForProcessLaunch should never be sent to the WebProcess. It must always be converted to a LoadRequest message. |
| 2298 | void WebPage::loadRequestWaitingForProcessLaunch(LoadParameters&&, URL&&, WebPageProxyIdentifier, bool) |
| 2299 | { |
| 2300 | RELEASE_ASSERT_NOT_REACHED()do { WTF::isIntegralOrPointerType(); compilerFenceForCrash(); WTFCrashWithInfo(2300, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); |
| 2301 | } |
| 2302 | |
| 2303 | void WebPage::loadDataImpl(std::optional<WebCore::NavigationIdentifier> navigationID, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<WebsitePoliciesData>&& websitePolicies, Ref<FragmentedSharedBuffer>&& sharedBuffer, ResourceRequest&& request, ResourceResponse&& response, URL&& unreachableURL, const UserData& userData, std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, SubstituteData::SessionHistoryVisibility sessionHistoryVisibility, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy) |
| 2304 | { |
| 2305 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 2306 | Ref mainFrame = m_mainFrame.copyRef(); |
| 2307 | setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain, mainFrame.get()); |
| 2308 | mainFrame->setIsSafeBrowsingCheckOngoing(SafeBrowsingCheckOngoing::No); |
| 2309 | #else |
| 2310 | UNUSED_PARAM(isNavigatingToAppBoundDomain)(void)isNavigatingToAppBoundDomain; |
| 2311 | #endif |
| 2312 | |
| 2313 | SendStopResponsivenessTimer stopper; |
| 2314 | |
| 2315 | m_pendingNavigationID = navigationID; |
| 2316 | m_internals->pendingWebsitePolicies = WTF::move(websitePolicies); |
| 2317 | |
| 2318 | SubstituteData substituteData(WTF::move(sharedBuffer), WTF::move(unreachableURL), WTF::move(response), sessionHistoryVisibility); |
| 2319 | |
| 2320 | // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess |
| 2321 | // to all the client to set up any needed state. |
| 2322 | m_loaderClient->willLoadDataRequest(*this, request, substituteData.content(), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(protect(userData.object()).get()).get()); |
| 2323 | |
| 2324 | RefPtr localFrame = m_mainFrame->coreLocalFrame() ? m_mainFrame->coreLocalFrame() : m_mainFrame->provisionalFrame(); |
| 2325 | if (!localFrame) { |
| 2326 | ASSERT_NOT_REACHED()((void)0); |
| 2327 | return; |
| 2328 | } |
| 2329 | |
| 2330 | // Initate the load in WebCore. |
| 2331 | FrameLoadRequest frameLoadRequest(*localFrame, WTF::move(request), WTF::move(substituteData)); |
| 2332 | frameLoadRequest.setShouldOpenExternalURLsPolicy(shouldOpenExternalURLsPolicy); |
| 2333 | frameLoadRequest.setShouldTreatAsContinuingLoad(shouldTreatAsContinuingLoad); |
| 2334 | frameLoadRequest.setIsRequestFromClientOrUserInput(); |
| 2335 | localFrame->loader().load(WTF::move(frameLoadRequest)); |
| 2336 | } |
| 2337 | |
| 2338 | void WebPage::loadData(LoadParameters&& loadParameters) |
| 2339 | { |
| 2340 | WEBPAGE_RELEASE_LOG(Loading, "loadData: navigationID=%" PRIu64"ll" "u" ", shouldTreatAsContinuingLoad=%u", loadParameters.navigationID ? loadParameters.navigationID->toUInt64() : 0, static_cast<unsigned>(loadParameters.shouldTreatAsContinuingLoad)); |
| 2341 | |
| 2342 | platformDidReceiveLoadParameters(loadParameters); |
| 2343 | |
| 2344 | RefPtr sharedBuffer = loadParameters.data; |
| 2345 | if (!sharedBuffer) { |
| 2346 | ASSERT_NOT_REACHED()((void)0); |
| 2347 | return; |
| 2348 | } |
| 2349 | |
| 2350 | URL baseURL; |
| 2351 | if (loadParameters.baseURLString.isEmpty()) |
| 2352 | baseURL = aboutBlankURL(); |
| 2353 | else { |
| 2354 | baseURL = URL { WTF::move(loadParameters.baseURLString) }; |
| 2355 | if (baseURL.isValid() && !baseURL.protocolIsInHTTPFamily()) |
| 2356 | LegacySchemeRegistry::registerURLSchemeAsHandledBySchemeHandler(baseURL.protocol().toString()); |
| 2357 | } |
| 2358 | |
| 2359 | if (loadParameters.isServiceWorkerLoad && corePage()) |
| 2360 | corePage()->markAsServiceWorkerPage(); |
| 2361 | |
| 2362 | ResourceResponse response(URL(), WTF::move(loadParameters.MIMEType), sharedBuffer->size(), WTF::move(loadParameters.encodingName)); |
| 2363 | loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTF::move(loadParameters.websitePolicies), sharedBuffer.releaseNonNull(), ResourceRequest(WTF::move(baseURL)), WTF::move(response), URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.sessionHistoryVisibility, loadParameters.shouldOpenExternalURLsPolicy); |
| 2364 | } |
| 2365 | |
| 2366 | void WebPage::loadAlternateHTML(LoadParameters&& loadParameters) |
| 2367 | { |
| 2368 | platformDidReceiveLoadParameters(loadParameters); |
| 2369 | |
| 2370 | URL baseURL = loadParameters.baseURLString.isEmpty() ? aboutBlankURL() : URL { WTF::move(loadParameters.baseURLString) }; |
| 2371 | URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL { WTF::move(loadParameters.unreachableURLString) }; |
| 2372 | URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL { WTF::move(loadParameters.provisionalLoadErrorURLString) }; |
| 2373 | RefPtr sharedBuffer = loadParameters.data; |
| 2374 | if (!sharedBuffer) { |
| 2375 | ASSERT_NOT_REACHED()((void)0); |
| 2376 | return; |
| 2377 | } |
| 2378 | m_mainFrame->coreLocalFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL); |
| 2379 | |
| 2380 | ResourceResponse response(URL(), WTF::move(loadParameters.MIMEType), sharedBuffer->size(), WTF::move(loadParameters.encodingName)); |
| 2381 | loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTF::move(loadParameters.websitePolicies), sharedBuffer.releaseNonNull(), ResourceRequest(WTF::move(baseURL)), WTF::move(response), WTF::move(unreachableURL), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, WebCore::SubstituteData::SessionHistoryVisibility::Hidden); |
| 2382 | m_mainFrame->coreLocalFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ }); |
| 2383 | } |
| 2384 | |
| 2385 | void WebPage::loadSimulatedRequestAndResponse(LoadParameters&& loadParameters, ResourceResponse&& simulatedResponse) |
| 2386 | { |
| 2387 | setLastNavigationWasAppInitiated(loadParameters.request.isAppInitiated()); |
| 2388 | RefPtr sharedBuffer = loadParameters.data; |
| 2389 | if (!sharedBuffer) { |
| 2390 | ASSERT_NOT_REACHED()((void)0); |
| 2391 | return; |
| 2392 | } |
| 2393 | loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTF::move(loadParameters.websitePolicies), sharedBuffer.releaseNonNull(), WTF::move(loadParameters.request), WTF::move(simulatedResponse), URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, SubstituteData::SessionHistoryVisibility::Visible); |
| 2394 | } |
| 2395 | |
| 2396 | void WebPage::stopLoading() |
| 2397 | { |
| 2398 | if (!m_page || !m_mainFrame->coreLocalFrame()) |
| 2399 | return; |
| 2400 | |
| 2401 | SendStopResponsivenessTimer stopper; |
| 2402 | |
| 2403 | Ref coreFrame = *m_mainFrame->coreLocalFrame(); |
| 2404 | coreFrame->loader().stopForUserCancel(); |
| 2405 | coreFrame->loader().completePageTransitionIfNeeded(); |
| 2406 | } |
| 2407 | |
| 2408 | void WebPage::stopLoadingDueToProcessSwap() |
| 2409 | { |
| 2410 | SetForScope isStoppingLoadingDueToProcessSwap(m_isStoppingLoadingDueToProcessSwap, true); |
| 2411 | stopLoading(); |
| 2412 | } |
| 2413 | |
| 2414 | bool WebPage::defersLoading() const |
| 2415 | { |
| 2416 | return m_page->defersLoading(); |
| 2417 | } |
| 2418 | |
| 2419 | void WebPage::reload(WebCore::NavigationIdentifier navigationID, OptionSet<WebCore::ReloadOption> reloadOptions, SandboxExtension::Handle&& sandboxExtensionHandle) |
| 2420 | { |
| 2421 | SendStopResponsivenessTimer stopper; |
| 2422 | |
| 2423 | ASSERT(!m_mainFrame->coreLocalFrame()->loader().frameHasLoaded() || !m_pendingNavigationID)((void)0); |
| 2424 | m_pendingNavigationID = navigationID; |
| 2425 | |
| 2426 | Ref mainFrame = m_mainFrame; |
| 2427 | m_sandboxExtensionTracker.beginReload(mainFrame.ptr(), WTF::move(sandboxExtensionHandle)); |
| 2428 | if (m_page && mainFrame->coreLocalFrame()) { |
| 2429 | bool isRequestFromClientOrUserInput = true; |
| 2430 | mainFrame->coreLocalFrame()->loader().reload(reloadOptions, isRequestFromClientOrUserInput); |
| 2431 | } else |
| 2432 | ASSERT_NOT_REACHED()((void)0); |
| 2433 | |
| 2434 | if (m_pendingNavigationID) { |
| 2435 | // This can happen if FrameLoader::reload() returns early because the document URL is empty. |
| 2436 | // The reload does nothing so we need to reset the pending navigation. See webkit.org/b/153210. |
| 2437 | m_pendingNavigationID = std::nullopt; |
| 2438 | } |
| 2439 | } |
| 2440 | |
| 2441 | void WebPage::goToBackForwardItem(GoToBackForwardItemParameters&& parameters) |
| 2442 | { |
| 2443 | WEBPAGE_RELEASE_LOG(Loading, "goToBackForwardItem: navigationID=%" PRIu64"ll" "u" ", backForwardItemID=%s, shouldTreatAsContinuingLoad=%u, lastNavigationWasAppInitiated=%d, existingNetworkResourceLoadIdentifierToResume=%" PRIu64"ll" "u", parameters.navigationID.toUInt64(), parameters.frameState->itemID->toString().utf8().data(), static_cast<unsigned>(parameters.shouldTreatAsContinuingLoad), parameters.lastNavigationWasAppInitiated, parameters.existingNetworkResourceLoadIdentifierToResume ? parameters.existingNetworkResourceLoadIdentifierToResume->toUInt64() : 0); |
| 2444 | SendStopResponsivenessTimer stopper; |
| 2445 | |
| 2446 | m_sandboxExtensionTracker.beginLoad(WTF::move(parameters.sandboxExtensionHandle)); |
| 2447 | |
| 2448 | m_lastNavigationWasAppInitiated = parameters.lastNavigationWasAppInitiated; |
| 2449 | if (RefPtr localMainFrame = protect(corePage())->localMainFrame()) { |
| 2450 | if (RefPtr documentLoader = localMainFrame->loader().documentLoader()) |
| 2451 | documentLoader->setLastNavigationWasAppInitiated(parameters.lastNavigationWasAppInitiated); |
| 2452 | } |
| 2453 | |
| 2454 | WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(parameters.existingNetworkResourceLoadIdentifierToResume); |
| 2455 | auto resumingLoadScope = makeScopeExit([] { |
| 2456 | WebProcess::singleton().webLoaderStrategy().setExistingNetworkResourceLoadIdentifierToResume(std::nullopt); |
| 2457 | }); |
| 2458 | |
| 2459 | ASSERT(isBackForwardLoadType(parameters.backForwardType))((void)0); |
| 2460 | |
| 2461 | RefPtr<HistoryItem> item; |
| 2462 | { |
| 2463 | auto ignoreHistoryItemChangesForScope = m_historyItemClient->ignoreChangesForScope(); |
| 2464 | item = toHistoryItem(m_historyItemClient, parameters.frameState); |
| 2465 | if (RefPtr localMainFrame = protect(corePage())->localMainFrame(); localMainFrame && item) |
| 2466 | localMainFrame->loader().setNavigationUpgradeToHTTPSBehavior(item->url().protocolIs("http"_s) ? NavigationUpgradeToHTTPSBehavior::Disabled : NavigationUpgradeToHTTPSBehavior::BasedOnPolicy); |
| 2467 | } |
| 2468 | |
| 2469 | LOG(Loading, "In WebProcess pid %i, WebPage %" PRIu64 " is navigating to back/forward URL %s", getCurrentProcessID(), m_identifier.toUInt64(), item->url().string().utf8().data())((void)0); |
| 2470 | |
| 2471 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 2472 | WebCore::PublicSuffixStore::singleton().addPublicSuffix(parameters.publicSuffix); |
| 2473 | #endif |
| 2474 | |
| 2475 | m_pendingNavigationID = parameters.navigationID; |
| 2476 | m_internals->pendingWebsitePolicies = WTF::move(parameters.websitePolicies); |
| 2477 | |
| 2478 | Ref targetFrame = m_mainFrame; |
| 2479 | if (RefPtr historyItemFrame = WebProcess::singleton().webFrame(item->frameID()); historyItemFrame && historyItemFrame->page() == this) |
| 2480 | targetFrame = historyItemFrame.releaseNonNull(); |
| 2481 | |
| 2482 | if (RefPtr targetLocalFrame = targetFrame->provisionalFrame() ? targetFrame->provisionalFrame() : targetFrame->coreLocalFrame()) |
| 2483 | protect(corePage())->goToItem(*targetLocalFrame, *item, parameters.backForwardType, parameters.shouldTreatAsContinuingLoad); |
| 2484 | } |
| 2485 | |
| 2486 | // GoToBackForwardItemWaitingForProcessLaunch should never be sent to the WebProcess. It must always be converted to a GoToBackForwardItem message. |
| 2487 | void WebPage::goToBackForwardItemWaitingForProcessLaunch(GoToBackForwardItemParameters&&, WebKit::WebPageProxyIdentifier) |
| 2488 | { |
| 2489 | RELEASE_ASSERT_NOT_REACHED()do { WTF::isIntegralOrPointerType(); compilerFenceForCrash(); WTFCrashWithInfo(2489, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); |
| 2490 | } |
| 2491 | |
| 2492 | void WebPage::tryRestoreScrollPosition() |
| 2493 | { |
| 2494 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 2495 | localMainFrame->loader().history().restoreScrollPositionAndViewState(); |
| 2496 | } |
| 2497 | |
| 2498 | WebPage* WebPage::fromCorePage(Page& page) |
| 2499 | { |
| 2500 | auto& client = page.chrome().client(); |
| 2501 | return client.isEmptyChromeClient() ? nullptr : downcast<WebChromeClient>(client).page(); |
| 2502 | } |
| 2503 | |
| 2504 | void WebPage::setSize(const WebCore::IntSize& viewSize) |
| 2505 | { |
| 2506 | if (m_viewSize == viewSize) |
| 2507 | return; |
| 2508 | |
| 2509 | m_viewSize = viewSize; |
| 2510 | RefPtr view = protect(protect(corePage())->mainFrame())->virtualView(); |
| 2511 | if (!view) { |
| 2512 | ASSERT_NOT_REACHED()((void)0); |
| 2513 | return; |
| 2514 | } |
| 2515 | |
| 2516 | view->resize(viewSize); |
| 2517 | protect(drawingArea())->setNeedsDisplay(); |
| 2518 | |
| 2519 | #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)(defined ENABLE_ACCESSIBILITY_ISOLATED_TREE && ENABLE_ACCESSIBILITY_ISOLATED_TREE ) |
| 2520 | cacheAXSize(m_viewSize); |
| 2521 | #endif |
| 2522 | } |
| 2523 | |
| 2524 | void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect) |
| 2525 | { |
| 2526 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 2527 | RefPtr localMainFrame = this->localMainFrame(); |
| 2528 | if (!localMainFrame) |
| 2529 | return; |
| 2530 | RefPtr mainFrameView = localMainFrame->view(); |
| 2531 | LocalDefaultSystemAppearance localAppearance(mainFrameView && mainFrameView->useDarkAppearance()); |
| 2532 | #endif |
| 2533 | |
| 2534 | GraphicsContextStateSaver stateSaver(graphicsContext); |
| 2535 | graphicsContext.clip(rect); |
| 2536 | |
| 2537 | protect(m_mainFrame->coreLocalFrame()->view())->paint(graphicsContext, rect); |
| 2538 | |
| 2539 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) || PLATFORM(WIN)(defined WTF_PLATFORM_WIN && WTF_PLATFORM_WIN) || PLATFORM(PLAYSTATION)(defined WTF_PLATFORM_PLAYSTATION && WTF_PLATFORM_PLAYSTATION ) |
| 2540 | if (!m_page->settings().acceleratedCompositingEnabled() && m_page->inspectorController().enabled() && m_page->inspectorController().shouldShowOverlay()) { |
| 2541 | graphicsContext.beginTransparencyLayer(1); |
| 2542 | m_page->inspectorController().drawHighlight(graphicsContext); |
| 2543 | graphicsContext.endTransparencyLayer(); |
| 2544 | } |
| 2545 | #endif |
| 2546 | } |
| 2547 | |
| 2548 | double WebPage::textZoomFactor() const |
| 2549 | { |
| 2550 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2551 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) |
| 2552 | return pluginView->pageScaleFactor(); |
| 2553 | #endif |
| 2554 | |
| 2555 | RefPtr frame = m_mainFrame->coreLocalFrame(); |
| 2556 | if (!frame) |
| 2557 | return 1; |
| 2558 | return frame->textZoomFactor(); |
| 2559 | } |
| 2560 | |
| 2561 | void WebPage::didSetTextZoomFactor(double zoomFactor) |
| 2562 | { |
| 2563 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2564 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) |
| 2565 | return pluginView->setPageScaleFactor(zoomFactor, std::nullopt); |
| 2566 | #endif |
| 2567 | |
| 2568 | if (!m_page) |
| 2569 | return; |
| 2570 | |
| 2571 | for (WeakRef frame : m_page->rootFrames()) |
| 2572 | frame->setTextZoomFactor(static_cast<float>(zoomFactor)); |
| 2573 | } |
| 2574 | |
| 2575 | double WebPage::pageZoomFactor() const |
| 2576 | { |
| 2577 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2578 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) { |
| 2579 | // Note that this maps page *scale* factor to page *zoom* factor. |
| 2580 | return pluginView->pageScaleFactor(); |
| 2581 | } |
| 2582 | #endif |
| 2583 | |
| 2584 | RefPtr frame = m_mainFrame->coreLocalFrame(); |
| 2585 | if (!frame) |
| 2586 | return 1; |
| 2587 | return frame->pageZoomFactor(); |
| 2588 | } |
| 2589 | |
| 2590 | void WebPage::didSetPageZoomFactor(double zoomFactor) |
| 2591 | { |
| 2592 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2593 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) { |
| 2594 | // Note that this maps page *zoom* factor to page *scale* factor. |
| 2595 | pluginView->setPageScaleFactor(zoomFactor, std::nullopt); |
| 2596 | return; |
| 2597 | } |
| 2598 | #endif |
| 2599 | |
| 2600 | if (!m_page) |
| 2601 | return; |
| 2602 | |
| 2603 | for (WeakRef frame : m_page->rootFrames()) |
| 2604 | frame->setPageZoomFactor(static_cast<float>(zoomFactor)); |
| 2605 | } |
| 2606 | |
| 2607 | static void dumpHistoryItem(HistoryItem& item, size_t indent, bool isCurrentItem, StringBuilder& stringBuilder, const String& directoryName) |
| 2608 | { |
| 2609 | if (isCurrentItem) |
| 2610 | stringBuilder.append("curr-> "_s); |
| 2611 | else { |
| 2612 | for (size_t i = 0; i < indent; ++i) |
| 2613 | stringBuilder.append(' '); |
| 2614 | } |
| 2615 | |
| 2616 | auto url = item.url(); |
| 2617 | if (url.protocolIsFile()) { |
| 2618 | size_t start = url.string().find(directoryName); |
| 2619 | if (start == WTF::notFound) |
| 2620 | start = 0; |
| 2621 | else |
| 2622 | start += directoryName.length(); |
| 2623 | stringBuilder.append("(file test):"_s, StringView { url.string() }.substring(start)); |
| 2624 | } else |
| 2625 | stringBuilder.append(url.string()); |
| 2626 | |
| 2627 | auto& target = item.target(); |
| 2628 | if (target.length()) |
| 2629 | stringBuilder.append(" (in frame \""_s, target, "\")"_s); |
| 2630 | |
| 2631 | stringBuilder.append('\n'); |
| 2632 | |
| 2633 | auto children = item.children(); |
| 2634 | std::ranges::stable_sort(children, [](auto& a, auto& b) { |
| 2635 | return codePointCompare(a->target(), b->target()) < 0; |
| 2636 | }); |
| 2637 | for (auto& child : children) |
| 2638 | dumpHistoryItem(child, indent + 4, false, stringBuilder, directoryName); |
| 2639 | } |
| 2640 | |
| 2641 | String WebPage::dumpHistoryForTesting(const String& directory) |
| 2642 | { |
| 2643 | if (!m_page) |
| 2644 | return { }; |
| 2645 | |
| 2646 | CheckedRef list = m_page->backForward(); |
| 2647 | |
| 2648 | StringBuilder builder; |
| 2649 | int begin = -list->backCount(); |
| 2650 | if (list->itemAtIndex(begin)->url() == aboutBlankURL()) |
| 2651 | ++begin; |
| 2652 | for (int i = begin; i <= static_cast<int>(list->forwardCount()); ++i) |
| 2653 | dumpHistoryItem(*list->itemAtIndex(i), 8, !i, builder, directory); |
| 2654 | return builder.toString(); |
| 2655 | } |
| 2656 | |
| 2657 | String WebPage::frameTextForTestingIncludingSubframes(bool includeSubframes) |
| 2658 | { |
| 2659 | return m_mainFrame->frameTextForTesting(includeSubframes); |
| 2660 | } |
| 2661 | |
| 2662 | void WebPage::windowScreenDidChange(PlatformDisplayID displayID, std::optional<unsigned> nominalFramesPerSecond) |
| 2663 | { |
| 2664 | m_page->chrome().windowScreenDidChange(displayID, nominalFramesPerSecond); |
| 2665 | |
| 2666 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 2667 | WebProcess::singleton().updatePageScreenProperties(); |
| 2668 | #endif |
| 2669 | } |
| 2670 | |
| 2671 | void WebPage::didScalePage(double scale, const IntPoint& origin) |
| 2672 | { |
| 2673 | double totalScale = scale * viewScaleFactor(); |
| 2674 | bool willChangeScaleFactor = totalScale != totalScaleFactor(); |
| 2675 | auto platformDidScalePageIfNeeded = makeScopeExit([willChangeScaleFactor, this, protectedThis = Ref { *this }] { |
| 2676 | if (willChangeScaleFactor) |
| 2677 | platformDidScalePage(); |
| 2678 | }); |
| 2679 | |
| 2680 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2681 | if (willChangeScaleFactor) { |
| 2682 | if (!m_inDynamicSizeUpdate) |
| 2683 | m_internals->dynamicSizeUpdateHistory.clear(); |
| 2684 | m_scaleWasSetByUIProcess = false; |
| 2685 | } |
| 2686 | #endif |
| 2687 | |
| 2688 | RefPtr page = m_page; |
| 2689 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2690 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) { |
| 2691 | // Whenever the PDF plug-in handles the page scale factor, make sure to reset WebCore's page scale. |
| 2692 | // Otherwise, we can end up with an immutable but non-1 page scale applied by WebCore on top of whatever the plugin does. |
| 2693 | if (page->pageScaleFactor() != 1) |
| 2694 | page->setPageScaleFactor(1, origin); |
| 2695 | pluginView->setPageScaleFactor(totalScale, { origin }); |
| 2696 | return; |
| 2697 | } |
| 2698 | #endif |
| 2699 | |
| 2700 | page->setPageScaleFactor(totalScale, origin); |
| 2701 | |
| 2702 | // We can't early return before setPageScaleFactor because the origin might be different. |
| 2703 | if (!willChangeScaleFactor) |
| 2704 | return; |
| 2705 | |
| 2706 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2707 | for (Ref pluginView : m_pluginViews) { |
| 2708 | if (pluginView->pluginHandlesPageScaleFactor()) |
| 2709 | pluginView->setPageScaleFactor(totalScale, { origin }); |
| 2710 | } |
| 2711 | #endif |
| 2712 | } |
| 2713 | |
| 2714 | void WebPage::didScalePageInViewCoordinates(double scale, const IntPoint& origin) |
| 2715 | { |
| 2716 | RefPtr frameView = localMainFrameView(); |
| 2717 | if (!frameView) |
| 2718 | return; |
| 2719 | auto adjustedOrigin = frameView->rootViewToContents(-origin); |
| 2720 | double scaleRatio = scale / pageScaleFactor(); |
| 2721 | adjustedOrigin.scale(scaleRatio); |
| 2722 | |
| 2723 | didScalePage(scale, adjustedOrigin); |
| 2724 | } |
| 2725 | |
| 2726 | void WebPage::didScalePageRelativeToScrollPosition(double scale, const IntPoint& origin) |
| 2727 | { |
| 2728 | RefPtr frameView = localMainFrameView(); |
| 2729 | if (!frameView) |
| 2730 | return; |
| 2731 | auto unscrolledOrigin = origin; |
| 2732 | IntRect unobscuredContentRect = frameView->unobscuredContentRectIncludingScrollbars(); |
| 2733 | unscrolledOrigin.moveBy(-unobscuredContentRect.location()); |
| 2734 | |
| 2735 | didScalePage(scale, -unscrolledOrigin); |
| 2736 | } |
| 2737 | |
| 2738 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2739 | |
| 2740 | void WebPage::platformDidScalePage() |
| 2741 | { |
| 2742 | } |
| 2743 | |
| 2744 | #endif |
| 2745 | |
| 2746 | void WebPage::scalePage(double scale, const IntPoint& origin) |
| 2747 | { |
| 2748 | didScalePage(scale, origin); |
| 2749 | send(Messages::WebPageProxy::PageScaleFactorDidChange(scale)); |
| 2750 | } |
| 2751 | |
| 2752 | double WebPage::totalScaleFactor() const |
| 2753 | { |
| 2754 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 2755 | if (RefPtr pluginView = mainFramePlugIn(); pluginView && pluginView->pluginHandlesPageScaleFactor()) |
| 2756 | return pluginView->pageScaleFactor(); |
| 2757 | #endif |
| 2758 | return m_page->pageScaleFactor(); |
| 2759 | } |
| 2760 | |
| 2761 | double WebPage::pageScaleFactor() const |
| 2762 | { |
| 2763 | return totalScaleFactor() / viewScaleFactor(); |
| 2764 | } |
| 2765 | |
| 2766 | double WebPage::viewScaleFactor() const |
| 2767 | { |
| 2768 | return m_page->viewScaleFactor(); |
| 2769 | } |
| 2770 | |
| 2771 | void WebPage::didScaleView(double scale) |
| 2772 | { |
| 2773 | if (viewScaleFactor() == scale) |
| 2774 | return; |
| 2775 | |
| 2776 | float pageScale = pageScaleFactor(); |
| 2777 | |
| 2778 | RefPtr page = m_page; |
| 2779 | IntPoint scrollPositionAtNewScale; |
| 2780 | if (RefPtr mainFrameView = protect(page->mainFrame())->virtualView()) { |
| 2781 | double scaleRatio = scale / viewScaleFactor(); |
| 2782 | scrollPositionAtNewScale = mainFrameView->scrollPosition(); |
| 2783 | scrollPositionAtNewScale.scale(scaleRatio); |
| 2784 | } |
| 2785 | |
| 2786 | page->setViewScaleFactor(scale); |
| 2787 | didScalePage(pageScale, scrollPositionAtNewScale); |
| 2788 | } |
| 2789 | |
| 2790 | void WebPage::scaleView(double scale) |
| 2791 | { |
| 2792 | if (scale == viewScaleFactor()) |
| 2793 | return; |
| 2794 | didScaleView(scale); |
| 2795 | send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale)); |
| 2796 | } |
| 2797 | |
| 2798 | void WebPage::setDeviceScaleFactor(float scaleFactor) |
| 2799 | { |
| 2800 | RefPtr page = m_page; |
| 2801 | if (scaleFactor == page->deviceScaleFactor()) |
| 2802 | return; |
| 2803 | |
| 2804 | page->setDeviceScaleFactor(scaleFactor); |
| 2805 | |
| 2806 | // Tell all our plug-in views that the device scale factor changed. |
| 2807 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 2808 | for (Ref pluginView : m_pluginViews) |
| 2809 | pluginView->setDeviceScaleFactor(scaleFactor); |
| 2810 | |
| 2811 | updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor); |
| 2812 | #endif |
| 2813 | |
| 2814 | #if USE(SKIA)(defined USE_SKIA && USE_SKIA) |
| 2815 | FontRenderOptions::singleton().setUseSubpixelPositioning(scaleFactor >= 2.); |
| 2816 | #endif |
| 2817 | |
| 2818 | if (findController().isShowingOverlay()) { |
| 2819 | // We must have updated layout to get the selection rects right. |
| 2820 | layoutIfNeeded(); |
| 2821 | findController().deviceScaleFactorDidChange(); |
| 2822 | } |
| 2823 | } |
| 2824 | |
| 2825 | float WebPage::deviceScaleFactor() const |
| 2826 | { |
| 2827 | return m_page->deviceScaleFactor(); |
| 2828 | } |
| 2829 | |
| 2830 | void WebPage::accessibilitySettingsDidChange() |
| 2831 | { |
| 2832 | protect(corePage())->accessibilitySettingsDidChange(); |
| 2833 | } |
| 2834 | |
| 2835 | void WebPage::enableAccessibilityForAllProcesses() |
| 2836 | { |
| 2837 | send(Messages::WebPageProxy::EnableAccessibilityForAllProcesses()); |
| 2838 | } |
| 2839 | |
| 2840 | void WebPage::enableAccessibility() |
| 2841 | { |
| 2842 | if (!WebCore::AXObjectCache::accessibilityEnabled()) |
| 2843 | WebCore::AXObjectCache::enableAccessibility(); |
| 2844 | } |
| 2845 | |
| 2846 | void WebPage::screenPropertiesDidChange(bool affectsStyle) |
| 2847 | { |
| 2848 | protect(corePage())->screenPropertiesDidChange(affectsStyle); |
| 2849 | } |
| 2850 | |
| 2851 | void WebPage::setUseFixedLayout(bool fixed) |
| 2852 | { |
| 2853 | // Do not overwrite current settings if initially setting it to false. |
| 2854 | if (m_useFixedLayout == fixed) |
| 2855 | return; |
| 2856 | m_useFixedLayout = fixed; |
| 2857 | |
| 2858 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2859 | m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed); |
| 2860 | #endif |
| 2861 | |
| 2862 | RefPtr view = localMainFrameView(); |
| 2863 | if (!view) |
| 2864 | return; |
| 2865 | |
| 2866 | view->setUseFixedLayout(fixed); |
| 2867 | if (!fixed) |
| 2868 | setFixedLayoutSize(IntSize()); |
| 2869 | |
| 2870 | send(Messages::WebPageProxy::UseFixedLayoutDidChange(fixed)); |
| 2871 | } |
| 2872 | |
| 2873 | bool WebPage::setFixedLayoutSize(const IntSize& size) |
| 2874 | { |
| 2875 | RefPtr view = localMainFrameView(); |
| 2876 | if (!view || view->fixedLayoutSize() == size) |
| 2877 | return false; |
| 2878 | |
| 2879 | LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier.toUInt64() << " setFixedLayoutSize " << size)((void)0); |
| 2880 | view->setFixedLayoutSize(size); |
| 2881 | |
| 2882 | send(Messages::WebPageProxy::FixedLayoutSizeDidChange(size)); |
| 2883 | return true; |
| 2884 | } |
| 2885 | |
| 2886 | IntSize WebPage::fixedLayoutSize() const |
| 2887 | { |
| 2888 | RefPtr view = localMainFrameView(); |
| 2889 | if (!view) |
| 2890 | return IntSize(); |
| 2891 | return view->fixedLayoutSize(); |
| 2892 | } |
| 2893 | |
| 2894 | void WebPage::setDefaultUnobscuredSize(const FloatSize& defaultUnobscuredSize) |
| 2895 | { |
| 2896 | if (defaultUnobscuredSize == m_defaultUnobscuredSize) |
| 2897 | return; |
| 2898 | |
| 2899 | m_defaultUnobscuredSize = defaultUnobscuredSize; |
| 2900 | |
| 2901 | updateSizeForCSSDefaultViewportUnits(); |
| 2902 | } |
| 2903 | |
| 2904 | void WebPage::updateSizeForCSSDefaultViewportUnits() |
| 2905 | { |
| 2906 | RefPtr mainFrameView = this->localMainFrameView(); |
| 2907 | if (!mainFrameView) |
| 2908 | return; |
| 2909 | |
| 2910 | auto defaultUnobscuredSize = m_defaultUnobscuredSize; |
| 2911 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 2912 | if (defaultUnobscuredSize.isEmpty()) |
| 2913 | defaultUnobscuredSize = m_viewportConfiguration.viewLayoutSize(); |
| 2914 | defaultUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize()); |
| 2915 | #endif |
| 2916 | mainFrameView->setSizeForCSSDefaultViewportUnits(defaultUnobscuredSize); |
| 2917 | } |
| 2918 | |
| 2919 | void WebPage::setMinimumUnobscuredSize(const FloatSize& minimumUnobscuredSize) |
| 2920 | { |
| 2921 | if (minimumUnobscuredSize == m_minimumUnobscuredSize) |
| 2922 | return; |
| 2923 | |
| 2924 | m_minimumUnobscuredSize = minimumUnobscuredSize; |
| 2925 | |
| 2926 | updateSizeForCSSSmallViewportUnits(); |
| 2927 | } |
| 2928 | |
| 2929 | void WebPage::updateSizeForCSSSmallViewportUnits() |
| 2930 | { |
| 2931 | RefPtr mainFrameView = this->localMainFrameView(); |
| 2932 | if (!mainFrameView) |
| 2933 | return; |
| 2934 | |
| 2935 | auto minimumUnobscuredSize = m_minimumUnobscuredSize; |
| 2936 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 2937 | if (minimumUnobscuredSize.isEmpty()) |
| 2938 | minimumUnobscuredSize = m_viewportConfiguration.viewLayoutSize(); |
| 2939 | minimumUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize()); |
| 2940 | #endif |
| 2941 | mainFrameView->setSizeForCSSSmallViewportUnits(minimumUnobscuredSize); |
| 2942 | } |
| 2943 | |
| 2944 | void WebPage::setMaximumUnobscuredSize(const FloatSize& maximumUnobscuredSize) |
| 2945 | { |
| 2946 | if (maximumUnobscuredSize == m_maximumUnobscuredSize) |
| 2947 | return; |
| 2948 | |
| 2949 | m_maximumUnobscuredSize = maximumUnobscuredSize; |
| 2950 | |
| 2951 | updateSizeForCSSLargeViewportUnits(); |
| 2952 | } |
| 2953 | |
| 2954 | void WebPage::updateSizeForCSSLargeViewportUnits() |
| 2955 | { |
| 2956 | RefPtr mainFrameView = this->localMainFrameView(); |
| 2957 | if (!mainFrameView) |
| 2958 | return; |
| 2959 | |
| 2960 | auto maximumUnobscuredSize = m_maximumUnobscuredSize; |
| 2961 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 2962 | if (maximumUnobscuredSize.isEmpty()) |
| 2963 | maximumUnobscuredSize = m_viewportConfiguration.viewLayoutSize(); |
| 2964 | maximumUnobscuredSize.scale(1 / m_viewportConfiguration.initialScaleIgnoringContentSize()); |
| 2965 | #endif |
| 2966 | mainFrameView->setSizeForCSSLargeViewportUnits(maximumUnobscuredSize); |
| 2967 | } |
| 2968 | |
| 2969 | void WebPage::disabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations) |
| 2970 | { |
| 2971 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2972 | if (m_viewportConfiguration.setDisabledAdaptations(disabledAdaptations)) |
| 2973 | viewportConfigurationChanged(); |
| 2974 | #else |
| 2975 | UNUSED_PARAM(disabledAdaptations)(void)disabledAdaptations; |
| 2976 | #endif |
| 2977 | } |
| 2978 | |
| 2979 | void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments) |
| 2980 | { |
| 2981 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 2982 | if (m_viewportConfiguration.setViewportArguments(viewportArguments)) |
| 2983 | viewportConfigurationChanged(); |
| 2984 | #elif PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) || PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) |
| 2985 | // Adjust view dimensions when using fixed layout. |
| 2986 | RefPtr localMainFrame = this->localMainFrame(); |
| 2987 | RefPtr view = localMainFrame ? localMainFrame->view() : nullptr; |
| 2988 | if (view && view->useFixedLayout() && !m_viewSize.isEmpty()) { |
| 2989 | Settings& settings = m_page->settings(); |
| 2990 | int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width(); |
| 2991 | int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height(); |
| 2992 | int minimumLayoutFallbackWidth = std::max<int>(settings.layoutFallbackWidth(), m_viewSize.width()); |
| 2993 | ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize); |
| 2994 | setFixedLayoutSize(roundedIntSize(attr.layoutSize)); |
| 2995 | scaleView(deviceWidth / attr.layoutSize.width()); |
| 2996 | } |
| 2997 | #else |
| 2998 | UNUSED_PARAM(viewportArguments)(void)viewportArguments; |
| 2999 | #endif |
| 3000 | } |
| 3001 | |
| 3002 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3003 | |
| 3004 | FloatSize WebPage::screenSizeForFingerprintingProtections(const LocalFrame& frame, FloatSize defaultSize) const |
| 3005 | { |
| 3006 | return frame.view() ? FloatSize { protect(frame.view())->unobscuredContentRectIncludingScrollbars().size() } : defaultSize; |
| 3007 | } |
| 3008 | |
| 3009 | #endif // !PLATFORM(IOS_FAMILY) |
| 3010 | |
| 3011 | void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones) |
| 3012 | { |
| 3013 | if (RefPtr page = m_page) |
| 3014 | page->addLayoutMilestones(milestones); |
| 3015 | } |
| 3016 | |
| 3017 | void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations) |
| 3018 | { |
| 3019 | protect(corePage())->setShouldSuppressScrollbarAnimations(suppressAnimations); |
| 3020 | } |
| 3021 | |
| 3022 | void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding) |
| 3023 | { |
| 3024 | protect(corePage())->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticity::Allowed : ScrollElasticity::None); |
| 3025 | } |
| 3026 | |
| 3027 | void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding) |
| 3028 | { |
| 3029 | protect(corePage())->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticity::Allowed : ScrollElasticity::None); |
| 3030 | } |
| 3031 | |
| 3032 | void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage) |
| 3033 | { |
| 3034 | if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage) |
| 3035 | m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage); |
| 3036 | } |
| 3037 | |
| 3038 | void WebPage::setPaginationMode(Pagination::Mode mode) |
| 3039 | { |
| 3040 | RefPtr page = m_page; |
| 3041 | Pagination pagination = page->pagination(); |
| 3042 | pagination.mode = static_cast<Pagination::Mode>(mode); |
| 3043 | page->setPagination(pagination); |
| 3044 | } |
| 3045 | |
| 3046 | void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns) |
| 3047 | { |
| 3048 | RefPtr page = m_page; |
| 3049 | Pagination pagination = page->pagination(); |
| 3050 | pagination.behavesLikeColumns = behavesLikeColumns; |
| 3051 | page->setPagination(pagination); |
| 3052 | } |
| 3053 | |
| 3054 | void WebPage::setPageLength(double pageLength) |
| 3055 | { |
| 3056 | RefPtr page = m_page; |
| 3057 | Pagination pagination = page->pagination(); |
| 3058 | pagination.pageLength = pageLength; |
| 3059 | page->setPagination(pagination); |
| 3060 | } |
| 3061 | |
| 3062 | void WebPage::setGapBetweenPages(double gap) |
| 3063 | { |
| 3064 | RefPtr page = m_page; |
| 3065 | Pagination pagination = page->pagination(); |
| 3066 | pagination.gap = gap; |
| 3067 | page->setPagination(pagination); |
| 3068 | } |
| 3069 | |
| 3070 | void WebPage::postInjectedBundleMessage(const String& messageName, const UserData& userData) |
| 3071 | { |
| 3072 | auto& webProcess = WebProcess::singleton(); |
| 3073 | RefPtr injectedBundle = webProcess.injectedBundle(); |
| 3074 | if (!injectedBundle) |
| 3075 | return; |
| 3076 | |
| 3077 | injectedBundle->didReceiveMessageToPage(Ref { *this }, messageName, webProcess.transformHandlesToObjects(protect(userData.object()).get())); |
| 3078 | } |
| 3079 | |
| 3080 | void WebPage::setUnderPageBackgroundColorOverride(WebCore::Color&& underPageBackgroundColorOverride) |
| 3081 | { |
| 3082 | protect(corePage())->setUnderPageBackgroundColorOverride(WTF::move(underPageBackgroundColorOverride)); |
| 3083 | } |
| 3084 | |
| 3085 | void WebPage::setShouldSuppressHDR(bool shouldSuppressHDR) |
| 3086 | { |
| 3087 | protect(corePage())->setShouldSuppressHDR(shouldSuppressHDR); |
| 3088 | } |
| 3089 | |
| 3090 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3091 | |
| 3092 | void WebPage::setHeaderPageBanner(PageBanner* pageBanner) |
| 3093 | { |
| 3094 | if (RefPtr headerBanner = m_headerBanner) |
| 3095 | headerBanner->detachFromPage(); |
| 3096 | |
| 3097 | m_headerBanner = pageBanner; |
| 3098 | |
| 3099 | if (RefPtr headerBanner = m_headerBanner) |
| 3100 | headerBanner->addToPage(PageBanner::Header, this); |
| 3101 | } |
| 3102 | |
| 3103 | PageBanner* WebPage::headerPageBanner() |
| 3104 | { |
| 3105 | return m_headerBanner.get(); |
| 3106 | } |
| 3107 | |
| 3108 | void WebPage::setFooterPageBanner(PageBanner* pageBanner) |
| 3109 | { |
| 3110 | if (RefPtr footerBanner = m_footerBanner) |
| 3111 | footerBanner->detachFromPage(); |
| 3112 | |
| 3113 | m_footerBanner = pageBanner; |
| 3114 | |
| 3115 | if (RefPtr footerBanner = m_footerBanner) |
| 3116 | footerBanner->addToPage(PageBanner::Footer, this); |
| 3117 | } |
| 3118 | |
| 3119 | PageBanner* WebPage::footerPageBanner() |
| 3120 | { |
| 3121 | return m_footerBanner.get(); |
| 3122 | } |
| 3123 | |
| 3124 | void WebPage::hidePageBanners() |
| 3125 | { |
| 3126 | if (RefPtr headerBanner = m_headerBanner) |
| 3127 | headerBanner->hide(); |
| 3128 | if (RefPtr footerBanner = m_footerBanner) |
| 3129 | footerBanner->hide(); |
| 3130 | } |
| 3131 | |
| 3132 | void WebPage::showPageBanners() |
| 3133 | { |
| 3134 | if (RefPtr headerBanner = m_headerBanner) |
| 3135 | headerBanner->showIfHidden(); |
| 3136 | if (RefPtr footerBanner = m_footerBanner) |
| 3137 | footerBanner->showIfHidden(); |
| 3138 | } |
| 3139 | |
| 3140 | #endif // !PLATFORM(IOS_FAMILY) |
| 3141 | |
| 3142 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 3143 | void WebPage::setHeaderBannerHeight(int height) |
| 3144 | { |
| 3145 | protect(corePage())->setHeaderHeight(height); |
| 3146 | } |
| 3147 | |
| 3148 | void WebPage::setFooterBannerHeight(int height) |
| 3149 | { |
| 3150 | protect(corePage())->setFooterHeight(height); |
| 3151 | } |
| 3152 | #endif |
| 3153 | |
| 3154 | RefPtr<ShareableBitmap> WebPage::shareableBitmapSnapshotForNode(Node& node) |
| 3155 | { |
| 3156 | // Ensure that the image contains at most 600K pixels, so that it is not too big. |
| 3157 | if (auto snapshot = snapshotNode(node, SnapshotOption::Shareable, 600 * 1024)) |
| 3158 | return snapshot->bitmap(); |
| 3159 | return nullptr; |
| 3160 | } |
| 3161 | |
| 3162 | void WebPage::takeRemoteSnapshot(IntRect snapshotRect, IntSize bitmapSize, SnapshotOptions snapshotOptions, RemoteSnapshotIdentifier snapshotIdentifier, CompletionHandler<void(bool)>&& completionHandler) |
| 3163 | { |
| 3164 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 3165 | ASSERT(m_page->settings().remoteSnapshottingEnabled())((void)0); |
| 3166 | |
| 3167 | RefPtr coreFrame = m_mainFrame->coreLocalFrame(); |
| 3168 | if (!coreFrame) { |
| 3169 | completionHandler(false); |
| 3170 | return; |
| 3171 | } |
| 3172 | |
| 3173 | RefPtr frameView = coreFrame->view(); |
| 3174 | if (!frameView) { |
| 3175 | completionHandler(false); |
| 3176 | return; |
| 3177 | } |
| 3178 | |
| 3179 | Ref remoteRenderingBackend = ensureRemoteRenderingBackendProxy(); |
| 3180 | m_remoteSnapshotState = { |
| 3181 | snapshotIdentifier, |
| 3182 | remoteRenderingBackend->createSnapshotRecorder(snapshotIdentifier), |
| 3183 | MainRunLoopSuccessCallbackAggregator::create(WTF::move(completionHandler)) |
| 3184 | }; |
| 3185 | |
| 3186 | auto originalLayoutViewportOverrideRect = frameView->layoutViewportOverrideRect(); |
| 3187 | |
| 3188 | auto originalPaintBehavior = frameView->paintBehavior(); |
| 3189 | auto paintBehavior = originalPaintBehavior; |
| 3190 | |
| 3191 | preSnapshotSetup(snapshotRect, bitmapSize, snapshotOptions, paintBehavior, *frameView); |
| 3192 | paintSnapshotAtSize(snapshotRect, bitmapSize, snapshotOptions, *coreFrame, *frameView, m_remoteSnapshotState->recorder); |
| 3193 | postSnapshotTakedown(originalPaintBehavior, paintBehavior, originalLayoutViewportOverrideRect, *frameView); |
| 3194 | |
| 3195 | remoteRenderingBackend->sinkSnapshotRecorderIntoSnapshotFrame(WTF::move(m_remoteSnapshotState->recorder), coreFrame->frameID(), Ref { m_remoteSnapshotState->callback }->chain()); |
| 3196 | m_remoteSnapshotState = std::nullopt; |
| 3197 | |
| 3198 | #else |
| 3199 | UNUSED_PARAM(snapshotRect)(void)snapshotRect; |
| 3200 | UNUSED_PARAM(bitmapSize)(void)bitmapSize; |
| 3201 | UNUSED_PARAM(snapshotOptions)(void)snapshotOptions; |
| 3202 | UNUSED_PARAM(snapshotIdentifier)(void)snapshotIdentifier; |
| 3203 | UNUSED_PARAM(completionHandler)(void)completionHandler; |
| 3204 | #endif |
| 3205 | } |
| 3206 | |
| 3207 | void WebPage::preSnapshotSetup(IntRect& snapshotRect, IntSize& bitmapSize, SnapshotOptions& snapshotOptions, OptionSet<PaintBehavior>& paintBehavior, LocalFrameView& frameView) |
| 3208 | { |
| 3209 | snapshotOptions.add(SnapshotOption::Shareable); |
| 3210 | |
| 3211 | auto originalPaintBehavior = frameView.paintBehavior(); |
| 3212 | |
| 3213 | if (snapshotOptions.contains(SnapshotOption::VisibleContentRect)) |
| 3214 | snapshotRect = frameView.visibleContentRect(); |
| 3215 | else if (snapshotOptions.contains(SnapshotOption::FullContentRect)) { |
| 3216 | snapshotRect = IntRect({ 0, 0 }, frameView.contentsSize()); |
| 3217 | frameView.setLayoutViewportOverrideRect(LayoutRect(snapshotRect)); |
| 3218 | paintBehavior.add(PaintBehavior::AnnotateLinks); |
| 3219 | } |
| 3220 | |
| 3221 | #if HAVE(SUPPORT_HDR_DISPLAY)(defined 1 && 1) |
| 3222 | if (snapshotOptions.contains(SnapshotOption::AllowHDR) && protect(corePage())->drawsHDRContent()) |
| 3223 | paintBehavior.add(PaintBehavior::DrawsHDRContent); |
| 3224 | #endif |
| 3225 | |
| 3226 | if (originalPaintBehavior != paintBehavior) |
| 3227 | frameView.setPaintBehavior(paintBehavior); |
| 3228 | |
| 3229 | if (bitmapSize.isEmpty()) { |
| 3230 | bitmapSize = snapshotRect.size(); |
| 3231 | if (!snapshotOptions.contains(SnapshotOption::ExcludeDeviceScaleFactor)) |
| 3232 | bitmapSize.scale(corePage()->deviceScaleFactor()); |
| 3233 | } |
| 3234 | } |
| 3235 | |
| 3236 | void WebPage::postSnapshotTakedown(OptionSet<PaintBehavior> originalPaintBehavior, OptionSet<PaintBehavior> paintBehavior, std::optional<LayoutRect> originalLayoutViewportOverrideRect, LocalFrameView& frameView) |
| 3237 | { |
| 3238 | if (originalPaintBehavior != paintBehavior) { |
| 3239 | frameView.setLayoutViewportOverrideRect(originalLayoutViewportOverrideRect); |
| 3240 | frameView.setPaintBehavior(originalPaintBehavior); |
| 3241 | } |
| 3242 | } |
| 3243 | |
| 3244 | void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, SnapshotOptions snapshotOptions, CompletionHandler<void(std::optional<ImageBufferBackendHandle>&&, Headroom)>&& completionHandler) |
| 3245 | { |
| 3246 | std::optional<ImageBufferBackendHandle> handle; |
| 3247 | RefPtr coreFrame = m_mainFrame->coreLocalFrame(); |
| 3248 | if (!coreFrame) { |
| 3249 | completionHandler(WTF::move(handle), Headroom::None); |
| 3250 | return; |
| 3251 | } |
| 3252 | |
| 3253 | RefPtr frameView = coreFrame->view(); |
| 3254 | if (!frameView) { |
| 3255 | completionHandler(WTF::move(handle), Headroom::None); |
| 3256 | return; |
| 3257 | } |
| 3258 | |
| 3259 | auto originalLayoutViewportOverrideRect = frameView->layoutViewportOverrideRect(); |
| 3260 | |
| 3261 | auto originalPaintBehavior = frameView->paintBehavior(); |
| 3262 | auto paintBehavior = originalPaintBehavior; |
| 3263 | |
| 3264 | preSnapshotSetup(snapshotRect, bitmapSize, snapshotOptions, paintBehavior, *frameView); |
| 3265 | |
| 3266 | Headroom headroom = Headroom::None; |
| 3267 | if (auto image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions, *coreFrame, *frameView)) { |
| 3268 | handle = image->createImageBufferBackendHandle(SharedMemory::Protection::ReadOnly); |
| 3269 | #if HAVE(SUPPORT_HDR_DISPLAY)(defined 1 && 1) |
| 3270 | if (image->context()) |
| 3271 | headroom = Headroom(image->context()->maxPaintedEDRHeadroom()); |
| 3272 | #endif |
| 3273 | } |
| 3274 | |
| 3275 | postSnapshotTakedown(originalPaintBehavior, paintBehavior, originalLayoutViewportOverrideRect, *frameView); |
| 3276 | completionHandler(WTF::move(handle), headroom); |
| 3277 | } |
| 3278 | |
| 3279 | RefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options) |
| 3280 | { |
| 3281 | RefPtr coreFrame = m_mainFrame->coreLocalFrame(); |
| 3282 | if (!coreFrame) |
| 3283 | return nullptr; |
| 3284 | |
| 3285 | RefPtr frameView = coreFrame->view(); |
| 3286 | if (!frameView) |
| 3287 | return nullptr; |
| 3288 | |
| 3289 | IntRect snapshotRect = rect; |
| 3290 | IntSize bitmapSize = snapshotRect.size(); |
| 3291 | if (options.contains(SnapshotOption::Printing)) { |
| 3292 | ASSERT(additionalScaleFactor == 1)((void)0); |
| 3293 | bitmapSize.setHeight(PrintContext::numberOfPages(*coreFrame, bitmapSize) * (bitmapSize.height() + 1) - 1); |
| 3294 | } else { |
| 3295 | double scaleFactor = additionalScaleFactor; |
| 3296 | if (!options.contains(SnapshotOption::ExcludeDeviceScaleFactor)) |
| 3297 | scaleFactor *= corePage()->deviceScaleFactor(); |
| 3298 | bitmapSize.scale(scaleFactor); |
| 3299 | } |
| 3300 | |
| 3301 | return snapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView); |
| 3302 | } |
| 3303 | |
| 3304 | void WebPage::paintSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, LocalFrame& frame, LocalFrameView& frameView, GraphicsContext& graphicsContext) |
| 3305 | { |
| 3306 | TraceScope snapshotScope(PaintSnapshotStart, PaintSnapshotEnd, options.toRaw()); |
| 3307 | |
| 3308 | IntRect snapshotRect = rect; |
| 3309 | float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width(); |
| 3310 | float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height(); |
| 3311 | float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor); |
| 3312 | |
| 3313 | if (options.contains(SnapshotOption::Printing)) { |
| 3314 | PrintContext::spoolAllPagesWithBoundaries(frame, graphicsContext, snapshotRect.size()); |
| 3315 | return; |
| 3316 | } |
| 3317 | |
| 3318 | Color backgroundColor; |
| 3319 | Color savedBackgroundColor; |
| 3320 | if (options.contains(SnapshotOption::TransparentBackground)) { |
| 3321 | backgroundColor = Color::transparentBlack; |
| 3322 | savedBackgroundColor = frameView.baseBackgroundColor(); |
| 3323 | frameView.setBaseBackgroundColor(backgroundColor); |
| 3324 | } else { |
| 3325 | Color documentBackgroundColor = frameView.documentBackgroundColor(); |
| 3326 | backgroundColor = (frame.settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView.baseBackgroundColor(); |
| 3327 | } |
| 3328 | graphicsContext.fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor); |
| 3329 | |
| 3330 | if (!options.contains(SnapshotOption::ExcludeDeviceScaleFactor)) { |
| 3331 | double deviceScaleFactor = frame.page()->deviceScaleFactor(); |
| 3332 | graphicsContext.applyDeviceScaleFactor(deviceScaleFactor); |
| 3333 | scaleFactor /= deviceScaleFactor; |
| 3334 | } |
| 3335 | |
| 3336 | graphicsContext.scale(scaleFactor); |
| 3337 | graphicsContext.translate(-snapshotRect.location()); |
| 3338 | |
| 3339 | LocalFrameView::SelectionInSnapshot shouldPaintSelection = LocalFrameView::IncludeSelection; |
| 3340 | if (options.contains(SnapshotOption::ExcludeSelectionHighlighting)) |
| 3341 | shouldPaintSelection = LocalFrameView::ExcludeSelection; |
| 3342 | |
| 3343 | LocalFrameView::CoordinateSpaceForSnapshot coordinateSpace = LocalFrameView::DocumentCoordinates; |
| 3344 | if (options.contains(SnapshotOption::InViewCoordinates)) |
| 3345 | coordinateSpace = LocalFrameView::ViewCoordinates; |
| 3346 | |
| 3347 | frameView.paintContentsForSnapshot(graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace); |
| 3348 | |
| 3349 | if (options.contains(SnapshotOption::PaintSelectionRectangle)) { |
| 3350 | FloatRect selectionRectangle = protect(frame.selection())->selectionBounds(); |
| 3351 | graphicsContext.setStrokeColor(Color::red); |
| 3352 | graphicsContext.strokeRect(selectionRectangle, 1); |
| 3353 | } |
| 3354 | |
| 3355 | if (options.contains(SnapshotOption::TransparentBackground)) |
| 3356 | frameView.setBaseBackgroundColor(savedBackgroundColor); |
| 3357 | } |
| 3358 | |
| 3359 | static DestinationColorSpace snapshotColorSpace(SnapshotOptions options, WebPage& page) |
| 3360 | { |
| 3361 | #if USE(CG)(defined 1 && 1) |
| 3362 | if (options.contains(SnapshotOption::UseScreenColorSpace)) { |
| 3363 | auto screenColorSpace = WebCore::screenColorSpace(protect(protect(protect(page.corePage())->mainFrame())->virtualView()).get()); |
| 3364 | #if HAVE(SUPPORT_HDR_DISPLAY)(defined 1 && 1) |
| 3365 | if (options.contains(SnapshotOption::AllowHDR) && protect(page.corePage())->drawsHDRContent()) { |
| 3366 | if (auto extendedScreenColorSpace = screenColorSpace.asExtended()) |
| 3367 | return *extendedScreenColorSpace; |
| 3368 | } |
| 3369 | #endif |
| 3370 | return screenColorSpace; |
| 3371 | } |
| 3372 | #endif |
| 3373 | |
| 3374 | #if HAVE(SUPPORT_HDR_DISPLAY)(defined 1 && 1) |
| 3375 | if (options.contains(SnapshotOption::AllowHDR) && protect(page.corePage())->drawsHDRContent()) |
| 3376 | return DestinationColorSpace::ExtendedSRGB(); |
| 3377 | #endif |
| 3378 | |
| 3379 | return DestinationColorSpace::SRGB(); |
| 3380 | } |
| 3381 | |
| 3382 | RefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, LocalFrame& frame, LocalFrameView& frameView) |
| 3383 | { |
| 3384 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 3385 | ImageOptions imageOptions = m_pluginViews.computeSize() ? ImageOption::Local : ImageOption::Shareable; |
| 3386 | #else |
| 3387 | ImageOptions imageOptions = ImageOption::Shareable; |
| 3388 | #endif |
| 3389 | |
| 3390 | if (options.contains(SnapshotOption::Accelerated)) |
| 3391 | imageOptions.add(ImageOption::Accelerated); |
| 3392 | if (options.contains(SnapshotOption::AllowHDR)) |
| 3393 | imageOptions.add(ImageOption::AllowHDR); |
| 3394 | |
| 3395 | auto snapshot = WebImage::create(bitmapSize, imageOptions, snapshotColorSpace(options, *this), &m_page->chrome().client()); |
| 3396 | if (!snapshot->context()) |
| 3397 | return nullptr; |
| 3398 | |
| 3399 | auto& graphicsContext = *snapshot->context(); |
| 3400 | #if HAVE(SUPPORT_HDR_DISPLAY)(defined 1 && 1) |
| 3401 | graphicsContext.setMaxEDRHeadroom(maxEDRHeadroomForDisplay(m_page->displayID())); |
| 3402 | #endif |
| 3403 | paintSnapshotAtSize(rect, bitmapSize, options, frame, frameView, graphicsContext); |
| 3404 | |
| 3405 | return snapshot; |
| 3406 | } |
| 3407 | |
| 3408 | RefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount) |
| 3409 | { |
| 3410 | RefPtr coreFrame = m_mainFrame->coreLocalFrame(); |
| 3411 | if (!coreFrame) |
| 3412 | return nullptr; |
| 3413 | |
| 3414 | RefPtr frameView = coreFrame->view(); |
| 3415 | if (!frameView) |
| 3416 | return nullptr; |
| 3417 | |
| 3418 | if (!node.renderer()) |
| 3419 | return nullptr; |
| 3420 | |
| 3421 | LayoutRect topLevelRect; |
| 3422 | IntRect snapshotRect = snappedIntRect(protect(node.renderer())->paintingRootRect(topLevelRect)); |
| 3423 | if (snapshotRect.isEmpty()) |
| 3424 | return nullptr; |
| 3425 | |
| 3426 | double scaleFactor = 1; |
| 3427 | IntSize snapshotSize = snapshotRect.size(); |
| 3428 | unsigned maximumHeight = maximumPixelCount / snapshotSize.width(); |
| 3429 | if (maximumHeight < static_cast<unsigned>(snapshotSize.height())) { |
| 3430 | scaleFactor = static_cast<double>(maximumHeight) / snapshotSize.height(); |
| 3431 | snapshotSize = IntSize(snapshotSize.width() * scaleFactor, maximumHeight); |
| 3432 | } |
| 3433 | |
| 3434 | auto snapshot = WebImage::create(snapshotSize, snapshotOptionsToImageOptions(options), snapshotColorSpace(options, *this), &m_page->chrome().client()); |
| 3435 | if (!snapshot->context()) |
| 3436 | return nullptr; |
| 3437 | |
| 3438 | auto& graphicsContext = *snapshot->context(); |
| 3439 | |
| 3440 | if (!options.contains(SnapshotOption::ExcludeDeviceScaleFactor)) { |
| 3441 | double deviceScaleFactor = corePage()->deviceScaleFactor(); |
| 3442 | graphicsContext.applyDeviceScaleFactor(deviceScaleFactor); |
| 3443 | scaleFactor /= deviceScaleFactor; |
| 3444 | } |
| 3445 | |
| 3446 | graphicsContext.scale(scaleFactor); |
| 3447 | graphicsContext.translate(-snapshotRect.location()); |
| 3448 | |
| 3449 | Color savedBackgroundColor = frameView->baseBackgroundColor(); |
| 3450 | frameView->setBaseBackgroundColor(Color::transparentBlack); |
| 3451 | frameView->setNodeToDraw(&node); |
| 3452 | |
| 3453 | frameView->paintContentsForSnapshot(graphicsContext, snapshotRect, LocalFrameView::ExcludeSelection, LocalFrameView::DocumentCoordinates); |
| 3454 | |
| 3455 | frameView->setBaseBackgroundColor(savedBackgroundColor); |
| 3456 | frameView->setNodeToDraw(nullptr); |
| 3457 | |
| 3458 | return snapshot; |
| 3459 | } |
| 3460 | |
| 3461 | void WebPage::pageDidScroll() |
| 3462 | { |
| 3463 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3464 | if (!m_inDynamicSizeUpdate) |
| 3465 | m_internals->dynamicSizeUpdateHistory.clear(); |
| 3466 | #endif |
| 3467 | m_pageScrolledHysteresis.impulse(); |
| 3468 | |
| 3469 | if (RefPtr view = protect(protect(corePage())->mainFrame())->virtualView()) |
| 3470 | send(Messages::WebPageProxy::PageDidScroll(view->scrollPosition())); |
| 3471 | } |
| 3472 | |
| 3473 | void WebPage::pageStoppedScrolling() |
| 3474 | { |
| 3475 | // Maintain the current history item's scroll position up-to-date. |
| 3476 | if (RefPtr frame = m_mainFrame->coreLocalFrame()) |
| 3477 | frame->loader().history().saveScrollPositionAndViewStateToItem(protect(frame->loader().history().currentItem()).get()); |
| 3478 | } |
| 3479 | |
| 3480 | void WebPage::setHasActiveAnimatedScrolls(bool hasActiveAnimatedScrolls) |
| 3481 | { |
| 3482 | send(Messages::WebPageProxy::SetHasActiveAnimatedScrolls(hasActiveAnimatedScrolls)); |
| 3483 | } |
| 3484 | |
| 3485 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 3486 | WebContextMenu& WebPage::contextMenu() |
| 3487 | { |
| 3488 | if (!m_contextMenu) |
| 3489 | m_contextMenu = WebContextMenu::create(*this); |
| 3490 | return *m_contextMenu; |
| 3491 | } |
| 3492 | |
| 3493 | RefPtr<WebContextMenu> WebPage::contextMenuAtPointInWindow(FrameIdentifier frameID, const DoublePoint& point) |
| 3494 | { |
| 3495 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 3496 | if (!frame) |
| 3497 | return nullptr; |
| 3498 | |
| 3499 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 3500 | if (!coreFrame) |
| 3501 | return nullptr; |
| 3502 | |
| 3503 | corePage()->contextMenuController().clearContextMenu(); |
| 3504 | |
| 3505 | // Simulate a mouse click to generate the correct menu. |
| 3506 | PlatformMouseEvent mousePressEvent(point, point, MouseButton::Right, PlatformEvent::Type::MousePressed, 1, { }, MonotonicTime::now(), WebCore::ForceAtClick, WebCore::SyntheticClickType::NoTap, MouseEventInputSource::UserDriven); |
| 3507 | coreFrame->eventHandler().handleMousePressEvent(mousePressEvent); |
| 3508 | bool handled = coreFrame->eventHandler().sendContextMenuEvent(mousePressEvent); |
| 3509 | RefPtr menu = handled ? &contextMenu() : nullptr; |
| 3510 | PlatformMouseEvent mouseReleaseEvent(point, point, MouseButton::Right, PlatformEvent::Type::MouseReleased, 1, { }, MonotonicTime::now(), WebCore::ForceAtClick, WebCore::SyntheticClickType::NoTap, MouseEventInputSource::UserDriven); |
| 3511 | coreFrame->eventHandler().handleMouseReleaseEvent(mouseReleaseEvent); |
| 3512 | |
| 3513 | return menu; |
| 3514 | } |
| 3515 | #endif |
| 3516 | |
| 3517 | // Events |
| 3518 | |
| 3519 | static const WebEvent* g_currentEvent = 0; |
| 3520 | |
| 3521 | // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to |
| 3522 | // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct |
| 3523 | // platform events passed to the event handler code. |
| 3524 | const WebEvent* WebPage::currentEvent() |
| 3525 | { |
| 3526 | return g_currentEvent; |
| 3527 | } |
| 3528 | |
| 3529 | void WebPage::freezeLayerTree(LayerTreeFreezeReason reason) |
| 3530 | { |
| 3531 | auto oldReasons = m_layerTreeFreezeReasons.toRaw(); |
| 3532 | UNUSED_PARAM(oldReasons)(void)oldReasons; |
| 3533 | m_layerTreeFreezeReasons.add(reason); |
| 3534 | WEBPAGE_RELEASE_LOG_FORWARDABLE(ProcessSuspension, WEBPAGE_FREEZE_LAYER_TREE, static_cast<unsigned>(reason), m_layerTreeFreezeReasons.toRaw(), oldReasons)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_FREEZE_LAYER_TREE(m_identifier. toUInt64(), static_cast<unsigned>(reason), m_layerTreeFreezeReasons .toRaw(), oldReasons); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogProcessSuspension .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::freezeLayerTree: Adding a reason to freeze layer tree (reason=%d, new=%d, old=%d)" ), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG73" ) = "[webPageID=%" "ll" "u" "] WebPage::freezeLayerTree: Adding a reason to freeze layer tree (reason=%d, new=%d, old=%d)" ; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf [__builtin_os_log_format_buffer_size("[webPageID=%" "ll" "u" "] WebPage::freezeLayerTree: Adding a reason to freeze layer tree (reason=%d, new=%d, old=%d)" , m_identifier.toUInt64(), static_cast<unsigned>(reason ), m_layerTreeFreezeReasons.toRaw(), oldReasons)]; _os_log_impl (&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "[webPageID=%" "ll" "u" "] WebPage::freezeLayerTree: Adding a reason to freeze layer tree (reason=%d, new=%d, old=%d)" , m_identifier.toUInt64(), static_cast<unsigned>(reason ), m_layerTreeFreezeReasons.toRaw(), oldReasons), (uint32_t)sizeof (_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0); |
| 3535 | updateDrawingAreaLayerTreeFreezeState(); |
| 3536 | } |
| 3537 | |
| 3538 | void WebPage::unfreezeLayerTree(LayerTreeFreezeReason reason) |
| 3539 | { |
| 3540 | auto oldReasons = m_layerTreeFreezeReasons.toRaw(); |
| 3541 | UNUSED_PARAM(oldReasons)(void)oldReasons; |
| 3542 | m_layerTreeFreezeReasons.remove(reason); |
| 3543 | WEBPAGE_RELEASE_LOG_FORWARDABLE(ProcessSuspension, WEBPAGE_UNFREEZE_LAYER_TREE, static_cast<unsigned>(reason), m_layerTreeFreezeReasons.toRaw(), oldReasons)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_UNFREEZE_LAYER_TREE(m_identifier .toUInt64(), static_cast<unsigned>(reason), m_layerTreeFreezeReasons .toRaw(), oldReasons); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogProcessSuspension .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::unfreezeLayerTree: Removing a reason to freeze layer tree (reason=%d, new=%d, old=%d)" ), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG74" ) = "[webPageID=%" "ll" "u" "] WebPage::unfreezeLayerTree: Removing a reason to freeze layer tree (reason=%d, new=%d, old=%d)" ; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf [__builtin_os_log_format_buffer_size("[webPageID=%" "ll" "u" "] WebPage::unfreezeLayerTree: Removing a reason to freeze layer tree (reason=%d, new=%d, old=%d)" , m_identifier.toUInt64(), static_cast<unsigned>(reason ), m_layerTreeFreezeReasons.toRaw(), oldReasons)]; _os_log_impl (&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "[webPageID=%" "ll" "u" "] WebPage::unfreezeLayerTree: Removing a reason to freeze layer tree (reason=%d, new=%d, old=%d)" , m_identifier.toUInt64(), static_cast<unsigned>(reason ), m_layerTreeFreezeReasons.toRaw(), oldReasons), (uint32_t)sizeof (_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0); |
| 3544 | updateDrawingAreaLayerTreeFreezeState(); |
| 3545 | } |
| 3546 | |
| 3547 | void WebPage::updateDrawingAreaLayerTreeFreezeState() |
| 3548 | { |
| 3549 | RefPtr drawingArea = m_drawingArea; |
| 3550 | if (!drawingArea) |
| 3551 | return; |
| 3552 | |
| 3553 | #if ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1) |
| 3554 | // When the browser is in the background, we should not freeze the layer tree |
| 3555 | // if the page has a video playing in picture-in-picture. |
| 3556 | RefPtr videoPresentationManager = m_videoPresentationManager; |
| 3557 | if (videoPresentationManager && videoPresentationManager->hasVideoPlayingInPictureInPicture() && m_layerTreeFreezeReasons.hasExactlyOneBitSet() && m_layerTreeFreezeReasons.contains(LayerTreeFreezeReason::BackgroundApplication)) { |
| 3558 | drawingArea->setLayerTreeStateIsFrozen(false); |
| 3559 | return; |
| 3560 | } |
| 3561 | #endif |
| 3562 | |
| 3563 | drawingArea->setLayerTreeStateIsFrozen(!!m_layerTreeFreezeReasons); |
| 3564 | } |
| 3565 | |
| 3566 | void WebPage::updateFrameScrollingMode(FrameIdentifier frameID, ScrollbarMode scrollingMode) |
| 3567 | { |
| 3568 | if (!m_page) |
| 3569 | return; |
| 3570 | |
| 3571 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 3572 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 3573 | if (!webFrame) |
| 3574 | return; |
| 3575 | |
| 3576 | RefPtr frame = webFrame->coreLocalFrame(); |
| 3577 | if (!frame) |
| 3578 | return; |
| 3579 | |
| 3580 | frame->setScrollingMode(scrollingMode); |
| 3581 | } |
| 3582 | |
| 3583 | void WebPage::tryMarkLayersVolatile(CompletionHandler<void(bool)>&& completionHandler) |
| 3584 | { |
| 3585 | RefPtr drawingArea = m_drawingArea; |
| 3586 | if (!drawingArea) { |
| 3587 | completionHandler(false); |
| 3588 | return; |
| 3589 | } |
| 3590 | |
| 3591 | drawingArea->tryMarkLayersVolatile(WTF::move(completionHandler)); |
| 3592 | } |
| 3593 | |
| 3594 | void WebPage::callVolatilityCompletionHandlers(bool succeeded) |
| 3595 | { |
| 3596 | auto completionHandlers = std::exchange(m_markLayersAsVolatileCompletionHandlers, { }); |
| 3597 | for (auto& completionHandler : completionHandlers) |
| 3598 | completionHandler(succeeded); |
| 3599 | } |
| 3600 | |
| 3601 | void WebPage::layerVolatilityTimerFired() |
| 3602 | { |
| 3603 | m_layerVolatilityTimerInterval *= 2; |
| 3604 | markLayersVolatileOrRetry(m_layerVolatilityTimerInterval > maximumLayerVolatilityTimerInterval ? MarkLayersVolatileDontRetryReason::TimedOut : MarkLayersVolatileDontRetryReason::None); |
| 3605 | } |
| 3606 | |
| 3607 | void WebPage::markLayersVolatile(CompletionHandler<void(bool)>&& completionHandler) |
| 3608 | { |
| 3609 | WEBPAGE_RELEASE_LOG_FORWARDABLE(Layers, WEBPAGE_MARK_LAYERS_VOLATILE)do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_MARK_LAYERS_VOLATILE(m_identifier .toUInt64()); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogLayers .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile"), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG75" ) = "[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile"; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile", m_identifier .toUInt64())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp , _os_fmt_str, (uint8_t *)__builtin_os_log_format(_os_fmt_buf , "[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile", m_identifier .toUInt64()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; } while (0); |
| 3610 | |
| 3611 | if (m_layerVolatilityTimer.isActive()) |
| 3612 | m_layerVolatilityTimer.stop(); |
| 3613 | |
| 3614 | if (completionHandler) |
| 3615 | m_markLayersAsVolatileCompletionHandlers.append(WTF::move(completionHandler)); |
| 3616 | |
| 3617 | m_layerVolatilityTimerInterval = initialLayerVolatilityTimerInterval; |
| 3618 | markLayersVolatileOrRetry(m_isSuspendedUnderLock ? MarkLayersVolatileDontRetryReason::SuspendedUnderLock : MarkLayersVolatileDontRetryReason::None); |
| 3619 | } |
| 3620 | |
| 3621 | void WebPage::markLayersVolatileOrRetry(MarkLayersVolatileDontRetryReason dontRetryReason) |
| 3622 | { |
| 3623 | tryMarkLayersVolatile([dontRetryReason, protectedThis = Ref { *this }](bool didSucceed) { |
| 3624 | protectedThis->tryMarkLayersVolatileCompletionHandler(dontRetryReason, didSucceed); |
| 3625 | }); |
| 3626 | } |
| 3627 | |
| 3628 | void WebPage::tryMarkLayersVolatileCompletionHandler(MarkLayersVolatileDontRetryReason dontRetryReason, bool didSucceed) |
| 3629 | { |
| 3630 | if (m_isClosed) |
| 3631 | return; |
| 3632 | |
| 3633 | if (didSucceed || dontRetryReason != MarkLayersVolatileDontRetryReason::None) { |
| 3634 | m_layerVolatilityTimer.stop(); |
| 3635 | if (didSucceed) |
| 3636 | WEBPAGE_RELEASE_LOG(Layers, "markLayersVolatile: Succeeded in marking layers as volatile"); |
| 3637 | else { |
| 3638 | switch (dontRetryReason) { |
| 3639 | case MarkLayersVolatileDontRetryReason::None: |
| 3640 | break; |
| 3641 | case MarkLayersVolatileDontRetryReason::SuspendedUnderLock: |
| 3642 | WEBPAGE_RELEASE_LOG(Layers, "markLayersVolatile: Did what we could to mark IOSurfaces as purgeable after locking the screen"); |
| 3643 | break; |
| 3644 | case MarkLayersVolatileDontRetryReason::TimedOut: |
| 3645 | WEBPAGE_RELEASE_LOG(Layers, "markLayersVolatile: Failed to mark layers as volatile within %gms", maximumLayerVolatilityTimerInterval.milliseconds()); |
| 3646 | break; |
| 3647 | } |
| 3648 | } |
| 3649 | callVolatilityCompletionHandlers(didSucceed); |
| 3650 | return; |
| 3651 | } |
| 3652 | |
| 3653 | if (m_markLayersAsVolatileCompletionHandlers.isEmpty()) { |
| 3654 | WEBPAGE_RELEASE_LOG(Layers, "markLayersVolatile: Failed to mark all layers as volatile, but will not retry because the operation was cancelled"); |
| 3655 | return; |
| 3656 | } |
| 3657 | |
| 3658 | WEBPAGE_RELEASE_LOG_FORWARDABLE(Layers, WEBPAGE_FAILED_TO_MARK_ALL_LAYERS_VOLATILE, m_layerVolatilityTimerInterval.milliseconds())do { if (auto* client = downcast<LogClient>(WebCore::logClient ().get())) client->WEBPAGE_FAILED_TO_MARK_ALL_LAYERS_VOLATILE (m_identifier.toUInt64(), m_layerVolatilityTimerInterval.milliseconds ()); else clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogLayers .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms" ), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG76" ) = "[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms" ; uint8_t _Alignas(16) __attribute__((uninitialized)) _os_fmt_buf [__builtin_os_log_format_buffer_size("[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms" , m_identifier.toUInt64(), m_layerVolatilityTimerInterval.milliseconds ())]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "[webPageID=%" "ll" "u" "] WebPage::markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms" , m_identifier.toUInt64(), m_layerVolatilityTimerInterval.milliseconds ()), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }) ; } }) clang diagnostic pop ; } while (0); |
| 3659 | m_layerVolatilityTimer.startOneShot(m_layerVolatilityTimerInterval); |
| 3660 | } |
| 3661 | |
| 3662 | void WebPage::cancelMarkLayersVolatile() |
| 3663 | { |
| 3664 | WEBPAGE_RELEASE_LOG(Layers, "cancelMarkLayersVolatile:"); |
| 3665 | m_layerVolatilityTimer.stop(); |
| 3666 | callVolatilityCompletionHandlers(false); |
| 3667 | } |
| 3668 | |
| 3669 | class CurrentEvent { |
| 3670 | public: |
| 3671 | explicit CurrentEvent(const WebEvent& event) |
| 3672 | : m_previousCurrentEvent(g_currentEvent) |
| 3673 | { |
| 3674 | g_currentEvent = &event; |
| 3675 | } |
| 3676 | |
| 3677 | ~CurrentEvent() |
| 3678 | { |
| 3679 | g_currentEvent = m_previousCurrentEvent.get(); |
| 3680 | } |
| 3681 | |
| 3682 | private: |
| 3683 | CheckedPtr<const WebEvent> m_previousCurrentEvent; |
| 3684 | }; |
| 3685 | |
| 3686 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 3687 | |
| 3688 | void WebPage::didDismissContextMenu() |
| 3689 | { |
| 3690 | corePage()->contextMenuController().didDismissContextMenu(); |
| 3691 | } |
| 3692 | |
| 3693 | void WebPage::showContextMenuFromFrame(const FrameInfoData& frameInfo, const ContextMenuContextData& contextMenuContextData, const UserData& userData) |
| 3694 | { |
| 3695 | flushPendingEditorStateUpdate(); |
| 3696 | send(Messages::WebPageProxy::ShowContextMenuFromFrame(frameInfo, contextMenuContextData, userData)); |
| 3697 | m_hasEverDisplayedContextMenu = true; |
| 3698 | scheduleFullEditorStateUpdate(); |
| 3699 | } |
| 3700 | |
| 3701 | #endif // ENABLE(CONTEXT_MENUS) |
| 3702 | |
| 3703 | #if ENABLE(CONTEXT_MENU_EVENT)(defined 1 && 1) |
| 3704 | void WebPage::contextMenuForKeyEvent() |
| 3705 | { |
| 3706 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 3707 | corePage()->contextMenuController().clearContextMenu(); |
| 3708 | #endif |
| 3709 | |
| 3710 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 3711 | if (!frame) |
| 3712 | return; |
| 3713 | |
| 3714 | bool handled = frame->eventHandler().sendContextMenuEventForKey(); |
| 3715 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 3716 | if (handled) |
| 3717 | protect(contextMenu())->show(); |
| 3718 | #else |
| 3719 | UNUSED_PARAM(handled)(void)handled; |
| 3720 | #endif |
| 3721 | } |
| 3722 | #endif |
| 3723 | |
| 3724 | void WebPage::mouseEvent(FrameIdentifier frameID, const WebMouseEvent& mouseEvent, std::optional<Vector<SandboxExtension::Handle>>&& sandboxExtensions) |
| 3725 | { |
| 3726 | SetForScope userIsInteractingChange { m_userIsInteracting, true }; |
| 3727 | |
| 3728 | m_internals->userActivity.impulse(); |
| 3729 | |
| 3730 | bool shouldHandleEvent = true; |
| 3731 | #if ENABLE(DRAG_SUPPORT)(defined 1 && 1) |
| 3732 | if (m_isStartingDrag) |
| 3733 | shouldHandleEvent = false; |
| 3734 | #endif |
| 3735 | |
| 3736 | if (!shouldHandleEvent) { |
| 3737 | send(Messages::WebPageProxy::DidReceiveEventIPC(mouseEvent.type(), false, std::nullopt)); |
| 3738 | return; |
| 3739 | } |
| 3740 | |
| 3741 | Vector<Ref<SandboxExtension>> mouseEventSandboxExtensions; |
| 3742 | if (sandboxExtensions) |
| 3743 | mouseEventSandboxExtensions = consumeSandboxExtensions(WTF::move(*sandboxExtensions)); |
| 3744 | |
| 3745 | bool handled = false; |
| 3746 | |
| 3747 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3748 | if (!handled && m_headerBanner) |
| 3749 | handled = Ref { *m_headerBanner }->mouseEvent(mouseEvent); |
| 3750 | if (!handled && m_footerBanner) |
| 3751 | handled = Ref { *m_footerBanner }->mouseEvent(mouseEvent); |
| 3752 | #endif // !PLATFORM(IOS_FAMILY) |
| 3753 | |
| 3754 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID); !handled && frame) { |
| 3755 | CurrentEvent currentEvent(mouseEvent); |
| 3756 | auto mouseEventResult = frame->handleMouseEvent(mouseEvent); |
| 3757 | if (auto remoteMouseEventData = mouseEventResult.remoteUserInputEventData()) { |
| 3758 | revokeSandboxExtensions(mouseEventSandboxExtensions); |
| 3759 | send(Messages::WebPageProxy::DidReceiveEventIPC(mouseEvent.type(), false, *remoteMouseEventData)); |
| 3760 | return; |
| 3761 | } |
| 3762 | handled = mouseEventResult.wasHandled(); |
| 3763 | } |
| 3764 | |
| 3765 | revokeSandboxExtensions(mouseEventSandboxExtensions); |
| 3766 | |
| 3767 | RefPtr drawingArea = m_drawingArea; |
| 3768 | bool shouldDeferDidReceiveEvent = [&] { |
| 3769 | if (!drawingArea) |
| 3770 | return false; |
| 3771 | |
| 3772 | if (mouseEvent.type() != WebEventType::MouseMove) |
| 3773 | return false; |
| 3774 | |
| 3775 | if (mouseEvent.button() != WebMouseEventButton::None) |
| 3776 | return false; |
| 3777 | |
| 3778 | if (mouseEvent.force()) |
| 3779 | return false; |
| 3780 | |
| 3781 | return true; |
| 3782 | }(); |
| 3783 | |
| 3784 | flushDeferredDidReceiveMouseEvent(); |
| 3785 | |
| 3786 | if (shouldDeferDidReceiveEvent) { |
| 3787 | // For mousemove events where the user is only hovering (not clicking and dragging), |
| 3788 | // we defer sending the DidReceiveEvent() IPC message until the end of the rendering |
| 3789 | // update to throttle the rate of these events to the rendering update frequency. |
| 3790 | // This logic works in tandem with the mouse event queue in the UI process, which |
| 3791 | // coalesces mousemove events until the DidReceiveEvent() message is received after |
| 3792 | // the rendering update. |
| 3793 | m_deferredDidReceiveMouseEvent = { { mouseEvent.type(), handled } }; |
| 3794 | protect(corePage())->scheduleRenderingUpdate({ }); |
| 3795 | return; |
| 3796 | } |
| 3797 | |
| 3798 | send(Messages::WebPageProxy::DidReceiveEventIPC(mouseEvent.type(), handled, std::nullopt)); |
| 3799 | |
| 3800 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3801 | if (mouseEvent.type() == WebEventType::MouseUp) |
| 3802 | removeTextInteractionSources(TextInteractionSource::Mouse); |
| 3803 | #endif |
| 3804 | } |
| 3805 | |
| 3806 | void WebPage::setLastKnownMousePosition(WebCore::FrameIdentifier frameID, const DoublePoint& eventPoint, const DoublePoint& globalPoint, std::optional<WebCore::LastKnownMousePositionSource>&& source) |
| 3807 | { |
| 3808 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 3809 | if (!frame || !frame->coreLocalFrame() || !frame->coreLocalFrame()->view()) |
| 3810 | return; |
| 3811 | |
| 3812 | frame->coreLocalFrame()->eventHandler().setLastKnownMousePosition(eventPoint, globalPoint, WTF::move(source)); |
| 3813 | } |
| 3814 | |
| 3815 | void WebPage::startDeferringResizeEvents() |
| 3816 | { |
| 3817 | protect(corePage())->startDeferringResizeEvents(); |
| 3818 | } |
| 3819 | |
| 3820 | void WebPage::flushDeferredResizeEvents() |
| 3821 | { |
| 3822 | protect(corePage())->flushDeferredResizeEvents(); |
| 3823 | } |
| 3824 | |
| 3825 | void WebPage::startDeferringScrollEvents() |
| 3826 | { |
| 3827 | protect(corePage())->startDeferringScrollEvents(); |
| 3828 | } |
| 3829 | |
| 3830 | void WebPage::flushDeferredScrollEvents() |
| 3831 | { |
| 3832 | protect(corePage())->flushDeferredScrollEvents(); |
| 3833 | } |
| 3834 | |
| 3835 | void WebPage::startDeferringIntersectionObservations() |
| 3836 | { |
| 3837 | protect(corePage())->startDeferringIntersectionObservations(); |
| 3838 | } |
| 3839 | |
| 3840 | void WebPage::flushDeferredIntersectionObservations() |
| 3841 | { |
| 3842 | protect(corePage())->flushDeferredIntersectionObservations(); |
| 3843 | } |
| 3844 | |
| 3845 | void WebPage::flushDeferredDidReceiveMouseEvent() |
| 3846 | { |
| 3847 | if (auto info = std::exchange(m_deferredDidReceiveMouseEvent, std::nullopt)) |
| 3848 | send(Messages::WebPageProxy::DidReceiveEventIPC(*info->type, info->handled, std::nullopt)); |
| 3849 | } |
| 3850 | |
| 3851 | void WebPage::performHitTestForMouseEvent(const WebMouseEvent& event, CompletionHandler<void(WebHitTestResultData&&, OptionSet<WebEventModifier>)>&& completionHandler) |
| 3852 | { |
| 3853 | auto modifiers = event.modifiers(); |
| 3854 | RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame()); |
| 3855 | if (!localMainFrame || !localMainFrame->view()) |
| 3856 | return completionHandler({ }, modifiers); |
| 3857 | |
| 3858 | auto hitTestResult = localMainFrame->eventHandler().getHitTestResultForMouseEvent(platform(event)); |
| 3859 | |
| 3860 | String toolTip; |
| 3861 | TextDirection toolTipDirection; |
| 3862 | corePage()->chrome().getToolTip(hitTestResult, toolTip, toolTipDirection); |
| 3863 | |
| 3864 | WebHitTestResultData hitTestResultData { hitTestResult, toolTip }; |
| 3865 | |
| 3866 | completionHandler(WTF::move(hitTestResultData), modifiers); |
| 3867 | } |
| 3868 | |
| 3869 | void WebPage::handleWheelEvent(FrameIdentifier frameID, const WebWheelEvent& event, const OptionSet<WheelEventProcessingSteps>& processingSteps, std::optional<bool> willStartSwipe, CompletionHandler<void(std::optional<WebCore::ScrollingNodeID>, std::optional<WebCore::WheelScrollGestureState>, bool, std::optional<RemoteUserInputEventData>)>&& completionHandler) |
| 3870 | { |
| 3871 | #if ENABLE(ASYNC_SCROLLING)(defined 1 && 1) |
| 3872 | RefPtr remoteScrollingCoordinator = dynamicDowncast<RemoteScrollingCoordinator>(scrollingCoordinator()); |
| 3873 | if (remoteScrollingCoordinator) |
| 3874 | remoteScrollingCoordinator->setCurrentWheelEventWillStartSwipe(willStartSwipe); |
| 3875 | #else |
| 3876 | UNUSED_PARAM(willStartSwipe)(void)willStartSwipe; |
| 3877 | #endif |
| 3878 | |
| 3879 | auto [handleWheelEventResult, _] = wheelEvent(frameID, event, processingSteps); |
| 3880 | #if ENABLE(ASYNC_SCROLLING)(defined 1 && 1) |
| 3881 | if (remoteScrollingCoordinator) { |
| 3882 | auto gestureInfo = remoteScrollingCoordinator->takeCurrentWheelGestureInfo(); |
| 3883 | completionHandler(gestureInfo.wheelGestureNode, gestureInfo.wheelGestureState, handleWheelEventResult.wasHandled(), handleWheelEventResult.remoteUserInputEventData()); |
| 3884 | return; |
| 3885 | } |
| 3886 | #endif |
| 3887 | completionHandler({ }, { }, handleWheelEventResult.wasHandled(), handleWheelEventResult.remoteUserInputEventData()); |
| 3888 | } |
| 3889 | |
| 3890 | std::pair<HandleUserInputEventResult, OptionSet<EventHandling>> WebPage::wheelEvent(const FrameIdentifier& frameID, const WebWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps> processingSteps) |
| 3891 | { |
| 3892 | m_internals->userActivity.impulse(); |
| 3893 | |
| 3894 | CurrentEvent currentEvent(wheelEvent); |
| 3895 | |
| 3896 | auto dispatchWheelEvent = [&](const WebWheelEvent& wheelEvent, OptionSet<WheelEventProcessingSteps> processingSteps) { |
| 3897 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 3898 | if (!frame || !frame->coreLocalFrame() || !frame->coreLocalFrame()->view()) |
| 3899 | return std::pair { HandleUserInputEventResult { false }, OptionSet<EventHandling> { } }; |
| 3900 | |
| 3901 | auto platformWheelEvent = platform(wheelEvent); |
| 3902 | return frame->coreLocalFrame()->eventHandler().handleWheelEvent(platformWheelEvent, processingSteps); |
| 3903 | }; |
| 3904 | |
| 3905 | auto [result, handling] = dispatchWheelEvent(wheelEvent, processingSteps); |
| 3906 | LOG_WITH_STREAM(WheelEvents, stream << "WebPage::wheelEvent - processing steps " << processingSteps << " handled " << result.wasHandled())((void)0); |
| 3907 | return { result, handling }; |
| 3908 | } |
| 3909 | |
| 3910 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 3911 | void WebPage::dispatchWheelEventWithoutScrolling(FrameIdentifier frameID, const WebWheelEvent& wheelEvent, CompletionHandler<void(bool)>&& completionHandler) |
| 3912 | { |
| 3913 | #if ENABLE(KINETIC_SCROLLING)(defined 1 && 1) |
| 3914 | RefPtr localMainFrame = this->localMainFrame(); |
| 3915 | auto gestureState = localMainFrame ? localMainFrame->eventHandler().wheelScrollGestureState() : std::nullopt; |
| 3916 | bool isCancelable = !gestureState || gestureState == WheelScrollGestureState::Blocking || wheelEvent.phase() == WebWheelEvent::Phase::Began; |
| 3917 | #else |
| 3918 | bool isCancelable = true; |
| 3919 | #endif |
| 3920 | auto [result, handling] = this->wheelEvent(frameID, wheelEvent, { isCancelable ? WheelEventProcessingSteps::BlockingDOMEventDispatch : WheelEventProcessingSteps::NonBlockingDOMEventDispatch }); |
| 3921 | // The caller of dispatchWheelEventWithoutScrolling never cares about DidReceiveEvent being sent back. |
| 3922 | completionHandler(result.wasHandled() && handling.contains(EventHandling::DefaultPrevented)); |
| 3923 | } |
| 3924 | #endif |
| 3925 | |
| 3926 | void WebPage::keyEvent(FrameIdentifier frameID, const WebKeyboardEvent& keyboardEvent) |
| 3927 | { |
| 3928 | SetForScope userIsInteractingChange { m_userIsInteracting, true }; |
| 3929 | |
| 3930 | m_internals->userActivity.impulse(); |
| 3931 | |
| 3932 | PlatformKeyboardEvent::setCurrentModifierState(platform(keyboardEvent).modifiers()); |
| 3933 | |
| 3934 | CurrentEvent currentEvent(keyboardEvent); |
| 3935 | |
| 3936 | bool handled = false; |
| 3937 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) |
| 3938 | handled = frame->handleKeyEvent(keyboardEvent); |
| 3939 | |
| 3940 | send(Messages::WebPageProxy::DidReceiveEventIPC(keyboardEvent.type(), handled, std::nullopt)); |
| 3941 | } |
| 3942 | |
| 3943 | bool WebPage::handleKeyEventByRelinquishingFocusToChrome(const KeyboardEvent& event) |
| 3944 | { |
| 3945 | if (m_page->tabKeyCyclesThroughElements()) |
| 3946 | return false; |
| 3947 | |
| 3948 | if (event.charCode() != '\t') |
| 3949 | return false; |
| 3950 | |
| 3951 | if (!event.shiftKey() || event.ctrlKey() || event.metaKey()) |
| 3952 | return false; |
| 3953 | |
| 3954 | ASSERT(event.type() == eventNames().keypressEvent)((void)0); |
| 3955 | // Allow a shift-tab keypress event to relinquish focus even if we don't allow tab to cycle between |
| 3956 | // elements inside the view. We can only do this for shift-tab, not tab itself because |
| 3957 | // tabKeyCyclesThroughElements is used to make tab character insertion work in editable web views. |
| 3958 | return protect(corePage())->focusController().relinquishFocusToChrome(FocusDirection::Backward); |
| 3959 | } |
| 3960 | |
| 3961 | void WebPage::validateCommand(const String& commandName, CompletionHandler<void(bool, int32_t)>&& completionHandler) |
| 3962 | { |
| 3963 | bool isEnabled = false; |
| 3964 | int32_t state = 0; |
| 3965 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 3966 | if (!frame) |
| 3967 | return completionHandler({ }, { }); |
| 3968 | |
| 3969 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 3970 | if (RefPtr pluginView = focusedPluginViewForFrame(*frame)) |
| 3971 | isEnabled = pluginView->isEditingCommandEnabled(commandName); |
| 3972 | else |
| 3973 | #endif |
| 3974 | { |
| 3975 | auto command = protect(frame->editor())->command(commandName); |
| 3976 | state = (command.state() != TriState::False); |
| 3977 | isEnabled = command.isSupported() && command.isEnabled(); |
| 3978 | } |
| 3979 | |
| 3980 | completionHandler(isEnabled, state); |
| 3981 | } |
| 3982 | |
| 3983 | void WebPage::executeEditCommand(const String& commandName, const String& argument) |
| 3984 | { |
| 3985 | executeEditingCommand(commandName, argument); |
| 3986 | } |
| 3987 | |
| 3988 | void WebPage::setNeedsFontAttributes(bool needsFontAttributes) |
| 3989 | { |
| 3990 | if (m_needsFontAttributes == needsFontAttributes) |
| 3991 | return; |
| 3992 | |
| 3993 | m_needsFontAttributes = needsFontAttributes; |
| 3994 | |
| 3995 | if (m_needsFontAttributes) |
| 3996 | scheduleFullEditorStateUpdate(); |
| 3997 | } |
| 3998 | |
| 3999 | void WebPage::setCurrentHistoryItemForReattach(Ref<FrameState>&& mainFrameState) |
| 4000 | { |
| 4001 | if (RefPtr localMainFrame = m_mainFrame->provisionalFrame() ? m_mainFrame->provisionalFrame() : m_mainFrame->coreLocalFrame()) |
| 4002 | localMainFrame->loader().history().setCurrentItem(toHistoryItem(m_historyItemClient, mainFrameState)); |
| 4003 | } |
| 4004 | |
| 4005 | void WebPage::requestFontAttributesAtSelectionStart(CompletionHandler<void(const WebCore::FontAttributes&)>&& completionHandler) |
| 4006 | { |
| 4007 | RefPtr focusedOrMainFrame = corePage()->focusController().focusedOrMainFrame(); |
| 4008 | if (!focusedOrMainFrame) |
| 4009 | return completionHandler({ }); |
| 4010 | completionHandler(protect(focusedOrMainFrame->editor())->fontAttributesAtSelectionStart()); |
| 4011 | } |
| 4012 | |
| 4013 | void WebPage::cancelCurrentInteractionInformationRequest() |
| 4014 | { |
| 4015 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 4016 | if (auto reply = WTF::move(m_pendingSynchronousPositionInformationReply)) |
| 4017 | reply(InteractionInformationAtPosition::invalidInformation()); |
| 4018 | #endif |
| 4019 | } |
| 4020 | |
| 4021 | #if ENABLE(TOUCH_EVENTS)(defined 0 && 0) |
| 4022 | static Expected<bool, WebCore::RemoteFrameGeometryTransformer> handleTouchEvent(FrameIdentifier frameID, const WebTouchEvent& touchEvent, Page* page) |
| 4023 | { |
| 4024 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 4025 | if (!frame) |
| 4026 | return false; |
| 4027 | |
| 4028 | RefPtr localFrame = frame->coreLocalFrame(); |
| 4029 | if (!localFrame || !localFrame->view()) |
| 4030 | return false; |
| 4031 | |
| 4032 | return localFrame->eventHandler().handleTouchEvent(platform(touchEvent)); |
| 4033 | } |
| 4034 | #endif |
| 4035 | |
| 4036 | RefPtr<WebCore::LocalFrame> WebPage::localRootFrame(std::optional<WebCore::FrameIdentifier> frameID) |
| 4037 | { |
| 4038 | if (RefPtr webFrame = WebProcess::singleton().webFrame(frameID)) { |
| 4039 | ASSERT(webFrame->coreLocalFrame())((void)0); |
| 4040 | ASSERT(webFrame->coreLocalFrame()->isRootFrame())((void)0); |
| 4041 | return webFrame->coreLocalFrame(); |
| 4042 | } |
| 4043 | ASSERT(m_page)((void)0); |
| 4044 | ASSERT(m_page->localMainFrame())((void)0); |
| 4045 | RefPtr page = m_page; |
| 4046 | return page ? page->localMainFrame() : nullptr; |
| 4047 | } |
| 4048 | |
| 4049 | #if ENABLE(IOS_TOUCH_EVENTS)(defined 0 && 0) |
| 4050 | Expected<bool, WebCore::RemoteFrameGeometryTransformer> WebPage::dispatchTouchEvent(FrameIdentifier frameID, const WebTouchEvent& touchEvent) |
| 4051 | { |
| 4052 | SetForScope userIsInteractingChange { m_userIsInteracting, true }; |
| 4053 | m_lastInteractionLocation = touchEvent.position(); |
| 4054 | CurrentEvent currentEvent(touchEvent); |
| 4055 | auto handleTouchEventResult = handleTouchEvent(frameID, touchEvent, m_page.get()); |
| 4056 | updatePotentialTapSecurityOrigin(touchEvent, handleTouchEventResult.value_or(false)); |
| 4057 | return handleTouchEventResult; |
| 4058 | } |
| 4059 | |
| 4060 | void WebPage::didBeginTouchPoint(FloatPoint locationInRootView) |
| 4061 | { |
| 4062 | m_hasAnyActiveTouchPoints = true; |
| 4063 | m_potentialTapSecurityOrigin = nullptr; |
| 4064 | m_lastTouchLocationBeforeTap = locationInRootView; |
| 4065 | } |
| 4066 | |
| 4067 | void WebPage::updatePotentialTapSecurityOrigin(const WebTouchEvent& touchEvent, bool wasHandled) |
| 4068 | { |
| 4069 | if (wasHandled) |
| 4070 | return; |
| 4071 | |
| 4072 | if (!touchEvent.isPotentialTap()) |
| 4073 | return; |
| 4074 | |
| 4075 | if (touchEvent.type() != WebEventType::TouchStart) |
| 4076 | return; |
| 4077 | |
| 4078 | RefPtr localMainFrame = this->localMainFrame(); |
| 4079 | if (!localMainFrame) |
| 4080 | return; |
| 4081 | |
| 4082 | RefPtr document = localMainFrame->document(); |
| 4083 | if (!document) |
| 4084 | return; |
| 4085 | |
| 4086 | if (!document->handlingTouchEvent()) |
| 4087 | return; |
| 4088 | |
| 4089 | RefPtr touchEventTargetFrame = localMainFrame; |
| 4090 | while (RefPtr localSubframe = dynamicDowncast<LocalFrame>(touchEventTargetFrame->eventHandler().touchEventTargetSubframe())) |
| 4091 | touchEventTargetFrame = WTF::move(localSubframe); |
| 4092 | |
| 4093 | auto& touches = touchEventTargetFrame->eventHandler().touches(); |
| 4094 | if (touches.isEmpty()) |
| 4095 | return; |
| 4096 | |
| 4097 | ASSERT(touches.size() == 1)((void)0); |
| 4098 | |
| 4099 | if (auto targetDocument = touchEventTargetFrame->document()) |
| 4100 | m_potentialTapSecurityOrigin = targetDocument->securityOrigin(); |
| 4101 | } |
| 4102 | #elif ENABLE(TOUCH_EVENTS)(defined 0 && 0) |
| 4103 | void WebPage::touchEvent(const WebTouchEvent& touchEvent, CompletionHandler<void(std::optional<WebEventType>, bool)>&& completionHandler) |
| 4104 | { |
| 4105 | RefPtr localMainFrame = this->localMainFrame(); |
| 4106 | if (!localMainFrame) |
| 4107 | return; |
| 4108 | |
| 4109 | CurrentEvent currentEvent(touchEvent); |
| 4110 | |
| 4111 | bool handled = handleTouchEvent(localMainFrame->frameID(), touchEvent, m_page.get()).value_or(false); |
| 4112 | |
| 4113 | completionHandler(touchEvent.type(), handled); |
| 4114 | } |
| 4115 | #endif |
| 4116 | |
| 4117 | void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint) |
| 4118 | { |
| 4119 | m_page->pointerCaptureController().cancelPointer(pointerId, documentPoint); |
| 4120 | } |
| 4121 | |
| 4122 | void WebPage::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId) |
| 4123 | { |
| 4124 | m_page->pointerCaptureController().touchWithIdentifierWasRemoved(pointerId); |
| 4125 | } |
| 4126 | |
| 4127 | void WebPage::resetPointerCapture() |
| 4128 | { |
| 4129 | m_page->pointerCaptureController().reset(); |
| 4130 | } |
| 4131 | |
| 4132 | #if ENABLE(MAC_GESTURE_EVENTS)(defined 0 && 0) |
| 4133 | static HandleUserInputEventResult handleGestureEvent(FrameIdentifier frameID, const WebGestureEvent& event, Page* page) |
| 4134 | { |
| 4135 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 4136 | if (!frame) |
| 4137 | return false; |
| 4138 | |
| 4139 | RefPtr coreLocalFrame = frame->coreLocalFrame(); |
| 4140 | if (!coreLocalFrame) |
| 4141 | return false; |
| 4142 | return coreLocalFrame->eventHandler().handleGestureEvent(platform(event)); |
| 4143 | } |
| 4144 | |
| 4145 | void WebPage::gestureEvent(FrameIdentifier frameID, const WebGestureEvent& gestureEvent, CompletionHandler<void(std::optional<WebEventType>, bool, std::optional<RemoteUserInputEventData>)>&& completionHandler) |
| 4146 | { |
| 4147 | CurrentEvent currentEvent(gestureEvent); |
| 4148 | auto result = handleGestureEvent(frameID, gestureEvent, m_page.get()); |
| 4149 | completionHandler(gestureEvent.type(), result.wasHandled(), result.remoteUserInputEventData()); |
| 4150 | } |
| 4151 | #endif |
| 4152 | |
| 4153 | bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity) |
| 4154 | { |
| 4155 | RefPtr focusedOrMainFrame = page->focusController().focusedOrMainFrame(); |
| 4156 | if (!focusedOrMainFrame) |
| 4157 | return false; |
| 4158 | return focusedOrMainFrame->eventHandler().scrollRecursively(direction, granularity); |
| 4159 | } |
| 4160 | |
| 4161 | bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity) |
| 4162 | { |
| 4163 | RefPtr focusedOrMainFrame = page->focusController().focusedOrMainFrame(); |
| 4164 | if (!focusedOrMainFrame) |
| 4165 | return false; |
| 4166 | return focusedOrMainFrame->eventHandler().logicalScrollRecursively(direction, granularity); |
| 4167 | } |
| 4168 | |
| 4169 | bool WebPage::scrollBy(WebCore::ScrollDirection scrollDirection, WebCore::ScrollGranularity scrollGranularity) |
| 4170 | { |
| 4171 | return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity)); |
| 4172 | } |
| 4173 | |
| 4174 | void WebPage::centerSelectionInVisibleArea() |
| 4175 | { |
| 4176 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 4177 | if (!frame) |
| 4178 | return; |
| 4179 | protect(frame->selection())->revealSelection({ SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways }); |
| 4180 | findController().showFindIndicatorInSelection(); |
| 4181 | } |
| 4182 | |
| 4183 | bool WebPage::isControlledByAutomation() const |
| 4184 | { |
| 4185 | return m_page->isControlledByAutomation(); |
| 4186 | } |
| 4187 | |
| 4188 | void WebPage::setControlledByAutomation(bool controlled) |
| 4189 | { |
| 4190 | m_page->setControlledByAutomation(controlled); |
| 4191 | } |
| 4192 | |
| 4193 | CheckedRef<PageInspectorTarget> WebPage::ensureInspectorTarget() |
| 4194 | { |
| 4195 | if (!m_inspectorTarget) |
| 4196 | m_inspectorTarget = makeUnique<PageInspectorTarget>(*this); |
| 4197 | return *m_inspectorTarget; |
| 4198 | } |
| 4199 | |
| 4200 | void WebPage::connectInspector(Inspector::FrontendChannel::ConnectionType connectionType) |
| 4201 | { |
| 4202 | ensureInspectorTarget()->connect(connectionType); |
| 4203 | } |
| 4204 | |
| 4205 | void WebPage::disconnectInspector() |
| 4206 | { |
| 4207 | ensureInspectorTarget()->disconnect(); |
| 4208 | } |
| 4209 | |
| 4210 | void WebPage::sendMessageToTargetBackend(const String& message) |
| 4211 | { |
| 4212 | ensureInspectorTarget()->sendMessageToTargetBackend(message); |
| 4213 | } |
| 4214 | |
| 4215 | void WebPage::insertNewlineInQuotedContent() |
| 4216 | { |
| 4217 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 4218 | if (!frame) |
| 4219 | return; |
| 4220 | if (frame->selection().isNone()) |
| 4221 | return; |
| 4222 | protect(frame->editor())->insertParagraphSeparatorInQuotedContent(); |
| 4223 | } |
| 4224 | |
| 4225 | #if ENABLE(REMOTE_INSPECTOR)(defined 1 && 1) |
| 4226 | void WebPage::setIndicating(bool indicating) |
| 4227 | { |
| 4228 | m_page->inspectorController().setIndicating(indicating); |
| 4229 | } |
| 4230 | #endif |
| 4231 | |
| 4232 | void WebPage::setBackgroundColor(const std::optional<WebCore::Color>& backgroundColor) |
| 4233 | { |
| 4234 | if (m_backgroundColor == backgroundColor) |
| 4235 | return; |
| 4236 | |
| 4237 | m_backgroundColor = backgroundColor; |
| 4238 | |
| 4239 | if (RefPtr frameView = localMainFrameView()) |
| 4240 | frameView->updateBackgroundRecursively(backgroundColor); |
| 4241 | |
| 4242 | RefPtr drawingArea = m_drawingArea; |
| 4243 | #if USE(COORDINATED_GRAPHICS)(defined USE_COORDINATED_GRAPHICS && USE_COORDINATED_GRAPHICS ) || USE(TEXTURE_MAPPER)(defined USE_TEXTURE_MAPPER && USE_TEXTURE_MAPPER) |
| 4244 | drawingArea->backgroundColorDidChange(); |
| 4245 | #endif |
| 4246 | drawingArea->setNeedsDisplay(); |
| 4247 | } |
| 4248 | |
| 4249 | void WebPage::setObscuredContentInsets(const FloatBoxExtent& obscuredContentInsets) |
| 4250 | { |
| 4251 | RefPtr page = m_page; |
| 4252 | if (obscuredContentInsets == page->obscuredContentInsets()) |
| 4253 | return; |
| 4254 | |
| 4255 | page->setObscuredContentInsets(obscuredContentInsets); |
| 4256 | |
| 4257 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 4258 | for (Ref pluginView : m_pluginViews) |
| 4259 | pluginView->obscuredContentInsetsDidChange(); |
| 4260 | #endif |
| 4261 | } |
| 4262 | |
| 4263 | #if ENABLE(BANNER_VIEW_OVERLAYS)(defined ENABLE_BANNER_VIEW_OVERLAYS && ENABLE_BANNER_VIEW_OVERLAYS ) |
| 4264 | void WebPage::setHasBannerViewOverlay(bool hasBannerViewOverlay) |
| 4265 | { |
| 4266 | m_page->setHasBannerViewOverlay(hasBannerViewOverlay); |
| 4267 | } |
| 4268 | #endif |
| 4269 | |
| 4270 | void WebPage::viewWillStartLiveResize() |
| 4271 | { |
| 4272 | if (!m_page) |
| 4273 | return; |
| 4274 | |
| 4275 | // FIXME: This should propagate to all ScrollableAreas. |
| 4276 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 4277 | if (!frame) |
| 4278 | return; |
| 4279 | |
| 4280 | if (RefPtr view = frame->view()) |
| 4281 | view->willStartLiveResize(); |
| 4282 | } |
| 4283 | |
| 4284 | void WebPage::viewWillEndLiveResize() |
| 4285 | { |
| 4286 | if (!m_page) |
| 4287 | return; |
| 4288 | |
| 4289 | // FIXME: This should propagate to all ScrollableAreas. |
| 4290 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 4291 | if (!frame) |
| 4292 | return; |
| 4293 | |
| 4294 | if (RefPtr view = frame->view()) |
| 4295 | view->willEndLiveResize(); |
| 4296 | } |
| 4297 | |
| 4298 | void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const std::optional<WebKeyboardEvent>& event, CompletionHandler<void()>&& completionHandler) |
| 4299 | { |
| 4300 | if (!m_page) |
| 4301 | return completionHandler(); |
| 4302 | |
| 4303 | SetForScope userIsInteractingChange { m_userIsInteracting, true }; |
| 4304 | |
| 4305 | CheckedRef focusController { m_page->focusController() }; |
| 4306 | RefPtr frame = focusController->focusedOrMainFrame(); |
| 4307 | if (!frame) |
| 4308 | return completionHandler(); |
| 4309 | protect(frame->document())->setFocusedElement(nullptr); |
| 4310 | |
| 4311 | if (isKeyboardEventValid && event && event->type() == WebEventType::KeyDown) { |
| 4312 | PlatformKeyboardEvent platformEvent(platform(CheckedRef { *event })); |
| 4313 | platformEvent.disambiguateKeyDownEvent(PlatformEvent::Type::RawKeyDown); |
| 4314 | focusController->setInitialFocus(forward ? FocusDirection::Forward : FocusDirection::Backward, &KeyboardEvent::create(platformEvent, &frame->windowProxy()).get()); |
| 4315 | completionHandler(); |
| 4316 | return; |
| 4317 | } |
| 4318 | |
| 4319 | focusController->setInitialFocus(forward ? FocusDirection::Forward : FocusDirection::Backward, nullptr); |
| 4320 | completionHandler(); |
| 4321 | } |
| 4322 | |
| 4323 | void WebPage::setCanStartMediaTimerFired() |
| 4324 | { |
| 4325 | if (RefPtr page = m_page) |
| 4326 | page->setCanStartMedia(true); |
| 4327 | } |
| 4328 | |
| 4329 | void WebPage::updateIsInWindow(bool isInitialState) |
| 4330 | { |
| 4331 | bool isInWindow = m_activityState.contains(WebCore::ActivityState::IsInWindow); |
| 4332 | |
| 4333 | if (!isInWindow) { |
| 4334 | m_setCanStartMediaTimer.stop(); |
| 4335 | protect(corePage())->setCanStartMedia(false); |
| 4336 | |
| 4337 | // The WebProcess does not yet know about this page; no need to tell it we're leaving the window. |
| 4338 | if (!isInitialState) |
| 4339 | WebProcess::singleton().pageWillLeaveWindow(m_identifier); |
| 4340 | } else { |
| 4341 | // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process |
| 4342 | // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing |
| 4343 | // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>. |
| 4344 | if (m_mayStartMediaWhenInWindow) |
| 4345 | m_setCanStartMediaTimer.startOneShot(0_s); |
| 4346 | |
| 4347 | WebProcess::singleton().pageDidEnterWindow(m_identifier); |
| 4348 | } |
| 4349 | |
| 4350 | if (isInWindow) |
| 4351 | layoutIfNeeded(); |
| 4352 | |
| 4353 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 4354 | for (Ref pluginView : m_pluginViews) |
| 4355 | pluginView->didChangeIsInWindow(); |
| 4356 | #endif |
| 4357 | } |
| 4358 | |
| 4359 | void WebPage::visibilityDidChange() |
| 4360 | { |
| 4361 | bool isVisible = m_activityState.contains(ActivityState::IsVisible); |
| 4362 | if (!isVisible) { |
| 4363 | // We save the document / scroll state when backgrounding a tab so that we are able to restore it |
| 4364 | // if it gets terminated while in the background. |
| 4365 | if (RefPtr frame = m_mainFrame->coreLocalFrame()) |
| 4366 | frame->loader().history().saveDocumentAndScrollState(); |
| 4367 | } |
| 4368 | } |
| 4369 | |
| 4370 | void WebPage::windowActivityDidChange() |
| 4371 | { |
| 4372 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 4373 | for (Ref pluginView : m_pluginViews) |
| 4374 | pluginView->windowActivityDidChange(); |
| 4375 | #endif |
| 4376 | } |
| 4377 | |
| 4378 | void WebPage::setActivityState(OptionSet<ActivityState> activityState, ActivityStateChangeID activityStateChangeID, CompletionHandler<void()>&& callback) |
| 4379 | { |
| 4380 | LOG_WITH_STREAM(ActivityState, stream << "WebPage " << identifier().toUInt64() << " setActivityState to " << activityState)((void)0); |
| 4381 | |
| 4382 | auto changed = m_activityState ^ activityState; |
| 4383 | m_activityState = activityState; |
| 4384 | |
| 4385 | if (changed) |
| 4386 | updateThrottleState(); |
| 4387 | |
| 4388 | ASSERT_WITH_MESSAGE(m_page, "setActivityState called on %" PRIu64 " but WebCore page was null", identifier().toUInt64())((void)0); |
| 4389 | if (RefPtr page = m_page) { |
| 4390 | SetForScope currentlyChangingActivityState { m_lastActivityStateChanges, changed }; |
| 4391 | page->setActivityState(activityState); |
| 4392 | } |
| 4393 | |
| 4394 | protect(drawingArea())->activityStateDidChange(changed, activityStateChangeID, WTF::move(callback)); |
| 4395 | WebProcess::singleton().pageActivityStateDidChange(m_identifier, changed); |
| 4396 | |
| 4397 | if (changed & ActivityState::IsInWindow) |
| 4398 | updateIsInWindow(); |
| 4399 | |
| 4400 | if (changed & ActivityState::IsVisible) |
| 4401 | visibilityDidChange(); |
| 4402 | |
| 4403 | if (changed & ActivityState::WindowIsActive) |
| 4404 | windowActivityDidChange(); |
| 4405 | } |
| 4406 | |
| 4407 | void WebPage::didStartPageTransition() |
| 4408 | { |
| 4409 | freezeLayerTree(LayerTreeFreezeReason::PageTransition); |
| 4410 | |
| 4411 | #if HAVE(TOUCH_BAR)(defined HAVE_TOUCH_BAR && HAVE_TOUCH_BAR) |
| 4412 | bool hasPreviouslyFocusedDueToUserInteraction = m_userInteractionsSincePageTransition.contains(UserInteractionFlag::FocusedElement); |
| 4413 | m_userInteractionsSincePageTransition = { }; |
| 4414 | #endif |
| 4415 | m_lastEditorStateWasContentEditable = EditorStateIsContentEditable::Unset; |
| 4416 | |
| 4417 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 4418 | if (hasPreviouslyFocusedDueToUserInteraction) |
| 4419 | send(Messages::WebPageProxy::SetHasFocusedElementWithUserInteraction(false)); |
| 4420 | #endif |
| 4421 | |
| 4422 | #if HAVE(TOUCH_BAR)(defined HAVE_TOUCH_BAR && HAVE_TOUCH_BAR) |
| 4423 | if (m_isTouchBarUpdateSuppressedForHiddenContentEditable) { |
| 4424 | m_isTouchBarUpdateSuppressedForHiddenContentEditable = false; |
| 4425 | send(Messages::WebPageProxy::SetIsTouchBarUpdateSuppressedForHiddenContentEditable(m_isTouchBarUpdateSuppressedForHiddenContentEditable)); |
| 4426 | } |
| 4427 | |
| 4428 | if (m_isNeverRichlyEditableForTouchBar) { |
| 4429 | m_isNeverRichlyEditableForTouchBar = false; |
| 4430 | send(Messages::WebPageProxy::SetIsNeverRichlyEditableForTouchBar(m_isNeverRichlyEditableForTouchBar)); |
| 4431 | } |
| 4432 | #endif |
| 4433 | |
| 4434 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 4435 | m_isShowingInputViewForFocusedElement = false; |
| 4436 | // This is used to enable a first-tap quirk. |
| 4437 | m_hasHandledSyntheticClick = false; |
| 4438 | #endif |
| 4439 | } |
| 4440 | |
| 4441 | void WebPage::didCompletePageTransition() |
| 4442 | { |
| 4443 | unfreezeLayerTree(LayerTreeFreezeReason::PageTransition); |
| 4444 | } |
| 4445 | |
| 4446 | void WebPage::setMainFrameDocumentVisualUpdatesAllowed(bool allowed) |
| 4447 | { |
| 4448 | if (allowed) |
| 4449 | unfreezeLayerTree(LayerTreeFreezeReason::DocumentVisualUpdatesNotAllowed); |
| 4450 | else |
| 4451 | freezeLayerTree(LayerTreeFreezeReason::DocumentVisualUpdatesNotAllowed); |
| 4452 | } |
| 4453 | |
| 4454 | void WebPage::show() |
| 4455 | { |
| 4456 | send(Messages::WebPageProxy::ShowPage()); |
| 4457 | } |
| 4458 | |
| 4459 | void WebPage::setIsTakingSnapshotsForApplicationSuspension(bool isTakingSnapshotsForApplicationSuspension) |
| 4460 | { |
| 4461 | WEBPAGE_RELEASE_LOG(Resize, "setIsTakingSnapshotsForApplicationSuspension(%d)", isTakingSnapshotsForApplicationSuspension); |
| 4462 | |
| 4463 | if (m_page) |
| 4464 | m_page->setIsTakingSnapshotsForApplicationSuspension(isTakingSnapshotsForApplicationSuspension); |
| 4465 | } |
| 4466 | |
| 4467 | void WebPage::setNeedsDOMWindowResizeEvent() |
| 4468 | { |
| 4469 | RefPtr page = m_page; |
| 4470 | if (!page) |
| 4471 | return; |
| 4472 | |
| 4473 | if (RefPtr localTopDocument = page->localTopDocument()) |
| 4474 | localTopDocument->setNeedsDOMWindowResizeEvent(); |
| 4475 | } |
| 4476 | |
| 4477 | String WebPage::userAgent(const URL& webCoreURL) const |
| 4478 | { |
| 4479 | String userAgent = platformUserAgent(webCoreURL); |
| 4480 | if (!userAgent.isEmpty()) |
| 4481 | return userAgent; |
| 4482 | return m_userAgent; |
| 4483 | } |
| 4484 | |
| 4485 | void WebPage::setUserAgent(String&& userAgent) |
| 4486 | { |
| 4487 | if (m_userAgent == userAgent) |
| 4488 | return; |
| 4489 | |
| 4490 | m_userAgent = WTF::move(userAgent); |
| 4491 | |
| 4492 | if (RefPtr page = m_page) |
| 4493 | page->userAgentChanged(); |
| 4494 | } |
| 4495 | |
| 4496 | void WebPage::setHasCustomUserAgent(bool hasCustomUserAgent) |
| 4497 | { |
| 4498 | m_hasCustomUserAgent = hasCustomUserAgent; |
| 4499 | } |
| 4500 | |
| 4501 | void WebPage::suspendActiveDOMObjectsAndAnimations() |
| 4502 | { |
| 4503 | protect(corePage())->suspendActiveDOMObjectsAndAnimations(); |
| 4504 | } |
| 4505 | |
| 4506 | void WebPage::resumeActiveDOMObjectsAndAnimations() |
| 4507 | { |
| 4508 | protect(corePage())->resumeActiveDOMObjectsAndAnimations(); |
| 4509 | } |
| 4510 | |
| 4511 | void WebPage::suspend(CompletionHandler<void(bool)>&& completionHandler) |
| 4512 | { |
| 4513 | RefPtr page = m_page; |
| 4514 | WEBPAGE_RELEASE_LOG(Loading, "suspend: m_page=%p", page.get()); |
| 4515 | if (!page) |
| 4516 | return completionHandler(false); |
| 4517 | |
| 4518 | freezeLayerTree(LayerTreeFreezeReason::PageSuspended); |
| 4519 | |
| 4520 | m_cachedPage = BackForwardCache::singleton().suspendPage(*page); |
| 4521 | ASSERT(m_cachedPage)((void)0); |
| 4522 | if (RefPtr mainFrame = m_mainFrame->coreLocalFrame()) |
| 4523 | mainFrame->detachFromAllOpenedFrames(); |
| 4524 | completionHandler(true); |
| 4525 | } |
| 4526 | |
| 4527 | void WebPage::resume(CompletionHandler<void(bool)>&& completionHandler) |
| 4528 | { |
| 4529 | RefPtr page = m_page; |
| 4530 | WEBPAGE_RELEASE_LOG(Loading, "resume: m_page=%p", page.get()); |
| 4531 | if (!page) |
| 4532 | return completionHandler(false); |
| 4533 | |
| 4534 | auto cachedPage = std::exchange(m_cachedPage, nullptr); |
| 4535 | ASSERT(cachedPage)((void)0); |
| 4536 | if (!cachedPage) |
| 4537 | return completionHandler(false); |
| 4538 | |
| 4539 | cachedPage->restore(*page); |
| 4540 | unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended); |
| 4541 | completionHandler(true); |
| 4542 | } |
| 4543 | |
| 4544 | IntPoint WebPage::screenToRootView(const IntPoint& point) |
| 4545 | { |
| 4546 | auto sendResult = sendSync(Messages::WebPageProxy::ScreenToRootView(point)); |
| 4547 | auto [windowPoint] = sendResult.takeReplyOr(IntPoint { }); |
| 4548 | return windowPoint; |
| 4549 | } |
| 4550 | |
| 4551 | IntPoint WebPage::rootViewToScreen(const IntPoint& point) |
| 4552 | { |
| 4553 | auto sendResult = sendSync(Messages::WebPageProxy::RootViewPointToScreen(point)); |
| 4554 | auto [screenPoint] = sendResult.takeReplyOr(IntPoint { }); |
| 4555 | return screenPoint; |
| 4556 | } |
| 4557 | |
| 4558 | IntRect WebPage::rootViewToScreen(const IntRect& rect) |
| 4559 | { |
| 4560 | auto sendResult = sendSync(Messages::WebPageProxy::RootViewRectToScreen(rect.toRectWithExtentsClippedToNumericLimits())); |
| 4561 | auto [screenRect] = sendResult.takeReplyOr(IntRect { }); |
| 4562 | return screenRect; |
| 4563 | } |
| 4564 | |
| 4565 | IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point) |
| 4566 | { |
| 4567 | auto sendResult = sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point)); |
| 4568 | auto [windowPoint] = sendResult.takeReplyOr(IntPoint { }); |
| 4569 | return windowPoint; |
| 4570 | } |
| 4571 | |
| 4572 | IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect) |
| 4573 | { |
| 4574 | auto sendResult = sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect)); |
| 4575 | auto [screenRect] = sendResult.takeReplyOr(IntRect { }); |
| 4576 | return screenRect; |
| 4577 | } |
| 4578 | |
| 4579 | #if ENABLE(ACCESSIBILITY_LOCAL_FRAME)(defined 1 && 1) |
| 4580 | void WebPage::requestFrameScreenPosition(FrameIdentifier frameID) |
| 4581 | { |
| 4582 | send(Messages::WebPageProxy::RequestFrameScreenPosition(frameID)); |
| 4583 | } |
| 4584 | #endif |
| 4585 | |
| 4586 | KeyboardUIMode WebPage::keyboardUIMode() |
| 4587 | { |
| 4588 | bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled(); |
| 4589 | return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0)); |
| 4590 | } |
| 4591 | |
| 4592 | void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, ContentWorldIdentifier worldIdentifier, bool wantsResult, CompletionHandler<void(Expected<JavaScriptEvaluationResult, std::optional<WebCore::ExceptionDetails>>)>&& completionHandler) |
| 4593 | { |
| 4594 | // NOTE: We need to be careful when running scripts that the objects we depend on don't |
| 4595 | // disappear during script execution. |
| 4596 | |
| 4597 | if (!frame || !frame->coreLocalFrame()) { |
| 4598 | completionHandler(makeUnexpected(ExceptionDetails { "Unable to execute JavaScript: Target frame could not be found in the page"_s, 0, 0, ExceptionDetails::Type::InvalidTargetFrame })); |
| 4599 | return; |
| 4600 | } |
| 4601 | |
| 4602 | RefPtr world = m_userContentController->worldForIdentifier(worldIdentifier); |
| 4603 | if (!world) { |
| 4604 | completionHandler(makeUnexpected(ExceptionDetails { "Unable to execute JavaScript: Cannot find specified content world"_s })); |
| 4605 | return; |
| 4606 | } |
| 4607 | |
| 4608 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 4609 | if (frame->shouldEnableInAppBrowserPrivacyProtections()) { |
| 4610 | completionHandler(makeUnexpected(ExceptionDetails { "Unable to execute JavaScript in a frame that is not in an app-bound domain"_s, 0, 0, ExceptionDetails::Type::AppBoundDomain })); |
| 4611 | if (RefPtr localTopDocument = protect(corePage())->localTopDocument()) |
| 4612 | localTopDocument->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain."_s); |
| 4613 | WEBPAGE_RELEASE_LOG_ERROR(Loading, "runJavaScript: Ignoring user script injection for non app-bound domain"); |
| 4614 | return; |
| 4615 | } |
| 4616 | #endif |
| 4617 | auto source = WTF::move(parameters.source).release(); |
| 4618 | if (!source) { |
| 4619 | completionHandler(makeUnexpected(ExceptionDetails { "Unable to execute JavaScript: out of memory"_s })); |
| 4620 | return; |
| 4621 | } |
| 4622 | |
| 4623 | bool shouldAllowUserInteraction = [&] { |
| 4624 | if (m_userIsInteracting) |
| 4625 | return true; |
| 4626 | |
| 4627 | if (parameters.forceUserGesture == ForceUserGesture::No) |
| 4628 | return false; |
| 4629 | |
| 4630 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 4631 | if (linkedOnOrAfterSDKWithBehavior(SDKAlignedBehavior::ProgrammaticFocusDuringUserScriptShowsInputViews)) |
| 4632 | return true; |
| 4633 | #endif |
| 4634 | |
| 4635 | return false; |
| 4636 | }(); |
| 4637 | |
| 4638 | SetForScope userIsInteractingChange { m_userIsInteracting, shouldAllowUserInteraction }; |
| 4639 | auto resolveFunction = [world = Ref { *world }, frame = Ref { *frame }, coreFrame = Ref { *frame->coreLocalFrame() }, wantsResult, completionHandler = WTF::move(completionHandler)] (ValueOrException result) mutable { |
| 4640 | if (!result) |
| 4641 | return completionHandler(makeUnexpected(result.error())); |
| 4642 | |
| 4643 | if (!wantsResult) |
| 4644 | return completionHandler(makeUnexpected(std::nullopt)); |
| 4645 | |
| 4646 | JSGlobalContextRef context = frame->jsContextForWorld(world.ptr()); |
| 4647 | JSValueRef jsValue = toRef(protect(coreFrame->script())->globalObject(Ref { world->coreWorld() }), result.value()); |
| 4648 | if (auto result = JavaScriptEvaluationResult::extract(context, jsValue)) |
| 4649 | return completionHandler(WTF::move(*result)); |
| 4650 | return completionHandler(makeUnexpected(std::nullopt)); |
| 4651 | }; |
| 4652 | |
| 4653 | auto mapArguments = [] (auto&& vector) -> std::optional<HashMap<String, Function<JSC::JSValue(JSC::JSGlobalObject&)>>> { |
| 4654 | if (!vector) |
| 4655 | return std::nullopt; |
| 4656 | HashMap<String, Function<JSC::JSValue(JSC::JSGlobalObject&)>> map; |
| 4657 | for (auto&& [key, result] : WTF::move(*vector)) { |
| 4658 | map.set(key, [result = WTF::move(result)] (JSC::JSGlobalObject& globalObject) mutable -> JSC::JSValue { |
| 4659 | return toJS(&globalObject, result.toJS(JSContextGetGlobalContext(toRef(&globalObject))).get()); |
| 4660 | }); |
| 4661 | } |
| 4662 | return { WTF::move(map) }; |
| 4663 | }; |
| 4664 | |
| 4665 | WebCore::RunJavaScriptParameters coreParameters { |
| 4666 | WTF::move(*source), |
| 4667 | WTF::move(parameters.taintedness), |
| 4668 | WTF::move(parameters.sourceURL), |
| 4669 | parameters.runAsAsyncFunction == WebCore::RunAsAsyncFunction::Yes, |
| 4670 | mapArguments(WTF::move(parameters.arguments)), |
| 4671 | parameters.forceUserGesture == WebCore::ForceUserGesture::Yes, |
| 4672 | parameters.removeTransientActivation |
| 4673 | }; |
| 4674 | |
| 4675 | JSLockHolder lock(commonVM()); |
| 4676 | protect(protect(frame->coreLocalFrame())->script())->executeAsynchronousUserAgentScriptInWorld(protect(world->coreWorld()), WTF::move(coreParameters), WTF::move(resolveFunction)); |
| 4677 | } |
| 4678 | |
| 4679 | void WebPage::runJavaScriptInFrameInScriptWorld(RunJavaScriptParameters&& parameters, std::optional<WebCore::FrameIdentifier> frameID, const ContentWorldData& worldData, bool wantsResult, CompletionHandler<void(Expected<JavaScriptEvaluationResult, std::optional<WebCore::ExceptionDetails>>)>&& completionHandler) |
| 4680 | { |
| 4681 | WEBPAGE_RELEASE_LOG(Process, "runJavaScriptInFrameInScriptWorld: frameID=%" PRIu64"ll" "u", frameID ? frameID->toUInt64() : 0); |
| 4682 | RefPtr webFrame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame(); |
| 4683 | |
| 4684 | m_userContentController->addContentWorldIfNecessary(worldData); |
| 4685 | |
| 4686 | runJavaScript(webFrame.get(), WTF::move(parameters), worldData.identifier, wantsResult, [this, protectedThis = Ref { *this }, completionHandler = WTF::move(completionHandler)](auto&& result) mutable { |
| 4687 | #if RELEASE_LOG_DISABLED!((defined 1 && 1) || (defined ENABLE_JOURNALD_LOG && ENABLE_JOURNALD_LOG) || (defined WTF_OS_ANDROID && WTF_OS_ANDROID )) |
| 4688 | UNUSED_PARAM(this)(void)this; |
| 4689 | #endif |
| 4690 | if (!result && result.error()) |
| 4691 | WEBPAGE_RELEASE_LOG_ERROR(Process, "runJavaScriptInFrameInScriptWorld: Request to run JavaScript failed with error %" PRIVATE_LOG_STRING"{private}s", result.error()->message.utf8().data()); |
| 4692 | else |
| 4693 | WEBPAGE_RELEASE_LOG(Process, "runJavaScriptInFrameInScriptWorld: Request to run JavaScript succeeded"); |
| 4694 | completionHandler(WTF::move(result)); |
| 4695 | }); |
| 4696 | } |
| 4697 | |
| 4698 | void WebPage::getContentsAsString(ContentAsStringIncludesChildFrames includeChildFrames, CompletionHandler<void(const String&)>&& callback) |
| 4699 | { |
| 4700 | switch (includeChildFrames) { |
| 4701 | case ContentAsStringIncludesChildFrames::No: |
| 4702 | callback(m_mainFrame->contentsAsString()); |
| 4703 | break; |
| 4704 | case ContentAsStringIncludesChildFrames::Yes: |
| 4705 | StringBuilder builder; |
| 4706 | for (RefPtr<Frame> frame = m_mainFrame->coreLocalFrame(); frame; frame = frame->tree().traverseNextRendered()) { |
| 4707 | if (RefPtr webFrame = WebFrame::fromCoreFrame(*frame)) |
| 4708 | builder.append(builder.isEmpty() ? ""_s : "\n\n"_s, webFrame->contentsAsString()); |
| 4709 | } |
| 4710 | callback(builder.toString()); |
| 4711 | break; |
| 4712 | } |
| 4713 | } |
| 4714 | |
| 4715 | #if ENABLE(MHTML)(defined 0 && 0) |
| 4716 | void WebPage::getContentsAsMHTMLData(CompletionHandler<void(const IPC::SharedBufferReference&)>&& callback) |
| 4717 | { |
| 4718 | callback(IPC::SharedBufferReference(MHTMLArchive::generateMHTMLData(m_page.get()))); |
| 4719 | } |
| 4720 | #endif |
| 4721 | |
| 4722 | void WebPage::getRenderTreeExternalRepresentation(CompletionHandler<void(const String&)>&& callback) |
| 4723 | { |
| 4724 | callback(renderTreeExternalRepresentation()); |
| 4725 | } |
| 4726 | |
| 4727 | static RefPtr<LocalFrame> frameWithSelection(Page* page) |
| 4728 | { |
| 4729 | for (RefPtr frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 4730 | RefPtr localFrame = dynamicDowncast<LocalFrame>(*frame); |
| 4731 | if (!localFrame) |
| 4732 | continue; |
| 4733 | if (localFrame->selection().isRange()) |
| 4734 | return localFrame; |
| 4735 | } |
| 4736 | return nullptr; |
| 4737 | } |
| 4738 | |
| 4739 | void WebPage::copyLinkWithHighlight() |
| 4740 | { |
| 4741 | RefPtr page = m_page; |
| 4742 | auto url = page->fragmentDirectiveURLForSelectedText(); |
| 4743 | RefPtr frame = page->focusController().focusedOrMainFrame(); |
| 4744 | if (!frame) |
| 4745 | return; |
| 4746 | |
| 4747 | if (url.isValid()) |
| 4748 | protect(frame->editor())->copyURL(url, { }); |
| 4749 | } |
| 4750 | |
| 4751 | void WebPage::getSelectionOrContentsAsString(CompletionHandler<void(const String&)>&& callback) |
| 4752 | { |
| 4753 | RefPtr focusedOrMainCoreFrame = corePage()->focusController().focusedOrMainFrame(); |
| 4754 | RefPtr focusedOrMainFrame = focusedOrMainCoreFrame ? WebFrame::fromCoreFrame(*focusedOrMainCoreFrame) : nullptr; |
| 4755 | |
| 4756 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 4757 | if (RefPtr pluginView = pluginViewForFrame(focusedOrMainCoreFrame.get())) { |
| 4758 | auto result = pluginView->selectionString(); |
| 4759 | if (result.isEmpty()) |
| 4760 | result = pluginView->fullDocumentString(); |
| 4761 | return callback(WTF::move(result)); |
| 4762 | } |
| 4763 | #endif |
| 4764 | |
| 4765 | String resultString = focusedOrMainFrame->selectionAsString(); |
| 4766 | if (resultString.isEmpty()) |
| 4767 | resultString = focusedOrMainFrame->contentsAsString(); |
| 4768 | callback(resultString); |
| 4769 | } |
| 4770 | |
| 4771 | void WebPage::getSourceForFrame(FrameIdentifier frameID, CompletionHandler<void(const String&)>&& callback) |
| 4772 | { |
| 4773 | String resultString; |
| 4774 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) |
| 4775 | resultString = frame->source(); |
| 4776 | |
| 4777 | callback(resultString); |
| 4778 | } |
| 4779 | |
| 4780 | void WebPage::getMainResourceDataOfFrame(FrameIdentifier frameID, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback) |
| 4781 | { |
| 4782 | RefPtr<FragmentedSharedBuffer> buffer; |
| 4783 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) { |
| 4784 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 4785 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 4786 | if (RefPtr pluginView = pluginViewForFrame(coreFrame.get())) |
| 4787 | buffer = pluginView->liveResourceData(); |
| 4788 | if (!buffer) |
| 4789 | #endif |
| 4790 | { |
| 4791 | if (RefPtr loader = coreFrame->loader().documentLoader()) |
| 4792 | buffer = loader->mainResourceData(); |
| 4793 | } |
| 4794 | } |
| 4795 | |
| 4796 | callback(IPC::SharedBufferReference(WTF::move(buffer))); |
| 4797 | } |
| 4798 | |
| 4799 | static RefPtr<FragmentedSharedBuffer> resourceDataForFrame(LocalFrame* frame, const URL& resourceURL) |
| 4800 | { |
| 4801 | RefPtr loader = frame->loader().documentLoader(); |
| 4802 | if (!loader) |
| 4803 | return nullptr; |
| 4804 | |
| 4805 | RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL); |
| 4806 | if (!subresource) |
| 4807 | return nullptr; |
| 4808 | |
| 4809 | return &subresource->data(); |
| 4810 | } |
| 4811 | |
| 4812 | void WebPage::getResourceDataFromFrame(FrameIdentifier frameID, const String& resourceURLString, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback) |
| 4813 | { |
| 4814 | RefPtr<FragmentedSharedBuffer> buffer; |
| 4815 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) { |
| 4816 | URL resourceURL { resourceURLString }; |
| 4817 | buffer = resourceDataForFrame(protect(frame->coreLocalFrame()).get(), resourceURL); |
| 4818 | } |
| 4819 | |
| 4820 | callback(IPC::SharedBufferReference(WTF::move(buffer))); |
| 4821 | } |
| 4822 | |
| 4823 | void WebPage::getWebArchiveOfFrameWithFileName(WebCore::FrameIdentifier frameID, const Vector<WebCore::MarkupExclusionRule>& exclusionRules, const String& fileName, CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& completionHandler) |
| 4824 | { |
| 4825 | std::optional<IPC::SharedBufferReference> result; |
| 4826 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 4827 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) { |
| 4828 | if (RetainPtr<CFDataRef> data = frame->webArchiveData(nullptr, nullptr, exclusionRules, fileName)) |
| 4829 | result = IPC::SharedBufferReference(SharedBuffer::create(data.get())); |
| 4830 | } |
| 4831 | #else |
| 4832 | UNUSED_PARAM(frameID)(void)frameID; |
| 4833 | #endif |
| 4834 | completionHandler(result); |
| 4835 | } |
| 4836 | |
| 4837 | void WebPage::getAccessibilityTreeData(CompletionHandler<void(const std::optional<IPC::SharedBufferReference>&)>&& callback) |
| 4838 | { |
| 4839 | IPC::SharedBufferReference dataBuffer; |
| 4840 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 4841 | if (auto treeData = protect(corePage())->accessibilityTreeData(IncludeDOMInfo::Yes)) { |
| 4842 | auto stream = adoptCF(CFWriteStreamCreateWithAllocatedBuffers(0, 0)); |
| 4843 | CFWriteStreamOpen(stream.get()); |
| 4844 | |
| 4845 | auto writeTreeToStream = [&stream](auto& tree) { |
| 4846 | auto utf8 = tree.utf8(); |
| 4847 | auto utf8Span = utf8.span(); |
| 4848 | CFWriteStreamWrite(stream.get(), byteCast<UInt8>(utf8Span.data()), utf8Span.size()); |
| 4849 | }; |
| 4850 | writeTreeToStream(treeData->liveTree); |
| 4851 | writeTreeToStream(treeData->isolatedTree); |
| 4852 | |
| 4853 | auto data = adoptCF(checked_cf_cast<CFDataRef>(CFWriteStreamCopyProperty(stream.get(), kCFStreamPropertyDataWritten))); |
| 4854 | CFWriteStreamClose(stream.get()); |
| 4855 | |
| 4856 | dataBuffer = IPC::SharedBufferReference(SharedBuffer::create(data.get())); |
| 4857 | } |
| 4858 | #endif |
| 4859 | callback(dataBuffer); |
| 4860 | } |
| 4861 | |
| 4862 | void WebPage::updateRenderingWithForcedRepaintWithoutCallback() |
| 4863 | { |
| 4864 | protect(drawingArea())->updateRenderingWithForcedRepaint(); |
| 4865 | } |
| 4866 | |
| 4867 | void WebPage::updateRenderingWithForcedRepaint(CompletionHandler<void()>&& completionHandler) |
| 4868 | { |
| 4869 | protect(drawingArea())->updateRenderingWithForcedRepaintAsync(*this, WTF::move(completionHandler)); |
| 4870 | } |
| 4871 | |
| 4872 | void WebPage::preferencesDidChange(const WebPreferencesStore& store, std::optional<uint64_t> sharedPreferencesVersion) |
| 4873 | { |
| 4874 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 4875 | if (sharedPreferencesVersion) { |
| 4876 | ASSERT(*sharedPreferencesVersion)((void)0); |
| 4877 | auto sendResult = protect(WebProcess::singleton().parentProcessConnection())->sendSync(Messages::WebProcessProxy::WaitForSharedPreferencesForWebProcessToSync { *sharedPreferencesVersion }, 0); |
| 4878 | auto [success] = sendResult.takeReplyOr(false); |
| 4879 | if (!success) |
| 4880 | return; // Sync IPC has timed out or WebProcessProxy is getting destroyed |
| 4881 | } |
| 4882 | #else |
| 4883 | UNUSED_PARAM(sharedPreferencesVersion)(void)sharedPreferencesVersion; |
| 4884 | #endif |
| 4885 | WebPreferencesStore::removeTestRunnerOverrides(); |
| 4886 | updatePreferences(store); |
| 4887 | } |
| 4888 | |
| 4889 | bool WebPage::isParentProcessAWebBrowser() const |
| 4890 | { |
| 4891 | #if HAVE(AUDIT_TOKEN)(defined 1 && 1) |
| 4892 | return isParentProcessAFullWebBrowser(WebProcess::singleton()); |
| 4893 | #endif |
| 4894 | return false; |
| 4895 | } |
| 4896 | |
| 4897 | void WebPage::adjustSettingsForLockdownMode(Settings& settings, const WebPreferencesStore* store) |
| 4898 | { |
| 4899 | bool originalSiteIsolationEnabled = settings.siteIsolationEnabled(); |
| 4900 | // Disable unstable Experimental settings, even if the user enabled them for local use. |
| 4901 | settings.disableUnstableFeaturesForModernWebKit(); |
| 4902 | Settings::disableGlobalUnstableFeaturesForModernWebKit(); |
| 4903 | settings.disableFeaturesForLockdownMode(); |
| 4904 | |
| 4905 | if (WebPreferences::forcedSiteIsolationAlwaysOnForTesting() && originalSiteIsolationEnabled) |
| 4906 | settings.setSiteIsolationEnabled(true); |
| 4907 | |
| 4908 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 4909 | if (settings.downloadableBinaryFontTrustedTypes() != DownloadableBinaryFontTrustedTypes::None) { |
| 4910 | auto downloadableBinaryFontTrustedTypes = DownloadableBinaryFontTrustedTypes::Restricted; |
| 4911 | #if HAVE(CTFONTMANAGER_CREATEMEMORYSAFEFONTDESCRIPTORFROMDATA)(defined 1 && 1) |
| 4912 | if (settings.lockdownFontParserEnabled()) |
| 4913 | downloadableBinaryFontTrustedTypes = DownloadableBinaryFontTrustedTypes::SafeFontParser; |
| 4914 | #endif |
| 4915 | settings.setDownloadableBinaryFontTrustedTypes(downloadableBinaryFontTrustedTypes); |
| 4916 | } |
| 4917 | #endif |
| 4918 | |
| 4919 | // FIXME: This seems like an odd place to put logic for setting global state in CoreGraphics. |
| 4920 | #if HAVE(LOCKDOWN_MODE_PDF_ADDITIONS)(defined HAVE_LOCKDOWN_MODE_PDF_ADDITIONS && HAVE_LOCKDOWN_MODE_PDF_ADDITIONS ) |
| 4921 | CGEnterLockdownModeForPDF(); |
| 4922 | #endif |
| 4923 | |
| 4924 | if (store) { |
| 4925 | settings.setAllowedMediaContainerTypes(store->getStringValueForKey(WebPreferencesKey::mediaContainerTypesAllowedInLockdownModeKey())); |
| 4926 | settings.setAllowedMediaCodecTypes(store->getStringValueForKey(WebPreferencesKey::mediaCodecTypesAllowedInLockdownModeKey())); |
| 4927 | settings.setAllowedMediaVideoCodecIDs(store->getStringValueForKey(WebPreferencesKey::mediaVideoCodecIDsAllowedInLockdownModeKey())); |
| 4928 | settings.setAllowedMediaAudioCodecIDs(store->getStringValueForKey(WebPreferencesKey::mediaAudioCodecIDsAllowedInLockdownModeKey())); |
| 4929 | settings.setAllowedMediaCaptionFormatTypes(store->getStringValueForKey(WebPreferencesKey::mediaCaptionFormatTypesAllowedInLockdownModeKey())); |
| 4930 | } |
| 4931 | } |
| 4932 | |
| 4933 | void WebPage::updatePreferences(const WebPreferencesStore& store) |
| 4934 | { |
| 4935 | updatePreferencesGenerated(store); |
| 4936 | |
| 4937 | Settings& settings = m_page->settings(); |
| 4938 | |
| 4939 | updateSettingsGenerated(store, settings); |
| 4940 | |
| 4941 | #if !PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) && !PLATFORM(WIN)(defined WTF_PLATFORM_WIN && WTF_PLATFORM_WIN) && !PLATFORM(PLAYSTATION)(defined WTF_PLATFORM_PLAYSTATION && WTF_PLATFORM_PLAYSTATION ) && !PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) |
| 4942 | if (!settings.acceleratedCompositingEnabled()) { |
| 4943 | WEBPAGE_RELEASE_LOG(Layers, "updatePreferences: acceleratedCompositingEnabled setting was false. WebKit cannot function in this mode; changing setting to true"); |
| 4944 | settings.setAcceleratedCompositingEnabled(true); |
| 4945 | } |
| 4946 | #endif |
| 4947 | |
| 4948 | bool requiresUserGestureForMedia = store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForMediaPlaybackKey()); |
| 4949 | settings.setRequiresUserGestureForVideoPlayback(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForVideoPlaybackKey())); |
| 4950 | settings.setRequiresUserGestureForAudioPlayback(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForAudioPlaybackKey())); |
| 4951 | settings.setUserInterfaceDirectionPolicy(static_cast<WebCore::UserInterfaceDirectionPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionPolicyKey()))); |
| 4952 | settings.setSystemLayoutDirection(static_cast<TextDirection>(store.getUInt32ValueForKey(WebPreferencesKey::systemLayoutDirectionKey()))); |
| 4953 | settings.setJavaScriptRuntimeFlags(static_cast<RuntimeFlags>(store.getUInt32ValueForKey(WebPreferencesKey::javaScriptRuntimeFlagsKey()))); |
| 4954 | settings.setStorageBlockingPolicy(static_cast<StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey()))); |
| 4955 | settings.setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey()))); |
| 4956 | #if ENABLE(DATA_DETECTION)(defined 1 && 1) |
| 4957 | settings.setDataDetectorTypes(static_cast<DataDetectorType>(store.getUInt32ValueForKey(WebPreferencesKey::dataDetectorTypesKey()))); |
| 4958 | #endif |
| 4959 | settings.setPitchCorrectionAlgorithm(static_cast<MediaPlayerEnums::PitchCorrectionAlgorithm>(store.getUInt32ValueForKey(WebPreferencesKey::pitchCorrectionAlgorithmKey()))); |
| 4960 | |
| 4961 | DatabaseManager::singleton().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey())); |
| 4962 | |
| 4963 | m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey()); |
| 4964 | |
| 4965 | bool isAppNapEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey()); |
| 4966 | if (m_isAppNapEnabled != isAppNapEnabled) { |
| 4967 | m_isAppNapEnabled = isAppNapEnabled; |
| 4968 | updateThrottleState(); |
| 4969 | } |
| 4970 | |
| 4971 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 4972 | m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey()); |
| 4973 | |
| 4974 | m_selectionFlippingEnabled = store.getBoolValueForKey(WebPreferencesKey::selectionFlippingEnabledKey()); |
| 4975 | #endif |
| 4976 | #if ENABLE(PAYMENT_REQUEST)(defined 1 && 1) |
| 4977 | settings.setPaymentRequestEnabled(store.getBoolValueForKey(WebPreferencesKey::applePayEnabledKey())); |
| 4978 | #endif |
| 4979 | |
| 4980 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 4981 | setForceAlwaysUserScalable(m_forceAlwaysUserScalable || store.getBoolValueForKey(WebPreferencesKey::forceAlwaysUserScalableKey())); |
| 4982 | #endif |
| 4983 | |
| 4984 | if (store.getBoolValueForKey(WebPreferencesKey::serviceWorkerEntitlementDisabledForTestingKey())) |
| 4985 | disableServiceWorkerEntitlement(); |
| 4986 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 4987 | bool shouldAllowServiceWorkersForAppBoundViews = m_limitsNavigationsToAppBoundDomains; |
| 4988 | #else |
| 4989 | bool shouldAllowServiceWorkersForAppBoundViews = false; |
| 4990 | #endif |
| 4991 | |
| 4992 | if (store.getBoolValueForKey(WebPreferencesKey::serviceWorkersEnabledKey())) { |
| 4993 | ASSERT(parentProcessHasServiceWorkerEntitlement() || shouldAllowServiceWorkersForAppBoundViews)((void)0); |
| 4994 | if (!parentProcessHasServiceWorkerEntitlement() && !shouldAllowServiceWorkersForAppBoundViews) |
| 4995 | settings.setServiceWorkersEnabled(false); |
| 4996 | } |
| 4997 | |
| 4998 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 4999 | m_needsInAppBrowserPrivacyQuirks = store.getBoolValueForKey(WebPreferencesKey::needsInAppBrowserPrivacyQuirksKey()); |
| 5000 | #endif |
| 5001 | |
| 5002 | settings.setPrivateClickMeasurementEnabled(store.getBoolValueForKey(WebPreferencesKey::privateClickMeasurementEnabledKey())); |
| 5003 | |
| 5004 | if (RefPtr drawingArea = m_drawingArea) |
| 5005 | drawingArea->updatePreferences(store); |
| 5006 | |
| 5007 | WebProcess::singleton().setChildProcessDebuggabilityEnabled(store.getBoolValueForKey(WebPreferencesKey::childProcessDebuggabilityEnabledKey())); |
| 5008 | |
| 5009 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5010 | downcast<WebMediaStrategy>(platformStrategies()->mediaStrategy()).setUseGPUProcess(m_shouldPlayMediaInGPUProcess); |
| 5011 | #if ENABLE(VIDEO)(defined 1 && 1) |
| 5012 | protect(WebProcess::singleton().remoteMediaPlayerManager())->setUseGPUProcess(m_shouldPlayMediaInGPUProcess); |
| 5013 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 5014 | platformStrategies()->mediaStrategy()->enableRemoteRenderer(MediaPlayerMediaEngineIdentifier::CocoaWebM, settings.webMUseRemoteAudioVideoRenderer()); |
| 5015 | platformStrategies()->mediaStrategy()->enableRemoteRenderer(MediaPlayerMediaEngineIdentifier::AVFoundationMSE, settings.mediaSourceUseRemoteAudioVideoRenderer()); |
| 5016 | #endif |
| 5017 | #endif |
| 5018 | #if HAVE(AVASSETREADER)(defined 1 && 1) |
| 5019 | protect(WebProcess::singleton().remoteImageDecoderAVFManager())->setUseGPUProcess(m_shouldPlayMediaInGPUProcess); |
| 5020 | #endif |
| 5021 | WebProcess::singleton().setUseGPUProcessForCanvasRendering(m_shouldRenderCanvasInGPUProcess); |
| 5022 | bool usingGPUProcessForDOMRendering = m_shouldRenderDOMInGPUProcess |
| 5023 | #if ENABLE(TILED_CA_DRAWING_AREA)(defined ENABLE_TILED_CA_DRAWING_AREA && ENABLE_TILED_CA_DRAWING_AREA ) |
| 5024 | && DrawingArea::supportsGPUProcessRendering(m_drawingAreaType); |
| 5025 | #else |
| 5026 | && DrawingArea::supportsGPUProcessRendering(); |
| 5027 | #endif |
| 5028 | WebProcess::singleton().setUseGPUProcessForDOMRendering(usingGPUProcessForDOMRendering); |
| 5029 | WebProcess::singleton().setUseGPUProcessForMedia(m_shouldPlayMediaInGPUProcess); |
| 5030 | #if ENABLE(WEBGL)(defined 1 && 1) |
| 5031 | WebProcess::singleton().setUseGPUProcessForWebGL(m_shouldRenderWebGLInGPUProcess); |
| 5032 | #endif |
| 5033 | #endif // ENABLE(GPU_PROCESS) |
| 5034 | |
| 5035 | #if ENABLE(IPC_TESTING_API)(defined ENABLE_IPC_TESTING_API && ENABLE_IPC_TESTING_API ) |
| 5036 | m_ipcTestingAPIEnabled = store.getBoolValueForKey(WebPreferencesKey::ipcTestingAPIEnabledKey()); |
| 5037 | |
| 5038 | protect(WebProcess::singleton().parentProcessConnection())->setIgnoreInvalidMessageForTesting(); |
| 5039 | if (auto* gpuProcessConnection = WebProcess::singleton().existingGPUProcessConnection()) |
| 5040 | gpuProcessConnection->connection().setIgnoreInvalidMessageForTesting(); |
| 5041 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 5042 | if (auto* modelProcessConnection = WebProcess::singleton().existingModelProcessConnection()) |
| 5043 | modelProcessConnection->connection().setIgnoreInvalidMessageForTesting(); |
| 5044 | #endif // ENABLE(MODEL_PROCESS) |
| 5045 | #endif // ENABLE(IPC_TESTING_API) |
| 5046 | |
| 5047 | #if ENABLE(VP9)(defined 1 && 1) && PLATFORM(COCOA)(defined 1 && 1) |
| 5048 | VP9TestingOverrides::singleton().setSWVPDecodersAlwaysEnabled(store.getBoolValueForKey(WebPreferencesKey::sWVPDecodersAlwaysEnabledKey())); |
| 5049 | #endif |
| 5050 | |
| 5051 | // FIXME: This should be automated by adding a new field in WebPreferences*.yaml |
| 5052 | // that indicates override state for Lockdown mode. https://webkit.org/b/233100. |
| 5053 | if (WebProcess::singleton().isLockdownModeEnabled()) |
| 5054 | adjustSettingsForLockdownMode(settings, &store); |
| 5055 | if (settings.forceLockdownFontParserEnabled()) |
| 5056 | settings.setDownloadableBinaryFontTrustedTypes(DownloadableBinaryFontTrustedTypes::SafeFontParser); |
| 5057 | |
| 5058 | #if ENABLE(ARKIT_INLINE_PREVIEW)(defined ENABLE_ARKIT_INLINE_PREVIEW && ENABLE_ARKIT_INLINE_PREVIEW ) |
| 5059 | m_useARKitForModel = store.getBoolValueForKey(WebPreferencesKey::useARKitForModelKey()); |
| 5060 | #endif |
| 5061 | #if HAVE(SCENEKIT)(defined HAVE_SCENEKIT && HAVE_SCENEKIT) |
| 5062 | m_useSceneKitForModel = store.getBoolValueForKey(WebPreferencesKey::useSceneKitForModelKey()); |
| 5063 | #endif |
| 5064 | |
| 5065 | if (settings.developerExtrasEnabled()) { |
| 5066 | settings.setShowMediaStatsContextMenuItemEnabled(true); |
| 5067 | settings.setTrackConfigurationEnabled(true); |
| 5068 | } |
| 5069 | |
| 5070 | #if ENABLE(WIRELESS_PLAYBACK_MEDIA_PLAYER)(defined ENABLE_WIRELESS_PLAYBACK_MEDIA_PLAYER && ENABLE_WIRELESS_PLAYBACK_MEDIA_PLAYER ) |
| 5071 | platformStrategies()->mediaStrategy()->setWirelessPlaybackMediaPlayerEnabled(store.getBoolValueForKey(WebPreferencesKey::wirelessPlaybackMediaPlayerEnabledKey())); |
| 5072 | #endif |
| 5073 | |
| 5074 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 5075 | for (Ref pluginView : m_pluginViews) |
| 5076 | pluginView->didChangeSettings(); |
| 5077 | #endif |
| 5078 | |
| 5079 | WebProcess::singleton().updateSharedPreferencesForWebProcess(WebKit::sharedPreferencesForWebProcess(store, WebProcess::singleton().isLockdownModeEnabled())); |
| 5080 | |
| 5081 | protect(corePage())->settingsDidChange(); |
| 5082 | } |
| 5083 | |
| 5084 | #if ENABLE(DATA_DETECTION)(defined 1 && 1) |
| 5085 | |
| 5086 | void WebPage::setDataDetectionResults(NSArray *detectionResults) |
| 5087 | { |
| 5088 | DataDetectionResult dataDetectionResult; |
| 5089 | dataDetectionResult.setResults(detectionResults); |
| 5090 | send(Messages::WebPageProxy::SetDataDetectionResult(dataDetectionResult)); |
| 5091 | } |
| 5092 | |
| 5093 | void WebPage::removeDataDetectedLinks(CompletionHandler<void(DataDetectionResult&&)>&& completionHandler) |
| 5094 | { |
| 5095 | for (RefPtr frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 5096 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame.get()); |
| 5097 | if (!localFrame) |
| 5098 | continue; |
| 5099 | RefPtr document = localFrame->document(); |
| 5100 | if (!document) |
| 5101 | continue; |
| 5102 | |
| 5103 | DataDetection::removeDataDetectedLinksInDocument(*document); |
| 5104 | |
| 5105 | if (auto* results = localFrame->dataDetectionResultsIfExists()) { |
| 5106 | // FIXME: It seems odd that we're clearing out all data detection results here, |
| 5107 | // instead of only data detectors that correspond to links. |
| 5108 | results->setDocumentLevelResults(nullptr); |
| 5109 | } |
| 5110 | } |
| 5111 | completionHandler({ }); |
| 5112 | } |
| 5113 | |
| 5114 | static void detectDataInFrame(const Ref<Frame>& frame, OptionSet<WebCore::DataDetectorType> dataDetectorTypes, const std::optional<double>& dataDetectionReferenceDate, UniqueRef<DataDetectionResult>&& mainFrameResult, CompletionHandler<void(DataDetectionResult&&)>&& completionHandler) |
| 5115 | { |
| 5116 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame.get()); |
| 5117 | if (!localFrame) { |
| 5118 | completionHandler(WTF::move(mainFrameResult.get())); |
| 5119 | return; |
| 5120 | } |
| 5121 | |
| 5122 | DataDetection::detectContentInFrame(localFrame.get(), dataDetectorTypes, dataDetectionReferenceDate, [localFrame, mainFrameResult = WTF::move(mainFrameResult), dataDetectionReferenceDate, completionHandler = WTF::move(completionHandler), dataDetectorTypes](NSArray *results) mutable { |
| 5123 | localFrame->dataDetectionResults().setDocumentLevelResults(results); |
| 5124 | if (localFrame->isMainFrame()) |
| 5125 | mainFrameResult->setResults(results); |
| 5126 | |
| 5127 | RefPtr next = localFrame->tree().traverseNext(); |
| 5128 | if (!next) { |
| 5129 | completionHandler(WTF::move(mainFrameResult.get())); |
| 5130 | return; |
| 5131 | } |
| 5132 | |
| 5133 | detectDataInFrame(Ref { *next }, dataDetectorTypes, dataDetectionReferenceDate, WTF::move(mainFrameResult), WTF::move(completionHandler)); |
| 5134 | }); |
| 5135 | } |
| 5136 | |
| 5137 | void WebPage::detectDataInAllFrames(OptionSet<WebCore::DataDetectorType> dataDetectorTypes, CompletionHandler<void(DataDetectionResult&&)>&& completionHandler) |
| 5138 | { |
| 5139 | auto mainFrameResult = makeUniqueRef<DataDetectionResult>(); |
| 5140 | detectDataInFrame(protect(protect(corePage())->mainFrame()).get(), dataDetectorTypes, m_dataDetectionReferenceDate, WTF::move(mainFrameResult), WTF::move(completionHandler)); |
| 5141 | } |
| 5142 | |
| 5143 | #endif // ENABLE(DATA_DETECTION) |
| 5144 | |
| 5145 | void WebPage::layoutIfNeeded() |
| 5146 | { |
| 5147 | protect(corePage())->layoutIfNeeded(); |
| 5148 | } |
| 5149 | |
| 5150 | void WebPage::updateRendering() |
| 5151 | { |
| 5152 | protect(corePage())->updateRendering(); |
| 5153 | |
| 5154 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 5155 | findController().redraw(); |
| 5156 | foundTextRangeController().redraw(); |
| 5157 | #endif |
| 5158 | } |
| 5159 | |
| 5160 | bool WebPage::hasRootFrames() |
| 5161 | { |
| 5162 | bool result = m_page && !m_page->rootFrames().isEmpty(); |
| 5163 | #if ASSERT_ENABLED0 |
| 5164 | if (!result) |
| 5165 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 5166 | #endif |
| 5167 | return result; |
| 5168 | } |
| 5169 | |
| 5170 | String WebPage::rootFrameOriginString() |
| 5171 | { |
| 5172 | auto rootFrameURL = [&] () -> URL { |
| 5173 | if (!m_page) |
| 5174 | return { }; |
| 5175 | if (m_page->rootFrames().isEmpty()) |
| 5176 | return { }; |
| 5177 | RefPtr documentLoader = m_page->rootFrames().begin()->get().loader().documentLoader(); |
| 5178 | if (!documentLoader) |
| 5179 | return { }; |
| 5180 | return documentLoader->url(); |
| 5181 | } (); |
| 5182 | |
| 5183 | Ref<SecurityOrigin> origin = SecurityOrigin::create(rootFrameURL); |
| 5184 | if (!origin->isOpaque()) |
| 5185 | return origin->toRawString(); |
| 5186 | |
| 5187 | // toRawString() is not supposed to work with opaque origins, and would just return "://". |
| 5188 | return makeString(rootFrameURL.protocol(), ':'); |
| 5189 | } |
| 5190 | |
| 5191 | void WebPage::didUpdateRendering(OptionSet<DidUpdateRenderingFlags> flags) |
| 5192 | { |
| 5193 | if (flags & DidUpdateRenderingFlags::PaintedLayers) { |
| 5194 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5195 | if (RefPtr proxy = m_remoteRenderingBackendProxy) |
| 5196 | proxy->didPaintLayers(); |
| 5197 | #endif |
| 5198 | } |
| 5199 | |
| 5200 | if (flags & DidUpdateRenderingFlags::NotifyUIProcess) { |
| 5201 | if (m_didUpdateRenderingAfterCommittingLoad) |
| 5202 | return; |
| 5203 | |
| 5204 | m_didUpdateRenderingAfterCommittingLoad = true; |
| 5205 | send(Messages::WebPageProxy::DidUpdateRenderingAfterCommittingLoad()); |
| 5206 | } |
| 5207 | |
| 5208 | protect(corePage())->didUpdateRendering(); |
| 5209 | } |
| 5210 | |
| 5211 | bool WebPage::shouldTriggerRenderingUpdate(unsigned rescheduledRenderingUpdateCount) const |
| 5212 | { |
| 5213 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5214 | static constexpr unsigned maxRescheduledRenderingUpdateCount = FullSpeedFramesPerSecond; |
| 5215 | if (rescheduledRenderingUpdateCount >= maxRescheduledRenderingUpdateCount) |
| 5216 | return true; |
| 5217 | |
| 5218 | static constexpr unsigned maxDelayedRenderingUpdateCount = 2; |
| 5219 | RefPtr proxy = m_remoteRenderingBackendProxy; |
| 5220 | if (proxy && proxy->delayedRenderingUpdateCount() > maxDelayedRenderingUpdateCount) |
| 5221 | return false; |
| 5222 | #endif |
| 5223 | return true; |
| 5224 | } |
| 5225 | |
| 5226 | void WebPage::finalizeRenderingUpdate(OptionSet<FinalizeRenderingUpdateFlags> flags) |
| 5227 | { |
| 5228 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 5229 | WTFBeginSignpost(this, FinalizeRenderingUpdate)do { if (true) [[unlikely]] do { if (WTFSignpostIndirectLoggingEnabled ) clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WTFSignpostLogHandle ()); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT); if (os_log_type_enabled (_log_tmp, _type_tmp)) { __extension__({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p("type=%d name=%d p=%" "lu" " ts=%llu " ""), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG77" ) = "type=%d name=%d p=%" "lu" " ts=%llu " ""; uint8_t _Alignas (16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("type=%d name=%d p=%" "lu" " ts=%llu " "", WTFOSSignpostTypeBeginInterval , WTFOSSignpostNameFinalizeRenderingUpdate, reinterpret_cast< uintptr_t>(((this))), WTFCurrentContinuousTime(Seconds())) ]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "type=%d name=%d p=%" "lu" " ts=%llu " "", WTFOSSignpostTypeBeginInterval, WTFOSSignpostNameFinalizeRenderingUpdate , reinterpret_cast<uintptr_t>(((this))), WTFCurrentContinuousTime (Seconds())), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; else do { RetainPtr< os_log_t> wtfHandle = WTFSignpostLogHandle(); const void* wtfPointer = (const void *)(((this))); os_signpost_id_t wtfSignpostID = wtfPointer ? os_signpost_id_make_with_pointer(wtfHandle.get( ), wtfPointer) : ((os_signpost_id_t)0xEEEEB0B5B2B2EEEE); clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" __extension__ ({ os_log_t _log_tmp = (wtfHandle.get()); os_signpost_type_t _type_tmp = (OS_SIGNPOST_INTERVAL_BEGIN); os_signpost_id_t _spid_tmp = (wtfSignpostID); if (_spid_tmp != ((os_signpost_id_t)0) && _spid_tmp != ((os_signpost_id_t)~0) && os_signpost_enabled (_log_tmp)) { __extension__({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert (__builtin_constant_p("" "" " %{signpost.description:begin_time}llu" ), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG78" ) = "" "" " %{signpost.description:begin_time}llu"; _Static_assert (__builtin_constant_p("FinalizeRenderingUpdate"), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_name_str[] __asm("LOS_LOG79" ) = "FinalizeRenderingUpdate"; uint8_t _Alignas(16) __attribute__ ((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("" "" " %{signpost.description:begin_time}llu", WTFCurrentContinuousTime (Seconds()))]; (_os_signpost_emit_with_name_impl)(&__dso_handle , _log_tmp, _type_tmp, _spid_tmp, _os_name_str, _os_fmt_str, ( uint8_t *)__builtin_os_log_format(_os_fmt_buf, "" "" " %{signpost.description:begin_time}llu" , WTFCurrentContinuousTime(Seconds())), (uint32_t)sizeof(_os_fmt_buf )) clang diagnostic pop ; }); } }); clang diagnostic pop } while (0); } while (0); } while (0); |
| 5230 | #endif |
| 5231 | |
| 5232 | protect(corePage())->finalizeRenderingUpdate(flags); |
| 5233 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5234 | if (RefPtr proxy = m_remoteRenderingBackendProxy) |
| 5235 | proxy->finalizeRenderingUpdate(); |
| 5236 | #endif |
| 5237 | flushDeferredDidReceiveMouseEvent(); |
| 5238 | |
| 5239 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 5240 | WTFEndSignpost(this, FinalizeRenderingUpdate)do { if (true) [[unlikely]] do { if (WTFSignpostIndirectLoggingEnabled ) clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WTFSignpostLogHandle ()); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT); if (os_log_type_enabled (_log_tmp, _type_tmp)) { __extension__({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p("type=%d name=%d p=%" "lu" " ts=%llu " ""), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG80" ) = "type=%d name=%d p=%" "lu" " ts=%llu " ""; uint8_t _Alignas (16) __attribute__((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("type=%d name=%d p=%" "lu" " ts=%llu " "", WTFOSSignpostTypeEndInterval , WTFOSSignpostNameFinalizeRenderingUpdate, reinterpret_cast< uintptr_t>(((this))), WTFCurrentContinuousTime(Seconds())) ]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "type=%d name=%d p=%" "lu" " ts=%llu " "", WTFOSSignpostTypeEndInterval, WTFOSSignpostNameFinalizeRenderingUpdate , reinterpret_cast<uintptr_t>(((this))), WTFCurrentContinuousTime (Seconds())), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; else do { RetainPtr< os_log_t> wtfHandle = WTFSignpostLogHandle(); const void* wtfPointer = (const void *)(((this))); os_signpost_id_t wtfSignpostID = wtfPointer ? os_signpost_id_make_with_pointer(wtfHandle.get( ), wtfPointer) : ((os_signpost_id_t)0xEEEEB0B5B2B2EEEE); clang diagnostic push clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" __extension__ ({ os_log_t _log_tmp = (wtfHandle.get()); os_signpost_type_t _type_tmp = (OS_SIGNPOST_INTERVAL_END); os_signpost_id_t _spid_tmp = ( wtfSignpostID); if (_spid_tmp != ((os_signpost_id_t)0) && _spid_tmp != ((os_signpost_id_t)~0) && os_signpost_enabled (_log_tmp)) { __extension__({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert (__builtin_constant_p("" "" " %{signpost.description:end_time}llu" ), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG81" ) = "" "" " %{signpost.description:end_time}llu"; _Static_assert (__builtin_constant_p("FinalizeRenderingUpdate"), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_name_str[] __asm("LOS_LOG82" ) = "FinalizeRenderingUpdate"; uint8_t _Alignas(16) __attribute__ ((uninitialized)) _os_fmt_buf[__builtin_os_log_format_buffer_size ("" "" " %{signpost.description:end_time}llu", WTFCurrentContinuousTime (Seconds()))]; (_os_signpost_emit_with_name_impl)(&__dso_handle , _log_tmp, _type_tmp, _spid_tmp, _os_name_str, _os_fmt_str, ( uint8_t *)__builtin_os_log_format(_os_fmt_buf, "" "" " %{signpost.description:end_time}llu" , WTFCurrentContinuousTime(Seconds())), (uint32_t)sizeof(_os_fmt_buf )) clang diagnostic pop ; }); } }); clang diagnostic pop } while (0); } while (0); } while (0); |
| 5241 | #endif |
| 5242 | } |
| 5243 | |
| 5244 | void WebPage::willStartRenderingUpdateDisplay() |
| 5245 | { |
| 5246 | if (m_isClosed) |
| 5247 | return; |
| 5248 | protect(corePage())->willStartRenderingUpdateDisplay(); |
| 5249 | } |
| 5250 | |
| 5251 | void WebPage::didCompleteRenderingUpdateDisplay() |
| 5252 | { |
| 5253 | if (m_isClosed) |
| 5254 | return; |
| 5255 | protect(corePage())->didCompleteRenderingUpdateDisplay(); |
| 5256 | } |
| 5257 | |
| 5258 | void WebPage::didCompleteRenderingFrame() |
| 5259 | { |
| 5260 | if (m_isClosed) |
| 5261 | return; |
| 5262 | protect(corePage())->didCompleteRenderingFrame(); |
| 5263 | } |
| 5264 | |
| 5265 | void WebPage::releaseMemory(Critical) |
| 5266 | { |
| 5267 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5268 | if (RefPtr renderingBackend = m_remoteRenderingBackendProxy) |
| 5269 | renderingBackend->releaseMemory(); |
| 5270 | #endif |
| 5271 | |
| 5272 | m_foundTextRangeController->clearCachedRanges(); |
| 5273 | } |
| 5274 | |
| 5275 | void WebPage::willDestroyDecodedDataForAllImages() |
| 5276 | { |
| 5277 | } |
| 5278 | |
| 5279 | unsigned WebPage::remoteImagesCountForTesting() const |
| 5280 | { |
| 5281 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 5282 | if (RefPtr renderingBackend = m_remoteRenderingBackendProxy) |
| 5283 | return renderingBackend->nativeImageCountForTesting(); |
| 5284 | #endif |
| 5285 | return 0; |
| 5286 | } |
| 5287 | |
| 5288 | WebInspectorBackend* WebPage::inspector(LazyCreationPolicy behavior) |
| 5289 | { |
| 5290 | if (m_isClosed) |
| 5291 | return nullptr; |
| 5292 | if (!m_inspector && behavior == LazyCreationPolicy::CreateIfNeeded) |
| 5293 | m_inspector = WebInspectorBackend::create(*this); |
| 5294 | return m_inspector.get(); |
| 5295 | } |
| 5296 | |
| 5297 | WebInspectorUI* WebPage::inspectorUI() |
| 5298 | { |
| 5299 | if (m_isClosed) |
| 5300 | return nullptr; |
| 5301 | if (!m_inspectorUI) |
| 5302 | m_inspectorUI = WebInspectorUI::create(*this); |
| 5303 | return m_inspectorUI.get(); |
| 5304 | } |
| 5305 | |
| 5306 | RemoteWebInspectorUI* WebPage::remoteInspectorUI() |
| 5307 | { |
| 5308 | if (m_isClosed) |
| 5309 | return nullptr; |
| 5310 | if (!m_remoteInspectorUI) |
| 5311 | m_remoteInspectorUI = RemoteWebInspectorUI::create(*this); |
| 5312 | return m_remoteInspectorUI.get(); |
| 5313 | } |
| 5314 | |
| 5315 | void WebPage::inspectorFrontendCountChanged(unsigned count) |
| 5316 | { |
| 5317 | send(Messages::WebPageProxy::DidChangeInspectorFrontendCount(count)); |
| 5318 | } |
| 5319 | |
| 5320 | #if ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1) |
| 5321 | PlaybackSessionManager& WebPage::playbackSessionManager() |
| 5322 | { |
| 5323 | if (!m_playbackSessionManager) |
| 5324 | m_playbackSessionManager = PlaybackSessionManager::create(*this); |
| 5325 | return *m_playbackSessionManager; |
| 5326 | } |
| 5327 | |
| 5328 | VideoPresentationManager& WebPage::videoPresentationManager() |
| 5329 | { |
| 5330 | if (!m_videoPresentationManager) |
| 5331 | m_videoPresentationManager = VideoPresentationManager::create(*this, protect(playbackSessionManager())); |
| 5332 | return *m_videoPresentationManager; |
| 5333 | } |
| 5334 | |
| 5335 | void WebPage::videoControlsManagerDidChange() |
| 5336 | { |
| 5337 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 5338 | protect(fullScreenManager())->videoControlsManagerDidChange(); |
| 5339 | #endif |
| 5340 | } |
| 5341 | |
| 5342 | void WebPage::startPlayingPredominantVideo(CompletionHandler<void(bool)>&& completion) |
| 5343 | { |
| 5344 | RefPtr mainFrame = m_mainFrame->coreLocalFrame(); |
| 5345 | if (!mainFrame) { |
| 5346 | completion(false); |
| 5347 | return; |
| 5348 | } |
| 5349 | |
| 5350 | RefPtr view = mainFrame->view(); |
| 5351 | if (!view) { |
| 5352 | completion(false); |
| 5353 | return; |
| 5354 | } |
| 5355 | |
| 5356 | RefPtr document = mainFrame->document(); |
| 5357 | if (!document) { |
| 5358 | completion(false); |
| 5359 | return; |
| 5360 | } |
| 5361 | |
| 5362 | Vector<Ref<HTMLMediaElement>> candidates; |
| 5363 | document->updateLayoutIgnorePendingStylesheets(); |
| 5364 | document->forEachMediaElement([&candidates](auto& element) { |
| 5365 | if (!element.canPlay()) |
| 5366 | return; |
| 5367 | |
| 5368 | if (!element.isVisibleInViewport()) |
| 5369 | return; |
| 5370 | |
| 5371 | candidates.append(element); |
| 5372 | }); |
| 5373 | |
| 5374 | RefPtr<HTMLMediaElement> largestElement; |
| 5375 | float largestArea = 0; |
| 5376 | auto unobscuredContentRect = view->unobscuredContentRect(); |
| 5377 | auto unobscuredArea = unobscuredContentRect.area<RecordOverflow>(); |
| 5378 | if (unobscuredArea.hasOverflowed()) { |
| 5379 | completion(false); |
| 5380 | return; |
| 5381 | } |
| 5382 | |
| 5383 | constexpr auto minimumViewportRatioForLargestMediaElement = 0.25; |
| 5384 | float minimumAreaForLargestElement = minimumViewportRatioForLargestMediaElement * unobscuredArea.value(); |
| 5385 | for (auto& candidate : candidates) { |
| 5386 | auto intersectionRect = intersection(unobscuredContentRect, candidate->boundingBoxInRootViewCoordinates()); |
| 5387 | if (intersectionRect.isEmpty()) |
| 5388 | continue; |
| 5389 | |
| 5390 | auto area = intersectionRect.area<RecordOverflow>(); |
| 5391 | if (area.hasOverflowed()) |
| 5392 | continue; |
| 5393 | |
| 5394 | if (area <= largestArea) |
| 5395 | continue; |
| 5396 | |
| 5397 | if (area < minimumAreaForLargestElement) |
| 5398 | continue; |
| 5399 | |
| 5400 | largestArea = area; |
| 5401 | largestElement = candidate.ptr(); |
| 5402 | } |
| 5403 | |
| 5404 | if (!largestElement) { |
| 5405 | completion(false); |
| 5406 | return; |
| 5407 | } |
| 5408 | |
| 5409 | UserGestureIndicator userGesture { IsProcessingUserGesture::Yes, document.get() }; |
| 5410 | largestElement->play(); |
| 5411 | completion(true); |
| 5412 | } |
| 5413 | |
| 5414 | #endif // ENABLE(VIDEO_PRESENTATION_MODE) |
| 5415 | |
| 5416 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 5417 | void WebPage::setSceneIdentifier(String&& sceneIdentifier) |
| 5418 | { |
| 5419 | AudioSession::singleton().setSceneIdentifier(sceneIdentifier); |
| 5420 | protect(m_page)->setSceneIdentifier(WTF::move(sceneIdentifier)); |
| 5421 | } |
| 5422 | |
| 5423 | void WebPage::setAllowsMediaDocumentInlinePlayback(bool allows) |
| 5424 | { |
| 5425 | protect(m_page)->setAllowsMediaDocumentInlinePlayback(allows); |
| 5426 | } |
| 5427 | #endif |
| 5428 | |
| 5429 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 5430 | WebFullScreenManager& WebPage::fullScreenManager() |
| 5431 | { |
| 5432 | if (!m_fullScreenManager) |
| 5433 | m_fullScreenManager = WebFullScreenManager::create(*this); |
| 5434 | return *m_fullScreenManager; |
| 5435 | } |
| 5436 | |
| 5437 | void WebPage::isInFullscreenChanged(IsInFullscreenMode isInFullscreenMode) |
| 5438 | { |
| 5439 | if (m_isInFullscreenMode == isInFullscreenMode) |
| 5440 | return; |
| 5441 | m_isInFullscreenMode = isInFullscreenMode; |
| 5442 | |
| 5443 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 5444 | resetViewportDefaultConfiguration(m_mainFrame.ptr(), m_isMobileDoctype); |
| 5445 | #endif |
| 5446 | } |
| 5447 | |
| 5448 | void WebPage::closeFullScreen() |
| 5449 | { |
| 5450 | removeReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen); |
| 5451 | |
| 5452 | send(Messages::WebFullScreenManagerProxy::Close()); |
| 5453 | } |
| 5454 | |
| 5455 | void WebPage::prepareToEnterElementFullScreen() |
| 5456 | { |
| 5457 | addReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen); |
| 5458 | } |
| 5459 | |
| 5460 | void WebPage::prepareToExitElementFullScreen() |
| 5461 | { |
| 5462 | removeReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen); |
| 5463 | } |
| 5464 | |
| 5465 | #endif // ENABLE(FULLSCREEN_API) |
| 5466 | |
| 5467 | void WebPage::addConsoleMessage(FrameIdentifier frameID, MessageSource messageSource, MessageLevel messageLevel, const String& message, std::optional<WebCore::ResourceLoaderIdentifier> requestID) |
| 5468 | { |
| 5469 | if (RefPtr frame = WebProcess::singleton().webFrame(frameID)) |
| 5470 | frame->addConsoleMessage(messageSource, messageLevel, message, requestID ? requestID->toUInt64() : 0); |
| 5471 | } |
| 5472 | |
| 5473 | void WebPage::enqueueSecurityPolicyViolationEvent(FrameIdentifier frameID, SecurityPolicyViolationEventInit&& eventInit) |
| 5474 | { |
| 5475 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 5476 | if (!frame) |
| 5477 | return; |
| 5478 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 5479 | if (!coreFrame) |
| 5480 | return; |
| 5481 | if (RefPtr document = coreFrame->document()) |
| 5482 | document->enqueueSecurityPolicyViolationEvent(WTF::move(eventInit)); |
| 5483 | } |
| 5484 | |
| 5485 | void WebPage::notifyReportObservers(FrameIdentifier frameID, Ref<WebCore::Report>&& report) |
| 5486 | { |
| 5487 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 5488 | if (!frame) |
| 5489 | return; |
| 5490 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 5491 | if (!coreFrame) |
| 5492 | return; |
| 5493 | if (RefPtr document = coreFrame->document()) |
| 5494 | protect(document->reportingScope())->notifyReportObservers(WTF::move(report)); |
| 5495 | } |
| 5496 | |
| 5497 | void WebPage::sendReportToEndpoints(FrameIdentifier frameID, URL&& baseURL, const Vector<String>& endpointURIs, const Vector<String>& endpointTokens, IPC::FormDataReference&& reportData, WebCore::ViolationReportType reportType) |
| 5498 | { |
| 5499 | auto report = reportData.takeData(); |
| 5500 | if (!report) |
| 5501 | return; |
| 5502 | |
| 5503 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 5504 | if (!frame || !frame->coreLocalFrame()) |
| 5505 | return; |
| 5506 | |
| 5507 | for (auto& url : endpointURIs) |
| 5508 | PingLoader::sendViolationReport(*protect(frame->coreLocalFrame()), URL { baseURL, url }, Ref { *report.get() }, reportType); |
| 5509 | |
| 5510 | RefPtr document = frame->coreLocalFrame()->document(); |
| 5511 | if (!document) |
| 5512 | return; |
| 5513 | |
| 5514 | for (auto& token : endpointTokens) { |
| 5515 | if (auto url = document->endpointURIForToken(token); !url.isEmpty()) |
| 5516 | PingLoader::sendViolationReport(*protect(frame->coreLocalFrame()), URL { baseURL, url }, Ref { *report.get() }, reportType); |
| 5517 | } |
| 5518 | } |
| 5519 | |
| 5520 | NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager() |
| 5521 | { |
| 5522 | if (m_notificationPermissionRequestManager) |
| 5523 | return m_notificationPermissionRequestManager.get(); |
| 5524 | |
| 5525 | m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this); |
| 5526 | return m_notificationPermissionRequestManager.get(); |
| 5527 | } |
| 5528 | |
| 5529 | #if ENABLE(DRAG_SUPPORT)(defined 1 && 1) |
| 5530 | |
| 5531 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 5532 | void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, OptionSet<DragOperation> draggingSourceOperationMask, SelectionData&& selectionData, OptionSet<DragApplicationFlags> flags, CompletionHandler<void(std::optional<DragOperation>, DragHandlingMethod, bool, unsigned, IntRect, IntRect, std::optional<RemoteUserInputEventData>)>&& completionHandler) |
| 5533 | { |
| 5534 | if (!m_page) |
| 5535 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::nullopt); |
| 5536 | |
| 5537 | RefPtr localMainFrame = this->localMainFrame(); |
| 5538 | if (!localMainFrame) |
| 5539 | return; |
| 5540 | |
| 5541 | DragData dragData(&selectionData, clientPosition, globalPosition, draggingSourceOperationMask, flags, anyDragDestinationAction(), m_identifier); |
| 5542 | switch (action) { |
| 5543 | case DragControllerAction::Entered: |
| 5544 | case DragControllerAction::Updated: { |
| 5545 | auto resolvedDragAction = m_page->dragController().dragEnteredOrUpdated(*localMainFrame, WTF::move(dragData)); |
| 5546 | if (std::holds_alternative<RemoteUserInputEventData>(resolvedDragAction)) |
| 5547 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::get<RemoteUserInputEventData>(resolvedDragAction)); |
| 5548 | auto dragOperation = std::get<std::optional<DragOperation>>(resolvedDragAction); |
| 5549 | return completionHandler(dragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }, { }, std::nullopt); |
| 5550 | } |
| 5551 | case DragControllerAction::Exited: |
| 5552 | m_page->dragController().dragExited(*localMainFrame, WTF::move(dragData)); |
| 5553 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::nullopt); |
| 5554 | |
| 5555 | case DragControllerAction::PerformDragOperation: { |
| 5556 | m_page->dragController().performDragOperation(WTF::move(dragData), *localMainFrame); |
| 5557 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::nullopt); |
| 5558 | } |
| 5559 | } |
| 5560 | ASSERT_NOT_REACHED()((void)0); |
| 5561 | } |
| 5562 | #else |
| 5563 | void WebPage::performDragControllerAction(std::optional<FrameIdentifier> frameID, DragControllerAction action, DragData&& dragData, CompletionHandler<void(std::optional<DragOperation>, DragHandlingMethod, bool, unsigned, IntRect, IntRect, std::optional<RemoteUserInputEventData>)>&& completionHandler) |
| 5564 | { |
| 5565 | if (!m_page) |
| 5566 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::nullopt); |
| 5567 | |
| 5568 | RefPtr frame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame(); |
| 5569 | if (!frame) { |
| 5570 | ASSERT_NOT_REACHED()((void)0); |
| 5571 | return; |
| 5572 | } |
| 5573 | |
| 5574 | RefPtr localFrame = frame->coreLocalFrame(); |
| 5575 | if (!localFrame) { |
| 5576 | ASSERT_NOT_REACHED()((void)0); |
| 5577 | return; |
| 5578 | } |
| 5579 | |
| 5580 | switch (action) { |
| 5581 | case DragControllerAction::Entered: |
| 5582 | case DragControllerAction::Updated: { |
| 5583 | auto resolvedDragAction = m_page->dragController().dragEnteredOrUpdated(*localFrame, WTF::move(dragData)); |
| 5584 | if (std::holds_alternative<RemoteUserInputEventData>(resolvedDragAction)) |
| 5585 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::get<RemoteUserInputEventData>(resolvedDragAction)); |
| 5586 | auto dragOperation = std::get<std::optional<DragOperation>>(resolvedDragAction); |
| 5587 | return completionHandler(dragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), m_page->dragCaretController().caretRectInRootViewCoordinates(), m_page->dragCaretController().editableElementRectInRootViewCoordinates(), std::nullopt); |
| 5588 | } |
| 5589 | case DragControllerAction::Exited: |
| 5590 | m_page->dragController().dragExited(*localFrame, WTF::move(dragData)); |
| 5591 | return completionHandler(std::nullopt, DragHandlingMethod::None, false, 0, { }, { }, std::nullopt); |
| 5592 | case DragControllerAction::PerformDragOperation: |
| 5593 | break; |
| 5594 | } |
| 5595 | ASSERT_NOT_REACHED()((void)0); |
| 5596 | } |
| 5597 | |
| 5598 | void WebPage::performDragOperation(std::optional<WebCore::FrameIdentifier> frameID, WebCore::DragData&& dragData, SandboxExtension::Handle&& sandboxExtensionHandle, Vector<SandboxExtension::Handle>&& sandboxExtensionsForUpload, CompletionHandler<void(DragOperationResult dragOperationResult)>&& completionHandler) |
| 5599 | { |
| 5600 | m_pendingDropSandboxExtensionHandle = WTF::move(sandboxExtensionHandle); |
| 5601 | m_pendingDropExtensionHandlesForFileUpload = WTF::move(sandboxExtensionsForUpload); |
| 5602 | |
| 5603 | RefPtr frame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame(); |
| 5604 | if (!frame) { |
| 5605 | ASSERT_NOT_REACHED()((void)0); |
| 5606 | completionHandler(false); |
| 5607 | return; |
| 5608 | } |
| 5609 | |
| 5610 | RefPtr localFrame = frame->coreLocalFrame(); |
| 5611 | if (!localFrame) { |
| 5612 | ASSERT_NOT_REACHED()((void)0); |
| 5613 | completionHandler(false); |
| 5614 | return; |
| 5615 | } |
| 5616 | |
| 5617 | DragEventTargetData dragEventTargetData = m_page->dragController().performDragOperation(WTF::move(dragData), *localFrame); |
| 5618 | |
| 5619 | WTF::switchOn(dragEventTargetData, [&](WebCore::DragEventHandled handled) { |
| 5620 | completionHandler(handled == WebCore::DragEventHandled::Yes); |
| 5621 | }, [&](WebCore::FrameIdentifier targetFrameID) { |
| 5622 | if (targetFrameID != *frameID && m_pendingDropSandboxExtensionHandle && m_pendingDropExtensionHandlesForFileUpload) { |
| 5623 | DragEventForwardingData result { |
| 5624 | targetFrameID, |
| 5625 | WTF::move(*m_pendingDropSandboxExtensionHandle), |
| 5626 | WTF::move(*m_pendingDropExtensionHandlesForFileUpload) |
| 5627 | }; |
| 5628 | completionHandler(WTF::move(result)); |
| 5629 | return; |
| 5630 | } |
| 5631 | completionHandler(false); |
| 5632 | }); |
| 5633 | } |
| 5634 | #endif |
| 5635 | |
| 5636 | void WebPage::dragEnded(std::optional<FrameIdentifier> frameID, IntPoint clientPosition, IntPoint globalPosition, OptionSet<DragOperation> dragOperationMask, CompletionHandler<void(std::optional<RemoteUserInputEventData>)>&& completionHandler) |
| 5637 | { |
| 5638 | IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController().dragOffset().x(), globalPosition.y() + m_page->dragController().dragOffset().y()); |
| 5639 | |
| 5640 | m_page->dragController().dragEnded(); |
| 5641 | RefPtr frame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame(); |
| 5642 | if (!frame) |
| 5643 | return completionHandler(std::nullopt); |
| 5644 | |
| 5645 | RefPtr localFrame = frame->coreLocalFrame(); |
| 5646 | if (!localFrame) |
| 5647 | return completionHandler(std::nullopt); |
| 5648 | |
| 5649 | RefPtr view = localFrame->view(); |
| 5650 | if (!view) |
| 5651 | return completionHandler(std::nullopt); |
| 5652 | |
| 5653 | // FIXME: These are fake modifier keys here, but they should be real ones instead. |
| 5654 | PlatformMouseEvent event(clientPosition, adjustedGlobalPosition, MouseButton::Left, PlatformEvent::Type::MouseMoved, 0, { }, MonotonicTime::now(), 0, WebCore::SyntheticClickType::NoTap, MouseEventInputSource::UserDriven); |
| 5655 | auto remoteUserInputEventData = localFrame->eventHandler().dragSourceEndedAt(event, dragOperationMask); |
| 5656 | |
| 5657 | completionHandler(remoteUserInputEventData); |
| 5658 | |
| 5659 | m_isStartingDrag = false; |
| 5660 | } |
| 5661 | |
| 5662 | void WebPage::willPerformLoadDragDestinationAction() |
| 5663 | { |
| 5664 | if (auto pendingDropSandboxExtensionHandle = std::exchange(m_pendingDropSandboxExtensionHandle, std::nullopt)) |
| 5665 | m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(SandboxExtension::create(WTF::move(pendingDropSandboxExtensionHandle.value()))); |
| 5666 | } |
| 5667 | |
| 5668 | void WebPage::mayPerformUploadDragDestinationAction() |
| 5669 | { |
| 5670 | if (!m_pendingDropExtensionHandlesForFileUpload) |
| 5671 | return; |
| 5672 | |
| 5673 | for (auto& extensionHandle : *m_pendingDropExtensionHandlesForFileUpload) { |
| 5674 | if (auto extension = SandboxExtension::create(WTF::move(extensionHandle))) |
| 5675 | extension->consumePermanently(); |
| 5676 | } |
| 5677 | |
| 5678 | m_pendingDropExtensionHandlesForFileUpload = std::nullopt; |
| 5679 | } |
| 5680 | |
| 5681 | void WebPage::didStartDrag(std::optional<FrameIdentifier> frameID) |
| 5682 | { |
| 5683 | m_isStartingDrag = false; |
| 5684 | |
| 5685 | if (RefPtr frame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame()) { |
| 5686 | if (RefPtr localFrame = frame->coreLocalFrame()) |
| 5687 | localFrame->eventHandler().didStartDrag(); |
| 5688 | } |
| 5689 | } |
| 5690 | |
| 5691 | void WebPage::dragCancelled() |
| 5692 | { |
| 5693 | m_isStartingDrag = false; |
| 5694 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 5695 | localMainFrame->eventHandler().dragCancelled(); |
| 5696 | } |
| 5697 | |
| 5698 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 5699 | void WebPage::modelDragEnded(NodeIdentifier nodeIdentifier) |
| 5700 | { |
| 5701 | RefPtr node = Node::fromIdentifier(nodeIdentifier); |
| 5702 | if (!node) |
| 5703 | return; |
| 5704 | |
| 5705 | RefPtr modelElement = dynamicDowncast<HTMLModelElement>(node); |
| 5706 | if (!modelElement) |
| 5707 | return; |
| 5708 | |
| 5709 | modelElement->resetModelTransformAfterDrag(); |
| 5710 | } |
| 5711 | #endif |
| 5712 | |
| 5713 | #endif // ENABLE(DRAG_SUPPORT) |
| 5714 | |
| 5715 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 5716 | void WebPage::requestInteractiveModelElementAtPoint(IntPoint clientPosition) |
| 5717 | { |
| 5718 | if (RefPtr localMainFrame = dynamicDowncast<LocalFrame>(m_page->mainFrame())) { |
| 5719 | auto nodeID = localMainFrame->eventHandler().requestInteractiveModelElementAtPoint(clientPosition); |
| 5720 | send(Messages::WebPageProxy::DidReceiveInteractiveModelElement(nodeID)); |
| 5721 | } else |
| 5722 | send(Messages::WebPageProxy::DidReceiveInteractiveModelElement(std::nullopt)); |
| 5723 | } |
| 5724 | |
| 5725 | void WebPage::stageModeSessionDidUpdate(std::optional<NodeIdentifier> nodeID, const TransformationMatrix& transform) |
| 5726 | { |
| 5727 | if (RefPtr localMainFrame = dynamicDowncast<LocalFrame>(m_page->mainFrame())) |
| 5728 | localMainFrame->eventHandler().stageModeSessionDidUpdate(nodeID, transform); |
| 5729 | } |
| 5730 | |
| 5731 | void WebPage::stageModeSessionDidEnd(std::optional<NodeIdentifier> nodeID) |
| 5732 | { |
| 5733 | if (RefPtr localMainFrame = dynamicDowncast<LocalFrame>(m_page->mainFrame())) |
| 5734 | localMainFrame->eventHandler().stageModeSessionDidEnd(nodeID); |
| 5735 | } |
| 5736 | #endif |
| 5737 | |
| 5738 | WebUndoStep* WebPage::webUndoStep(WebUndoStepID stepID) |
| 5739 | { |
| 5740 | return m_undoStepMap.get(stepID); |
| 5741 | } |
| 5742 | |
| 5743 | void WebPage::addWebUndoStep(WebUndoStepID stepID, Ref<WebUndoStep>&& entry) |
| 5744 | { |
| 5745 | auto addResult = m_undoStepMap.set(stepID, WTF::move(entry)); |
| 5746 | ASSERT_UNUSED(addResult, addResult.isNewEntry)((void)addResult); |
| 5747 | } |
| 5748 | |
| 5749 | void WebPage::removeWebEditCommand(WebUndoStepID stepID) |
| 5750 | { |
| 5751 | if (auto undoStep = m_undoStepMap.take(stepID)) |
| 5752 | undoStep->didRemoveFromUndoManager(); |
| 5753 | } |
| 5754 | |
| 5755 | void WebPage::unapplyEditCommand(uint32_t undoVersion, WebUndoStepID stepID, CompletionHandler<void()>&& completionHandler) |
| 5756 | { |
| 5757 | if (undoVersion < m_currentUndoVersion) |
| 5758 | return completionHandler(); |
| 5759 | |
| 5760 | m_currentUndoVersion = undoVersion; |
| 5761 | |
| 5762 | RefPtr step = webUndoStep(stepID); |
| 5763 | if (!step) |
| 5764 | return completionHandler(); |
| 5765 | |
| 5766 | protect(step->step())->unapply(); |
| 5767 | completionHandler(); |
| 5768 | } |
| 5769 | |
| 5770 | void WebPage::reapplyEditCommand(uint32_t undoVersion, WebUndoStepID stepID, CompletionHandler<void()>&& completionHandler) |
| 5771 | { |
| 5772 | if (undoVersion < m_currentUndoVersion) |
| 5773 | return completionHandler(); |
| 5774 | |
| 5775 | m_currentUndoVersion = undoVersion; |
| 5776 | |
| 5777 | RefPtr step = webUndoStep(stepID); |
| 5778 | if (!step) |
| 5779 | return completionHandler(); |
| 5780 | |
| 5781 | setIsInRedo(true); |
| 5782 | protect(step->step())->reapply(); |
| 5783 | setIsInRedo(false); |
| 5784 | completionHandler(); |
| 5785 | } |
| 5786 | |
| 5787 | void WebPage::didRemoveEditCommand(WebUndoStepID commandID) |
| 5788 | { |
| 5789 | removeWebEditCommand(commandID); |
| 5790 | } |
| 5791 | |
| 5792 | void WebPage::closeCurrentTypingCommand() |
| 5793 | { |
| 5794 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 5795 | if (!frame) |
| 5796 | return; |
| 5797 | |
| 5798 | if (RefPtr document = frame->document()) |
| 5799 | protect(document->editor())->closeTyping(); |
| 5800 | } |
| 5801 | |
| 5802 | void WebPage::setActivePopupMenu(WebPopupMenu* menu) |
| 5803 | { |
| 5804 | m_activePopupMenu = menu; |
| 5805 | } |
| 5806 | |
| 5807 | WebColorChooser* WebPage::activeColorChooser() const |
| 5808 | { |
| 5809 | return m_activeColorChooser.get(); |
| 5810 | } |
| 5811 | |
| 5812 | void WebPage::setActiveColorChooser(WebColorChooser* colorChooser) |
| 5813 | { |
| 5814 | m_activeColorChooser = colorChooser; |
| 5815 | } |
| 5816 | |
| 5817 | void WebPage::didEndColorPicker() |
| 5818 | { |
| 5819 | if (RefPtr activeColorChooser = m_activeColorChooser.get()) |
| 5820 | activeColorChooser->didEndChooser(); |
| 5821 | } |
| 5822 | |
| 5823 | void WebPage::didChooseColor(const WebCore::Color& color) |
| 5824 | { |
| 5825 | if (RefPtr activeColorChooser = m_activeColorChooser.get()) |
| 5826 | activeColorChooser->didChooseColor(color); |
| 5827 | } |
| 5828 | |
| 5829 | void WebPage::setActiveDataListSuggestionPicker(WebDataListSuggestionPicker& dataListSuggestionPicker) |
| 5830 | { |
| 5831 | m_activeDataListSuggestionPicker = dataListSuggestionPicker; |
| 5832 | } |
| 5833 | |
| 5834 | void WebPage::didSelectDataListOption(const String& selectedOption) |
| 5835 | { |
| 5836 | if (RefPtr activeDataListSuggestionPicker = m_activeDataListSuggestionPicker.get()) |
| 5837 | activeDataListSuggestionPicker->didSelectOption(selectedOption); |
| 5838 | } |
| 5839 | |
| 5840 | void WebPage::didCloseSuggestions() |
| 5841 | { |
| 5842 | if (RefPtr picker = std::exchange(m_activeDataListSuggestionPicker, nullptr).get()) |
| 5843 | picker->didCloseSuggestions(); |
| 5844 | } |
| 5845 | |
| 5846 | void WebPage::setActiveDateTimeChooser(WebDateTimeChooser& dateTimeChooser) |
| 5847 | { |
| 5848 | m_activeDateTimeChooser = dateTimeChooser; |
| 5849 | } |
| 5850 | |
| 5851 | void WebPage::didChooseDate(const String& date) |
| 5852 | { |
| 5853 | if (RefPtr activeDateTimeChooser = m_activeDateTimeChooser.get()) |
| 5854 | activeDateTimeChooser->didChooseDate(date); |
| 5855 | } |
| 5856 | |
| 5857 | void WebPage::didEndDateTimePicker() |
| 5858 | { |
| 5859 | if (auto chooser = std::exchange(m_activeDateTimeChooser, nullptr)) |
| 5860 | chooser->didEndChooser(); |
| 5861 | } |
| 5862 | |
| 5863 | void WebPage::setActiveOpenPanelResultListener(Ref<WebOpenPanelResultListener>&& openPanelResultListener) |
| 5864 | { |
| 5865 | m_activeOpenPanelResultListener = WTF::move(openPanelResultListener); |
| 5866 | } |
| 5867 | |
| 5868 | void WebPage::setTextIndicator(RefPtr<WebCore::TextIndicator>&& textIndicator) |
| 5869 | { |
| 5870 | send(Messages::WebPageProxy::SetTextIndicatorFromFrame(m_mainFrame->frameID(), WTF::move(textIndicator), WebCore::TextIndicatorLifetime::Temporary)); |
| 5871 | } |
| 5872 | |
| 5873 | void WebPage::updateTextIndicator(RefPtr<WebCore::TextIndicator>&& textIndicator) |
| 5874 | { |
| 5875 | send(Messages::WebPageProxy::UpdateTextIndicatorFromFrame(m_mainFrame->frameID(), WTF::move(textIndicator))); |
| 5876 | } |
| 5877 | |
| 5878 | void WebPage::replaceStringMatchesFromInjectedBundle(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly) |
| 5879 | { |
| 5880 | findController().replaceMatches(matchIndices, replacementText, selectionOnly); |
| 5881 | } |
| 5882 | |
| 5883 | void WebPage::findString(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(std::optional<FrameIdentifier>, Vector<IntRect>&&, uint32_t, int32_t, bool)>&& completionHandler) |
| 5884 | { |
| 5885 | findController().findString(string, options, maxMatchCount, WTF::move(completionHandler)); |
| 5886 | } |
| 5887 | |
| 5888 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) |
| 5889 | void WebPage::findStringIncludingImages(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(std::optional<FrameIdentifier>, Vector<IntRect>&&, uint32_t, int32_t, bool)>&& completionHandler) |
| 5890 | { |
| 5891 | findController().findStringIncludingImages(string, options, maxMatchCount, WTF::move(completionHandler)); |
| 5892 | } |
| 5893 | #endif |
| 5894 | |
| 5895 | void WebPage::findStringMatches(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(Vector<Vector<WebCore::IntRect>>, int32_t)>&& completionHandler) |
| 5896 | { |
| 5897 | findController().findStringMatches(string, options, maxMatchCount, WTF::move(completionHandler)); |
| 5898 | } |
| 5899 | |
| 5900 | void WebPage::findTextRangesForStringMatches(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(HashMap<WebCore::FrameIdentifier, Vector<WebFoundTextRange>>&&)>&& completionHandler) |
| 5901 | { |
| 5902 | foundTextRangeController().findTextRangesForStringMatches(string, options, maxMatchCount, WTF::move(completionHandler)); |
| 5903 | } |
| 5904 | |
| 5905 | void WebPage::replaceFoundTextRangeWithString(const WebFoundTextRange& range, const String& string) |
| 5906 | { |
| 5907 | foundTextRangeController().replaceFoundTextRangeWithString(range, string); |
| 5908 | } |
| 5909 | |
| 5910 | void WebPage::decorateTextRangeWithStyle(const WebFoundTextRange& range, WebKit::FindDecorationStyle style) |
| 5911 | { |
| 5912 | foundTextRangeController().decorateTextRangeWithStyle(range, style); |
| 5913 | } |
| 5914 | |
| 5915 | void WebPage::scrollTextRangeToVisible(const WebFoundTextRange& range) |
| 5916 | { |
| 5917 | foundTextRangeController().scrollTextRangeToVisible(range); |
| 5918 | } |
| 5919 | |
| 5920 | void WebPage::clearAllDecoratedFoundText() |
| 5921 | { |
| 5922 | hideFindUI(); |
| 5923 | foundTextRangeController().clearAllDecoratedFoundText(); |
| 5924 | } |
| 5925 | |
| 5926 | void WebPage::didBeginTextSearchOperation() |
| 5927 | { |
| 5928 | foundTextRangeController().didBeginTextSearchOperation(); |
| 5929 | } |
| 5930 | |
| 5931 | void WebPage::requestRectForFoundTextRange(const WebFoundTextRange& range, CompletionHandler<void(WebCore::FloatRect)>&& completionHandler) |
| 5932 | { |
| 5933 | foundTextRangeController().requestRectForFoundTextRange(range, WTF::move(completionHandler)); |
| 5934 | } |
| 5935 | |
| 5936 | void WebPage::addLayerForFindOverlay(CompletionHandler<void(std::optional<WebCore::PlatformLayerIdentifier>)>&& completionHandler) |
| 5937 | { |
| 5938 | foundTextRangeController().addLayerForFindOverlay(WTF::move(completionHandler)); |
| 5939 | } |
| 5940 | |
| 5941 | void WebPage::removeLayerForFindOverlay(CompletionHandler<void()>&& completionHandler) |
| 5942 | { |
| 5943 | foundTextRangeController().removeLayerForFindOverlay(); |
| 5944 | completionHandler(); |
| 5945 | } |
| 5946 | |
| 5947 | void WebPage::getImageForFindMatch(uint32_t matchIndex) |
| 5948 | { |
| 5949 | findController().getImageForFindMatch(matchIndex); |
| 5950 | } |
| 5951 | |
| 5952 | void WebPage::selectFindMatch(uint32_t matchIndex) |
| 5953 | { |
| 5954 | findController().selectFindMatch(matchIndex); |
| 5955 | } |
| 5956 | |
| 5957 | void WebPage::indicateFindMatch(uint32_t matchIndex) |
| 5958 | { |
| 5959 | findController().indicateFindMatch(matchIndex); |
| 5960 | } |
| 5961 | |
| 5962 | void WebPage::hideFindUI() |
| 5963 | { |
| 5964 | findController().hideFindUI(); |
| 5965 | } |
| 5966 | |
| 5967 | void WebPage::countStringMatches(const String& string, OptionSet<FindOptions> options, uint32_t maxMatchCount, CompletionHandler<void(uint32_t)>&& completionHandler) |
| 5968 | { |
| 5969 | findController().countStringMatches(string, options, maxMatchCount, WTF::move(completionHandler)); |
| 5970 | } |
| 5971 | |
| 5972 | void WebPage::replaceMatches(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly, CompletionHandler<void(uint64_t)>&& completionHandler) |
| 5973 | { |
| 5974 | auto numberOfReplacements = findController().replaceMatches(matchIndices, replacementText, selectionOnly); |
| 5975 | completionHandler(numberOfReplacements); |
| 5976 | } |
| 5977 | |
| 5978 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 5979 | void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex) |
| 5980 | { |
| 5981 | changeSelectedIndex(newIndex); |
| 5982 | m_activePopupMenu = nullptr; |
| 5983 | } |
| 5984 | |
| 5985 | void WebPage::changeSelectedIndex(int32_t index) |
| 5986 | { |
| 5987 | if (RefPtr menu = m_activePopupMenu) |
| 5988 | menu->didChangeSelectedIndex(index); |
| 5989 | } |
| 5990 | #endif |
| 5991 | |
| 5992 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 5993 | void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, std::span<const uint8_t> iconData) |
| 5994 | { |
| 5995 | RefPtr activeOpenPanelResultListener = m_activeOpenPanelResultListener; |
| 5996 | if (!activeOpenPanelResultListener) |
| 5997 | return; |
| 5998 | |
| 5999 | RefPtr<Icon> icon; |
| 6000 | if (!iconData.empty()) { |
| 6001 | RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size())); |
| 6002 | RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get())); |
| 6003 | RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithPNGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault)); |
| 6004 | if (!imageRef) |
| 6005 | imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault)); |
| 6006 | icon = Icon::create(WTF::move(imageRef)); |
| 6007 | } |
| 6008 | |
| 6009 | activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get()); |
| 6010 | m_activeOpenPanelResultListener = nullptr; |
| 6011 | } |
| 6012 | #endif |
| 6013 | |
| 6014 | void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files, const Vector<String>& replacementFiles) |
| 6015 | { |
| 6016 | if (RefPtr activeOpenPanelResultListener = std::exchange(m_activeOpenPanelResultListener, nullptr)) |
| 6017 | activeOpenPanelResultListener->didChooseFiles(files, replacementFiles); |
| 6018 | } |
| 6019 | |
| 6020 | void WebPage::didCancelForOpenPanel() |
| 6021 | { |
| 6022 | if (RefPtr activeOpenPanelResultListener = std::exchange(m_activeOpenPanelResultListener, nullptr)) |
| 6023 | activeOpenPanelResultListener->didCancelFileChoosing(); |
| 6024 | } |
| 6025 | |
| 6026 | #if ENABLE(SANDBOX_EXTENSIONS)(defined 1 && 1) |
| 6027 | void WebPage::extendSandboxForFilesFromOpenPanel(Vector<SandboxExtension::Handle>&& handles) |
| 6028 | { |
| 6029 | bool result = SandboxExtension::consumePermanently(handles); |
| 6030 | if (!result) { |
| 6031 | // We have reports of cases where this fails for some unknown reason, <rdar://problem/10156710>. |
| 6032 | WTFLogAlways("WebPage::extendSandboxForFileFromOpenPanel(): Could not consume a sandbox extension"); |
| 6033 | } |
| 6034 | } |
| 6035 | #endif |
| 6036 | |
| 6037 | #if ENABLE(GEOLOCATION)(defined 1 && 1) |
| 6038 | void WebPage::didReceiveGeolocationPermissionDecision(GeolocationIdentifier geolocationID, const String& authorizationToken) |
| 6039 | { |
| 6040 | m_geolocationPermissionRequestManager->didReceiveGeolocationPermissionDecision(geolocationID, authorizationToken); |
| 6041 | } |
| 6042 | #endif |
| 6043 | |
| 6044 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) |
| 6045 | |
| 6046 | void WebPage::userMediaAccessWasGranted(UserMediaRequestIdentifier userMediaID, WebCore::CaptureDevice&& audioDevice, WebCore::CaptureDevice&& videoDevice, WebCore::MediaDeviceHashSalts&& mediaDeviceIdentifierHashSalts, Vector<SandboxExtension::Handle>&& handles, CompletionHandler<void()>&& completionHandler) |
| 6047 | { |
| 6048 | SandboxExtension::consumePermanently(handles); |
| 6049 | |
| 6050 | m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, WTF::move(audioDevice), WTF::move(videoDevice), WTF::move(mediaDeviceIdentifierHashSalts), WTF::move(completionHandler)); |
| 6051 | } |
| 6052 | |
| 6053 | void WebPage::userMediaAccessWasDenied(UserMediaRequestIdentifier userMediaID, uint64_t reason, String&& message, WebCore::MediaConstraintType invalidConstraint) |
| 6054 | { |
| 6055 | m_userMediaPermissionRequestManager->userMediaAccessWasDenied(userMediaID, static_cast<MediaAccessDenialReason>(reason), WTF::move(message), invalidConstraint); |
| 6056 | } |
| 6057 | |
| 6058 | void WebPage::captureDevicesChanged() |
| 6059 | { |
| 6060 | m_userMediaPermissionRequestManager->captureDevicesChanged(); |
| 6061 | } |
| 6062 | |
| 6063 | void WebPage::voiceActivityDetected() |
| 6064 | { |
| 6065 | protect(corePage())->voiceActivityDetected(); |
| 6066 | } |
| 6067 | |
| 6068 | #if USE(GSTREAMER)(defined USE_GSTREAMER && USE_GSTREAMER) |
| 6069 | void WebPage::setOrientationForMediaCapture(uint64_t rotation) |
| 6070 | { |
| 6071 | m_page->forEachDocument([&](auto& document) { |
| 6072 | document.orientationChanged(rotation); |
| 6073 | }); |
| 6074 | } |
| 6075 | |
| 6076 | void WebPage::setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted) |
| 6077 | { |
| 6078 | MockRealtimeMediaSourceCenter::setMockCaptureDevicesInterrupted(isCameraInterrupted, isMicrophoneInterrupted); |
| 6079 | } |
| 6080 | |
| 6081 | void WebPage::triggerMockCaptureConfigurationChange(bool forCamera, bool forMicrophone, bool forDisplay) |
| 6082 | { |
| 6083 | MockRealtimeMediaSourceCenter::singleton().triggerMockCaptureConfigurationChange(forCamera, forMicrophone, forDisplay); |
| 6084 | } |
| 6085 | #endif // USE(GSTREAMER) |
| 6086 | |
| 6087 | #endif // ENABLE(MEDIA_STREAM) |
| 6088 | |
| 6089 | #if ENABLE(ENCRYPTED_MEDIA)(defined 1 && 1) |
| 6090 | void WebPage::mediaKeySystemWasGranted(MediaKeySystemRequestIdentifier mediaKeySystemID, String&& mediaKeysHashSalt) |
| 6091 | { |
| 6092 | m_mediaKeySystemPermissionRequestManager->mediaKeySystemWasGranted(mediaKeySystemID, WTF::move(mediaKeysHashSalt)); |
| 6093 | } |
| 6094 | |
| 6095 | void WebPage::mediaKeySystemWasDenied(MediaKeySystemRequestIdentifier mediaKeySystemID, String&& message) |
| 6096 | { |
| 6097 | m_mediaKeySystemPermissionRequestManager->mediaKeySystemWasDenied(mediaKeySystemID, WTF::move(message)); |
| 6098 | } |
| 6099 | #endif |
| 6100 | |
| 6101 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 6102 | void WebPage::advanceToNextMisspelling(bool startBeforeSelection) |
| 6103 | { |
| 6104 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6105 | if (!frame) |
| 6106 | return; |
| 6107 | |
| 6108 | protect(frame->editor())->advanceToNextMisspelling(startBeforeSelection); |
| 6109 | } |
| 6110 | #endif |
| 6111 | |
| 6112 | bool WebPage::hasRichlyEditableSelection() const |
| 6113 | { |
| 6114 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6115 | if (!frame) |
| 6116 | return false; |
| 6117 | |
| 6118 | if (m_page->dragCaretController().isContentRichlyEditable()) |
| 6119 | return true; |
| 6120 | |
| 6121 | return frame->selection().selection().isContentRichlyEditable(); |
| 6122 | } |
| 6123 | |
| 6124 | void WebPage::changeSpellingToWord(const String& word) |
| 6125 | { |
| 6126 | replaceSelectionWithText(protect(corePage()->focusController().focusedOrMainFrame()).get(), word); |
| 6127 | } |
| 6128 | |
| 6129 | void WebPage::unmarkAllMisspellings() |
| 6130 | { |
| 6131 | for (RefPtr frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 6132 | RefPtr localFrame = dynamicDowncast<LocalFrame>(*frame); |
| 6133 | if (!localFrame) |
| 6134 | continue; |
| 6135 | if (RefPtr document = localFrame->document()) |
| 6136 | protect(document->markers())->removeMarkers(DocumentMarkerType::Spelling); |
| 6137 | } |
| 6138 | } |
| 6139 | |
| 6140 | void WebPage::unmarkAllBadGrammar() |
| 6141 | { |
| 6142 | for (RefPtr frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 6143 | RefPtr localFrame = dynamicDowncast<LocalFrame>(*frame); |
| 6144 | if (!localFrame) |
| 6145 | continue; |
| 6146 | if (RefPtr document = localFrame->document()) |
| 6147 | protect(document->markers())->removeMarkers(DocumentMarkerType::Grammar); |
| 6148 | } |
| 6149 | } |
| 6150 | |
| 6151 | #if USE(APPKIT)(defined USE_APPKIT && USE_APPKIT) |
| 6152 | void WebPage::uppercaseWord(FrameIdentifier frameID) |
| 6153 | { |
| 6154 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6155 | if (!frame) |
| 6156 | return; |
| 6157 | |
| 6158 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6159 | if (!coreFrame) |
| 6160 | return; |
| 6161 | |
| 6162 | protect(coreFrame->editor())->uppercaseWord(); |
| 6163 | } |
| 6164 | |
| 6165 | void WebPage::lowercaseWord(FrameIdentifier frameID) |
| 6166 | { |
| 6167 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6168 | if (!frame) |
| 6169 | return; |
| 6170 | |
| 6171 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6172 | if (!coreFrame) |
| 6173 | return; |
| 6174 | |
| 6175 | protect(coreFrame->editor())->lowercaseWord(); |
| 6176 | } |
| 6177 | |
| 6178 | void WebPage::capitalizeWord(FrameIdentifier frameID) |
| 6179 | { |
| 6180 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6181 | if (!frame) |
| 6182 | return; |
| 6183 | |
| 6184 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6185 | if (!coreFrame) |
| 6186 | return; |
| 6187 | |
| 6188 | |
| 6189 | protect(coreFrame->editor())->capitalizeWord(); |
| 6190 | } |
| 6191 | |
| 6192 | void WebPage::convertToTraditionalChinese(FrameIdentifier frameID) |
| 6193 | { |
| 6194 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6195 | if (!frame) |
| 6196 | return; |
| 6197 | |
| 6198 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6199 | if (!coreFrame) |
| 6200 | return; |
| 6201 | |
| 6202 | protect(coreFrame->editor())->convertToTraditionalChinese(); |
| 6203 | } |
| 6204 | |
| 6205 | void WebPage::convertToSimplifiedChinese(FrameIdentifier frameID) |
| 6206 | { |
| 6207 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6208 | if (!frame) |
| 6209 | return; |
| 6210 | |
| 6211 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6212 | if (!coreFrame) |
| 6213 | return; |
| 6214 | |
| 6215 | protect(coreFrame->editor())->convertToSimplifiedChinese(); |
| 6216 | } |
| 6217 | #endif |
| 6218 | |
| 6219 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 6220 | void WebPage::setTextForActivePopupMenu(int32_t index) |
| 6221 | { |
| 6222 | if (RefPtr menu = m_activePopupMenu) |
| 6223 | menu->setTextForIndex(index); |
| 6224 | } |
| 6225 | #endif |
| 6226 | |
| 6227 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 6228 | void WebPage::failedToShowPopupMenu() |
| 6229 | { |
| 6230 | if (!m_activePopupMenu) |
| 6231 | return; |
| 6232 | |
| 6233 | m_activePopupMenu->client()->popupDidHide(); |
| 6234 | } |
| 6235 | #endif |
| 6236 | |
| 6237 | #if ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 6238 | void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item) |
| 6239 | { |
| 6240 | if (auto contextMenu = std::exchange(m_contextMenu, nullptr)) |
| 6241 | contextMenu->itemSelected(item); |
| 6242 | } |
| 6243 | #endif |
| 6244 | |
| 6245 | void WebPage::replaceSelectionWithText(LocalFrame* frame, const String& text) |
| 6246 | { |
| 6247 | return protect(frame->editor())->replaceSelectionWithText(text, WebCore::Editor::SelectReplacement::Yes, WebCore::Editor::SmartReplace::No); |
| 6248 | } |
| 6249 | |
| 6250 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 6251 | void WebPage::clearSelection() |
| 6252 | { |
| 6253 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6254 | if (!frame) |
| 6255 | return; |
| 6256 | |
| 6257 | protect(frame->selection())->clear(); |
| 6258 | } |
| 6259 | #endif |
| 6260 | |
| 6261 | void WebPage::restoreSelectionInFocusedEditableElement() |
| 6262 | { |
| 6263 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6264 | if (!frame) |
| 6265 | return; |
| 6266 | |
| 6267 | if (!frame->selection().isNone()) |
| 6268 | return; |
| 6269 | |
| 6270 | if (RefPtr document = frame->document()) { |
| 6271 | if (RefPtr element = document->focusedElement()) |
| 6272 | element->updateFocusAppearance(SelectionRestorationMode::RestoreOrSelectAll, SelectionRevealMode::DoNotReveal); |
| 6273 | } |
| 6274 | } |
| 6275 | |
| 6276 | bool WebPage::mainFrameHasCustomContentProvider() const |
| 6277 | { |
| 6278 | if (RefPtr frame = localMainFrame()) { |
| 6279 | auto* webFrameLoaderClient = dynamicDowncast<WebLocalFrameLoaderClient>(frame->loader().client()); |
| 6280 | ASSERT(webFrameLoaderClient)((void)0); |
| 6281 | return webFrameLoaderClient->frameHasCustomContentProvider(); |
| 6282 | } |
| 6283 | |
| 6284 | return false; |
| 6285 | } |
| 6286 | |
| 6287 | void WebPage::updateMainFrameScrollOffsetPinning() |
| 6288 | { |
| 6289 | RefPtr frameView = localMainFrameView(); |
| 6290 | if (!frameView) |
| 6291 | return; |
| 6292 | |
| 6293 | auto pinnedState = frameView->edgePinnedState(); |
| 6294 | if (pinnedState != m_cachedMainFramePinnedState) { |
| 6295 | send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(pinnedState)); |
| 6296 | m_cachedMainFramePinnedState = pinnedState; |
| 6297 | } |
| 6298 | } |
| 6299 | |
| 6300 | void WebPage::mainFrameDidLayout() |
| 6301 | { |
| 6302 | ScriptDisallowedScope::InMainThread scriptDisallowedScope; |
| 6303 | |
| 6304 | unsigned pageCount = protect(corePage())->pageCountAssumingLayoutIsUpToDate(); |
| 6305 | if (pageCount != m_cachedPageCount) { |
| 6306 | send(Messages::WebPageProxy::DidChangePageCount(pageCount)); |
| 6307 | m_cachedPageCount = pageCount; |
| 6308 | } |
| 6309 | |
| 6310 | #if PLATFORM(COCOA)(defined 1 && 1) || PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 6311 | if (RefPtr viewGestureGeometryCollector = m_viewGestureGeometryCollector) |
| 6312 | viewGestureGeometryCollector->mainFrameDidLayout(); |
| 6313 | #endif |
| 6314 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 6315 | if (RefPtr frameView = localMainFrameView()) { |
| 6316 | IntSize newContentSize = frameView->contentsSize(); |
| 6317 | LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier.toUInt64() << " mainFrameDidLayout setting content size to " << newContentSize)((void)0); |
| 6318 | if (m_viewportConfiguration.setContentsSize(newContentSize)) |
| 6319 | viewportConfigurationChanged(); |
| 6320 | } |
| 6321 | #endif |
| 6322 | } |
| 6323 | |
| 6324 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 6325 | |
| 6326 | void WebPage::addPluginView(PluginView& pluginView) |
| 6327 | { |
| 6328 | ASSERT(!m_pluginViews.contains(pluginView))((void)0); |
| 6329 | m_pluginViews.add(pluginView); |
| 6330 | } |
| 6331 | |
| 6332 | void WebPage::removePluginView(PluginView& pluginView) |
| 6333 | { |
| 6334 | ASSERT(m_pluginViews.contains(pluginView))((void)0); |
| 6335 | m_pluginViews.remove(pluginView); |
| 6336 | } |
| 6337 | |
| 6338 | #endif // ENABLE(PDF_PLUGIN) |
| 6339 | |
| 6340 | void WebPage::sendSetWindowFrame(const FloatRect& windowFrame) |
| 6341 | { |
| 6342 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 6343 | m_hasCachedWindowFrame = false; |
| 6344 | #endif |
| 6345 | send(Messages::WebPageProxy::SetWindowFrame(windowFrame)); |
| 6346 | } |
| 6347 | |
| 6348 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 6349 | |
| 6350 | void WebPage::windowAndViewFramesChanged(const ViewWindowCoordinates& coordinates, CompletionHandler<void()>&& completionHandler) |
| 6351 | { |
| 6352 | m_windowFrameInScreenCoordinates = coordinates.windowFrameInScreenCoordinates; |
| 6353 | m_windowFrameInUnflippedScreenCoordinates = coordinates.windowFrameInUnflippedScreenCoordinates; |
| 6354 | m_viewFrameInWindowCoordinates = coordinates.viewFrameInWindowCoordinates; |
| 6355 | |
| 6356 | m_accessibilityPosition = coordinates.accessibilityViewCoordinates; |
| 6357 | #if ENABLE(ACCESSIBILITY_ISOLATED_TREE)(defined ENABLE_ACCESSIBILITY_ISOLATED_TREE && ENABLE_ACCESSIBILITY_ISOLATED_TREE ) |
| 6358 | cacheAXPosition(m_accessibilityPosition); |
| 6359 | #endif |
| 6360 | |
| 6361 | m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty(); |
| 6362 | |
| 6363 | if (completionHandler) |
| 6364 | completionHandler(); |
| 6365 | } |
| 6366 | |
| 6367 | void WebPage::updateMouseEventTargetAfterWindowAndViewFramesChanged(const DoublePoint& mousePositionInView, const DoublePoint& currentMouseGlobalPosition) |
| 6368 | { |
| 6369 | RefPtr localMainFrame = m_mainFrame->coreLocalFrame(); |
| 6370 | if (!localMainFrame) |
| 6371 | return; |
| 6372 | |
| 6373 | setLastKnownMousePosition(localMainFrame->frameID(), mousePositionInView, currentMouseGlobalPosition); |
| 6374 | localMainFrame->eventHandler().updateMouseEventTargetAfterLayoutIfNeeded(); |
| 6375 | } |
| 6376 | |
| 6377 | #endif |
| 6378 | |
| 6379 | void WebPage::setMainFrameIsScrollable(bool isScrollable) |
| 6380 | { |
| 6381 | m_mainFrameIsScrollable = isScrollable; |
| 6382 | protect(drawingArea())->mainFrameScrollabilityChanged(isScrollable); |
| 6383 | |
| 6384 | if (RefPtr frameView = m_mainFrame->coreLocalFrame()->view()) { |
| 6385 | frameView->setCanHaveScrollbars(isScrollable); |
| 6386 | frameView->setProhibitsScrolling(!isScrollable); |
| 6387 | } |
| 6388 | } |
| 6389 | |
| 6390 | bool WebPage::windowIsFocused() const |
| 6391 | { |
| 6392 | return m_page->focusController().isActive(); |
| 6393 | } |
| 6394 | |
| 6395 | bool WebPage::windowAndWebPageAreFocused() const |
| 6396 | { |
| 6397 | return isVisible() && m_page->focusController().isFocused() && m_page->focusController().isActive(); |
| 6398 | } |
| 6399 | |
| 6400 | bool WebPage::dispatchMessage(IPC::Connection& connection, IPC::Decoder& decoder) |
| 6401 | { |
| 6402 | if (decoder.messageReceiverName() == Messages::WebInspectorBackend::messageReceiverName()) { |
| 6403 | if (RefPtr inspector = this->inspector()) |
| 6404 | inspector->didReceiveMessage(connection, decoder); |
| 6405 | return true; |
| 6406 | } |
| 6407 | |
| 6408 | if (decoder.messageReceiverName() == Messages::WebInspectorUI::messageReceiverName()) { |
| 6409 | if (RefPtr inspectorUI = this->inspectorUI()) |
| 6410 | inspectorUI->didReceiveMessage(connection, decoder); |
| 6411 | return true; |
| 6412 | } |
| 6413 | |
| 6414 | if (decoder.messageReceiverName() == Messages::RemoteWebInspectorUI::messageReceiverName()) { |
| 6415 | if (RefPtr remoteInspectorUI = this->remoteInspectorUI()) |
| 6416 | remoteInspectorUI->didReceiveMessage(connection, decoder); |
| 6417 | return true; |
| 6418 | } |
| 6419 | |
| 6420 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 6421 | if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) { |
| 6422 | protect(fullScreenManager())->didReceiveMessage(connection, decoder); |
| 6423 | return true; |
| 6424 | } |
| 6425 | #endif |
| 6426 | return false; |
| 6427 | } |
| 6428 | |
| 6429 | #if ENABLE(ASYNC_SCROLLING)(defined 1 && 1) |
| 6430 | ScrollingCoordinator* WebPage::scrollingCoordinator() const |
| 6431 | { |
| 6432 | return protect(corePage())->scrollingCoordinator(); |
| 6433 | } |
| 6434 | |
| 6435 | #endif |
| 6436 | |
| 6437 | WebPage::SandboxExtensionTracker::~SandboxExtensionTracker() |
| 6438 | { |
| 6439 | invalidate(); |
| 6440 | } |
| 6441 | |
| 6442 | void WebPage::SandboxExtensionTracker::invalidate() |
| 6443 | { |
| 6444 | m_pendingProvisionalSandboxExtension = nullptr; |
| 6445 | |
| 6446 | if (RefPtr extension = std::exchange(m_provisionalSandboxExtension, nullptr)) |
| 6447 | extension->revoke(); |
| 6448 | |
| 6449 | if (RefPtr extension = std::exchange(m_committedSandboxExtension, nullptr)) |
| 6450 | extension->revoke(); |
| 6451 | } |
| 6452 | |
| 6453 | void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(RefPtr<SandboxExtension>&& pendingDropSandboxExtension) |
| 6454 | { |
| 6455 | setPendingProvisionalSandboxExtension(WTF::move(pendingDropSandboxExtension)); |
| 6456 | } |
| 6457 | |
| 6458 | void WebPage::SandboxExtensionTracker::beginLoad(SandboxExtension::Handle&& handle) |
| 6459 | { |
| 6460 | setPendingProvisionalSandboxExtension(SandboxExtension::create(WTF::move(handle))); |
| 6461 | } |
| 6462 | |
| 6463 | void WebPage::SandboxExtensionTracker::beginReload(WebFrame* frame, SandboxExtension::Handle&& handle) |
| 6464 | { |
| 6465 | ASSERT_UNUSED(frame, frame->isMainFrame())((void)frame); |
| 6466 | |
| 6467 | // Maintain existing provisional SandboxExtension in case of a reload, if the new handle is null. This is needed |
| 6468 | // because the UIProcess sends us a null handle if it already sent us a handle for this path in the past. |
| 6469 | if (auto sandboxExtension = SandboxExtension::create(WTF::move(handle))) |
| 6470 | setPendingProvisionalSandboxExtension(WTF::move(sandboxExtension)); |
| 6471 | } |
| 6472 | |
| 6473 | void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(RefPtr<SandboxExtension>&& pendingProvisionalSandboxExtension) |
| 6474 | { |
| 6475 | m_pendingProvisionalSandboxExtension = WTF::move(pendingProvisionalSandboxExtension); |
| 6476 | } |
| 6477 | |
| 6478 | bool WebPage::SandboxExtensionTracker::shouldReuseCommittedSandboxExtension(WebFrame* frame) |
| 6479 | { |
| 6480 | ASSERT(frame->isMainFrame())((void)0); |
| 6481 | |
| 6482 | FrameLoader& frameLoader = frame->coreLocalFrame()->loader(); |
| 6483 | FrameLoadType frameLoadType = frameLoader.loadType(); |
| 6484 | |
| 6485 | // If the page is being reloaded, it should reuse whatever extension is committed. |
| 6486 | if (isReload(frameLoadType)) |
| 6487 | return true; |
| 6488 | |
| 6489 | if (m_pendingProvisionalSandboxExtension) |
| 6490 | return false; |
| 6491 | |
| 6492 | RefPtr documentLoader = frameLoader.documentLoader(); |
| 6493 | RefPtr provisionalDocumentLoader = frameLoader.provisionalDocumentLoader(); |
| 6494 | if (!documentLoader || !provisionalDocumentLoader) |
| 6495 | return false; |
| 6496 | |
| 6497 | if (documentLoader->url().protocolIsFile() && provisionalDocumentLoader->url().protocolIsFile()) |
| 6498 | return true; |
| 6499 | |
| 6500 | return false; |
| 6501 | } |
| 6502 | |
| 6503 | void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame) |
| 6504 | { |
| 6505 | if (!frame->isMainFrame()) |
| 6506 | return; |
| 6507 | |
| 6508 | // We should only reuse the commited sandbox extension if it is not null. It can be |
| 6509 | // null if the last load was for an error page. |
| 6510 | if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) |
| 6511 | m_pendingProvisionalSandboxExtension = m_committedSandboxExtension; |
| 6512 | |
| 6513 | ASSERT(!m_provisionalSandboxExtension)((void)0); |
| 6514 | |
| 6515 | m_provisionalSandboxExtension = WTF::move(m_pendingProvisionalSandboxExtension); |
| 6516 | if (RefPtr extension = m_provisionalSandboxExtension) |
| 6517 | extension->consume(); |
| 6518 | } |
| 6519 | |
| 6520 | void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame) |
| 6521 | { |
| 6522 | if (!frame->isMainFrame()) |
| 6523 | return; |
| 6524 | |
| 6525 | if (RefPtr committedSandboxExtension = m_committedSandboxExtension) |
| 6526 | committedSandboxExtension->revoke(); |
| 6527 | |
| 6528 | m_committedSandboxExtension = WTF::move(m_provisionalSandboxExtension); |
| 6529 | |
| 6530 | // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started. |
| 6531 | // This extension is not cleared, because it does not pertain to the failed load, and will be needed. |
| 6532 | } |
| 6533 | |
| 6534 | void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame) |
| 6535 | { |
| 6536 | if (!frame->isMainFrame()) |
| 6537 | return; |
| 6538 | |
| 6539 | if (RefPtr extension = std::exchange(m_provisionalSandboxExtension, nullptr)) |
| 6540 | extension->revoke(); |
| 6541 | |
| 6542 | // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started |
| 6543 | // (notably, if the current one fails because the new one cancels it). This extension is not cleared, |
| 6544 | // because it does not pertain to the failed load, and will be needed. |
| 6545 | } |
| 6546 | |
| 6547 | void WebPage::setCustomTextEncodingName(const String& encoding) |
| 6548 | { |
| 6549 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 6550 | localMainFrame->loader().reloadWithOverrideEncoding(encoding); |
| 6551 | } |
| 6552 | |
| 6553 | void WebPage::didRemoveBackForwardItem(BackForwardFrameItemIdentifier frameItemID) |
| 6554 | { |
| 6555 | WebBackForwardListProxy::removeItem(frameItemID); |
| 6556 | } |
| 6557 | |
| 6558 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 6559 | void WebPage::setCaretAnimatorType(WebCore::CaretAnimatorType caretType) |
| 6560 | { |
| 6561 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6562 | if (!frame) |
| 6563 | return; |
| 6564 | |
| 6565 | protect(frame->selection())->caretAnimatorInvalidated(caretType); |
| 6566 | } |
| 6567 | |
| 6568 | void WebPage::setCaretBlinkingSuspended(bool suspended) |
| 6569 | { |
| 6570 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 6571 | if (!frame) |
| 6572 | return; |
| 6573 | |
| 6574 | protect(frame->selection())->setCaretBlinkingSuspended(suspended); |
| 6575 | } |
| 6576 | |
| 6577 | #endif |
| 6578 | |
| 6579 | void WebPage::setUseColorAppearance(bool useDarkAppearance, bool useElevatedUserInterfaceLevel) |
| 6580 | { |
| 6581 | protect(corePage())->setUseColorAppearance(useDarkAppearance, useElevatedUserInterfaceLevel); |
| 6582 | |
| 6583 | if (RefPtr inspectorUI = m_inspectorUI) |
| 6584 | inspectorUI->effectiveAppearanceDidChange(useDarkAppearance ? WebCore::InspectorFrontendClient::Appearance::Dark : WebCore::InspectorFrontendClient::Appearance::Light); |
| 6585 | |
| 6586 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 6587 | for (Ref pluginView : m_pluginViews) |
| 6588 | pluginView->effectiveAppearanceDidChange(); |
| 6589 | #endif |
| 6590 | } |
| 6591 | |
| 6592 | void WebPage::swipeAnimationDidStart() |
| 6593 | { |
| 6594 | freezeLayerTree(LayerTreeFreezeReason::SwipeAnimation); |
| 6595 | corePage()->setIsInSwipeAnimation(true); |
| 6596 | } |
| 6597 | |
| 6598 | void WebPage::swipeAnimationDidEnd() |
| 6599 | { |
| 6600 | unfreezeLayerTree(LayerTreeFreezeReason::SwipeAnimation); |
| 6601 | corePage()->setIsInSwipeAnimation(false); |
| 6602 | } |
| 6603 | |
| 6604 | void WebPage::beginPrinting(FrameIdentifier frameID, const PrintInfo& printInfo) |
| 6605 | { |
| 6606 | RELEASE_LOG(Printing, "Begin printing.")clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogPrinting .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("Begin printing."), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG83" ) = "Begin printing."; uint8_t _Alignas(16) __attribute__((uninitialized )) _os_fmt_buf[__builtin_os_log_format_buffer_size("Begin printing." )]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "Begin printing." ), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; |
| 6607 | |
| 6608 | PrintContextAccessScope scope { *this }; |
| 6609 | |
| 6610 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 6611 | if (!frame) |
| 6612 | return; |
| 6613 | |
| 6614 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 6615 | if (!coreFrame) |
| 6616 | return; |
| 6617 | |
| 6618 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 6619 | if (pdfDocumentForPrintingFrame(coreFrame.get())) |
| 6620 | return; |
| 6621 | #endif |
| 6622 | |
| 6623 | if (!m_printContext) { |
| 6624 | m_printContext = PrintContext::create(coreFrame.get()); |
| 6625 | protect(corePage())->dispatchBeforePrintEvent(); |
| 6626 | } |
| 6627 | RefPtr printContext = m_printContext; |
| 6628 | |
| 6629 | freezeLayerTree(LayerTreeFreezeReason::Printing); |
| 6630 | |
| 6631 | auto computedPageSize = printContext->computedPageSize(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight), printInfo.margin); |
| 6632 | |
| 6633 | printContext->begin(computedPageSize.width(), computedPageSize.height()); |
| 6634 | |
| 6635 | // PrintContext::begin() performed a synchronous layout which might have executed a |
| 6636 | // script that closed the WebPage, clearing m_printContext. |
| 6637 | // See <rdar://problem/49731211> for cases of this happening. |
| 6638 | printContext = m_printContext; |
| 6639 | if (!printContext) { |
| 6640 | unfreezeLayerTree(LayerTreeFreezeReason::Printing); |
| 6641 | return; |
| 6642 | } |
| 6643 | |
| 6644 | float fullPageHeight; |
| 6645 | printContext->computePageRects(FloatRect(0, 0, computedPageSize.width(), computedPageSize.height()), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true); |
| 6646 | |
| 6647 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 6648 | if (!m_printOperation) |
| 6649 | m_printOperation = makeUnique<WebPrintOperationGtk>(printInfo); |
| 6650 | #endif |
| 6651 | } |
| 6652 | |
| 6653 | void WebPage::endPrinting(CompletionHandler<void()>&& completionHandler) |
| 6654 | { |
| 6655 | RELEASE_LOG(Printing, "End printing.")clang diagnostic push
clang diagnostic ignored "-Wunknown-warning-option" clang diagnostic ignored "-Wunsafe-buffer-usage" clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call" clang diagnostic ignored "-Wunsafe-buffer-usage-in-format-attr-call" [[clang ::suppress]] __extension__({ os_log_t _log_tmp = (WebKit2LogPrinting .osLogChannel); os_log_type_t _type_tmp = (OS_LOG_TYPE_DEFAULT ); if (os_log_type_enabled(_log_tmp, _type_tmp)) { __extension__ ({ clang diagnostic push clang diagnostic ignored "-Wvla" clang diagnostic error "-Wformat" _Static_assert(__builtin_constant_p ("End printing."), "format/label/description argument must be a string constant" ); __attribute__((section("__TEXT,__oslogstring,cstring_literals" ),internal_linkage)) static const char _os_fmt_str[] __asm("LOS_LOG84" ) = "End printing."; uint8_t _Alignas(16) __attribute__((uninitialized )) _os_fmt_buf[__builtin_os_log_format_buffer_size("End printing." )]; _os_log_impl(&__dso_handle, _log_tmp, _type_tmp, _os_fmt_str , (uint8_t *)__builtin_os_log_format(_os_fmt_buf, "End printing." ), (uint32_t)sizeof(_os_fmt_buf)) clang diagnostic pop ; }); } }) clang diagnostic pop ; |
| 6656 | |
| 6657 | if (m_inActivePrintContextAccessScope) { |
| 6658 | m_shouldEndPrintingImmediately = true; |
| 6659 | completionHandler(); |
| 6660 | return; |
| 6661 | } |
| 6662 | endPrintingImmediately(); |
| 6663 | completionHandler(); |
| 6664 | } |
| 6665 | |
| 6666 | void WebPage::endPrintingImmediately() |
| 6667 | { |
| 6668 | RELEASE_ASSERT(!m_inActivePrintContextAccessScope)do { if (__builtin_expect(!!(!(!m_inActivePrintContextAccessScope )), 0)) do { WTF::isIntegralOrPointerType(); compilerFenceForCrash (); WTFCrashWithInfo(6668, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); } while (0); |
| 6669 | m_shouldEndPrintingImmediately = false; |
| 6670 | |
| 6671 | unfreezeLayerTree(LayerTreeFreezeReason::Printing); |
| 6672 | |
| 6673 | if (m_printContext) { |
| 6674 | m_printContext = nullptr; |
| 6675 | protect(corePage())->dispatchAfterPrintEvent(); |
| 6676 | } |
| 6677 | } |
| 6678 | |
| 6679 | void WebPage::computePagesForPrinting(FrameIdentifier frameID, const PrintInfo& printInfo, CompletionHandler<void(const Vector<WebCore::IntRect>&, double, const WebCore::FloatBoxExtent&)>&& completionHandler) |
| 6680 | { |
| 6681 | PrintContextAccessScope scope { *this }; |
| 6682 | Vector<IntRect> resultPageRects; |
| 6683 | double resultTotalScaleFactorForPrinting = 1; |
| 6684 | auto computedPageMargin = printInfo.margin; |
| 6685 | computePagesForPrintingImpl(frameID, printInfo, resultPageRects, resultTotalScaleFactorForPrinting, computedPageMargin); |
| 6686 | completionHandler(resultPageRects, resultTotalScaleFactorForPrinting, computedPageMargin); |
| 6687 | } |
| 6688 | |
| 6689 | void WebPage::computePagesForPrintingImpl(FrameIdentifier frameID, const PrintInfo& printInfo, Vector<WebCore::IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting, FloatBoxExtent& computedPageMargin) |
| 6690 | { |
| 6691 | ASSERT(resultPageRects.isEmpty())((void)0); |
| 6692 | |
| 6693 | beginPrinting(frameID, printInfo); |
| 6694 | |
| 6695 | if (RefPtr printContext = m_printContext) { |
| 6696 | PrintContextAccessScope scope { *this }; |
| 6697 | resultPageRects = printContext->pageRects(); |
| 6698 | computedPageMargin = printContext->computedPageMargin(printInfo.margin); |
| 6699 | auto computedPageSize = printContext->computedPageSize(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight), printInfo.margin); |
| 6700 | resultTotalScaleFactorForPrinting = printContext->computeAutomaticScaleFactor(computedPageSize) * printInfo.pageSetupScaleFactor; |
| 6701 | } |
| 6702 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 6703 | else |
| 6704 | computePagesForPrintingPDFDocument(frameID, printInfo, resultPageRects); |
| 6705 | #endif // PLATFORM(COCOA) |
| 6706 | |
| 6707 | // If we're asked to print, we should actually print at least a blank page. |
| 6708 | if (resultPageRects.isEmpty()) |
| 6709 | resultPageRects.append(IntRect(0, 0, 1, 1)); |
| 6710 | } |
| 6711 | |
| 6712 | void WebPage::paintRemoteFrameContents(FrameIdentifier frameID, const IntRect& rect, GraphicsContext& context) |
| 6713 | { |
| 6714 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 6715 | // Painting remote frames supported only for snapshot purposes. |
| 6716 | if (!m_remoteSnapshotState || m_remoteSnapshotState->recorder.ptr() != &context) |
| 6717 | return; |
| 6718 | sendWithAsyncReply(Messages::WebPageProxy::DrawFrameToSnapshot(frameID, rect, m_remoteSnapshotState->identifier), Ref { m_remoteSnapshotState->callback }->chain()); |
| 6719 | m_remoteSnapshotState->recorder->drawSnapshotFrame(frameID); |
| 6720 | #else |
| 6721 | UNUSED_PARAM(frameID)(void)frameID; |
| 6722 | UNUSED_PARAM(rect)(void)rect; |
| 6723 | UNUSED_PARAM(context)(void)context; |
| 6724 | #endif |
| 6725 | } |
| 6726 | |
| 6727 | void WebPage::drawToSnapshot(const std::optional<FloatRect>& rect, bool allowTransparentBackground, RemoteSnapshotIdentifier snapshotIdentifier, CompletionHandler<void(std::optional<IntSize>)>&& completionHandler) |
| 6728 | { |
| 6729 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 6730 | ASSERT(m_page->settings().remoteSnapshottingEnabled())((void)0); |
| 6731 | |
| 6732 | RefPtr localMainFrame = this->localMainFrame(); |
| 6733 | |
| 6734 | if (!localMainFrame) { |
| 6735 | completionHandler(std::nullopt); |
| 6736 | return; |
| 6737 | } |
| 6738 | |
| 6739 | Ref frameView = *localMainFrame->view(); |
| 6740 | auto snapshotRect = IntRect { rect.value_or(FloatRect { { }, frameView->contentsSize() }) }; |
| 6741 | auto snapshotSize = snapshotRect.size(); |
| 6742 | |
| 6743 | Ref remoteRenderingBackend = ensureRemoteRenderingBackendProxy(); |
| 6744 | m_remoteSnapshotState = { |
| 6745 | snapshotIdentifier, |
| 6746 | remoteRenderingBackend->createSnapshotRecorder(snapshotIdentifier), |
| 6747 | MainRunLoopSuccessCallbackAggregator::create([completionHandler = WTF::move(completionHandler), snapshotSize] (bool success) mutable { |
| 6748 | completionHandler(success ? std::optional<IntSize>(snapshotSize) : std::nullopt); |
| 6749 | }) |
| 6750 | }; |
| 6751 | |
| 6752 | drawMainFrameToPDF(*localMainFrame, m_remoteSnapshotState->recorder, snapshotRect, allowTransparentBackground); |
| 6753 | |
| 6754 | remoteRenderingBackend->sinkSnapshotRecorderIntoSnapshotFrame(WTF::move(m_remoteSnapshotState->recorder), localMainFrame->frameID(), Ref { m_remoteSnapshotState->callback }->chain()); |
| 6755 | m_remoteSnapshotState = std::nullopt; |
| 6756 | #else |
| 6757 | UNUSED_PARAM(rect)(void)rect; |
| 6758 | UNUSED_PARAM(allowTransparentBackground)(void)allowTransparentBackground; |
| 6759 | UNUSED_PARAM(snapshotIdentifier)(void)snapshotIdentifier; |
| 6760 | UNUSED_PARAM(completionHandler)(void)completionHandler; |
| 6761 | #endif |
| 6762 | } |
| 6763 | |
| 6764 | void WebPage::drawFrameToSnapshot(FrameIdentifier frameID, const IntRect& rect, RemoteSnapshotIdentifier snapshotIdentifier, CompletionHandler<void(bool)>&& completionHandler) |
| 6765 | { |
| 6766 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 6767 | ASSERT(m_page->settings().siteIsolationEnabled())((void)0); |
| 6768 | |
| 6769 | // FIXME: Error handling, so that the GPUP doesn't wait for something not coming. |
| 6770 | |
| 6771 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 6772 | if (!webFrame) { |
| 6773 | ASSERT_NOT_REACHED()((void)0); |
| 6774 | completionHandler(false); |
| 6775 | return; |
| 6776 | } |
| 6777 | |
| 6778 | RefPtr coreLocalFrame = webFrame->coreLocalFrame(); |
| 6779 | if (!coreLocalFrame) { |
| 6780 | ASSERT_NOT_REACHED()((void)0); |
| 6781 | completionHandler(false); |
| 6782 | return; |
| 6783 | } |
| 6784 | |
| 6785 | RefPtr frameView = coreLocalFrame->view(); |
| 6786 | if (!frameView) { |
| 6787 | completionHandler(false); |
| 6788 | return; |
| 6789 | } |
| 6790 | |
| 6791 | Ref remoteRenderingBackend = ensureRemoteRenderingBackendProxy(); |
| 6792 | m_remoteSnapshotState = { snapshotIdentifier, remoteRenderingBackend->createSnapshotRecorder(snapshotIdentifier), MainRunLoopSuccessCallbackAggregator::create(WTF::move(completionHandler)) }; |
| 6793 | |
| 6794 | LocalFrameView::SelectionInSnapshot shouldPaintSelection = LocalFrameView::IncludeSelection; |
| 6795 | LocalFrameView::CoordinateSpaceForSnapshot coordinateSpace = LocalFrameView::DocumentCoordinates; |
| 6796 | |
| 6797 | frameView->paintContentsForSnapshot(m_remoteSnapshotState->recorder, rect, shouldPaintSelection, coordinateSpace); |
| 6798 | |
| 6799 | remoteRenderingBackend->sinkSnapshotRecorderIntoSnapshotFrame(WTF::move(m_remoteSnapshotState->recorder), frameID, Ref { m_remoteSnapshotState->callback }->chain()); |
| 6800 | |
| 6801 | m_remoteSnapshotState = std::nullopt; |
| 6802 | #else |
| 6803 | UNUSED_PARAM(frameID)(void)frameID; |
| 6804 | UNUSED_PARAM(rect)(void)rect; |
| 6805 | UNUSED_PARAM(snapshotIdentifier)(void)snapshotIdentifier; |
| 6806 | UNUSED_PARAM(completionHandler)(void)completionHandler; |
| 6807 | #endif |
| 6808 | } |
| 6809 | |
| 6810 | void WebPage::drawMainFrameToPDF(LocalFrame& localMainFrame, GraphicsContext& context, IntRect& snapshotRect, bool allowTransparentBackground) |
| 6811 | { |
| 6812 | Ref frameView = *localMainFrame.view(); |
| 6813 | |
| 6814 | auto originalLayoutViewportOverrideRect = frameView->layoutViewportOverrideRect(); |
| 6815 | frameView->setLayoutViewportOverrideRect(LayoutRect(snapshotRect)); |
| 6816 | auto originalPaintBehavior = frameView->paintBehavior(); |
| 6817 | |
| 6818 | frameView->setPaintBehavior(originalPaintBehavior | PaintBehavior::AnnotateLinks); |
| 6819 | |
| 6820 | auto originalColor = frameView->baseBackgroundColor(); |
| 6821 | if (allowTransparentBackground) { |
| 6822 | frameView->setTransparent(true); |
| 6823 | frameView->setBaseBackgroundColor(Color::transparentBlack); |
| 6824 | } |
| 6825 | |
| 6826 | pdfSnapshotAtSize(localMainFrame, context, snapshotRect, { }); |
| 6827 | |
| 6828 | if (allowTransparentBackground) { |
| 6829 | frameView->setTransparent(false); |
| 6830 | frameView->setBaseBackgroundColor(originalColor); |
| 6831 | } |
| 6832 | |
| 6833 | frameView->setLayoutViewportOverrideRect(originalLayoutViewportOverrideRect); |
| 6834 | frameView->setPaintBehavior(originalPaintBehavior); |
| 6835 | } |
| 6836 | |
| 6837 | void WebPage::pdfSnapshotAtSize(LocalFrame& localMainFrame, GraphicsContext& context, const IntRect& snapshotRect, SnapshotOptions options) |
| 6838 | { |
| 6839 | Ref frameView = *localMainFrame.view(); |
| 6840 | |
| 6841 | auto rect = snapshotRect; |
| 6842 | auto bitmapSize = rect.size(); |
| 6843 | |
| 6844 | int64_t remainingHeight = bitmapSize.height(); |
| 6845 | int64_t nextRectY = rect.y(); |
| 6846 | while (remainingHeight > 0) { |
| 6847 | // PDFs have a per-page height limit of 200 inches at 72dpi. |
| 6848 | // We'll export one PDF page at a time, up to that maximum height. |
| 6849 | static const int64_t maxPageHeight = 72 * 200; |
| 6850 | bitmapSize.setHeight(std::min(remainingHeight, maxPageHeight)); |
| 6851 | rect.setHeight(bitmapSize.height()); |
| 6852 | rect.setY(nextRectY); |
| 6853 | |
| 6854 | context.beginPage(FloatRect { { }, bitmapSize }); |
| 6855 | context.scale({ 1, -1 }); |
| 6856 | context.translate(0, -bitmapSize.height()); |
| 6857 | |
| 6858 | paintSnapshotAtSize(rect, bitmapSize, options, localMainFrame, frameView, context); |
| 6859 | |
| 6860 | context.endPage(); |
| 6861 | |
| 6862 | nextRectY += bitmapSize.height(); |
| 6863 | remainingHeight -= maxPageHeight; |
| 6864 | } |
| 6865 | } |
| 6866 | |
| 6867 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 6868 | void WebPage::drawPagesForPrinting(FrameIdentifier frameID, const PrintInfo& printInfo, CompletionHandler<void(std::optional<SharedMemory::Handle>&&, WebCore::ResourceError&&)>&& completionHandler) |
| 6869 | { |
| 6870 | beginPrinting(frameID, printInfo); |
| 6871 | if (RefPtr printContext = m_printContext; printContext && m_printOperation) { |
| 6872 | m_printOperation->startPrint(printContext.get(), [this, protectedThis = Ref { *this }, completionHandler = WTF::move(completionHandler)] (RefPtr<WebCore::FragmentedSharedBuffer>&& data, WebCore::ResourceError&& error) mutable { |
| 6873 | m_printOperation = nullptr; |
| 6874 | std::optional<SharedMemory::Handle> ipcHandle; |
| 6875 | if (error.isNull()) { |
| 6876 | auto sharedMemory = SharedMemory::copyBuffer(*data); |
| 6877 | ipcHandle = sharedMemory->createHandle(SharedMemory::Protection::ReadOnly); |
| 6878 | } |
| 6879 | completionHandler(WTF::move(ipcHandle), WTF::move(error)); |
| 6880 | }); |
| 6881 | return; |
| 6882 | } |
| 6883 | completionHandler(std::nullopt, { }); |
| 6884 | } |
| 6885 | #endif |
| 6886 | |
| 6887 | void WebPage::addResourceRequest(WebCore::ResourceLoaderIdentifier identifier, const WebCore::ResourceRequest& request, const DocumentLoader* loader, LocalFrame* frame) |
| 6888 | { |
| 6889 | bool isHTTPRequest = request.url().protocolIsInHTTPFamily(); |
| 6890 | |
| 6891 | // Ignore main resource loads here, since they can start in one process and end up in another. |
| 6892 | // See 283102@main for an explanation for how we handle main resource loads. We also ignore |
| 6893 | // very low priority loads like ping and beacon requests to match previous PLT heuristics. |
| 6894 | // We consider file requests as part of the PLT network heuristic for ease of API testing. |
| 6895 | if (frame && request.requester() != ResourceRequestRequester::Main && request.priority() != WebCore::ResourceLoadPriority::VeryLow && (isHTTPRequest || request.url().protocolIsFile())) { |
| 6896 | auto frameID = frame->frameID(); |
| 6897 | auto& identifiers = m_networkResourceRequestIdentifiersForPageLoadTiming.ensure(frameID, [] { |
| 6898 | return HashSet<WebCore::ResourceLoaderIdentifier> { }; |
| 6899 | }).iterator->value; |
| 6900 | if (identifiers.isEmpty()) |
| 6901 | send(Messages::WebPageProxy::StartNetworkRequestsForPageLoadTiming(frameID)); |
| 6902 | identifiers.add(identifier); |
| 6903 | } |
| 6904 | |
| 6905 | if (!isHTTPRequest) |
| 6906 | return; |
| 6907 | |
| 6908 | if (m_mainFrameProgressCompleted && !UserGestureIndicator::processingUserGesture()) |
| 6909 | return; |
| 6910 | |
| 6911 | ASSERT(!m_trackedNetworkResourceRequestIdentifiers.contains(identifier))((void)0); |
| 6912 | bool wasEmpty = m_trackedNetworkResourceRequestIdentifiers.isEmpty(); |
| 6913 | m_trackedNetworkResourceRequestIdentifiers.add(identifier); |
| 6914 | if (wasEmpty) |
| 6915 | send(Messages::WebPageProxy::SetNetworkRequestsInProgress(true)); |
| 6916 | } |
| 6917 | |
| 6918 | void WebPage::removeResourceRequest(WebCore::ResourceLoaderIdentifier identifier, LocalFrame* frame) |
| 6919 | { |
| 6920 | if (frame) { |
| 6921 | auto frameID = frame->frameID(); |
| 6922 | if (auto it = m_networkResourceRequestIdentifiersForPageLoadTiming.find(frameID); it != m_networkResourceRequestIdentifiersForPageLoadTiming.end()) { |
| 6923 | if (it->value.remove(identifier) && it->value.isEmpty()) |
| 6924 | send(Messages::WebPageProxy::EndNetworkRequestsForPageLoadTiming(frameID, WallTime::now())); |
| 6925 | } |
| 6926 | } |
| 6927 | |
| 6928 | if (!m_trackedNetworkResourceRequestIdentifiers.remove(identifier)) |
| 6929 | return; |
| 6930 | |
| 6931 | if (m_trackedNetworkResourceRequestIdentifiers.isEmpty()) |
| 6932 | send(Messages::WebPageProxy::SetNetworkRequestsInProgress(false)); |
| 6933 | } |
| 6934 | |
| 6935 | void WebPage::setMediaVolume(float volume) |
| 6936 | { |
| 6937 | protect(corePage())->setMediaVolume(volume); |
| 6938 | } |
| 6939 | |
| 6940 | void WebPage::setMuted(MediaProducerMutedStateFlags state, CompletionHandler<void()>&& completionHandler) |
| 6941 | { |
| 6942 | protect(corePage())->setMuted(state); |
| 6943 | completionHandler(); |
| 6944 | } |
| 6945 | |
| 6946 | void WebPage::stopMediaCapture(MediaProducerMediaCaptureKind kind, CompletionHandler<void()>&& completionHandler) |
| 6947 | { |
| 6948 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) |
| 6949 | protect(corePage())->stopMediaCapture(kind); |
| 6950 | #endif |
| 6951 | completionHandler(); |
| 6952 | } |
| 6953 | |
| 6954 | void WebPage::processWillSuspend() |
| 6955 | { |
| 6956 | if (RefPtr manager = mediaSessionManagerIfExists()) |
| 6957 | manager->processWillSuspend(); |
| 6958 | } |
| 6959 | |
| 6960 | void WebPage::processDidResume() |
| 6961 | { |
| 6962 | if (RefPtr manager = mediaSessionManagerIfExists()) |
| 6963 | manager->processDidResume(); |
| 6964 | } |
| 6965 | |
| 6966 | void WebPage::didReceiveRemoteCommand(PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument) |
| 6967 | { |
| 6968 | if (RefPtr manager = mediaSessionManagerIfExists()) |
| 6969 | manager->processDidReceiveRemoteControlCommand(type, argument); |
| 6970 | } |
| 6971 | |
| 6972 | void WebPage::setMayStartMediaWhenInWindow(bool mayStartMedia) |
| 6973 | { |
| 6974 | if (mayStartMedia == m_mayStartMediaWhenInWindow) |
| 6975 | return; |
| 6976 | |
| 6977 | m_mayStartMediaWhenInWindow = mayStartMedia; |
| 6978 | if (m_mayStartMediaWhenInWindow && m_page->isInWindow()) |
| 6979 | m_setCanStartMediaTimer.startOneShot(0_s); |
| 6980 | } |
| 6981 | |
| 6982 | void WebPage::runModal() |
| 6983 | { |
| 6984 | if (m_isClosed) |
| 6985 | return; |
| 6986 | if (m_isRunningModal) |
| 6987 | return; |
| 6988 | |
| 6989 | m_isRunningModal = true; |
| 6990 | send(Messages::WebPageProxy::RunModal()); |
| 6991 | #if ASSERT_ENABLED0 |
| 6992 | Ref<WebPage> protector(*this); |
| 6993 | #endif |
| 6994 | RunLoop::run(); |
| 6995 | } |
| 6996 | |
| 6997 | bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request) |
| 6998 | { |
| 6999 | if (LegacySchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol())) |
| 7000 | return true; |
| 7001 | |
| 7002 | if (request.url().protocolIsBlob()) |
| 7003 | return true; |
| 7004 | |
| 7005 | return platformCanHandleRequest(request); |
| 7006 | } |
| 7007 | |
| 7008 | void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length, bool suppressUnderline, const Vector<CompositionHighlight>& highlights, const HashMap<String, Vector<WebCore::CharacterRange>>& annotations) |
| 7009 | { |
| 7010 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7011 | if (!frame) |
| 7012 | return; |
| 7013 | |
| 7014 | Ref editor = frame->editor(); |
| 7015 | if (!editor->canEdit()) |
| 7016 | return; |
| 7017 | |
| 7018 | Vector<CompositionUnderline> underlines; |
| 7019 | if (!suppressUnderline) |
| 7020 | underlines.append(CompositionUnderline(0, compositionString.length(), CompositionUnderlineColor::TextColor, Color(Color::black), false)); |
| 7021 | |
| 7022 | editor->setComposition(compositionString, underlines, highlights, annotations, from, from + length); |
| 7023 | } |
| 7024 | |
| 7025 | bool WebPage::hasCompositionForTesting() |
| 7026 | { |
| 7027 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7028 | if (!frame) |
| 7029 | return false; |
| 7030 | |
| 7031 | return frame->editor().hasComposition(); |
| 7032 | } |
| 7033 | |
| 7034 | void WebPage::confirmCompositionForTesting(const String& compositionString) |
| 7035 | { |
| 7036 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7037 | if (!frame) |
| 7038 | return; |
| 7039 | |
| 7040 | Ref editor = frame->editor(); |
| 7041 | if (!editor->canEdit()) |
| 7042 | return; |
| 7043 | |
| 7044 | if (compositionString.isNull()) |
| 7045 | editor->confirmComposition(); |
| 7046 | editor->confirmComposition(compositionString); |
| 7047 | } |
| 7048 | |
| 7049 | void WebPage::wheelEventHandlersChanged(bool hasHandlers) |
| 7050 | { |
| 7051 | if (m_hasWheelEventHandlers == hasHandlers) |
| 7052 | return; |
| 7053 | |
| 7054 | m_hasWheelEventHandlers = hasHandlers; |
| 7055 | recomputeShortCircuitHorizontalWheelEventsState(); |
| 7056 | } |
| 7057 | |
| 7058 | static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea) |
| 7059 | { |
| 7060 | RefPtr scrollbar = scrollableArea->horizontalScrollbar(); |
| 7061 | return scrollbar && scrollbar->enabled(); |
| 7062 | } |
| 7063 | |
| 7064 | static bool pageContainsAnyHorizontalScrollbars(LocalFrame* mainFrame) |
| 7065 | { |
| 7066 | if (!mainFrame) |
| 7067 | return false; |
| 7068 | |
| 7069 | if (RefPtr frameView = mainFrame->view()) { |
| 7070 | if (hasEnabledHorizontalScrollbar(frameView.get())) |
| 7071 | return true; |
| 7072 | } |
| 7073 | |
| 7074 | for (RefPtr<Frame> frame = mainFrame; frame; frame = frame->tree().traverseNext()) { |
| 7075 | RefPtr localFrame = dynamicDowncast<LocalFrame>(*frame); |
| 7076 | if (!localFrame) |
| 7077 | continue; |
| 7078 | |
| 7079 | RefPtr frameView = localFrame->view(); |
| 7080 | if (!frameView) |
| 7081 | continue; |
| 7082 | |
| 7083 | auto scrollableAreas = frameView->scrollableAreas(); |
| 7084 | if (!scrollableAreas) |
| 7085 | continue; |
| 7086 | |
| 7087 | for (CheckedRef scrollableArea : *scrollableAreas) { |
| 7088 | if (!scrollableArea->scrollbarsCanBeActive()) |
| 7089 | continue; |
| 7090 | |
| 7091 | if (hasEnabledHorizontalScrollbar(scrollableArea.ptr())) |
| 7092 | return true; |
| 7093 | } |
| 7094 | } |
| 7095 | |
| 7096 | return false; |
| 7097 | } |
| 7098 | |
| 7099 | void WebPage::recomputeShortCircuitHorizontalWheelEventsState() |
| 7100 | { |
| 7101 | bool canShortCircuitHorizontalWheelEvents = !m_hasWheelEventHandlers; |
| 7102 | |
| 7103 | if (canShortCircuitHorizontalWheelEvents) { |
| 7104 | // Check if we have any horizontal scroll bars on the page. |
| 7105 | if (pageContainsAnyHorizontalScrollbars(localMainFrame().get())) |
| 7106 | canShortCircuitHorizontalWheelEvents = false; |
| 7107 | } |
| 7108 | |
| 7109 | if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents) |
| 7110 | return; |
| 7111 | |
| 7112 | m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents; |
| 7113 | send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents)); |
| 7114 | } |
| 7115 | |
| 7116 | Frame* WebPage::mainFrame() const |
| 7117 | { |
| 7118 | return m_page ? &m_page->mainFrame() : nullptr; |
| 7119 | } |
| 7120 | |
| 7121 | RefPtr<WebCore::LocalFrame> WebPage::localMainFrame() const |
| 7122 | { |
| 7123 | if (RefPtr page = m_page) |
| 7124 | return page->localMainFrame(); |
| 7125 | return nullptr; |
| 7126 | } |
| 7127 | |
| 7128 | RefPtr<WebCore::Document> WebPage::localTopDocument() const |
| 7129 | { |
| 7130 | if (RefPtr page = m_page) |
| 7131 | return page->localTopDocument(); |
| 7132 | return nullptr; |
| 7133 | } |
| 7134 | |
| 7135 | FrameView* WebPage::mainFrameView() const |
| 7136 | { |
| 7137 | if (RefPtr frame = mainFrame()) |
| 7138 | return frame->virtualView(); |
| 7139 | return nullptr; |
| 7140 | } |
| 7141 | |
| 7142 | LocalFrameView* WebPage::localMainFrameView() const |
| 7143 | { |
| 7144 | return dynamicDowncast<LocalFrameView>(mainFrameView()); |
| 7145 | } |
| 7146 | |
| 7147 | bool WebPage::shouldUseCustomContentProviderForResponse(const ResourceResponse& response) |
| 7148 | { |
| 7149 | auto& mimeType = response.mimeType(); |
| 7150 | if (mimeType.isNull()) |
| 7151 | return false; |
| 7152 | |
| 7153 | return m_mimeTypesWithCustomContentProviders.contains(mimeType); |
| 7154 | } |
| 7155 | |
| 7156 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) || PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) |
| 7157 | |
| 7158 | static RefPtr<LocalFrame> targetFrameForEditing(WebPage& page) |
| 7159 | { |
| 7160 | RefPtr targetFrame = page.corePage()->focusController().focusedOrMainFrame(); |
| 7161 | if (!targetFrame) |
| 7162 | return nullptr; |
| 7163 | |
| 7164 | Editor& editor = targetFrame->editor(); |
| 7165 | if (!editor.canEdit()) |
| 7166 | return nullptr; |
| 7167 | |
| 7168 | if (editor.hasComposition()) { |
| 7169 | // We should verify the parent node of this IME composition node are |
| 7170 | // editable because JavaScript may delete a parent node of the composition |
| 7171 | // node. In this case, WebKit crashes while deleting texts from the parent |
| 7172 | // node, which doesn't exist any longer. |
| 7173 | if (auto range = editor.compositionRange()) { |
| 7174 | if (!range->startContainer().isContentEditable()) |
| 7175 | return nullptr; |
| 7176 | } |
| 7177 | } |
| 7178 | return targetFrame; |
| 7179 | } |
| 7180 | |
| 7181 | void WebPage::cancelComposition(const String& compositionString) |
| 7182 | { |
| 7183 | if (RefPtr targetFrame = targetFrameForEditing(*this)) |
| 7184 | protect(targetFrame->editor())->confirmComposition(compositionString); |
| 7185 | } |
| 7186 | |
| 7187 | void WebPage::deleteSurrounding(int64_t offset, unsigned characterCount) |
| 7188 | { |
| 7189 | RefPtr targetFrame = targetFrameForEditing(*this); |
| 7190 | if (!targetFrame) |
| 7191 | return; |
| 7192 | |
| 7193 | auto& selection = targetFrame->selection().selection(); |
| 7194 | if (selection.isNone()) |
| 7195 | return; |
| 7196 | |
| 7197 | auto selectionStart = selection.visibleStart(); |
| 7198 | auto surroundingRange = makeSimpleRange(startOfEditableContent(selectionStart), selectionStart); |
| 7199 | if (!surroundingRange) |
| 7200 | return; |
| 7201 | |
| 7202 | Ref rootNode = surroundingRange->start.container->treeScope().rootNode(); |
| 7203 | auto characterRange = WebCore::CharacterRange(WebCore::characterCount(*surroundingRange) + offset, characterCount); |
| 7204 | auto selectionRange = resolveCharacterRange(makeRangeSelectingNodeContents(rootNode), characterRange); |
| 7205 | |
| 7206 | targetFrame->editor().setIgnoreSelectionChanges(true); |
| 7207 | protect(targetFrame->selection())->setSelection(VisibleSelection(selectionRange)); |
| 7208 | targetFrame->editor().deleteSelectionWithSmartDelete(false); |
| 7209 | targetFrame->editor().setIgnoreSelectionChanges(false); |
| 7210 | sendEditorStateUpdate(); |
| 7211 | } |
| 7212 | |
| 7213 | #endif |
| 7214 | |
| 7215 | void WebPage::didApplyStyle() |
| 7216 | { |
| 7217 | sendEditorStateUpdate(); |
| 7218 | } |
| 7219 | |
| 7220 | void WebPage::didChangeContents() |
| 7221 | { |
| 7222 | sendEditorStateUpdate(); |
| 7223 | } |
| 7224 | |
| 7225 | void WebPage::didScrollSelection() |
| 7226 | { |
| 7227 | didChangeSelectionOrOverflowScrollPosition(); |
| 7228 | } |
| 7229 | |
| 7230 | void WebPage::didChangeSelection(LocalFrame& frame) |
| 7231 | { |
| 7232 | didChangeSelectionOrOverflowScrollPosition(); |
| 7233 | |
| 7234 | if (m_userIsInteracting && frame.selection().isRange()) |
| 7235 | m_userInteractionsSincePageTransition.add(UserInteractionFlag::SelectedRange); |
| 7236 | |
| 7237 | #if ENABLE(WRITING_TOOLS)(defined 1 && 1) |
| 7238 | protect(corePage())->updateStateForSelectedSuggestionIfNeeded(); |
| 7239 | #endif |
| 7240 | |
| 7241 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7242 | resetLastSelectedReplacementRangeIfNeeded(); |
| 7243 | |
| 7244 | if (!std::exchange(m_sendAutocorrectionContextAfterFocusingElement, false)) |
| 7245 | return; |
| 7246 | |
| 7247 | callOnMainRunLoop([protectedThis = Ref { *this }, frame = Ref { frame }] { |
| 7248 | if (!frame->document() || !frame->document()->hasLivingRenderTree() || frame->selection().isNone()) [[unlikely]] |
| 7249 | return; |
| 7250 | |
| 7251 | protectedThis->preemptivelySendAutocorrectionContext(); |
| 7252 | }); |
| 7253 | #endif // PLATFORM(IOS_FAMILY) |
| 7254 | } |
| 7255 | |
| 7256 | void WebPage::didChangeSelectionOrOverflowScrollPosition() |
| 7257 | { |
| 7258 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7259 | if (!frame) |
| 7260 | return; |
| 7261 | |
| 7262 | // The act of getting Dictionary Popup info can make selection changes that we should not propagate to the UIProcess. |
| 7263 | // Specifically, if there is a caret selection, it will change to a range selection of the word around the caret. And |
| 7264 | // then it will change back. |
| 7265 | if (frame->editor().isGettingDictionaryPopupInfo()) |
| 7266 | return; |
| 7267 | |
| 7268 | // Similarly, we don't want to propagate changes to the web process when inserting text asynchronously, since we will |
| 7269 | // end up with a range selection very briefly right before inserting the text. |
| 7270 | if (m_isSelectingTextWhileInsertingAsynchronously) |
| 7271 | return; |
| 7272 | |
| 7273 | #if HAVE(TOUCH_BAR)(defined HAVE_TOUCH_BAR && HAVE_TOUCH_BAR) |
| 7274 | bool hasPreviouslyFocusedDueToUserInteraction = m_userInteractionsSincePageTransition.contains(UserInteractionFlag::FocusedElement); |
| 7275 | if (m_userIsInteracting && m_focusedElement) |
| 7276 | m_userInteractionsSincePageTransition.add(UserInteractionFlag::FocusedElement); |
| 7277 | |
| 7278 | if (!hasPreviouslyFocusedDueToUserInteraction && m_userInteractionsSincePageTransition.contains(UserInteractionFlag::FocusedElement)) { |
| 7279 | RefPtr document = frame->document(); |
| 7280 | if (document->quirks().isTouchBarUpdateSuppressedForHiddenContentEditable()) { |
| 7281 | m_isTouchBarUpdateSuppressedForHiddenContentEditable = true; |
| 7282 | send(Messages::WebPageProxy::SetIsTouchBarUpdateSuppressedForHiddenContentEditable(m_isTouchBarUpdateSuppressedForHiddenContentEditable)); |
| 7283 | } |
| 7284 | |
| 7285 | if (document->quirks().isNeverRichlyEditableForTouchBar()) { |
| 7286 | m_isNeverRichlyEditableForTouchBar = true; |
| 7287 | send(Messages::WebPageProxy::SetIsNeverRichlyEditableForTouchBar(m_isNeverRichlyEditableForTouchBar)); |
| 7288 | } |
| 7289 | |
| 7290 | send(Messages::WebPageProxy::SetHasFocusedElementWithUserInteraction(true)); |
| 7291 | } |
| 7292 | |
| 7293 | // Abandon the current inline input session if selection changed for any other reason but an input method direct action. |
| 7294 | // FIXME: This logic should be in WebCore. |
| 7295 | // FIXME: Many changes that affect composition node do not go through didChangeSelection(). We need to do something when DOM manipulation affects the composition, because otherwise input method's idea about it will be different from Editor's. |
| 7296 | // FIXME: We can't cancel composition when selection changes to NoSelection, but we probably should. |
| 7297 | Ref editor = frame->editor(); |
| 7298 | if (editor->hasComposition() && !frame->editor().ignoreSelectionChanges() && !frame->selection().isNone()) { |
| 7299 | editor->cancelComposition(); |
| 7300 | if (RefPtr document = frame->document()) |
| 7301 | discardedComposition(*document); |
| 7302 | return; |
| 7303 | } |
| 7304 | #endif // HAVE(TOUCH_BAR) |
| 7305 | |
| 7306 | scheduleFullEditorStateUpdate(); |
| 7307 | } |
| 7308 | |
| 7309 | void WebPage::resetFocusedElementForFrame(WebFrame* frame) |
| 7310 | { |
| 7311 | #if PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) || PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) |
| 7312 | if (frame->isMainFrame() || corePage()->focusController().focusedOrMainFrame() == frame->coreLocalFrame()) |
| 7313 | m_page->editorClient().setInputMethodState(nullptr); |
| 7314 | #endif |
| 7315 | |
| 7316 | if (!m_focusedElement) |
| 7317 | return; |
| 7318 | |
| 7319 | if (frame->isMainFrame() || m_focusedElement->document().frame() == frame->coreLocalFrame()) { |
| 7320 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7321 | m_sendAutocorrectionContextAfterFocusingElement = false; |
| 7322 | send(Messages::WebPageProxy::ElementDidBlur()); |
| 7323 | #elif PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 7324 | send(Messages::WebPageProxy::SetEditableElementIsFocused(false)); |
| 7325 | #endif |
| 7326 | m_focusedElement = nullptr; |
| 7327 | } |
| 7328 | } |
| 7329 | |
| 7330 | void WebPage::elementDidRefocus(Element& element, const FocusOptions& options) |
| 7331 | { |
| 7332 | elementDidFocus(element, options); |
| 7333 | |
| 7334 | if (m_userIsInteracting) |
| 7335 | scheduleFullEditorStateUpdate(); |
| 7336 | } |
| 7337 | |
| 7338 | bool WebPage::shouldDispatchUpdateAfterFocusingElement(const Element& element) const |
| 7339 | { |
| 7340 | if (m_focusedElement == &element || m_recentlyBlurredElement == &element) { |
| 7341 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7342 | return !m_isShowingInputViewForFocusedElement; |
| 7343 | #else |
| 7344 | return false; |
| 7345 | #endif |
| 7346 | } |
| 7347 | return true; |
| 7348 | } |
| 7349 | |
| 7350 | static bool isTextFormControlOrEditableContent(const WebCore::Element& element) |
| 7351 | { |
| 7352 | return is<HTMLTextFormControlElement>(element) || element.hasEditableStyle(); |
| 7353 | } |
| 7354 | |
| 7355 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) && ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 7356 | static bool shouldExitFullscreenAfterFocusingElement(const WebCore::Element& element) |
| 7357 | { |
| 7358 | if (!protect(protect(element.document())->fullscreen())->isFullscreen()) |
| 7359 | return false; |
| 7360 | |
| 7361 | if (RefPtr input = dynamicDowncast<const HTMLInputElement>(element)) |
| 7362 | return input->isTextField(); |
| 7363 | |
| 7364 | return is<HTMLTextAreaElement>(element) || element.hasEditableStyle(); |
| 7365 | } |
| 7366 | #endif |
| 7367 | |
| 7368 | void WebPage::elementDidFocus(Element& element, const FocusOptions& options) |
| 7369 | { |
| 7370 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7371 | m_updateFocusedElementInformationTimer.stop(); |
| 7372 | #endif |
| 7373 | |
| 7374 | if (!shouldDispatchUpdateAfterFocusingElement(element)) { |
| 7375 | updateInputContextAfterBlurringAndRefocusingElementIfNeeded(element); |
| 7376 | m_focusedElement = element; |
| 7377 | m_recentlyBlurredElement = nullptr; |
| 7378 | return; |
| 7379 | } |
| 7380 | |
| 7381 | if (is<HTMLSelectElement>(element) || isTextFormControlOrEditableContent(element)) { |
| 7382 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7383 | bool isChangingFocusedElement = m_focusedElement != &element; |
| 7384 | #endif |
| 7385 | m_focusedElement = element; |
| 7386 | m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = false; |
| 7387 | |
| 7388 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7389 | |
| 7390 | #if ENABLE(FULLSCREEN_API)(defined 1 && 1) |
| 7391 | if (shouldExitFullscreenAfterFocusingElement(element)) |
| 7392 | protect(protect(element.document())->fullscreen())->fullyExitFullscreen(); |
| 7393 | #endif |
| 7394 | if (isChangingFocusedElement && (m_userIsInteracting || m_keyboardIsAttached)) |
| 7395 | m_sendAutocorrectionContextAfterFocusingElement = true; |
| 7396 | |
| 7397 | auto information = focusedElementInformation(); |
| 7398 | if (!information) |
| 7399 | return; |
| 7400 | |
| 7401 | RefPtr<API::Object> userData; |
| 7402 | |
| 7403 | m_formClient->willBeginInputSession(this, &element, protect(WebFrame::fromCoreFrame(*protect(element.document().frame()))).get(), m_userIsInteracting, userData); |
| 7404 | |
| 7405 | if (!userData) { |
| 7406 | auto userInfo = element.userInfo(); |
| 7407 | if (!userInfo.isNull()) { |
| 7408 | if (auto data = JSON::Value::parseJSON(element.userInfo())) |
| 7409 | userData = userDataFromJSONData(*data); |
| 7410 | } |
| 7411 | } |
| 7412 | |
| 7413 | information->preventScroll = options.preventScroll; |
| 7414 | send(Messages::WebPageProxy::ElementDidFocus(information.value(), m_userIsInteracting, m_recentlyBlurredElement, m_lastActivityStateChanges, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 7415 | #elif PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 7416 | // FIXME: This can be unified with the iOS code above by bringing ElementDidFocus to macOS. |
| 7417 | // This also doesn't take other noneditable controls into account, such as input type color. |
| 7418 | send(Messages::WebPageProxy::SetEditableElementIsFocused(!element.hasTagName(WebCore::HTMLNames::selectTag))); |
| 7419 | #endif |
| 7420 | m_recentlyBlurredElement = nullptr; |
| 7421 | } |
| 7422 | } |
| 7423 | |
| 7424 | void WebPage::elementDidBlur(WebCore::Element& element) |
| 7425 | { |
| 7426 | if (m_focusedElement == &element) { |
| 7427 | m_recentlyBlurredElement = WTF::move(m_focusedElement); |
| 7428 | callOnMainRunLoop([protectedThis = Ref { *this }] { |
| 7429 | if (protectedThis->m_recentlyBlurredElement) { |
| 7430 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7431 | protectedThis->send(Messages::WebPageProxy::ElementDidBlur()); |
| 7432 | #elif PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 7433 | protectedThis->send(Messages::WebPageProxy::SetEditableElementIsFocused(false)); |
| 7434 | #endif |
| 7435 | } |
| 7436 | protectedThis->m_recentlyBlurredElement = nullptr; |
| 7437 | }); |
| 7438 | m_hasPendingInputContextUpdateAfterBlurringAndRefocusingElement = false; |
| 7439 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7440 | m_sendAutocorrectionContextAfterFocusingElement = false; |
| 7441 | #endif |
| 7442 | } |
| 7443 | } |
| 7444 | |
| 7445 | void WebPage::focusedElementDidChangeInputMode(WebCore::Element& element, WebCore::InputMode mode) |
| 7446 | { |
| 7447 | if (m_focusedElement != &element) |
| 7448 | return; |
| 7449 | |
| 7450 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7451 | ASSERT(is<HTMLElement>(element))((void)0); |
| 7452 | ASSERT(downcast<HTMLElement>(element).canonicalInputMode() == mode)((void)0); |
| 7453 | |
| 7454 | if (!isTextFormControlOrEditableContent(element)) |
| 7455 | return; |
| 7456 | |
| 7457 | send(Messages::WebPageProxy::FocusedElementDidChangeInputMode(mode)); |
| 7458 | #else |
| 7459 | UNUSED_PARAM(mode)(void)mode; |
| 7460 | #endif |
| 7461 | } |
| 7462 | |
| 7463 | void WebPage::focusedSelectElementDidChangeOptions(const WebCore::HTMLSelectElement& element) |
| 7464 | { |
| 7465 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7466 | if (m_focusedElement != &element) |
| 7467 | return; |
| 7468 | |
| 7469 | m_updateFocusedElementInformationTimer.restart(); |
| 7470 | #else |
| 7471 | UNUSED_PARAM(element)(void)element; |
| 7472 | #endif |
| 7473 | } |
| 7474 | |
| 7475 | void WebPage::didUpdateComposition() |
| 7476 | { |
| 7477 | sendEditorStateUpdate(); |
| 7478 | } |
| 7479 | |
| 7480 | void WebPage::didEndUserTriggeredSelectionChanges() |
| 7481 | { |
| 7482 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7483 | if (!frame) |
| 7484 | return; |
| 7485 | |
| 7486 | if (!frame->editor().ignoreSelectionChanges()) |
| 7487 | sendEditorStateUpdate(); |
| 7488 | } |
| 7489 | |
| 7490 | void WebPage::discardedComposition(const Document& document) |
| 7491 | { |
| 7492 | send(Messages::WebPageProxy::CompositionWasCanceled()); |
| 7493 | if (!document.hasLivingRenderTree()) |
| 7494 | return; |
| 7495 | |
| 7496 | sendEditorStateUpdate(); |
| 7497 | } |
| 7498 | |
| 7499 | void WebPage::canceledComposition() |
| 7500 | { |
| 7501 | send(Messages::WebPageProxy::CompositionWasCanceled()); |
| 7502 | sendEditorStateUpdate(); |
| 7503 | } |
| 7504 | |
| 7505 | void WebPage::navigateServiceWorkerClient(ScriptExecutionContextIdentifier documentIdentifier, const URL& url, CompletionHandler<void(WebCore::ScheduleLocationChangeResult)>&& callback) |
| 7506 | { |
| 7507 | RefPtr document = Document::allDocumentsMap().get(documentIdentifier); |
| 7508 | if (!document) { |
| 7509 | callback(WebCore::ScheduleLocationChangeResult::Stopped); |
| 7510 | return; |
| 7511 | } |
| 7512 | document->navigateFromServiceWorker(url, WTF::move(callback)); |
| 7513 | } |
| 7514 | |
| 7515 | void WebPage::setAlwaysShowsHorizontalScroller(bool alwaysShowsHorizontalScroller) |
| 7516 | { |
| 7517 | if (alwaysShowsHorizontalScroller == m_alwaysShowsHorizontalScroller) |
| 7518 | return; |
| 7519 | |
| 7520 | m_alwaysShowsHorizontalScroller = alwaysShowsHorizontalScroller; |
| 7521 | |
| 7522 | RefPtr view = protect(protect(corePage())->mainFrame())->virtualView(); |
| 7523 | if (!alwaysShowsHorizontalScroller) |
| 7524 | view->setHorizontalScrollbarLock(false); |
| 7525 | view->setHorizontalScrollbarMode(alwaysShowsHorizontalScroller ? ScrollbarMode::AlwaysOn : m_mainFrameIsScrollable ? ScrollbarMode::Auto : ScrollbarMode::AlwaysOff, alwaysShowsHorizontalScroller || !m_mainFrameIsScrollable); |
| 7526 | } |
| 7527 | |
| 7528 | void WebPage::setAlwaysShowsVerticalScroller(bool alwaysShowsVerticalScroller) |
| 7529 | { |
| 7530 | if (alwaysShowsVerticalScroller == m_alwaysShowsVerticalScroller) |
| 7531 | return; |
| 7532 | |
| 7533 | m_alwaysShowsVerticalScroller = alwaysShowsVerticalScroller; |
| 7534 | |
| 7535 | RefPtr view = protect(protect(corePage())->mainFrame())->virtualView(); |
| 7536 | if (!alwaysShowsVerticalScroller) |
| 7537 | view->setVerticalScrollbarLock(false); |
| 7538 | view->setVerticalScrollbarMode(alwaysShowsVerticalScroller ? ScrollbarMode::AlwaysOn : m_mainFrameIsScrollable ? ScrollbarMode::Auto : ScrollbarMode::AlwaysOff, alwaysShowsVerticalScroller || !m_mainFrameIsScrollable); |
| 7539 | } |
| 7540 | |
| 7541 | void WebPage::setMinimumSizeForAutoLayout(const IntSize& size) |
| 7542 | { |
| 7543 | if (m_minimumSizeForAutoLayout == size) |
| 7544 | return; |
| 7545 | |
| 7546 | m_minimumSizeForAutoLayout = size; |
| 7547 | |
| 7548 | RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame()); |
| 7549 | if (!localMainFrame) |
| 7550 | return; |
| 7551 | |
| 7552 | RefPtr view = localMainFrame->view(); |
| 7553 | if (size.width() <= 0) { |
| 7554 | view->enableFixedWidthAutoSizeMode(false, { }); |
| 7555 | return; |
| 7556 | } |
| 7557 | |
| 7558 | view->enableFixedWidthAutoSizeMode(true, { size.width(), std::max(size.height(), 1) }); |
| 7559 | } |
| 7560 | |
| 7561 | void WebPage::setSizeToContentAutoSizeMaximumSize(const IntSize& size) |
| 7562 | { |
| 7563 | if (m_sizeToContentAutoSizeMaximumSize == size) |
| 7564 | return; |
| 7565 | |
| 7566 | m_sizeToContentAutoSizeMaximumSize = size; |
| 7567 | |
| 7568 | RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame()); |
| 7569 | if (!localMainFrame) |
| 7570 | return; |
| 7571 | |
| 7572 | RefPtr view = localMainFrame->view(); |
| 7573 | if (size.width() <= 0 || size.height() <= 0) { |
| 7574 | view->enableSizeToContentAutoSizeMode(false, { }); |
| 7575 | return; |
| 7576 | } |
| 7577 | |
| 7578 | view->enableSizeToContentAutoSizeMode(true, size); |
| 7579 | } |
| 7580 | |
| 7581 | void WebPage::setAutoSizingShouldExpandToViewHeight(bool shouldExpand) |
| 7582 | { |
| 7583 | if (m_autoSizingShouldExpandToViewHeight == shouldExpand) |
| 7584 | return; |
| 7585 | |
| 7586 | m_autoSizingShouldExpandToViewHeight = shouldExpand; |
| 7587 | |
| 7588 | if (RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame())) |
| 7589 | protect(localMainFrame->view())->setAutoSizeFixedMinimumHeight(shouldExpand ? m_viewSize.height() : 0); |
| 7590 | } |
| 7591 | |
| 7592 | void WebPage::setViewportSizeForCSSViewportUnits(std::optional<WebCore::FloatSize> viewportSize) |
| 7593 | { |
| 7594 | if (m_viewportSizeForCSSViewportUnits == viewportSize) |
| 7595 | return; |
| 7596 | |
| 7597 | m_viewportSizeForCSSViewportUnits = viewportSize; |
| 7598 | if (m_viewportSizeForCSSViewportUnits) { |
| 7599 | if (RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame())) |
| 7600 | protect(localMainFrame->view())->setSizeForCSSDefaultViewportUnits(*m_viewportSizeForCSSViewportUnits); |
| 7601 | } |
| 7602 | } |
| 7603 | |
| 7604 | bool WebPage::isIOSurfaceLosslessCompressionEnabled() const |
| 7605 | { |
| 7606 | return m_page->settings().iOSurfaceLosslessCompressionEnabled(); |
| 7607 | } |
| 7608 | |
| 7609 | bool WebPage::isSmartInsertDeleteEnabled() |
| 7610 | { |
| 7611 | return m_page->settings().smartInsertDeleteEnabled(); |
| 7612 | } |
| 7613 | |
| 7614 | void WebPage::setSmartInsertDeleteEnabled(bool enabled) |
| 7615 | { |
| 7616 | if (m_page->settings().smartInsertDeleteEnabled() != enabled) { |
| 7617 | m_page->settings().setSmartInsertDeleteEnabled(enabled); |
| 7618 | setSelectTrailingWhitespaceEnabled(!enabled); |
| 7619 | } |
| 7620 | } |
| 7621 | |
| 7622 | bool WebPage::isSelectTrailingWhitespaceEnabled() const |
| 7623 | { |
| 7624 | return m_page->settings().selectTrailingWhitespaceEnabled(); |
| 7625 | } |
| 7626 | |
| 7627 | void WebPage::setSelectTrailingWhitespaceEnabled(bool enabled) |
| 7628 | { |
| 7629 | if (m_page->settings().selectTrailingWhitespaceEnabled() != enabled) { |
| 7630 | m_page->settings().setSelectTrailingWhitespaceEnabled(enabled); |
| 7631 | setSmartInsertDeleteEnabled(!enabled); |
| 7632 | } |
| 7633 | } |
| 7634 | |
| 7635 | bool WebPage::canShowResponse(const WebCore::ResourceResponse& response) const |
| 7636 | { |
| 7637 | return canShowMIMEType(response.mimeType(), [&](auto& mimeType, auto allowedPlugins) { |
| 7638 | return protect(corePage())->pluginData().supportsWebVisibleMimeTypeForURL(mimeType, allowedPlugins, response.url()); |
| 7639 | }); |
| 7640 | } |
| 7641 | |
| 7642 | bool WebPage::canShowMIMEType(const String& mimeType) const |
| 7643 | { |
| 7644 | return canShowMIMEType(mimeType, [&](auto& mimeType, auto allowedPlugins) { |
| 7645 | return protect(corePage())->pluginData().supportsWebVisibleMimeType(mimeType, allowedPlugins); |
| 7646 | }); |
| 7647 | } |
| 7648 | |
| 7649 | bool WebPage::canShowMIMEType(const String& mimeType, NOESCAPE[[clang::noescape]] const Function<bool(const String&, PluginData::AllowedPluginTypes)>& pluginsSupport) const |
| 7650 | { |
| 7651 | if (MIMETypeRegistry::canShowMIMEType(mimeType)) |
| 7652 | return true; |
| 7653 | |
| 7654 | if (!mimeType.isNull() && m_mimeTypesWithCustomContentProviders.contains(mimeType)) |
| 7655 | return true; |
| 7656 | |
| 7657 | // We can use application plugins even if plugins aren't enabled. |
| 7658 | if (pluginsSupport(mimeType, PluginData::OnlyApplicationPlugins)) |
| 7659 | return true; |
| 7660 | |
| 7661 | #if ENABLE(PDFJS)(defined 0 && 0) |
| 7662 | if (m_page->settings().pdfJSViewerEnabled() && MIMETypeRegistry::isPDFMIMEType(mimeType)) |
| 7663 | return true; |
| 7664 | #endif |
| 7665 | |
| 7666 | return false; |
| 7667 | } |
| 7668 | |
| 7669 | void WebPage::addTextCheckingRequest(TextCheckerRequestID requestID, Ref<TextCheckingRequest>&& request) |
| 7670 | { |
| 7671 | m_pendingTextCheckingRequestMap.add(requestID, WTF::move(request)); |
| 7672 | } |
| 7673 | |
| 7674 | void WebPage::didFinishCheckingText(TextCheckerRequestID requestID, const Vector<TextCheckingResult>& result) |
| 7675 | { |
| 7676 | RefPtr<TextCheckingRequest> request = m_pendingTextCheckingRequestMap.take(requestID); |
| 7677 | if (!request) |
| 7678 | return; |
| 7679 | |
| 7680 | request->didSucceed(result); |
| 7681 | } |
| 7682 | |
| 7683 | void WebPage::didCancelCheckingText(TextCheckerRequestID requestID) |
| 7684 | { |
| 7685 | RefPtr<TextCheckingRequest> request = m_pendingTextCheckingRequestMap.take(requestID); |
| 7686 | if (!request) |
| 7687 | return; |
| 7688 | |
| 7689 | request->didCancel(); |
| 7690 | } |
| 7691 | |
| 7692 | void WebPage::willReplaceMultipartContent(const WebFrame& frame) |
| 7693 | { |
| 7694 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7695 | if (!frame.isMainFrame()) |
| 7696 | return; |
| 7697 | |
| 7698 | m_previousExposedContentRect = protect(drawingArea())->exposedContentRect(); |
| 7699 | #endif |
| 7700 | } |
| 7701 | |
| 7702 | void WebPage::didReplaceMultipartContent(const WebFrame& frame) |
| 7703 | { |
| 7704 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7705 | if (!frame.isMainFrame()) |
| 7706 | return; |
| 7707 | |
| 7708 | // Restore the previous exposed content rect so that it remains fixed when replacing content |
| 7709 | // from multipart/x-mixed-replace streams. |
| 7710 | protect(drawingArea())->setExposedContentRect(m_previousExposedContentRect); |
| 7711 | #endif |
| 7712 | } |
| 7713 | |
| 7714 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 7715 | static void setCanIgnoreViewportArgumentsToAvoidExcessiveZoomIfNeeded(ViewportConfiguration& configuration, LocalFrame* frame, bool shouldIgnoreMetaViewport) |
| 7716 | { |
| 7717 | if (RefPtr document = frame ? frame->document() : nullptr; document && document->quirks().shouldIgnoreViewportArgumentsToAvoidExcessiveZoom()) |
| 7718 | configuration.setCanIgnoreViewportArgumentsToAvoidExcessiveZoom(shouldIgnoreMetaViewport); |
| 7719 | } |
| 7720 | |
| 7721 | static void setCanIgnoreViewportArgumentsToAvoidEnlargedViewIfNeeded(ViewportConfiguration& configuration, LocalFrame* frame) |
| 7722 | { |
| 7723 | if (RefPtr document = frame ? frame->document() : nullptr; document && document->quirks().shouldIgnoreViewportArgumentsToAvoidEnlargedView()) |
| 7724 | configuration.setCanIgnoreViewportArgumentsToAvoidEnlargedView(true); |
| 7725 | } |
| 7726 | #endif |
| 7727 | |
| 7728 | void WebPage::didCommitLoad(WebFrame* frame) |
| 7729 | { |
| 7730 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7731 | auto firstTransactionIDAfterDidCommitLoad = downcast<RemoteLayerTreeDrawingArea>(*protect(drawingArea())).nextTransactionID(); |
| 7732 | frame->setFirstLayerTreeTransactionIDAfterDidCommitLoad(firstTransactionIDAfterDidCommitLoad); |
| 7733 | cancelPotentialTapInFrame(*frame); |
| 7734 | #endif |
| 7735 | resetFocusedElementForFrame(frame); |
| 7736 | |
| 7737 | if (frame->isMainFrame()) |
| 7738 | m_textManipulationIncludesSubframes = false; |
| 7739 | else if (m_textManipulationIncludesSubframes) |
| 7740 | startTextManipulationForFrame(*protect(frame->coreLocalFrame())); |
| 7741 | |
| 7742 | if (!frame->isRootFrame()) |
| 7743 | return; |
| 7744 | |
| 7745 | if (RefPtr drawingArea = m_drawingArea) |
| 7746 | drawingArea->sendEnterAcceleratedCompositingModeIfNeeded(); |
| 7747 | |
| 7748 | ASSERT(!frame->coreLocalFrame()->loader().stateMachine().creatingInitialEmptyDocument())((void)0); |
| 7749 | unfreezeLayerTree(LayerTreeFreezeReason::ProcessSwap); |
| 7750 | |
| 7751 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) |
| 7752 | for (auto& [element, completionHandlers] : m_elementsPendingTextRecognition) { |
| 7753 | for (auto& completionHandler : completionHandlers) |
| 7754 | completionHandler({ }); |
| 7755 | } |
| 7756 | m_elementsPendingTextRecognition.clear(); |
| 7757 | #endif |
| 7758 | |
| 7759 | clearLoadedSubresourceDomains(); |
| 7760 | |
| 7761 | // If previous URL is invalid, then it's not a real page that's being navigated away from. |
| 7762 | // Most likely, this is actually the first load to be committed in this page. |
| 7763 | if (frame->coreLocalFrame()->loader().previousURL().isValid()) |
| 7764 | reportUsedFeatures(); |
| 7765 | |
| 7766 | // Only restore the scale factor for standard frame loads (of the main frame). |
| 7767 | if (frame->coreLocalFrame()->loader().loadType() == FrameLoadType::Standard) { |
| 7768 | RefPtr page = frame->coreLocalFrame()->page(); |
| 7769 | |
| 7770 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) |
| 7771 | // As a very special case, we disable non-default layout modes in WKView for main-frame PluginDocuments. |
| 7772 | // Ideally we would only worry about this in WKView or the WKViewLayoutStrategies, but if we allow |
| 7773 | // a round-trip to the UI process, you'll see the wrong scale temporarily. So, we reset it here, and then |
| 7774 | // again later from the UI process. |
| 7775 | if (frame->coreLocalFrame()->document()->isPluginDocument()) { |
| 7776 | scaleView(1); |
| 7777 | setUseFixedLayout(false); |
| 7778 | } |
| 7779 | #endif |
| 7780 | |
| 7781 | if (page && page->pageScaleFactor() != 1) |
| 7782 | scalePage(1, IntPoint()); |
| 7783 | } |
| 7784 | |
| 7785 | // This timer can race with loading and clobber the scroll position saved on the current history item. |
| 7786 | m_pageScrolledHysteresis.cancel(); |
| 7787 | |
| 7788 | m_didUpdateRenderingAfterCommittingLoad = false; |
| 7789 | |
| 7790 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7791 | if (auto scope = std::exchange(m_ignoreSelectionChangeScopeForDictation, nullptr)) |
| 7792 | scope->invalidate(); |
| 7793 | m_sendAutocorrectionContextAfterFocusingElement = false; |
| 7794 | m_hasReceivedVisibleContentRectsAfterDidCommitLoad = false; |
| 7795 | m_hasRestoredExposedContentRectAfterDidCommitLoad = false; |
| 7796 | m_internals->lastTransactionIDWithScaleChange = firstTransactionIDAfterDidCommitLoad; |
| 7797 | m_scaleWasSetByUIProcess = false; |
| 7798 | m_userHasChangedPageScaleFactor = false; |
| 7799 | m_previousViewportConfigurationMinimumScale = { }; |
| 7800 | m_estimatedLatency = Seconds(1.0 / 60); |
| 7801 | m_shouldRevealCurrentSelectionAfterInsertion = true; |
| 7802 | m_internals->lastLayerTreeTransactionIdAndPageScaleBeforeScalingPage = std::nullopt; |
| 7803 | m_lastSelectedReplacementRange = { }; |
| 7804 | m_bidiSelectionFlippingState = BidiSelectionFlippingState::NotFlipping; |
| 7805 | |
| 7806 | invokePendingSyntheticClickCallback(SyntheticClickResult::PageInvalid); |
| 7807 | |
| 7808 | #if ENABLE(IOS_TOUCH_EVENTS)(defined 0 && 0) |
| 7809 | auto queuedEvents = makeUniqueRef<EventDispatcher::TouchEventQueue>(); |
| 7810 | WebProcess::singleton().eventDispatcher().takeQueuedTouchEventsForPage(*this, queuedEvents); |
| 7811 | cancelAsynchronousTouchEvents(WTF::move(queuedEvents)); |
| 7812 | #endif |
| 7813 | m_lastTouchLocationBeforeTap = { }; |
| 7814 | m_hasAnyActiveTouchPoints = false; |
| 7815 | m_activeTextInteractionSources = { }; |
| 7816 | #endif // PLATFORM(IOS_FAMILY) |
| 7817 | |
| 7818 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 7819 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 7820 | resetViewportDefaultConfiguration(frame); |
| 7821 | |
| 7822 | bool viewportChanged = false; |
| 7823 | |
| 7824 | setCanIgnoreViewportArgumentsToAvoidExcessiveZoomIfNeeded(m_viewportConfiguration, coreFrame.get(), shouldIgnoreMetaViewport()); |
| 7825 | setCanIgnoreViewportArgumentsToAvoidEnlargedViewIfNeeded(m_viewportConfiguration, coreFrame.get()); |
| 7826 | |
| 7827 | m_viewportConfiguration.setPrefersHorizontalScrollingBelowDesktopViewportWidths(shouldEnableViewportBehaviorsForResizableWindows()); |
| 7828 | |
| 7829 | LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier.toUInt64() << " didCommitLoad setting content size to " << coreFrame->view()->contentsSize())((void)0); |
| 7830 | if (m_viewportConfiguration.setContentsSize(protect(coreFrame->view())->contentsSize())) |
| 7831 | viewportChanged = true; |
| 7832 | |
| 7833 | if (m_viewportConfiguration.setViewportArguments(protect(coreFrame->document())->viewportArguments())) |
| 7834 | viewportChanged = true; |
| 7835 | |
| 7836 | if (m_viewportConfiguration.setIsKnownToLayOutWiderThanViewport(false)) |
| 7837 | viewportChanged = true; |
| 7838 | |
| 7839 | if (viewportChanged) |
| 7840 | viewportConfigurationChanged(); |
| 7841 | #endif // ENABLE(META_VIEWPORT) |
| 7842 | |
| 7843 | #if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1) |
| 7844 | m_textAutoSizingAdjustmentTimer.stop(); |
| 7845 | #endif |
| 7846 | |
| 7847 | #if USE(OS_STATE)(defined 1 && 1) |
| 7848 | m_loadCommitTime = WallTime::now(); |
| 7849 | #endif |
| 7850 | |
| 7851 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 7852 | m_updateLayoutViewportHeightExpansionTimer.stop(); |
| 7853 | m_shouldRescheduleLayoutViewportHeightExpansionTimer = false; |
| 7854 | #endif |
| 7855 | removeReasonsToDisallowLayoutViewportHeightExpansion(m_disallowLayoutViewportHeightExpansionReasons); |
| 7856 | |
| 7857 | #if ENABLE(ADVANCED_PRIVACY_PROTECTIONS)(defined 1 && 1) |
| 7858 | if (coreFrame->isMainFrame() && !usesEphemeralSession()) { |
| 7859 | if (RefPtr loader = protect(coreFrame->document())->loader(); loader |
| 7860 | && loader->advancedPrivacyProtections().contains(AdvancedPrivacyProtections::BaselineProtections)) |
| 7861 | WEBPAGE_RELEASE_LOG(AdvancedPrivacyProtections, "didCommitLoad: advanced privacy protections enabled in non-ephemeral session"); |
| 7862 | } |
| 7863 | #endif |
| 7864 | |
| 7865 | themeColorChanged(); |
| 7866 | |
| 7867 | m_lastNodeBeforeWritingSuggestions = { }; |
| 7868 | |
| 7869 | WebProcess::singleton().updateActivePages(m_processDisplayName); |
| 7870 | |
| 7871 | updateMainFrameScrollOffsetPinning(); |
| 7872 | |
| 7873 | updateMockAccessibilityElementAfterCommittingLoad(); |
| 7874 | |
| 7875 | #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)(defined 1 && 1) |
| 7876 | m_elementsToExcludeFromRemoveBackground.clear(); |
| 7877 | #endif |
| 7878 | |
| 7879 | #if USE(UICONTEXTMENU)(defined 1 && 1) |
| 7880 | m_hasActiveContextMenuInteraction = false; |
| 7881 | #endif |
| 7882 | |
| 7883 | m_needsFixedContainerEdgesUpdate = true; |
| 7884 | |
| 7885 | flushDeferredDidReceiveMouseEvent(); |
| 7886 | |
| 7887 | if (frame && frame->isMainFrame()) |
| 7888 | m_networkResourceRequestIdentifiersForPageLoadTiming.clear(); |
| 7889 | } |
| 7890 | |
| 7891 | void WebPage::didFinishDocumentLoad(WebFrame& frame) |
| 7892 | { |
| 7893 | if (!frame.isMainFrame()) |
| 7894 | return; |
| 7895 | |
| 7896 | #if ENABLE(VIEWPORT_RESIZING)(defined (defined 1 && 1) && (defined 1 && 1)) |
| 7897 | shrinkToFitContent(ZoomToInitialScale::Yes); |
| 7898 | #endif |
| 7899 | } |
| 7900 | |
| 7901 | void WebPage::didFinishLoad(WebFrame& frame) |
| 7902 | { |
| 7903 | if (!frame.isMainFrame()) |
| 7904 | return; |
| 7905 | |
| 7906 | WebProcess::singleton().sendPrewarmInformation(frame.url()); |
| 7907 | |
| 7908 | #if ENABLE(VIEWPORT_RESIZING)(defined (defined 1 && 1) && (defined 1 && 1)) |
| 7909 | shrinkToFitContent(ZoomToInitialScale::Yes); |
| 7910 | #endif |
| 7911 | |
| 7912 | #if ENABLE(WEB_PAGE_SPATIAL_BACKDROP)(defined ENABLE_WEB_PAGE_SPATIAL_BACKDROP && ENABLE_WEB_PAGE_SPATIAL_BACKDROP ) |
| 7913 | spatialBackdropSourceChanged(); |
| 7914 | #endif |
| 7915 | } |
| 7916 | |
| 7917 | void WebPage::didSameDocumentNavigationForFrame(WebFrame& frame) |
| 7918 | { |
| 7919 | RefPtr<API::Object> userData; |
| 7920 | |
| 7921 | auto navigationID = protect(frame.coreLocalFrame()->loader().documentLoader())->navigationID(); |
| 7922 | |
| 7923 | if (frame.isMainFrame()) |
| 7924 | m_pendingNavigationID = std::nullopt; |
| 7925 | |
| 7926 | // Notify the bundle client. |
| 7927 | injectedBundleLoaderClient().didSameDocumentNavigationForFrame(*this, frame, SameDocumentNavigationType::AnchorNavigation, userData); |
| 7928 | |
| 7929 | // Notify the UIProcess. |
| 7930 | send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(frame.frameID(), navigationID, SameDocumentNavigationType::AnchorNavigation, protect(frame.coreLocalFrame()->document())->url(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 7931 | |
| 7932 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 7933 | for (Ref pluginView : m_pluginViews) |
| 7934 | pluginView->didSameDocumentNavigationForFrame(frame); |
| 7935 | #endif |
| 7936 | } |
| 7937 | |
| 7938 | void WebPage::didNavigateWithinPageForFrame(WebFrame& frame) |
| 7939 | { |
| 7940 | if (frame.isMainFrame()) |
| 7941 | m_pendingNavigationID = std::nullopt; |
| 7942 | } |
| 7943 | |
| 7944 | void WebPage::testProcessIncomingSyncMessagesWhenWaitingForSyncReply(CompletionHandler<void(bool)>&& reply) |
| 7945 | { |
| 7946 | RELEASE_ASSERT(IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC())do { if (__builtin_expect(!!(!(IPC::UnboundedSynchronousIPCScope ::hasOngoingUnboundedSyncIPC())), 0)) do { WTF::isIntegralOrPointerType (); compilerFenceForCrash(); WTFCrashWithInfo(7946, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); } while (0); |
| 7947 | reply(true); |
| 7948 | } |
| 7949 | |
| 7950 | std::optional<SimpleRange> WebPage::currentSelectionAsRange() |
| 7951 | { |
| 7952 | RefPtr frame = frameWithSelection(m_page.get()); |
| 7953 | if (!frame) |
| 7954 | return std::nullopt; |
| 7955 | |
| 7956 | return frame->selection().selection().toNormalizedRange(); |
| 7957 | } |
| 7958 | |
| 7959 | void WebPage::reportUsedFeatures() |
| 7960 | { |
| 7961 | Vector<String> namedFeatures; |
| 7962 | m_loaderClient->featuresUsedInPage(*this, namedFeatures); |
| 7963 | } |
| 7964 | |
| 7965 | void WebPage::sendEditorStateUpdate() |
| 7966 | { |
| 7967 | m_needsEditorStateVisualDataUpdate = true; |
| 7968 | |
| 7969 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 7970 | if (!frame) |
| 7971 | return; |
| 7972 | |
| 7973 | if (frame->editor().ignoreSelectionChanges() || !frame->document() || !frame->document()->hasLivingRenderTree()) |
| 7974 | return; |
| 7975 | |
| 7976 | m_pendingEditorStateUpdateStatus = PendingEditorStateUpdateStatus::NotScheduled; |
| 7977 | |
| 7978 | // If we immediately dispatch an EditorState update to the UI process, layout may not be up to date yet. |
| 7979 | // If that is the case, just send what we have (i.e. don't include post-layout data) and wait until the |
| 7980 | // next layer tree commit to compute and send the complete EditorState over. |
| 7981 | auto state = editorState(); |
| 7982 | send(Messages::WebPageProxy::EditorStateChanged(state)); |
| 7983 | if (!state.hasPostLayoutData() && !shouldAvoidComputingPostLayoutDataForEditorState()) |
| 7984 | scheduleFullEditorStateUpdate(); |
| 7985 | } |
| 7986 | |
| 7987 | void WebPage::scheduleFullEditorStateUpdate() |
| 7988 | { |
| 7989 | m_needsEditorStateVisualDataUpdate = true; |
| 7990 | |
| 7991 | if (hasPendingEditorStateUpdate()) { |
| 7992 | if (m_isChangingSelectionForAccessibility) |
| 7993 | m_pendingEditorStateUpdateStatus = PendingEditorStateUpdateStatus::ScheduledDuringAccessibilitySelectionChange; |
| 7994 | return; |
| 7995 | } |
| 7996 | |
| 7997 | if (m_isChangingSelectionForAccessibility) |
| 7998 | m_pendingEditorStateUpdateStatus = PendingEditorStateUpdateStatus::ScheduledDuringAccessibilitySelectionChange; |
| 7999 | else |
| 8000 | m_pendingEditorStateUpdateStatus = PendingEditorStateUpdateStatus::Scheduled; |
| 8001 | |
| 8002 | protect(corePage())->scheduleRenderingUpdate(RenderingUpdateStep::LayerFlush); |
| 8003 | } |
| 8004 | |
| 8005 | void WebPage::loadAndDecodeImage(WebCore::ResourceRequest&& request, std::optional<WebCore::FloatSize> sizeConstraint, uint64_t maximumBytesFromNetwork, CompletionHandler<void(Expected<Ref<WebCore::ShareableBitmap>, WebCore::ResourceError>&&)>&& completionHandler) |
| 8006 | { |
| 8007 | URL url = request.url(); |
| 8008 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::LoadImageForDecoding(WTF::move(request), m_webPageProxyIdentifier, maximumBytesFromNetwork), [completionHandler = WTF::move(completionHandler), sizeConstraint, url] (Expected<Ref<WebCore::FragmentedSharedBuffer>, WebCore::ResourceError>&& result) mutable { |
| 8009 | if (!result) |
| 8010 | return completionHandler(makeUnexpected(WTF::move(result.error()))); |
| 8011 | |
| 8012 | Ref bitmapImage = WebCore::BitmapImage::create(nullptr); |
| 8013 | bitmapImage->setData(result->ptr(), true); |
| 8014 | RefPtr nativeImage = bitmapImage->primaryNativeImage(); |
| 8015 | if (!nativeImage) |
| 8016 | return completionHandler(makeUnexpected(decodeError(url))); |
| 8017 | |
| 8018 | FloatSize sourceSize = nativeImage->size(); |
| 8019 | FloatSize destinationSize = sourceSize; |
| 8020 | if (sizeConstraint) |
| 8021 | destinationSize = largestRectWithAspectRatioInsideRect(sourceSize.aspectRatio(), FloatRect({ }, sizeConstraint->shrunkTo(sourceSize))).size(); |
| 8022 | |
| 8023 | IntSize roundedDestinationSize = flooredIntSize(destinationSize); |
| 8024 | auto sourceColorSpace = nativeImage->colorSpace(); |
| 8025 | auto destinationColorSpace = sourceColorSpace.supportsOutput() ? sourceColorSpace : DestinationColorSpace::SRGB(); |
| 8026 | auto bitmap = ShareableBitmap::create({ roundedDestinationSize, destinationColorSpace }); |
| 8027 | if (!bitmap) |
| 8028 | return completionHandler(makeUnexpected<ResourceError>({ })); |
| 8029 | |
| 8030 | auto context = bitmap->createGraphicsContext(); |
| 8031 | if (!context) |
| 8032 | return completionHandler(makeUnexpected<ResourceError>({ })); |
| 8033 | |
| 8034 | context->drawNativeImage(*nativeImage, FloatRect({ }, roundedDestinationSize), FloatRect({ }, sourceSize), { CompositeOperator::Copy }); |
| 8035 | |
| 8036 | completionHandler(bitmap.releaseNonNull()); |
| 8037 | }); |
| 8038 | } |
| 8039 | |
| 8040 | #if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) || PLATFORM(WPE)(defined WTF_PLATFORM_WPE && WTF_PLATFORM_WPE) || PLATFORM(GTK)(defined WTF_PLATFORM_GTK && WTF_PLATFORM_GTK) |
| 8041 | void WebPage::flushPendingThemeColorChange() |
| 8042 | { |
| 8043 | if (!m_pendingThemeColorChange) |
| 8044 | return; |
| 8045 | |
| 8046 | m_pendingThemeColorChange = false; |
| 8047 | |
| 8048 | send(Messages::WebPageProxy::ThemeColorChanged(protect(corePage())->themeColor())); |
| 8049 | } |
| 8050 | #endif |
| 8051 | |
| 8052 | void WebPage::flushPendingPageExtendedBackgroundColorChange() |
| 8053 | { |
| 8054 | if (!m_pendingPageExtendedBackgroundColorChange) |
| 8055 | return; |
| 8056 | |
| 8057 | m_pendingPageExtendedBackgroundColorChange = false; |
| 8058 | |
| 8059 | send(Messages::WebPageProxy::PageExtendedBackgroundColorDidChange(protect(corePage())->pageExtendedBackgroundColor())); |
| 8060 | } |
| 8061 | |
| 8062 | void WebPage::flushPendingSampledPageTopColorChange() |
| 8063 | { |
| 8064 | if (!m_pendingSampledPageTopColorChange) |
| 8065 | return; |
| 8066 | |
| 8067 | m_pendingSampledPageTopColorChange = false; |
| 8068 | |
| 8069 | send(Messages::WebPageProxy::SampledPageTopColorChanged(protect(corePage())->sampledPageTopColor())); |
| 8070 | } |
| 8071 | |
| 8072 | #if ENABLE(WEB_PAGE_SPATIAL_BACKDROP)(defined ENABLE_WEB_PAGE_SPATIAL_BACKDROP && ENABLE_WEB_PAGE_SPATIAL_BACKDROP ) |
| 8073 | void WebPage::spatialBackdropSourceChanged() |
| 8074 | { |
| 8075 | RefPtr page = m_page; |
| 8076 | if (page->settings().webPageSpatialBackdropEnabled()) |
| 8077 | send(Messages::WebPageProxy::SpatialBackdropSourceChanged(page->spatialBackdropSource())); |
| 8078 | } |
| 8079 | #endif |
| 8080 | |
| 8081 | #if ENABLE(MODEL_ELEMENT_IMMERSIVE)(defined ENABLE_MODEL_ELEMENT_IMMERSIVE && ENABLE_MODEL_ELEMENT_IMMERSIVE ) |
| 8082 | void WebPage::allowImmersiveElement(CompletionHandler<void(bool)>&& completion) |
| 8083 | { |
| 8084 | sendWithAsyncReply(Messages::WebPageProxy::AllowImmersiveElement(), WTF::move(completion)); |
| 8085 | } |
| 8086 | |
| 8087 | void WebPage::presentImmersiveElement(const LayerHostingContextIdentifier contextID, CompletionHandler<void(bool)>&& completion) |
| 8088 | { |
| 8089 | sendWithAsyncReply(Messages::WebPageProxy::PresentImmersiveElement(contextID), WTF::move(completion)); |
| 8090 | } |
| 8091 | |
| 8092 | void WebPage::dismissImmersiveElement(CompletionHandler<void()>&& completion) |
| 8093 | { |
| 8094 | sendWithAsyncReply(Messages::WebPageProxy::DismissImmersiveElement(), WTF::move(completion)); |
| 8095 | } |
| 8096 | |
| 8097 | void WebPage::exitImmersive() const |
| 8098 | { |
| 8099 | if (RefPtr localTopDocument = this->localTopDocument(); RefPtr protectedImmersive = localTopDocument->immersiveIfExists()) |
| 8100 | protectedImmersive->exitImmersive(); |
| 8101 | } |
| 8102 | |
| 8103 | bool WebPage::allowsImmersiveEnvironments() const |
| 8104 | { |
| 8105 | return m_allowsImmersiveEnvironments; |
| 8106 | } |
| 8107 | #endif |
| 8108 | |
| 8109 | void WebPage::flushPendingEditorStateUpdate() |
| 8110 | { |
| 8111 | if (!hasPendingEditorStateUpdate()) |
| 8112 | return; |
| 8113 | |
| 8114 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 8115 | if (!frame) |
| 8116 | return; |
| 8117 | |
| 8118 | if (frame->editor().ignoreSelectionChanges()) |
| 8119 | return; |
| 8120 | |
| 8121 | sendEditorStateUpdate(); |
| 8122 | } |
| 8123 | |
| 8124 | void WebPage::updateWebsitePolicies(WebsitePoliciesData&& websitePolicies) |
| 8125 | { |
| 8126 | RefPtr page = m_page; |
| 8127 | if (!page) |
| 8128 | return; |
| 8129 | |
| 8130 | if (auto* remoteMainFrameClient = m_mainFrame->remoteFrameClient()) { |
| 8131 | remoteMainFrameClient->applyWebsitePolicies(WTF::move(websitePolicies)); |
| 8132 | return; |
| 8133 | } |
| 8134 | |
| 8135 | RefPtr localMainFrame = this->localMainFrame(); |
| 8136 | RefPtr documentLoader = localMainFrame ? localMainFrame->loader().documentLoader() : nullptr; |
| 8137 | if (!documentLoader) |
| 8138 | return; |
| 8139 | |
| 8140 | m_allowsContentJavaScriptFromMostRecentNavigation = websitePolicies.allowsContentJavaScript; |
| 8141 | WebsitePoliciesData::applyToDocumentLoader(WTF::move(websitePolicies), *documentLoader); |
| 8142 | |
| 8143 | #if ENABLE(VIDEO)(defined 1 && 1) |
| 8144 | page->updateMediaElementRateChangeRestrictions(); |
| 8145 | #endif |
| 8146 | |
| 8147 | #if ENABLE(META_VIEWPORT)(defined 1 && 1) |
| 8148 | setCanIgnoreViewportArgumentsToAvoidExcessiveZoomIfNeeded(m_viewportConfiguration, localMainFrame.get(), shouldIgnoreMetaViewport()); |
| 8149 | setCanIgnoreViewportArgumentsToAvoidEnlargedViewIfNeeded(m_viewportConfiguration, localMainFrame.get()); |
| 8150 | #endif |
| 8151 | } |
| 8152 | |
| 8153 | unsigned WebPage::extendIncrementalRenderingSuppression() |
| 8154 | { |
| 8155 | unsigned token = m_maximumRenderingSuppressionToken + 1; |
| 8156 | while (!HashSet<unsigned>::isValidValue(token) || m_activeRenderingSuppressionTokens.contains(token)) |
| 8157 | token++; |
| 8158 | |
| 8159 | m_activeRenderingSuppressionTokens.add(token); |
| 8160 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 8161 | protect(localMainFrame->view())->setVisualUpdatesAllowedByClient(false); |
| 8162 | |
| 8163 | m_maximumRenderingSuppressionToken = token; |
| 8164 | |
| 8165 | return token; |
| 8166 | } |
| 8167 | |
| 8168 | void WebPage::stopExtendingIncrementalRenderingSuppression(unsigned token) |
| 8169 | { |
| 8170 | if (!m_activeRenderingSuppressionTokens.remove(token)) |
| 8171 | return; |
| 8172 | |
| 8173 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 8174 | protect(localMainFrame->view())->setVisualUpdatesAllowedByClient(!shouldExtendIncrementalRenderingSuppression()); |
| 8175 | } |
| 8176 | |
| 8177 | WebCore::ScrollPinningBehavior WebPage::scrollPinningBehavior() |
| 8178 | { |
| 8179 | return m_internals->scrollPinningBehavior; |
| 8180 | } |
| 8181 | |
| 8182 | void WebPage::setScrollPinningBehavior(WebCore::ScrollPinningBehavior pinning) |
| 8183 | { |
| 8184 | m_internals->scrollPinningBehavior = pinning; |
| 8185 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 8186 | protect(localMainFrame->view())->setScrollPinningBehavior(m_internals->scrollPinningBehavior); |
| 8187 | } |
| 8188 | |
| 8189 | void WebPage::setScrollbarOverlayStyle(std::optional<WebCore::ScrollbarOverlayStyle> scrollbarStyle) |
| 8190 | { |
| 8191 | m_scrollbarOverlayStyle = scrollbarStyle; |
| 8192 | |
| 8193 | if (RefPtr localMainFrame = this->localMainFrame()) |
| 8194 | protect(localMainFrame->view())->recalculateScrollbarOverlayStyle(); |
| 8195 | } |
| 8196 | |
| 8197 | Ref<DocumentLoader> WebPage::createDocumentLoader(LocalFrame& frame, ResourceRequest&& request, SubstituteData&& substituteData, ResourceRequest&& originalRequest) |
| 8198 | { |
| 8199 | auto documentLoader = DocumentLoader::create(WTF::move(request), WTF::move(substituteData), WTF::move(originalRequest)); |
| 8200 | |
| 8201 | documentLoader->setLastNavigationWasAppInitiated(m_lastNavigationWasAppInitiated); |
| 8202 | |
| 8203 | if (frame.isMainFrame() || m_page->settings().siteIsolationEnabled()) { |
| 8204 | if (m_pendingNavigationID) { |
| 8205 | documentLoader->setNavigationID(*m_pendingNavigationID); |
| 8206 | m_pendingNavigationID = std::nullopt; |
| 8207 | } |
| 8208 | |
| 8209 | if (m_internals->pendingWebsitePolicies && frame.isMainFrame()) { |
| 8210 | m_allowsContentJavaScriptFromMostRecentNavigation = m_internals->pendingWebsitePolicies->allowsContentJavaScript; |
| 8211 | WebsitePoliciesData::applyToDocumentLoader(*std::exchange(m_internals->pendingWebsitePolicies, std::nullopt), documentLoader); |
| 8212 | } |
| 8213 | } |
| 8214 | |
| 8215 | return documentLoader; |
| 8216 | } |
| 8217 | |
| 8218 | Ref<DocumentLoader> WebPage::createDocumentLoader(LocalFrame& frame, ResourceRequest&& request, SubstituteData&& substituteData) |
| 8219 | { |
| 8220 | return createDocumentLoader(frame, WTF::move(request), WTF::move(substituteData), { }); |
| 8221 | } |
| 8222 | |
| 8223 | void WebPage::updateCachedDocumentLoader(DocumentLoader& documentLoader, LocalFrame& frame) |
| 8224 | { |
| 8225 | if (m_pendingNavigationID && frame.isMainFrame()) { |
| 8226 | documentLoader.setNavigationID(*m_pendingNavigationID); |
| 8227 | m_pendingNavigationID = std::nullopt; |
| 8228 | } |
| 8229 | } |
| 8230 | |
| 8231 | void WebPage::getBytecodeProfile(CompletionHandler<void(const String&)>&& callback) |
| 8232 | { |
| 8233 | if (!commonVM().m_perBytecodeProfiler) [[likely]] |
| 8234 | return callback({ }); |
| 8235 | |
| 8236 | String result = commonVM().m_perBytecodeProfiler->toJSON()->toJSONString(); |
| 8237 | ASSERT(result.length())((void)0); |
| 8238 | callback(result); |
| 8239 | } |
| 8240 | |
| 8241 | void WebPage::getSamplingProfilerOutput(CompletionHandler<void(const String&)>&& callback) |
| 8242 | { |
| 8243 | #if ENABLE(SAMPLING_PROFILER)(defined 1 && 1) |
| 8244 | RefPtr samplingProfiler = commonVM().samplingProfiler(); |
| 8245 | if (!samplingProfiler) |
| 8246 | return callback({ }); |
| 8247 | |
| 8248 | StringPrintStream result; |
| 8249 | samplingProfiler->reportTopFunctions(result); |
| 8250 | samplingProfiler->reportTopBytecodes(result); |
| 8251 | callback(result.toString()); |
| 8252 | #else |
| 8253 | callback({ }); |
| 8254 | #endif |
| 8255 | } |
| 8256 | |
| 8257 | void WebPage::didChangeScrollOffsetForFrame(LocalFrame& frame) |
| 8258 | { |
| 8259 | if (!frame.isMainFrame()) |
| 8260 | return; |
| 8261 | |
| 8262 | // If this is called when tearing down a FrameView, the WebCore::Frame's |
| 8263 | // current FrameView will be null. |
| 8264 | if (!frame.view()) |
| 8265 | return; |
| 8266 | |
| 8267 | updateMainFrameScrollOffsetPinning(); |
| 8268 | } |
| 8269 | |
| 8270 | void WebPage::postMessage(const String& messageName, API::Object* messageBody) |
| 8271 | { |
| 8272 | send(Messages::WebPageProxy::HandleMessage(messageName, UserData(WebProcess::singleton().transformObjectsToHandles(messageBody)))); |
| 8273 | } |
| 8274 | |
| 8275 | void WebPage::postMessageIgnoringFullySynchronousMode(const String& messageName, API::Object* messageBody) |
| 8276 | { |
| 8277 | send(Messages::WebPageProxy::HandleMessage(messageName, UserData(WebProcess::singleton().transformObjectsToHandles(messageBody))), IPC::SendOption::DispatchMessageEvenWhenWaitingForSyncReply); |
| 8278 | } |
| 8279 | |
| 8280 | void WebPage::postSynchronousMessageForTesting(const String& messageName, API::Object* messageBody, RefPtr<API::Object>& returnData) |
| 8281 | { |
| 8282 | auto& webProcess = WebProcess::singleton(); |
| 8283 | |
| 8284 | auto sendResult = sendSync(Messages::WebPageProxy::HandleSynchronousMessage(messageName, UserData(webProcess.transformObjectsToHandles(messageBody))), Seconds::infinity(), IPC::SendSyncOption::UseFullySynchronousModeForTesting); |
| 8285 | if (sendResult.succeeded()) { |
| 8286 | auto& [returnUserData] = sendResult.reply(); |
| 8287 | returnData = webProcess.transformHandlesToObjects(protect(returnUserData.object()).get()); |
| 8288 | } else |
| 8289 | returnData = nullptr; |
| 8290 | } |
| 8291 | |
| 8292 | void WebPage::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument) |
| 8293 | { |
| 8294 | if (RefPtr drawingArea = m_drawingArea) |
| 8295 | drawingArea->setShouldScaleViewToFitDocument(shouldScaleViewToFitDocument); |
| 8296 | } |
| 8297 | |
| 8298 | void WebPage::imageOrMediaDocumentSizeChanged(const IntSize& newSize) |
| 8299 | { |
| 8300 | send(Messages::WebPageProxy::ImageOrMediaDocumentSizeChanged(newSize)); |
| 8301 | } |
| 8302 | |
| 8303 | void WebPage::addUserScript(String&& source, InjectedBundleScriptWorld& world, WebCore::UserContentInjectedFrames injectedFrames, WebCore::UserScriptInjectionTime injectionTime, WebCore::UserContentMatchParentFrame matchParentFrame) |
| 8304 | { |
| 8305 | WebCore::UserScript userScript { WTF::move(source), URL(aboutBlankURL()), Vector<String>(), Vector<String>(), injectionTime, injectedFrames, matchParentFrame }; |
| 8306 | |
| 8307 | Ref { m_userContentController }->addUserScript(world, WTF::move(userScript)); |
| 8308 | } |
| 8309 | |
| 8310 | void WebPage::addUserStyleSheet(const String& source, WebCore::UserContentInjectedFrames injectedFrames) |
| 8311 | { |
| 8312 | WebCore::UserStyleSheet userStyleSheet { source, aboutBlankURL(), Vector<String>(), Vector<String>(), injectedFrames }; |
| 8313 | |
| 8314 | Ref { m_userContentController }->addUserStyleSheet(InjectedBundleScriptWorld::normalWorldSingleton(), WTF::move(userStyleSheet)); |
| 8315 | } |
| 8316 | |
| 8317 | void WebPage::removeAllUserContent() |
| 8318 | { |
| 8319 | Ref { m_userContentController }->removeAllUserContent(); |
| 8320 | } |
| 8321 | |
| 8322 | void WebPage::updateIntrinsicContentSizeIfNeeded(const WebCore::IntSize& size) |
| 8323 | { |
| 8324 | m_pendingIntrinsicContentSize = std::nullopt; |
| 8325 | if (!minimumSizeForAutoLayout().width() && !sizeToContentAutoSizeMaximumSize().width() && !sizeToContentAutoSizeMaximumSize().height()) |
| 8326 | return; |
| 8327 | ASSERT(localMainFrameView())((void)0); |
| 8328 | ASSERT(localMainFrameView()->isFixedWidthAutoSizeEnabled() || localMainFrameView()->isSizeToContentAutoSizeEnabled())((void)0); |
| 8329 | ASSERT(!localMainFrameView()->needsLayout())((void)0); |
| 8330 | if (m_lastSentIntrinsicContentSize == size) |
| 8331 | return; |
| 8332 | m_lastSentIntrinsicContentSize = size; |
| 8333 | send(Messages::WebPageProxy::DidChangeIntrinsicContentSize(size)); |
| 8334 | } |
| 8335 | |
| 8336 | void WebPage::flushPendingIntrinsicContentSizeUpdate() |
| 8337 | { |
| 8338 | if (auto pendingSize = std::exchange(m_pendingIntrinsicContentSize, std::nullopt)) |
| 8339 | updateIntrinsicContentSizeIfNeeded(*pendingSize); |
| 8340 | } |
| 8341 | |
| 8342 | void WebPage::scheduleIntrinsicContentSizeUpdate(const IntSize& size) |
| 8343 | { |
| 8344 | if (!minimumSizeForAutoLayout().width() && !sizeToContentAutoSizeMaximumSize().width() && !sizeToContentAutoSizeMaximumSize().height()) |
| 8345 | return; |
| 8346 | ASSERT(localMainFrameView())((void)0); |
| 8347 | ASSERT(localMainFrameView()->isFixedWidthAutoSizeEnabled() || localMainFrameView()->isSizeToContentAutoSizeEnabled())((void)0); |
| 8348 | ASSERT(!localMainFrameView()->needsLayout())((void)0); |
| 8349 | m_pendingIntrinsicContentSize = size; |
| 8350 | } |
| 8351 | |
| 8352 | void WebPage::dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone> milestones) |
| 8353 | { |
| 8354 | RefPtr<API::Object> userData; |
| 8355 | injectedBundleLoaderClient().didReachLayoutMilestone(*this, milestones, userData); |
| 8356 | |
| 8357 | // Clients should not set userData for this message, and it won't be passed through. |
| 8358 | ASSERT(!userData)((void)0); |
| 8359 | |
| 8360 | // The drawing area might want to defer dispatch of didLayout to the UI process. |
| 8361 | if (RefPtr drawingArea = m_drawingArea) { |
| 8362 | static auto paintMilestones = OptionSet<WebCore::LayoutMilestone> { WebCore::LayoutMilestone::DidHitRelevantRepaintedObjectsAreaThreshold, WebCore::LayoutMilestone::DidFirstPaintAfterSuppressedIncrementalRendering, WebCore::LayoutMilestone::DidRenderSignificantAmountOfText, WebCore::LayoutMilestone::DidFirstMeaningfulPaint }; |
| 8363 | auto drawingAreaRelatedMilestones = milestones & paintMilestones; |
| 8364 | if (drawingAreaRelatedMilestones && drawingArea->addMilestonesToDispatch(drawingAreaRelatedMilestones)) |
| 8365 | milestones.remove(drawingAreaRelatedMilestones); |
| 8366 | } |
| 8367 | if (milestones.contains(WebCore::LayoutMilestone::DidFirstLayout) && localMainFrameView()) { |
| 8368 | // Ensure we never send DidFirstLayout milestone without updating the intrinsic size. |
| 8369 | updateIntrinsicContentSizeIfNeeded(localMainFrameView()->autoSizingIntrinsicContentSize()); |
| 8370 | } |
| 8371 | |
| 8372 | send(Messages::WebPageProxy::DidReachLayoutMilestone(milestones, WallTime::now())); |
| 8373 | } |
| 8374 | |
| 8375 | void WebPage::didRestoreScrollPosition() |
| 8376 | { |
| 8377 | send(Messages::WebPageProxy::DidRestoreScrollPosition()); |
| 8378 | } |
| 8379 | |
| 8380 | void WebPage::setUserInterfaceLayoutDirection(uint32_t direction) |
| 8381 | { |
| 8382 | m_userInterfaceLayoutDirection = static_cast<WebCore::UserInterfaceLayoutDirection>(direction); |
| 8383 | protect(corePage())->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection); |
| 8384 | } |
| 8385 | |
| 8386 | #if ENABLE(GAMEPAD)(defined 1 && 1) |
| 8387 | |
| 8388 | void WebPage::gamepadActivity(const Vector<std::optional<GamepadData>>& gamepadDatas, EventMakesGamepadsVisible eventVisibilty) |
| 8389 | { |
| 8390 | WebGamepadProvider::singleton().gamepadActivity(gamepadDatas, eventVisibilty); |
| 8391 | } |
| 8392 | |
| 8393 | void WebPage::gamepadsRecentlyAccessed() |
| 8394 | { |
| 8395 | send(Messages::WebPageProxy::GamepadsRecentlyAccessed()); |
| 8396 | } |
| 8397 | |
| 8398 | #if PLATFORM(VISION)(defined WTF_PLATFORM_VISION && WTF_PLATFORM_VISION) |
| 8399 | void WebPage::allowGamepadAccess() |
| 8400 | { |
| 8401 | corePage()->allowGamepadAccess(); |
| 8402 | } |
| 8403 | #endif |
| 8404 | |
| 8405 | #endif // ENABLE(GAMEPAD) |
| 8406 | |
| 8407 | #if ENABLE(POINTER_LOCK)(defined 1 && 1) |
| 8408 | void WebPage::didAcquirePointerLock() |
| 8409 | { |
| 8410 | corePage()->pointerLockController().didAcquirePointerLock(); |
| 8411 | } |
| 8412 | |
| 8413 | void WebPage::didNotAcquirePointerLock() |
| 8414 | { |
| 8415 | corePage()->pointerLockController().didNotAcquirePointerLock(); |
| 8416 | } |
| 8417 | |
| 8418 | void WebPage::didLosePointerLock() |
| 8419 | { |
| 8420 | corePage()->pointerLockController().didLosePointerLock(); |
| 8421 | } |
| 8422 | #endif |
| 8423 | |
| 8424 | void WebPage::didGetLoadDecisionForIcon(bool decision, CallbackID loadIdentifier, CompletionHandler<void(const IPC::SharedBufferReference&)>&& completionHandler) |
| 8425 | { |
| 8426 | RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame()); |
| 8427 | if (!localMainFrame) |
| 8428 | return completionHandler({ }); |
| 8429 | RefPtr documentLoader = localMainFrame->loader().documentLoader(); |
| 8430 | if (!documentLoader) |
| 8431 | return completionHandler({ }); |
| 8432 | |
| 8433 | documentLoader->didGetLoadDecisionForIcon(decision, loadIdentifier.toInteger(), [completionHandler = WTF::move(completionHandler)] (WebCore::FragmentedSharedBuffer* iconData) mutable { |
| 8434 | completionHandler(IPC::SharedBufferReference(RefPtr { iconData })); |
| 8435 | }); |
| 8436 | } |
| 8437 | |
| 8438 | WebURLSchemeHandlerProxy* WebPage::urlSchemeHandlerForScheme(StringView scheme) |
| 8439 | { |
| 8440 | return m_schemeToURLSchemeHandlerProxyMap.get<StringViewHashTranslator>(scheme); |
| 8441 | } |
| 8442 | |
| 8443 | void WebPage::stopAllURLSchemeTasks() |
| 8444 | { |
| 8445 | HashSet<Ref<WebURLSchemeHandlerProxy>> handlers; |
| 8446 | for (auto& handler : m_schemeToURLSchemeHandlerProxyMap.values()) |
| 8447 | handlers.add(handler); |
| 8448 | |
| 8449 | for (auto& handler : handlers) |
| 8450 | handler->stopAllTasks(); |
| 8451 | } |
| 8452 | |
| 8453 | void WebPage::registerURLSchemeHandler(WebURLSchemeHandlerIdentifier handlerIdentifier, const String& scheme) |
| 8454 | { |
| 8455 | WEBPAGE_RELEASE_LOG(Process, "registerURLSchemeHandler: Registered handler %" PRIu64"ll" "u" " for the '%s' scheme", handlerIdentifier.toUInt64(), scheme.utf8().data()); |
| 8456 | WebCore::LegacySchemeRegistry::registerURLSchemeAsHandledBySchemeHandler(scheme); |
| 8457 | WebCore::LegacySchemeRegistry::registerURLSchemeAsCORSEnabled(scheme); |
| 8458 | auto schemeResult = m_schemeToURLSchemeHandlerProxyMap.add(scheme, WebURLSchemeHandlerProxy::create(*this, handlerIdentifier)); |
| 8459 | m_identifierToURLSchemeHandlerProxyMap.add(handlerIdentifier, Ref { schemeResult.iterator->value }.get()); |
| 8460 | } |
| 8461 | |
| 8462 | void WebPage::urlSchemeTaskWillPerformRedirection(WebURLSchemeHandlerIdentifier handlerIdentifier, WebCore::ResourceLoaderIdentifier taskIdentifier, ResourceResponse&& response, ResourceRequest&& request, CompletionHandler<void(WebCore::ResourceRequest&&)>&& completionHandler) |
| 8463 | { |
| 8464 | RefPtr handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier); |
| 8465 | ASSERT(handler)((void)0); |
| 8466 | |
| 8467 | auto actualNewRequest = request; |
| 8468 | handler->taskDidPerformRedirection(taskIdentifier, WTF::move(response), WTF::move(request), WTF::move(completionHandler)); |
| 8469 | } |
| 8470 | |
| 8471 | void WebPage::urlSchemeTaskDidPerformRedirection(WebURLSchemeHandlerIdentifier handlerIdentifier, WebCore::ResourceLoaderIdentifier taskIdentifier, ResourceResponse&& response, ResourceRequest&& request) |
| 8472 | { |
| 8473 | RefPtr handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier); |
| 8474 | ASSERT(handler)((void)0); |
| 8475 | |
| 8476 | handler->taskDidPerformRedirection(taskIdentifier, WTF::move(response), WTF::move(request), [] (ResourceRequest&&) {}); |
| 8477 | } |
| 8478 | |
| 8479 | void WebPage::urlSchemeTaskDidReceiveResponse(WebURLSchemeHandlerIdentifier handlerIdentifier, WebCore::ResourceLoaderIdentifier taskIdentifier, ResourceResponse&& response) |
| 8480 | { |
| 8481 | RefPtr handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier); |
| 8482 | ASSERT(handler)((void)0); |
| 8483 | |
| 8484 | handler->taskDidReceiveResponse(taskIdentifier, WTF::move(response)); |
| 8485 | } |
| 8486 | |
| 8487 | void WebPage::urlSchemeTaskDidReceiveData(WebURLSchemeHandlerIdentifier handlerIdentifier, WebCore::ResourceLoaderIdentifier taskIdentifier, Ref<WebCore::SharedBuffer>&& data) |
| 8488 | { |
| 8489 | RefPtr handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier); |
| 8490 | ASSERT(handler)((void)0); |
| 8491 | |
| 8492 | handler->taskDidReceiveData(taskIdentifier, WTF::move(data)); |
| 8493 | } |
| 8494 | |
| 8495 | void WebPage::urlSchemeTaskDidComplete(WebURLSchemeHandlerIdentifier handlerIdentifier, WebCore::ResourceLoaderIdentifier taskIdentifier, const ResourceError& error) |
| 8496 | { |
| 8497 | RefPtr handler = m_identifierToURLSchemeHandlerProxyMap.get(handlerIdentifier); |
| 8498 | ASSERT(handler)((void)0); |
| 8499 | |
| 8500 | handler->taskDidComplete(taskIdentifier, error); |
| 8501 | } |
| 8502 | |
| 8503 | void WebPage::setIsSuspended(bool suspended, CompletionHandler<void(std::optional<bool>)>&& completionHandler) |
| 8504 | { |
| 8505 | if (m_isSuspended == suspended) |
| 8506 | return completionHandler({ }); |
| 8507 | |
| 8508 | m_isSuspended = suspended; |
| 8509 | |
| 8510 | if (!suspended) |
| 8511 | return completionHandler({ }); |
| 8512 | |
| 8513 | // Unfrozen on drawing area reset. |
| 8514 | freezeLayerTree(LayerTreeFreezeReason::PageSuspended); |
| 8515 | |
| 8516 | // Only the committed WebPage gets application visibility notifications from the UIProcess, so make sure |
| 8517 | // we don't hold a BackgroundApplication freeze reason when transitioning from committed to suspended. |
| 8518 | unfreezeLayerTree(LayerTreeFreezeReason::BackgroundApplication); |
| 8519 | |
| 8520 | WebProcess::singleton().sendPrewarmInformation(m_mainFrame->url()); |
| 8521 | |
| 8522 | suspendForProcessSwap(WTF::move(completionHandler)); |
| 8523 | } |
| 8524 | |
| 8525 | void WebPage::hasStorageAccess(RegistrableDomain&& subFrameDomain, RegistrableDomain&& topFrameDomain, WebFrame& frame, CompletionHandler<void(bool)>&& completionHandler) |
| 8526 | { |
| 8527 | if (hasPageLevelStorageAccess(topFrameDomain, subFrameDomain)) { |
| 8528 | completionHandler(true); |
| 8529 | return; |
| 8530 | } |
| 8531 | |
| 8532 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::HasStorageAccess(WTF::move(subFrameDomain), WTF::move(topFrameDomain), frame.frameID(), m_identifier), WTF::move(completionHandler)); |
| 8533 | } |
| 8534 | |
| 8535 | void WebPage::requestStorageAccess(RegistrableDomain&& subFrameDomain, RegistrableDomain&& topFrameDomain, WebFrame& frame, StorageAccessScope scope, HasOrShouldIgnoreUserGesture hasOrShouldIgnoreUserGesture, CompletionHandler<void(WebCore::RequestStorageAccessResult)>&& completionHandler) |
| 8536 | { |
| 8537 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::RequestStorageAccess(WTF::move(subFrameDomain), WTF::move(topFrameDomain), frame.frameID(), m_identifier, m_webPageProxyIdentifier, scope, hasOrShouldIgnoreUserGesture), [this, protectedThis = Ref { *this }, completionHandler = WTF::move(completionHandler), frame = Ref { frame }, pageID = m_identifier, frameID = frame.frameID()](RequestStorageAccessResult result) mutable { |
| 8538 | if (result.wasGranted == StorageAccessWasGranted::Yes) { |
| 8539 | switch (result.scope) { |
| 8540 | case StorageAccessScope::PerFrame: |
| 8541 | if (RefPtr localFrameLoaderClient = frame->localFrameLoaderClient()) |
| 8542 | localFrameLoaderClient->setHasFrameSpecificStorageAccess({ frameID, pageID }); |
| 8543 | break; |
| 8544 | case StorageAccessScope::PerPage: |
| 8545 | addDomainWithPageLevelStorageAccess(result.topFrameDomain, result.subFrameDomain); |
| 8546 | break; |
| 8547 | } |
| 8548 | } |
| 8549 | completionHandler(result); |
| 8550 | }); |
| 8551 | } |
| 8552 | |
| 8553 | void WebPage::setLoginStatus(RegistrableDomain&& domain, IsLoggedIn loggedInStatus, CompletionHandler<void()>&& completionHandler) |
| 8554 | { |
| 8555 | RefPtr page = corePage(); |
| 8556 | if (!page) |
| 8557 | return completionHandler(); |
| 8558 | auto lastAuthentication = page->lastAuthentication() ? std::optional(*page->lastAuthentication()) : std::nullopt; |
| 8559 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::SetLoginStatus(WTF::move(domain), loggedInStatus, lastAuthentication), WTF::move(completionHandler)); |
| 8560 | } |
| 8561 | |
| 8562 | void WebPage::isLoggedIn(RegistrableDomain&& domain, CompletionHandler<void(bool)>&& completionHandler) |
| 8563 | { |
| 8564 | WebProcess::singleton().ensureNetworkProcessConnection().connection().sendWithAsyncReply(Messages::NetworkConnectionToWebProcess::IsLoggedIn(WTF::move(domain)), WTF::move(completionHandler)); |
| 8565 | } |
| 8566 | |
| 8567 | void WebPage::addDomainWithPageLevelStorageAccess(const RegistrableDomain& topLevelDomain, const RegistrableDomain& resourceDomain) |
| 8568 | { |
| 8569 | m_internals->domainsWithPageLevelStorageAccess.add(topLevelDomain, HashSet<RegistrableDomain> { }).iterator->value.add(resourceDomain); |
| 8570 | |
| 8571 | // Some sites have quirks where multiple login domains require storage access. |
| 8572 | if (auto additionalLoginDomain = NetworkStorageSession::findAdditionalLoginDomain(topLevelDomain, resourceDomain)) |
| 8573 | m_internals->domainsWithPageLevelStorageAccess.add(topLevelDomain, HashSet<RegistrableDomain> { }).iterator->value.add(*additionalLoginDomain); |
| 8574 | } |
| 8575 | |
| 8576 | bool WebPage::hasPageLevelStorageAccess(const RegistrableDomain& topLevelDomain, const RegistrableDomain& resourceDomain) const |
| 8577 | { |
| 8578 | auto it = m_internals->domainsWithPageLevelStorageAccess.find(topLevelDomain); |
| 8579 | return it != m_internals->domainsWithPageLevelStorageAccess.end() && it->value.contains(resourceDomain); |
| 8580 | } |
| 8581 | |
| 8582 | void WebPage::clearPageLevelStorageAccess() |
| 8583 | { |
| 8584 | m_internals->domainsWithPageLevelStorageAccess.clear(); |
| 8585 | } |
| 8586 | |
| 8587 | void WebPage::revokeFrameSpecificStorageAccess() |
| 8588 | { |
| 8589 | for (RefPtr frame = m_mainFrame->coreFrame(); frame; frame = frame->tree().traverseNext()) { |
| 8590 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame); |
| 8591 | if (!localFrame) |
| 8592 | continue; |
| 8593 | if (auto* client = dynamicDowncast<WebLocalFrameLoaderClient>(localFrame->loader().client())) |
| 8594 | client->revokeFrameSpecificStorageAccess(); |
| 8595 | } |
| 8596 | } |
| 8597 | |
| 8598 | void WebPage::wasLoadedWithDataTransferFromPrevalentResource() |
| 8599 | { |
| 8600 | if (RefPtr localTopDocument = this->localTopDocument()) |
| 8601 | localTopDocument->wasLoadedWithDataTransferFromPrevalentResource(); |
| 8602 | } |
| 8603 | |
| 8604 | void WebPage::didLoadFromRegistrableDomain(RegistrableDomain&& targetDomain) |
| 8605 | { |
| 8606 | if (targetDomain != RegistrableDomain(m_mainFrame->url())) |
| 8607 | m_internals->loadedSubresourceDomains.add(targetDomain); |
| 8608 | } |
| 8609 | |
| 8610 | void WebPage::getLoadedSubresourceDomains(CompletionHandler<void(Vector<RegistrableDomain>)>&& completionHandler) |
| 8611 | { |
| 8612 | completionHandler(copyToVector(m_internals->loadedSubresourceDomains)); |
| 8613 | } |
| 8614 | |
| 8615 | void WebPage::clearLoadedSubresourceDomains() |
| 8616 | { |
| 8617 | m_internals->loadedSubresourceDomains.clear(); |
| 8618 | } |
| 8619 | |
| 8620 | const HashSet<WebCore::RegistrableDomain>& WebPage::loadedSubresourceDomains() const |
| 8621 | { |
| 8622 | return m_internals->loadedSubresourceDomains; |
| 8623 | } |
| 8624 | |
| 8625 | #if ENABLE(DEVICE_ORIENTATION)(defined 1 && 1) |
| 8626 | void WebPage::shouldAllowDeviceOrientationAndMotionAccess(FrameIdentifier frameID, FrameInfoData&& frameInfo, bool mayPrompt, CompletionHandler<void(DeviceOrientationOrMotionPermissionState)>&& completionHandler) |
| 8627 | { |
| 8628 | sendWithAsyncReply(Messages::WebPageProxy::ShouldAllowDeviceOrientationAndMotionAccess(frameID, WTF::move(frameInfo), mayPrompt), WTF::move(completionHandler)); |
| 8629 | } |
| 8630 | #endif |
| 8631 | |
| 8632 | void WebPage::showShareSheet(ShareDataWithParsedURL&& shareData, WTF::CompletionHandler<void(bool)>&& callback) |
| 8633 | { |
| 8634 | sendWithAsyncReply(Messages::WebPageProxy::ShowShareSheet(WTF::move(shareData)), WTF::move(callback)); |
| 8635 | } |
| 8636 | |
| 8637 | void WebPage::showContactPicker(WebCore::ContactsRequestData&& requestData, CompletionHandler<void(std::optional<Vector<WebCore::ContactInfo>>&&)>&& callback) |
| 8638 | { |
| 8639 | sendWithAsyncReply(Messages::WebPageProxy::ShowContactPicker(WTF::move(requestData)), WTF::move(callback)); |
| 8640 | } |
| 8641 | |
| 8642 | #if ENABLE(WEB_AUTHN)(defined 1 && 1) |
| 8643 | void WebPage::showDigitalCredentialsPicker(const WebCore::DigitalCredentialsRequestData& requestData, CompletionHandler<void(Expected<WebCore::DigitalCredentialsResponseData, WebCore::ExceptionData>&&)>&& completionHandler) |
| 8644 | { |
| 8645 | sendWithAsyncReply(Messages::WebPageProxy::ShowDigitalCredentialsPicker(requestData), WTF::move(completionHandler)); |
| 8646 | } |
| 8647 | |
| 8648 | void WebPage::dismissDigitalCredentialsPicker(CompletionHandler<void(bool)>&& completionHandler) |
| 8649 | { |
| 8650 | sendWithAsyncReply(Messages::WebPageProxy::DismissDigitalCredentialsPicker(), WTF::move(completionHandler)); |
| 8651 | } |
| 8652 | #endif |
| 8653 | |
| 8654 | WebCore::DOMPasteAccessResponse WebPage::requestDOMPasteAccess(DOMPasteAccessCategory pasteAccessCategory, FrameIdentifier frameID, const String& originIdentifier) |
| 8655 | { |
| 8656 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 8657 | // FIXME: Computing and sending an autocorrection context is a workaround for the fact that autocorrection context |
| 8658 | // requests on iOS are currently synchronous in the web process. This allows us to immediately fulfill pending |
| 8659 | // autocorrection context requests in the UI process on iOS before handling the DOM paste request. This workaround |
| 8660 | // should be removed once <rdar://problem/16207002> is resolved. |
| 8661 | preemptivelySendAutocorrectionContext(); |
| 8662 | #endif |
| 8663 | |
| 8664 | AXRelayProcessSuspendedNotification(*this); |
| 8665 | |
| 8666 | auto sendResult = sendSyncWithDelayedReply(Messages::WebPageProxy::RequestDOMPasteAccess(pasteAccessCategory, frameID, rectForElementAtInteractionLocation(), originIdentifier)); |
| 8667 | auto [response] = sendResult.takeReplyOr(WebCore::DOMPasteAccessResponse::DeniedForGesture); |
| 8668 | return response; |
| 8669 | } |
| 8670 | |
| 8671 | void WebPage::simulateDeviceMotionChange(double xAcceleration, double yAcceleration, double zAcceleration, double xAccelerationIncludingGravity, double yAccelerationIncludingGravity, double zAccelerationIncludingGravity, double xRotationRate, double yRotationRate, double zRotationRate) |
| 8672 | { |
| 8673 | #if ENABLE(DEVICE_ORIENTATION)(defined 1 && 1) && PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 8674 | for (RefPtr frame = mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 8675 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame.get()); |
| 8676 | if (!localFrame) |
| 8677 | continue; |
| 8678 | |
| 8679 | if (RefPtr document = localFrame->document()) |
| 8680 | document->simulateDeviceMotionChange(xAcceleration, yAcceleration, zAcceleration, xAccelerationIncludingGravity, yAccelerationIncludingGravity, zAccelerationIncludingGravity, xRotationRate, yRotationRate, zRotationRate); |
| 8681 | } |
| 8682 | #endif |
| 8683 | } |
| 8684 | |
| 8685 | void WebPage::simulateDeviceOrientationChange(double alpha, double beta, double gamma) |
| 8686 | { |
| 8687 | #if ENABLE(DEVICE_ORIENTATION)(defined 1 && 1) && PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 8688 | for (RefPtr frame = mainFrame(); frame; frame = frame->tree().traverseNext()) { |
| 8689 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame.get()); |
| 8690 | if (!localFrame) |
| 8691 | continue; |
| 8692 | |
| 8693 | if (RefPtr document = localFrame->document()) |
| 8694 | document->simulateDeviceOrientationChange(alpha, beta, gamma); |
| 8695 | } |
| 8696 | #endif |
| 8697 | } |
| 8698 | |
| 8699 | #if USE(SYSTEM_PREVIEW)(defined 1 && 1) |
| 8700 | void WebPage::systemPreviewActionTriggered(WebCore::SystemPreviewInfo previewInfo, const String& message) |
| 8701 | { |
| 8702 | RefPtr document = Document::allDocumentsMap().get(*previewInfo.element.documentIdentifier); |
| 8703 | if (!document) |
| 8704 | return; |
| 8705 | |
| 8706 | auto pageID = document->pageID(); |
| 8707 | if (!pageID || previewInfo.element.webPageIdentifier != pageID.value()) |
| 8708 | return; |
| 8709 | |
| 8710 | document->dispatchSystemPreviewActionEvent(previewInfo, message); |
| 8711 | } |
| 8712 | #endif |
| 8713 | |
| 8714 | #if ENABLE(SPEECH_SYNTHESIS)(defined 1 && 1) |
| 8715 | void WebPage::speakingErrorOccurred() |
| 8716 | { |
| 8717 | if (auto observer = protect(corePage())->speechSynthesisClient()->observer()) |
| 8718 | observer->speakingErrorOccurred(); |
| 8719 | } |
| 8720 | |
| 8721 | void WebPage::boundaryEventOccurred(bool wordBoundary, unsigned charIndex, unsigned charLength) |
| 8722 | { |
| 8723 | if (auto observer = protect(corePage())->speechSynthesisClient()->observer()) |
| 8724 | observer->boundaryEventOccurred(wordBoundary, charIndex, charLength); |
| 8725 | } |
| 8726 | |
| 8727 | void WebPage::voicesDidChange() |
| 8728 | { |
| 8729 | if (auto observer = protect(corePage())->speechSynthesisClient()->observer()) |
| 8730 | observer->voicesChanged(); |
| 8731 | } |
| 8732 | #endif |
| 8733 | |
| 8734 | #if ENABLE(ATTACHMENT_ELEMENT)(defined 1 && 1) |
| 8735 | |
| 8736 | void WebPage::insertAttachment(const String& identifier, std::optional<uint64_t>&& fileSize, const String& fileName, const String& contentType, CompletionHandler<void()>&& callback) |
| 8737 | { |
| 8738 | RefPtr frame = corePage()->focusController().focusedOrMainFrame(); |
| 8739 | if (!frame) |
| 8740 | return callback(); |
| 8741 | |
| 8742 | protect(frame->editor())->insertAttachment(identifier, WTF::move(fileSize), AtomString { fileName }, AtomString { contentType }); |
| 8743 | callback(); |
| 8744 | } |
| 8745 | |
| 8746 | void WebPage::updateAttachmentAttributes(const String& identifier, std::optional<uint64_t>&& fileSize, const String& contentType, const String& fileName, const IPC::SharedBufferReference& associatedElementData, CompletionHandler<void()>&& callback) |
| 8747 | { |
| 8748 | if (RefPtr attachment = attachmentElementWithIdentifier(identifier)) { |
| 8749 | protect(attachment->document())->updateLayout(); |
| 8750 | attachment->updateAttributes(WTF::move(fileSize), AtomString { contentType }, AtomString { fileName }); |
| 8751 | attachment->updateAssociatedElementWithData(contentType, associatedElementData.isNull() ? WebCore::SharedBuffer::create() : associatedElementData.unsafeBuffer().releaseNonNull()); |
| 8752 | } |
| 8753 | callback(); |
| 8754 | } |
| 8755 | |
| 8756 | void WebPage::updateAttachmentIcon(const String& identifier, std::optional<ShareableBitmap::Handle>&& iconHandle, const WebCore::FloatSize& size) |
| 8757 | { |
| 8758 | if (RefPtr attachment = attachmentElementWithIdentifier(identifier)) { |
| 8759 | if (auto icon = iconHandle ? ShareableBitmap::create(WTF::move(*iconHandle)) : nullptr) { |
| 8760 | if (attachment->isWideLayout()) { |
| 8761 | if (auto imageBuffer = ImageBuffer::create(icon->size(), RenderingMode::Unaccelerated, RenderingPurpose::Unspecified, 1.0, DestinationColorSpace::SRGB(), PixelFormat::BGRA8)) { |
| 8762 | icon->paint(imageBuffer->context(), IntPoint::zero(), IntRect(IntPoint::zero(), icon->size())); |
| 8763 | attachment->updateIconForWideLayout(encodeData(WTF::move(imageBuffer), "image/png"_s)); |
| 8764 | return; |
| 8765 | } |
| 8766 | } else { |
| 8767 | attachment->updateIconForNarrowLayout(icon->createImage(), size); |
| 8768 | return; |
| 8769 | } |
| 8770 | } |
| 8771 | |
| 8772 | if (attachment->isWideLayout()) |
| 8773 | attachment->updateIconForWideLayout({ }); |
| 8774 | else |
| 8775 | attachment->updateIconForNarrowLayout({ }, size); |
| 8776 | } |
| 8777 | } |
| 8778 | |
| 8779 | void WebPage::requestAttachmentIcon(const String& identifier, const WebCore::FloatSize& size) |
| 8780 | { |
| 8781 | if (RefPtr attachment = attachmentElementWithIdentifier(identifier)) { |
| 8782 | String fileName; |
| 8783 | if (RefPtr file = attachment->file()) |
| 8784 | fileName = file->path(); |
| 8785 | send(Messages::WebPageProxy::RequestAttachmentIcon(identifier, attachment->attachmentType(), fileName, attachment->attachmentTitle(), size)); |
| 8786 | } |
| 8787 | } |
| 8788 | |
| 8789 | RefPtr<HTMLAttachmentElement> WebPage::attachmentElementWithIdentifier(const String& identifier) const |
| 8790 | { |
| 8791 | // FIXME: Handle attachment elements in subframes too as well. |
| 8792 | if (RefPtr localTopDocument = this->localTopDocument()) |
| 8793 | return localTopDocument->attachmentForIdentifier(identifier); |
| 8794 | |
| 8795 | return nullptr; |
| 8796 | } |
| 8797 | |
| 8798 | #endif // ENABLE(ATTACHMENT_ELEMENT) |
| 8799 | |
| 8800 | #if ENABLE(APPLICATION_MANIFEST)(defined 1 && 1) |
| 8801 | |
| 8802 | void WebPage::getApplicationManifest(CompletionHandler<void(const std::optional<WebCore::ApplicationManifest>&)>&& completionHandler) |
| 8803 | { |
| 8804 | RefPtr mainFrameDocument = m_mainFrame->coreLocalFrame()->document(); |
| 8805 | RefPtr loader = mainFrameDocument ? mainFrameDocument->loader() : nullptr; |
| 8806 | if (!loader) |
| 8807 | return completionHandler(std::nullopt); |
| 8808 | |
| 8809 | loader->loadApplicationManifest(WTF::move(completionHandler)); |
| 8810 | } |
| 8811 | |
| 8812 | #endif // ENABLE(APPLICATION_MANIFEST) |
| 8813 | |
| 8814 | void WebPage::getTextFragmentMatch(CompletionHandler<void(const String&)>&& completionHandler) |
| 8815 | { |
| 8816 | if (!m_mainFrame->coreLocalFrame()) { |
| 8817 | completionHandler({ }); |
| 8818 | return; |
| 8819 | } |
| 8820 | |
| 8821 | RefPtr document = m_mainFrame->coreLocalFrame()->document(); |
| 8822 | if (!document) { |
| 8823 | completionHandler({ }); |
| 8824 | return; |
| 8825 | } |
| 8826 | |
| 8827 | auto fragmentDirective = document->fragmentDirective(); |
| 8828 | if (fragmentDirective.isEmpty()) { |
| 8829 | completionHandler({ }); |
| 8830 | return; |
| 8831 | } |
| 8832 | FragmentDirectiveParser fragmentDirectiveParser(fragmentDirective); |
| 8833 | if (!fragmentDirectiveParser.isValid()) { |
| 8834 | completionHandler({ }); |
| 8835 | return; |
| 8836 | } |
| 8837 | |
| 8838 | auto parsedTextDirectives = fragmentDirectiveParser.parsedTextDirectives(); |
| 8839 | auto highlightRanges = FragmentDirectiveRangeFinder::findRangesFromTextDirectives(parsedTextDirectives, *document); |
| 8840 | if (highlightRanges.isEmpty()) { |
| 8841 | completionHandler({ }); |
| 8842 | return; |
| 8843 | } |
| 8844 | |
| 8845 | completionHandler(plainText(highlightRanges.first())); |
| 8846 | } |
| 8847 | |
| 8848 | void WebPage::updateCurrentModifierState(OptionSet<PlatformEvent::Modifier> modifiers) |
| 8849 | { |
| 8850 | PlatformKeyboardEvent::setCurrentModifierState(modifiers); |
| 8851 | } |
| 8852 | |
| 8853 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 8854 | |
| 8855 | WebCore::IntRect WebPage::rectForElementAtInteractionLocation() const |
| 8856 | { |
| 8857 | return { }; |
| 8858 | } |
| 8859 | |
| 8860 | void WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded(Element&) |
| 8861 | { |
| 8862 | } |
| 8863 | |
| 8864 | #endif // !PLATFORM(IOS_FAMILY) |
| 8865 | |
| 8866 | void WebPage::setCanShowPlaceholder(const WebCore::ElementContext& elementContext, bool canShowPlaceholder) |
| 8867 | { |
| 8868 | RefPtr<Element> element = elementForContext(elementContext); |
| 8869 | if (RefPtr textFormControl = dynamicDowncast<HTMLTextFormControlElement>(element)) |
| 8870 | textFormControl->setCanShowPlaceholder(canShowPlaceholder); |
| 8871 | } |
| 8872 | |
| 8873 | RefPtr<Element> WebPage::elementForContext(const ElementContext& elementContext) const |
| 8874 | { |
| 8875 | if (elementContext.webPageIdentifier != m_identifier) |
| 8876 | return nullptr; |
| 8877 | |
| 8878 | RefPtr element = elementContext.nodeIdentifier ? dynamicDowncast<Element>(Node::fromIdentifier(*elementContext.nodeIdentifier)) : nullptr; |
| 8879 | if (!element) |
| 8880 | return nullptr; |
| 8881 | |
| 8882 | if (!element->isConnected() || element->document().identifier() != elementContext.documentIdentifier || element->document().page() != m_page.get()) |
| 8883 | return nullptr; |
| 8884 | |
| 8885 | return element; |
| 8886 | } |
| 8887 | |
| 8888 | std::optional<WebCore::ElementContext> WebPage::contextForElement(const WebCore::Element& element) const |
| 8889 | { |
| 8890 | Ref document = element.document(); |
| 8891 | if (!m_page || document->page() != m_page.get()) |
| 8892 | return std::nullopt; |
| 8893 | |
| 8894 | RefPtr frame = document->frame(); |
| 8895 | if (!frame) |
| 8896 | return std::nullopt; |
| 8897 | |
| 8898 | return WebCore::ElementContext { element.boundingBoxInRootViewCoordinates(), m_identifier, document->identifier(), element.nodeIdentifier() }; |
| 8899 | } |
| 8900 | |
| 8901 | void WebPage::startTextManipulations(Vector<WebCore::TextManipulationController::ExclusionRule>&& exclusionRules, bool includeSubframes, CompletionHandler<void()>&& completionHandler) |
| 8902 | { |
| 8903 | if (!m_page) |
| 8904 | return completionHandler(); |
| 8905 | |
| 8906 | m_internals->textManipulationExclusionRules = WTF::move(exclusionRules); |
| 8907 | m_textManipulationIncludesSubframes = includeSubframes; |
| 8908 | if (m_textManipulationIncludesSubframes) { |
| 8909 | for (RefPtr<Frame> frame = m_mainFrame->coreFrame(); frame; frame = frame->tree().traverseNext()) |
| 8910 | startTextManipulationForFrame(*frame); |
| 8911 | } else if (RefPtr frame = m_mainFrame->coreLocalFrame()) |
| 8912 | startTextManipulationForFrame(*frame); |
| 8913 | |
| 8914 | // For now, we assume startObservingParagraphs find all paragraphs synchronously at once. |
| 8915 | completionHandler(); |
| 8916 | } |
| 8917 | |
| 8918 | void WebPage::startTextManipulationForFrame(WebCore::Frame& frame) |
| 8919 | { |
| 8920 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame); |
| 8921 | RefPtr document = localFrame ? localFrame->document() : nullptr; |
| 8922 | if (!document || document->textManipulationControllerIfExists()) |
| 8923 | return; |
| 8924 | |
| 8925 | auto exclusionRules = *m_internals->textManipulationExclusionRules; |
| 8926 | protect(document->textManipulationController())->startObservingParagraphs([webPage = WeakPtr { *this }] (Document& document, const Vector<WebCore::TextManipulationItem>& items) { |
| 8927 | RefPtr frame = document.frame(); |
| 8928 | if (!webPage || !frame) |
| 8929 | return; |
| 8930 | |
| 8931 | RefPtr webFrame = WebFrame::fromCoreFrame(*frame); |
| 8932 | if (!webFrame) |
| 8933 | return; |
| 8934 | |
| 8935 | webPage->send(Messages::WebPageProxy::DidFindTextManipulationItems(items)); |
| 8936 | }, WTF::move(exclusionRules)); |
| 8937 | } |
| 8938 | |
| 8939 | void WebPage::completeTextManipulation(const Vector<WebCore::TextManipulationItem>& items, |
| 8940 | CompletionHandler<void(const WebCore::TextManipulationController::ManipulationResult&)>&& completionHandler) |
| 8941 | { |
| 8942 | if (!m_page) { |
| 8943 | completionHandler({ }); |
| 8944 | return; |
| 8945 | } |
| 8946 | |
| 8947 | if (items.isEmpty()) { |
| 8948 | completionHandler({ }); |
| 8949 | return; |
| 8950 | } |
| 8951 | |
| 8952 | auto currentFrameID = items[0].frameID; |
| 8953 | |
| 8954 | auto completeManipulationForItems = [&](const Vector<WebCore::TextManipulationItem>& items) -> WebCore::TextManipulationController::ManipulationResult { |
| 8955 | ASSERT(!items.isEmpty())((void)0); |
| 8956 | RefPtr frame = WebProcess::singleton().webFrame(currentFrameID); |
| 8957 | if (!frame) |
| 8958 | return { }; |
| 8959 | |
| 8960 | RefPtr coreFrame = frame->coreLocalFrame(); |
| 8961 | if (!coreFrame) |
| 8962 | return { }; |
| 8963 | |
| 8964 | CheckedPtr controller = coreFrame->document()->textManipulationControllerIfExists(); |
| 8965 | if (!controller) |
| 8966 | return { }; |
| 8967 | |
| 8968 | return controller->completeManipulation(items); |
| 8969 | }; |
| 8970 | |
| 8971 | bool containsItemsForMultipleFrames = std::ranges::any_of(items, [&](auto& item) { |
| 8972 | return currentFrameID != item.frameID; |
| 8973 | }); |
| 8974 | if (!containsItemsForMultipleFrames) |
| 8975 | return completionHandler(completeManipulationForItems(items)); |
| 8976 | |
| 8977 | WebCore::TextManipulationController::ManipulationResult resultForAllItems; |
| 8978 | |
| 8979 | auto completeManipulationForCurrentFrame = [&](uint64_t startIndexForCurrentFrame, Vector<WebCore::TextManipulationItem> itemsForCurrentFrame) { |
| 8980 | auto result = completeManipulationForItems(std::exchange(itemsForCurrentFrame, { })); |
| 8981 | for (auto& failure : result.failures) |
| 8982 | failure.index += startIndexForCurrentFrame; |
| 8983 | for (auto& index : result.succeededIndexes) |
| 8984 | index += startIndexForCurrentFrame; |
| 8985 | resultForAllItems.failures.appendVector(WTF::move(result.failures)); |
| 8986 | resultForAllItems.succeededIndexes.appendVector(WTF::move(result.succeededIndexes)); |
| 8987 | }; |
| 8988 | |
| 8989 | uint64_t indexForCurrentItem = 0; |
| 8990 | uint64_t itemCount = 0; |
| 8991 | for (auto& item : items) { |
| 8992 | if (currentFrameID != item.frameID) { |
| 8993 | RELEASE_ASSERT(indexForCurrentItem >= itemCount)do { if (__builtin_expect(!!(!(indexForCurrentItem >= itemCount )), 0)) do { WTF::isIntegralOrPointerType(); compilerFenceForCrash (); WTFCrashWithInfo(8993, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); } while (0); |
| 8994 | completeManipulationForCurrentFrame(indexForCurrentItem - itemCount, items.subspan(indexForCurrentItem - itemCount, itemCount)); |
| 8995 | currentFrameID = item.frameID; |
| 8996 | itemCount = 0; |
| 8997 | } |
| 8998 | ++indexForCurrentItem; |
| 8999 | ++itemCount; |
| 9000 | } |
| 9001 | RELEASE_ASSERT(indexForCurrentItem >= itemCount)do { if (__builtin_expect(!!(!(indexForCurrentItem >= itemCount )), 0)) do { WTF::isIntegralOrPointerType(); compilerFenceForCrash (); WTFCrashWithInfo(9001, "/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit/WebProcess/WebPage/WebPage.cpp" , __PRETTY_FUNCTION__ ); } while (false); } while (0); |
| 9002 | completeManipulationForCurrentFrame(indexForCurrentItem - itemCount, items.subspan(indexForCurrentItem - itemCount, itemCount)); |
| 9003 | |
| 9004 | completionHandler(resultForAllItems); |
| 9005 | } |
| 9006 | |
| 9007 | PAL::SessionID WebPage::sessionID() const |
| 9008 | { |
| 9009 | return WebProcess::singleton().sessionID(); |
| 9010 | } |
| 9011 | |
| 9012 | bool WebPage::usesEphemeralSession() const |
| 9013 | { |
| 9014 | return sessionID().isEphemeral(); |
| 9015 | } |
| 9016 | |
| 9017 | void WebPage::configureLoggingChannel(const String& channelName, WTFLogChannelState state, WTFLogLevel level) |
| 9018 | { |
| 9019 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 9020 | if (RefPtr gpuProcessConnection = WebProcess::singleton().existingGPUProcessConnection()) |
| 9021 | gpuProcessConnection->configureLoggingChannel(channelName, state, level); |
| 9022 | #endif |
| 9023 | |
| 9024 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 9025 | if (auto* modelProcessConnection = WebProcess::singleton().existingModelProcessConnection()) |
| 9026 | modelProcessConnection->configureLoggingChannel(channelName, state, level); |
| 9027 | #endif |
| 9028 | |
| 9029 | send(Messages::WebPageProxy::ConfigureLoggingChannel(channelName, state, level)); |
| 9030 | } |
| 9031 | |
| 9032 | #if !PLATFORM(COCOA)(defined 1 && 1) |
| 9033 | |
| 9034 | void WebPage::getPDFFirstPageSize(WebCore::FrameIdentifier, CompletionHandler<void(WebCore::FloatSize)>&& completionHandler) |
| 9035 | { |
| 9036 | completionHandler({ }); |
| 9037 | } |
| 9038 | |
| 9039 | void WebPage::getProcessDisplayName(CompletionHandler<void(String&&)>&& completionHandler) |
| 9040 | { |
| 9041 | completionHandler({ }); |
| 9042 | } |
| 9043 | |
| 9044 | void WebPage::updateMockAccessibilityElementAfterCommittingLoad() |
| 9045 | { |
| 9046 | } |
| 9047 | |
| 9048 | #endif |
| 9049 | |
| 9050 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) || !ENABLE(DRAG_SUPPORT)(defined 1 && 1) |
| 9051 | |
| 9052 | void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement&) |
| 9053 | { |
| 9054 | } |
| 9055 | |
| 9056 | #endif |
| 9057 | |
| 9058 | #if ENABLE(MODEL_PROCESS)(defined 0 && 0) |
| 9059 | void WebPage::setHasModelElement(bool hasModelElement) |
| 9060 | { |
| 9061 | send(Messages::WebPageProxy::SetHasModelElement(hasModelElement)); |
| 9062 | } |
| 9063 | #endif |
| 9064 | |
| 9065 | #if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1) |
| 9066 | void WebPage::textAutoSizingAdjustmentTimerFired() |
| 9067 | { |
| 9068 | protect(corePage())->recomputeTextAutoSizingInAllFrames(); |
| 9069 | } |
| 9070 | |
| 9071 | void WebPage::textAutosizingUsesIdempotentModeChanged() |
| 9072 | { |
| 9073 | if (!m_page->settings().textAutosizingUsesIdempotentMode()) |
| 9074 | m_textAutoSizingAdjustmentTimer.stop(); |
| 9075 | } |
| 9076 | #endif // ENABLE(TEXT_AUTOSIZING) |
| 9077 | |
| 9078 | #if ENABLE(WEBXR)(defined 0 && 0) |
| 9079 | PlatformXRSystemProxy& WebPage::xrSystemProxy() |
| 9080 | { |
| 9081 | if (!m_xrSystemProxy) |
| 9082 | lazyInitialize(m_xrSystemProxy, makeUniqueWithoutRefCountedCheck<PlatformXRSystemProxy>(*this)); |
| 9083 | return *m_xrSystemProxy; |
| 9084 | } |
| 9085 | #endif |
| 9086 | |
| 9087 | void WebPage::setOverriddenMediaType(const String& mediaType) |
| 9088 | { |
| 9089 | if (mediaType == m_overriddenMediaType) |
| 9090 | return; |
| 9091 | |
| 9092 | m_overriddenMediaType = AtomString(mediaType); |
| 9093 | protect(corePage())->updateStyleAfterChangeInEnvironment(); |
| 9094 | } |
| 9095 | |
| 9096 | void WebPage::updateCORSDisablingPatterns(Vector<String>&& patterns) |
| 9097 | { |
| 9098 | RefPtr page = m_page; |
| 9099 | if (!page) |
| 9100 | return; |
| 9101 | |
| 9102 | m_corsDisablingPatterns = WTF::move(patterns); |
| 9103 | synchronizeCORSDisablingPatternsWithNetworkProcess(); |
| 9104 | page->setCORSDisablingPatterns(parseAndAllowAccessToCORSDisablingPatterns(m_corsDisablingPatterns)); |
| 9105 | } |
| 9106 | |
| 9107 | void WebPage::synchronizeCORSDisablingPatternsWithNetworkProcess() |
| 9108 | { |
| 9109 | // FIXME: We should probably have this mechanism done between UIProcess and NetworkProcess directly. |
| 9110 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::SetCORSDisablingPatterns(m_identifier, m_corsDisablingPatterns), 0); |
| 9111 | } |
| 9112 | |
| 9113 | #if ENABLE(ACCESSIBILITY_ANIMATION_CONTROL)(defined 1 && 1) |
| 9114 | void WebPage::isAnyAnimationAllowedToPlayDidChange(bool anyAnimationCanPlay) |
| 9115 | { |
| 9116 | send(Messages::WebPageProxy::IsAnyAnimationAllowedToPlayDidChange(anyAnimationCanPlay)); |
| 9117 | } |
| 9118 | #endif |
| 9119 | |
| 9120 | void WebPage::isPlayingMediaDidChange(WebCore::MediaProducerMediaStateFlags state) |
| 9121 | { |
| 9122 | send(Messages::WebPageProxy::IsPlayingMediaDidChange(state)); |
| 9123 | } |
| 9124 | |
| 9125 | #if ENABLE(MEDIA_USAGE)(defined ENABLE_MEDIA_USAGE && ENABLE_MEDIA_USAGE) |
| 9126 | void WebPage::addMediaUsageManagerSession(MediaSessionIdentifier identifier, const String& bundleIdentifier, const URL& pageURL) |
| 9127 | { |
| 9128 | send(Messages::WebPageProxy::AddMediaUsageManagerSession(identifier, bundleIdentifier, pageURL)); |
| 9129 | } |
| 9130 | |
| 9131 | void WebPage::updateMediaUsageManagerSessionState(MediaSessionIdentifier identifier, const MediaUsageInfo& usage) |
| 9132 | { |
| 9133 | send(Messages::WebPageProxy::UpdateMediaUsageManagerSessionState(identifier, usage)); |
| 9134 | } |
| 9135 | |
| 9136 | void WebPage::removeMediaUsageManagerSession(MediaSessionIdentifier identifier) |
| 9137 | { |
| 9138 | send(Messages::WebPageProxy::RemoveMediaUsageManagerSession(identifier)); |
| 9139 | } |
| 9140 | #endif // ENABLE(MEDIA_USAGE) |
| 9141 | |
| 9142 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) |
| 9143 | |
| 9144 | void WebPage::requestTextRecognition(Element& element, TextRecognitionOptions&& options, CompletionHandler<void(RefPtr<Element>&&)>&& completion) |
| 9145 | { |
| 9146 | RefPtr htmlElement = dynamicDowncast<HTMLElement>(element); |
| 9147 | if (!htmlElement) { |
| 9148 | if (completion) |
| 9149 | completion({ }); |
| 9150 | return; |
| 9151 | } |
| 9152 | |
| 9153 | if (protect(corePage())->hasCachedTextRecognitionResult(*htmlElement)) { |
| 9154 | if (completion) { |
| 9155 | RefPtr<Element> imageOverlayHost; |
| 9156 | if (ImageOverlay::hasOverlay(*htmlElement)) |
| 9157 | imageOverlayHost = element; |
| 9158 | completion(WTF::move(imageOverlayHost)); |
| 9159 | } |
| 9160 | return; |
| 9161 | } |
| 9162 | |
| 9163 | auto matchIndex = m_elementsPendingTextRecognition.findIf([&] (auto& elementAndCompletionHandlers) { |
| 9164 | return elementAndCompletionHandlers.first == &element; |
| 9165 | }); |
| 9166 | |
| 9167 | if (matchIndex != notFound) { |
| 9168 | if (completion) |
| 9169 | m_elementsPendingTextRecognition[matchIndex].second.append(WTF::move(completion)); |
| 9170 | return; |
| 9171 | } |
| 9172 | |
| 9173 | CheckedPtr renderImage = dynamicDowncast<RenderImage>(element.renderer()); |
| 9174 | if (!renderImage) { |
| 9175 | if (completion) |
| 9176 | completion({ }); |
| 9177 | return; |
| 9178 | } |
| 9179 | |
| 9180 | Vector<CompletionHandler<void(RefPtr<Element>&&)>> completionHandlers; |
| 9181 | if (completion) |
| 9182 | completionHandlers.append(WTF::move(completion)); |
| 9183 | m_elementsPendingTextRecognition.append({ WeakPtr { element }, WTF::move(completionHandlers) }); |
| 9184 | |
| 9185 | auto bitmap = createShareableBitmapAsync(*renderImage, { |
| 9186 | std::nullopt, |
| 9187 | AllowAnimatedImages::No, |
| 9188 | options.allowSnapshots == TextRecognitionOptions::AllowSnapshots::Yes ? UseSnapshotForTransparentImages::Yes : UseSnapshotForTransparentImages::No |
| 9189 | })->whenSettled(RunLoop::mainSingleton(), [weakThis = WeakPtr { *this }, weakElement = WeakPtr { *htmlElement }, options = WTF::move(options)](auto&& result) mutable { |
| 9190 | |
| 9191 | auto resolveAndRemoveHandlerFollowingError = [weakPage = weakThis](WeakPtr<WebCore::HTMLElement, WebCore::WeakPtrImplWithEventTargetData>& originalElement) { |
| 9192 | RefPtr page = weakPage.get(); |
| 9193 | if (!page) |
| 9194 | return; |
| 9195 | |
| 9196 | page->m_elementsPendingTextRecognition.removeAllMatching([&] (auto& elementAndCompletionHandlers) { |
| 9197 | auto& [element, completionHandlers] = elementAndCompletionHandlers; |
| 9198 | if (element.get() && originalElement != element) |
| 9199 | return false; |
| 9200 | |
| 9201 | for (auto& completionHandler : completionHandlers) { |
| 9202 | if (completionHandler) |
| 9203 | completionHandler({ }); |
| 9204 | } |
| 9205 | return true; |
| 9206 | }); |
| 9207 | }; |
| 9208 | |
| 9209 | if (!weakThis || !result || !weakElement) { |
| 9210 | resolveAndRemoveHandlerFollowingError(weakElement); |
| 9211 | return; |
| 9212 | } |
| 9213 | |
| 9214 | auto bitmapHandle = (*result)->createHandle(); |
| 9215 | if (!bitmapHandle) { |
| 9216 | resolveAndRemoveHandlerFollowingError(weakElement); |
| 9217 | return; |
| 9218 | } |
| 9219 | |
| 9220 | CheckedPtr renderImage = dynamicDowncast<RenderImage>(weakElement->renderer()); |
| 9221 | if (!renderImage) { |
| 9222 | resolveAndRemoveHandlerFollowingError(weakElement); |
| 9223 | return; |
| 9224 | } |
| 9225 | |
| 9226 | RefPtr protectedThis = weakThis.get(); |
| 9227 | if (!protectedThis) |
| 9228 | return; |
| 9229 | |
| 9230 | auto cachedImage = renderImage->cachedImage(); |
| 9231 | auto imageURL = cachedImage ? protect(weakElement->document())->completeURL(cachedImage->url().string()) : URL { }; |
| 9232 | protectedThis->sendWithAsyncReply(Messages::WebPageProxy::RequestTextRecognition(WTF::move(imageURL), WTF::move(*bitmapHandle), options.sourceLanguageIdentifier, options.targetLanguageIdentifier), [weakThis, weakElement, resolveAndRemoveHandlerFollowingError = WTF::move(resolveAndRemoveHandlerFollowingError)] (auto&& result) mutable { |
| 9233 | RefPtr protectedThis = weakThis.get(); |
| 9234 | if (!protectedThis) |
| 9235 | return; |
| 9236 | |
| 9237 | RefPtr htmlElement = weakElement.get(); |
| 9238 | if (!htmlElement) { |
| 9239 | resolveAndRemoveHandlerFollowingError(weakElement); |
| 9240 | return; |
| 9241 | } |
| 9242 | |
| 9243 | ImageOverlay::updateWithTextRecognitionResult(*htmlElement, result); |
| 9244 | |
| 9245 | auto matchIndex = protectedThis->m_elementsPendingTextRecognition.findIf([&] (auto& elementAndCompletionHandlers) { |
| 9246 | return elementAndCompletionHandlers.first == htmlElement.get(); |
| 9247 | }); |
| 9248 | |
| 9249 | if (matchIndex == notFound) |
| 9250 | return; |
| 9251 | |
| 9252 | RefPtr imageOverlayHost = ImageOverlay::hasOverlay(*htmlElement) ? htmlElement.get() : nullptr; |
| 9253 | for (auto& completionHandler : protectedThis->m_elementsPendingTextRecognition[matchIndex].second) |
| 9254 | completionHandler(imageOverlayHost.copyRef()); |
| 9255 | |
| 9256 | protectedThis->m_elementsPendingTextRecognition.removeAt(matchIndex); |
| 9257 | }); |
| 9258 | }); |
| 9259 | } |
| 9260 | |
| 9261 | void WebPage::updateWithTextRecognitionResult(const TextRecognitionResult& result, const ElementContext& context, const FloatPoint& location, CompletionHandler<void(TextRecognitionUpdateResult)>&& completionHandler) |
| 9262 | { |
| 9263 | auto elementToUpdate = elementForContext(context); |
| 9264 | RefPtr htmlElementToUpdate = dynamicDowncast<HTMLElement>(elementToUpdate); |
| 9265 | if (!htmlElementToUpdate) { |
| 9266 | completionHandler(TextRecognitionUpdateResult::NoText); |
| 9267 | return; |
| 9268 | } |
| 9269 | |
| 9270 | RefPtr localMainFrame = dynamicDowncast<WebCore::LocalFrame>(corePage()->mainFrame()); |
| 9271 | if (!localMainFrame) { |
| 9272 | completionHandler(TextRecognitionUpdateResult::NoText); |
| 9273 | return; |
| 9274 | } |
| 9275 | |
| 9276 | ImageOverlay::updateWithTextRecognitionResult(*htmlElementToUpdate, result); |
| 9277 | auto hitTestResult = localMainFrame->eventHandler().hitTestResultAtPoint(roundedIntPoint(location), { |
| 9278 | HitTestRequest::Type::ReadOnly, |
| 9279 | HitTestRequest::Type::Active, |
| 9280 | HitTestRequest::Type::AllowVisibleChildFrameContentOnly, |
| 9281 | }); |
| 9282 | |
| 9283 | RefPtr nodeAtLocation = hitTestResult.innerNonSharedNode(); |
| 9284 | auto updateResult = ([&] { |
| 9285 | if (!nodeAtLocation || nodeAtLocation->shadowHost() != elementToUpdate || !ImageOverlay::isInsideOverlay(*nodeAtLocation)) |
| 9286 | return TextRecognitionUpdateResult::NoText; |
| 9287 | |
| 9288 | #if ENABLE(DATA_DETECTION)(defined 1 && 1) |
| 9289 | if (DataDetection::findDataDetectionResultElementInImageOverlay(location, *htmlElementToUpdate)) |
| 9290 | return TextRecognitionUpdateResult::DataDetector; |
| 9291 | #endif |
| 9292 | |
| 9293 | if (ImageOverlay::isOverlayText(*nodeAtLocation)) |
| 9294 | return TextRecognitionUpdateResult::Text; |
| 9295 | |
| 9296 | return TextRecognitionUpdateResult::NoText; |
| 9297 | })(); |
| 9298 | |
| 9299 | completionHandler(updateResult); |
| 9300 | } |
| 9301 | |
| 9302 | void WebPage::startVisualTranslation(const String& sourceLanguageIdentifier, const String& targetLanguageIdentifier) |
| 9303 | { |
| 9304 | RefPtr frame = m_mainFrame->coreFrame(); |
| 9305 | if (!frame) |
| 9306 | return; |
| 9307 | |
| 9308 | protect(protect(corePage())->imageAnalysisQueue())->enqueueAllImagesIfNeeded(*frame, sourceLanguageIdentifier, targetLanguageIdentifier); |
| 9309 | } |
| 9310 | |
| 9311 | #endif // ENABLE(IMAGE_ANALYSIS) |
| 9312 | |
| 9313 | void WebPage::requestImageBitmap(const ElementContext& context, CompletionHandler<void(std::optional<ShareableBitmap::Handle>&&, const String& sourceMIMEType)>&& completion) |
| 9314 | { |
| 9315 | RefPtr element = elementForContext(context); |
| 9316 | if (!element) { |
| 9317 | completion({ }, { }); |
| 9318 | return; |
| 9319 | } |
| 9320 | |
| 9321 | CheckedPtr renderImage = dynamicDowncast<RenderImage>(element->renderer()); |
| 9322 | if (!renderImage) { |
| 9323 | completion({ }, { }); |
| 9324 | return; |
| 9325 | } |
| 9326 | |
| 9327 | auto bitmap = createShareableBitmap(*renderImage); |
| 9328 | if (!bitmap) { |
| 9329 | completion({ }, { }); |
| 9330 | return; |
| 9331 | } |
| 9332 | |
| 9333 | auto handle = bitmap->createHandle(); |
| 9334 | if (!handle) { |
| 9335 | completion({ }, { }); |
| 9336 | return; |
| 9337 | } |
| 9338 | |
| 9339 | String mimeType; |
| 9340 | if (auto* cachedImage = renderImage->cachedImage()) { |
Local variable 'cachedImage' is uncounted and unsafe | |
| 9341 | if (RefPtr image = cachedImage->image()) |
| 9342 | mimeType = image->mimeType(); |
| 9343 | } |
| 9344 | ASSERT(!mimeType.isEmpty())((void)0); |
| 9345 | completion(WTF::move(*handle), mimeType); |
| 9346 | } |
| 9347 | |
| 9348 | #if ENABLE(MEDIA_CONTROLS_CONTEXT_MENUS)(defined 1 && 1) && USE(UICONTEXTMENU)(defined 1 && 1) |
| 9349 | void WebPage::showMediaControlsContextMenu(FloatRect&& targetFrame, Vector<MediaControlsContextMenuItem>&& items, WebCore::HTMLMediaElementIdentifier identifier, CompletionHandler<void(MediaControlsContextMenuItem::ID)>&& completionHandler) |
| 9350 | { |
| 9351 | RefPtr frame = m_mainFrame->coreFrame(); |
| 9352 | if (!frame) { |
| 9353 | completionHandler(MediaControlsContextMenuItem::invalidID); |
| 9354 | return; |
| 9355 | } |
| 9356 | |
| 9357 | sendWithAsyncReply(Messages::WebPageProxy::ShowMediaControlsContextMenu(WTF::move(targetFrame), WTF::move(items), protect(WebFrame::fromCoreFrame(*frame))->info(), identifier), completionHandler); |
| 9358 | } |
| 9359 | #endif // ENABLE(MEDIA_CONTROLS_CONTEXT_MENUS) && USE(UICONTEXTMENU) |
| 9360 | |
| 9361 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 9362 | |
| 9363 | void WebPage::animationDidFinishForElement(const WebCore::Element&) |
| 9364 | { |
| 9365 | } |
| 9366 | |
| 9367 | #endif |
| 9368 | |
| 9369 | #if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1) |
| 9370 | void WebPage::setIsNavigatingToAppBoundDomain(std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, WebFrame& frame) |
| 9371 | { |
| 9372 | frame.setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain); |
| 9373 | |
| 9374 | m_navigationHasOccured = true; |
| 9375 | } |
| 9376 | |
| 9377 | void WebPage::notifyPageOfAppBoundBehavior() |
| 9378 | { |
| 9379 | if (!m_navigationHasOccured && !m_limitsNavigationsToAppBoundDomains) |
| 9380 | send(Messages::WebPageProxy::SetHasExecutedAppBoundBehaviorBeforeNavigation()); |
| 9381 | } |
| 9382 | #endif |
| 9383 | |
| 9384 | #if ENABLE(GPU_PROCESS)(defined 1 && 1) |
| 9385 | RemoteRenderingBackendProxy& WebPage::ensureRemoteRenderingBackendProxy() |
| 9386 | { |
| 9387 | if (!m_remoteRenderingBackendProxy) |
| 9388 | m_remoteRenderingBackendProxy = RemoteRenderingBackendProxy::create(*this); |
| 9389 | return *m_remoteRenderingBackendProxy; |
| 9390 | } |
| 9391 | #endif |
| 9392 | |
| 9393 | Vector<Ref<SandboxExtension>> WebPage::consumeSandboxExtensions(Vector<SandboxExtension::Handle>&& sandboxExtensions) |
| 9394 | { |
| 9395 | return WTF::compactMap(WTF::move(sandboxExtensions), [](SandboxExtension::Handle&& sandboxExtension) -> RefPtr<SandboxExtension> { |
| 9396 | auto extension = SandboxExtension::create(WTF::move(sandboxExtension)); |
| 9397 | if (!extension) |
| 9398 | return nullptr; |
| 9399 | bool ok = extension->consume(); |
| 9400 | ASSERT_UNUSED(ok, ok)((void)ok); |
| 9401 | return extension; |
| 9402 | }); |
| 9403 | } |
| 9404 | |
| 9405 | void WebPage::revokeSandboxExtensions(Vector<Ref<SandboxExtension>>& sandboxExtensions) |
| 9406 | { |
| 9407 | for (auto& sandboxExtension : sandboxExtensions) |
| 9408 | sandboxExtension->revoke(); |
| 9409 | sandboxExtensions.clear(); |
| 9410 | } |
| 9411 | |
| 9412 | void WebPage::createTextFragmentDirectiveFromSelection(CompletionHandler<void(URL&&)>&& completionHandler) |
| 9413 | { |
| 9414 | auto url = protect(corePage())->fragmentDirectiveURLForSelectedText(); |
| 9415 | completionHandler(WTF::move(url)); |
| 9416 | } |
| 9417 | |
| 9418 | void WebPage::getTextFragmentRanges(CompletionHandler<void(const Vector<EditingRange>&&)>&& completionHandler) |
| 9419 | { |
| 9420 | RefPtr focusedOrMainFrame = corePage()->focusController().focusedOrMainFrame(); |
| 9421 | if (!focusedOrMainFrame) { |
| 9422 | completionHandler({ }); |
| 9423 | return; |
| 9424 | } |
| 9425 | RefPtr document = focusedOrMainFrame->document(); |
| 9426 | |
| 9427 | RefPtr frame = document->frame(); |
| 9428 | if (!frame) { |
| 9429 | completionHandler({ }); |
| 9430 | return; |
| 9431 | } |
| 9432 | |
| 9433 | Vector<EditingRange> editingRanges; |
| 9434 | if (RefPtr highlightRegistry = document->fragmentHighlightRegistryIfExists()) { |
| 9435 | for (auto& highlight : highlightRegistry->map()) { |
| 9436 | for (auto& highlightRange : highlight.value->highlightRanges()) { |
| 9437 | Ref<AbstractRange> range = highlightRange->range(); |
| 9438 | editingRanges.append(EditingRange::fromRange(*frame, makeSimpleRange(range))); |
| 9439 | } |
| 9440 | } |
| 9441 | } |
| 9442 | |
| 9443 | completionHandler(WTF::move(editingRanges)); |
| 9444 | } |
| 9445 | |
| 9446 | #if ENABLE(APP_HIGHLIGHTS)(defined 1 && 1) |
| 9447 | WebCore::CreateNewGroupForHighlight WebPage::highlightIsNewGroup() const |
| 9448 | { |
| 9449 | return m_internals->highlightIsNewGroup; |
| 9450 | } |
| 9451 | |
| 9452 | WebCore::HighlightRequestOriginatedInApp WebPage::highlightRequestOriginatedInApp() const |
| 9453 | { |
| 9454 | return m_internals->highlightRequestOriginatedInApp; |
| 9455 | } |
| 9456 | |
| 9457 | void WebPage::createAppHighlightInSelectedRange(WebCore::CreateNewGroupForHighlight createNewGroup, WebCore::HighlightRequestOriginatedInApp requestOriginatedInApp, CompletionHandler<void(WebCore::AppHighlight&&)>&& completionHandler) |
| 9458 | { |
| 9459 | SetForScope highlightIsNewGroupScope { m_internals->highlightIsNewGroup, createNewGroup }; |
| 9460 | SetForScope highlightRequestOriginScope { m_internals->highlightRequestOriginatedInApp, requestOriginatedInApp }; |
| 9461 | |
| 9462 | RefPtr focusedOrMainFrame = corePage()->focusController().focusedOrMainFrame(); |
| 9463 | if (!focusedOrMainFrame) |
| 9464 | return; |
| 9465 | RefPtr document = focusedOrMainFrame->document(); |
| 9466 | |
| 9467 | RefPtr frame = document->frame(); |
| 9468 | if (!frame) |
| 9469 | return; |
| 9470 | |
| 9471 | auto selectionRange = frame->selection().selection().toNormalizedRange(); |
| 9472 | if (!selectionRange) |
| 9473 | return; |
| 9474 | |
| 9475 | protect(document->appHighlightRegistry())->addAnnotationHighlightWithRange(StaticRange::create(selectionRange.value())); |
| 9476 | document->appHighlightStorage().storeAppHighlight(StaticRange::create(selectionRange.value()), [completionHandler = WTF::move(completionHandler), protectedThis = Ref { *this }, this] (WebCore::AppHighlight&& highlight) mutable { |
| 9477 | highlight.isNewGroup = m_internals->highlightIsNewGroup; |
| 9478 | highlight.requestOriginatedInApp = m_internals->highlightRequestOriginatedInApp; |
| 9479 | completionHandler(WTF::move(highlight)); |
| 9480 | }); |
| 9481 | } |
| 9482 | |
| 9483 | void WebPage::restoreAppHighlightsAndScrollToIndex(Vector<SharedMemory::Handle>&& memoryHandles, const std::optional<unsigned> index) |
| 9484 | { |
| 9485 | RefPtr focusedOrMainFrame = corePage()->focusController().focusedOrMainFrame(); |
| 9486 | if (!focusedOrMainFrame) |
| 9487 | return; |
| 9488 | RefPtr document = focusedOrMainFrame->document(); |
| 9489 | |
| 9490 | unsigned i = 0; |
| 9491 | for (auto&& handle : memoryHandles) { |
| 9492 | auto sharedMemory = SharedMemory::map(WTF::move(handle), SharedMemory::Protection::ReadOnly); |
| 9493 | if (!sharedMemory) |
| 9494 | continue; |
| 9495 | |
| 9496 | document->appHighlightStorage().restoreAndScrollToAppHighlight(sharedMemory->createSharedBuffer(handle.size()), i == index ? ScrollToHighlight::Yes : ScrollToHighlight::No); |
| 9497 | i++; |
| 9498 | } |
| 9499 | } |
| 9500 | |
| 9501 | void WebPage::setAppHighlightsVisibility(WebCore::HighlightVisibility appHighlightVisibility) |
| 9502 | { |
| 9503 | m_appHighlightsVisible = appHighlightVisibility; |
| 9504 | for (RefPtr<Frame> frame = m_mainFrame->coreLocalFrame(); frame; frame = frame->tree().traverseNextRendered()) { |
| 9505 | RefPtr localFrame = dynamicDowncast<LocalFrame>(frame.get()); |
| 9506 | if (!localFrame) |
| 9507 | continue; |
| 9508 | if (RefPtr document = localFrame->document()) |
| 9509 | protect(document->appHighlightRegistry())->setHighlightVisibility(appHighlightVisibility); |
| 9510 | } |
| 9511 | } |
| 9512 | |
| 9513 | #endif |
| 9514 | |
| 9515 | #if ENABLE(MEDIA_SESSION_COORDINATOR)(defined ENABLE_MEDIA_SESSION_COORDINATOR && ENABLE_MEDIA_SESSION_COORDINATOR ) |
| 9516 | void WebPage::createMediaSessionCoordinator(const String& identifier, CompletionHandler<void(bool)>&& completionHandler) |
| 9517 | { |
| 9518 | RefPtr document = m_mainFrame->coreLocalFrame()->document(); |
| 9519 | if (!document || !document->window()) { |
| 9520 | completionHandler(false); |
| 9521 | return; |
| 9522 | } |
| 9523 | |
| 9524 | protect(corePage())->setMediaSessionCoordinator(RemoteMediaSessionCoordinator::create(*this, identifier)); |
| 9525 | completionHandler(true); |
| 9526 | } |
| 9527 | #endif |
| 9528 | |
| 9529 | void WebPage::lastNavigationWasAppInitiated(CompletionHandler<void(bool)>&& completionHandler) |
| 9530 | { |
| 9531 | RefPtr localTopDocument = this->localTopDocument(); |
| 9532 | if (!localTopDocument) |
| 9533 | return completionHandler(false); |
| 9534 | return completionHandler(localTopDocument->loader()->lastNavigationWasAppInitiated()); |
| 9535 | } |
| 9536 | |
| 9537 | #if HAVE(TRANSLATION_UI_SERVICES)(defined 1 && 1) && ENABLE(CONTEXT_MENUS)(defined 0 && 0) |
| 9538 | |
| 9539 | void WebPage::handleContextMenuTranslation(const TranslationContextMenuInfo& info) |
| 9540 | { |
| 9541 | send(Messages::WebPageProxy::HandleContextMenuTranslation(info)); |
| 9542 | } |
| 9543 | #endif |
| 9544 | |
| 9545 | void WebPage::scrollToRect(const WebCore::FloatRect& targetRect, const WebCore::FloatPoint&) |
| 9546 | { |
| 9547 | RefPtr frameView = localMainFrameView(); |
| 9548 | if (!frameView) |
| 9549 | return; |
| 9550 | frameView->setScrollPosition(IntPoint(targetRect.minXMinYCorner())); |
| 9551 | } |
| 9552 | |
| 9553 | void WebPage::setContentOffset(std::optional<int> x, std::optional<int> y, WebCore::ScrollIsAnimated animated) |
| 9554 | { |
| 9555 | RefPtr frameView = localMainFrameView(); |
| 9556 | if (!frameView) |
| 9557 | return; |
| 9558 | |
| 9559 | auto options = WebCore::ScrollPositionChangeOptions::createProgrammatic(); |
| 9560 | options.animated = animated; |
| 9561 | |
| 9562 | frameView->setScrollOffsetWithOptions(x, y, options); |
| 9563 | } |
| 9564 | |
| 9565 | void WebPage::scrollToEdge(WebCore::RectEdges<bool> edges, WebCore::ScrollIsAnimated animated) |
| 9566 | { |
| 9567 | RefPtr frameView = localMainFrameView(); |
| 9568 | if (!frameView) |
| 9569 | return; |
| 9570 | |
| 9571 | auto options = WebCore::ScrollPositionChangeOptions::createProgrammatic(); |
| 9572 | options.animated = animated; |
| 9573 | |
| 9574 | frameView->scrollToEdgeWithOptions(edges, options); |
| 9575 | } |
| 9576 | |
| 9577 | #if ENABLE(IMAGE_ANALYSIS)(defined 1 && 1) && ENABLE(VIDEO)(defined 1 && 1) |
| 9578 | void WebPage::beginTextRecognitionForVideoInElementFullScreen(const HTMLVideoElement& element) |
| 9579 | { |
| 9580 | CheckedPtr renderer = element.renderer(); |
| 9581 | if (!renderer) |
| 9582 | return; |
| 9583 | |
| 9584 | auto rectInRootView = renderer->videoBoxInRootView(); |
| 9585 | if (rectInRootView.isEmpty()) |
| 9586 | return; |
| 9587 | |
| 9588 | m_elementIsPerformingTextRecognitionInElementFullScreen = element.identifier(); |
| 9589 | element.bitmapImageForCurrentTime()->whenSettled(RunLoop::mainSingleton(), [weakThis = WeakPtr { *this }, rectInRootView, identifier = element.identifier()](auto&& result) { |
| 9590 | if (!result) |
| 9591 | return; |
| 9592 | RefPtr protectedThis = weakThis.get(); |
| 9593 | if (!protectedThis || protectedThis->m_elementIsPerformingTextRecognitionInElementFullScreen != identifier) |
| 9594 | return; |
| 9595 | if (auto handle = (*result)->createHandle()) |
| 9596 | protectedThis->send(Messages::WebPageProxy::BeginTextRecognitionForVideoInElementFullScreen(processQualify(identifier), WTF::move(*handle), rectInRootView)); |
| 9597 | protectedThis->m_elementIsPerformingTextRecognitionInElementFullScreen.reset(); |
| 9598 | }); |
| 9599 | } |
| 9600 | |
| 9601 | void WebPage::cancelTextRecognitionForVideoInElementFullScreen() |
| 9602 | { |
| 9603 | m_elementIsPerformingTextRecognitionInElementFullScreen.reset(); |
| 9604 | send(Messages::WebPageProxy::CancelTextRecognitionForVideoInElementFullScreen()); |
| 9605 | } |
| 9606 | #endif // ENABLE(IMAGE_ANALYSIS) && ENABLE(VIDEO) |
| 9607 | |
| 9608 | #if ENABLE(ARKIT_INLINE_PREVIEW_IOS)(defined 0 && 0) |
| 9609 | void WebPage::modelInlinePreviewDidLoad(WebCore::PlatformLayerIdentifier layerID) |
| 9610 | { |
| 9611 | ARKitInlinePreviewModelPlayerIOS::pageLoadedModelInlinePreview(*this, layerID); |
| 9612 | } |
| 9613 | |
| 9614 | void WebPage::modelInlinePreviewDidFailToLoad(WebCore::PlatformLayerIdentifier layerID, const WebCore::ResourceError& error) |
| 9615 | { |
| 9616 | ARKitInlinePreviewModelPlayerIOS::pageFailedToLoadModelInlinePreview(*this, layerID, error); |
| 9617 | } |
| 9618 | #endif |
| 9619 | |
| 9620 | #if ENABLE(IMAGE_ANALYSIS_ENHANCEMENTS)(defined 1 && 1) |
| 9621 | |
| 9622 | void WebPage::shouldAllowRemoveBackground(const ElementContext& context, CompletionHandler<void(bool)>&& completion) const |
| 9623 | { |
| 9624 | auto element = elementForContext(context); |
| 9625 | completion(element && !m_elementsToExcludeFromRemoveBackground.contains(*element)); |
| 9626 | } |
| 9627 | |
| 9628 | #endif |
| 9629 | |
| 9630 | #if HAVE(UIKIT_RESIZABLE_WINDOWS)(defined 1 && 1) |
| 9631 | |
| 9632 | void WebPage::setIsWindowResizingEnabled(bool value) |
| 9633 | { |
| 9634 | if (m_isWindowResizingEnabled == value) |
| 9635 | return; |
| 9636 | |
| 9637 | m_isWindowResizingEnabled = value; |
| 9638 | m_viewportConfiguration.setPrefersHorizontalScrollingBelowDesktopViewportWidths(shouldEnableViewportBehaviorsForResizableWindows()); |
| 9639 | } |
| 9640 | |
| 9641 | #endif // HAVE(UIKIT_RESIZABLE_WINDOWS) |
| 9642 | |
| 9643 | #if ENABLE(INTERACTION_REGIONS_IN_EVENT_REGION)(defined ENABLE_INTERACTION_REGIONS_IN_EVENT_REGION && ENABLE_INTERACTION_REGIONS_IN_EVENT_REGION) |
| 9644 | |
| 9645 | void WebPage::setInteractionRegionsEnabled(bool enable) |
| 9646 | { |
| 9647 | WEBPAGE_RELEASE_LOG(Process, "setInteractionRegionsEnabled: enable state = %d for page %p", (int)enable, (void*)m_page.get()); |
| 9648 | if (!m_page) |
| 9649 | return; |
| 9650 | |
| 9651 | m_page->setInteractionRegionsEnabled(enable); |
| 9652 | } |
| 9653 | |
| 9654 | #endif // ENABLE(INTERACTION_REGIONS_IN_EVENT_REGION) |
| 9655 | |
| 9656 | bool WebPage::handlesPageScaleGesture() |
| 9657 | { |
| 9658 | #if !ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 9659 | return false; |
| 9660 | #else |
| 9661 | RefPtr plugin = mainFramePlugIn(); |
| 9662 | return plugin && plugin->pluginHandlesPageScaleFactor(); |
| 9663 | #endif |
| 9664 | } |
| 9665 | |
| 9666 | void WebPage::generateTestReport(String&& message, String&& group) |
| 9667 | { |
| 9668 | if (RefPtr localTopDocument = this->localTopDocument()) |
| 9669 | protect(localTopDocument->reportingScope())->generateTestReport(WTF::move(message), WTF::move(group)); |
| 9670 | } |
| 9671 | |
| 9672 | #if ENABLE(ACCESSIBILITY_ANIMATION_CONTROL)(defined 1 && 1) |
| 9673 | void WebPage::updateImageAnimationEnabled() |
| 9674 | { |
| 9675 | protect(corePage())->setImageAnimationEnabled(WebProcess::singleton().imageAnimationEnabled()); |
| 9676 | } |
| 9677 | |
| 9678 | void WebPage::pauseAllAnimations(CompletionHandler<void()>&& completionHandler) |
| 9679 | { |
| 9680 | protect(corePage())->setImageAnimationEnabled(false); |
| 9681 | completionHandler(); |
| 9682 | } |
| 9683 | |
| 9684 | void WebPage::playAllAnimations(CompletionHandler<void()>&& completionHandler) |
| 9685 | { |
| 9686 | protect(corePage())->setImageAnimationEnabled(true); |
| 9687 | completionHandler(); |
| 9688 | } |
| 9689 | #endif // ENABLE(ACCESSIBILITY_ANIMATION_CONTROL) |
| 9690 | |
| 9691 | #if ENABLE(ACCESSIBILITY_NON_BLINKING_CURSOR)(defined 0 && 0) |
| 9692 | void WebPage::updatePrefersNonBlinkingCursor() |
| 9693 | { |
| 9694 | if (RefPtr page = corePage()) { |
| 9695 | page->setPrefersNonBlinkingCursor(WebProcess::singleton().prefersNonBlinkingCursor()); |
| 9696 | page->forEachDocument([&](auto& document) { |
| 9697 | document.selection().setPrefersNonBlinkingCursor(WebProcess::singleton().prefersNonBlinkingCursor()); |
| 9698 | }); |
| 9699 | } |
| 9700 | } |
| 9701 | #endif |
| 9702 | |
| 9703 | bool WebPage::isUsingUISideCompositing() const |
| 9704 | { |
| 9705 | #if ENABLE(TILED_CA_DRAWING_AREA)(defined ENABLE_TILED_CA_DRAWING_AREA && ENABLE_TILED_CA_DRAWING_AREA ) |
| 9706 | return m_drawingAreaType == DrawingAreaType::RemoteLayerTree; |
| 9707 | #elif PLATFORM(COCOA)(defined 1 && 1) |
| 9708 | return true; |
| 9709 | #else |
| 9710 | return false; |
| 9711 | #endif |
| 9712 | } |
| 9713 | |
| 9714 | #if ENABLE(ADVANCED_PRIVACY_PROTECTIONS)(defined 1 && 1) |
| 9715 | |
| 9716 | void WebPage::setLinkDecorationFilteringData(Vector<WebCore::LinkDecorationFilteringData>&& strings) |
| 9717 | { |
| 9718 | m_internals->linkDecorationFilteringData.clear(); |
| 9719 | |
| 9720 | for (auto& data : strings) { |
| 9721 | if (!m_internals->linkDecorationFilteringData.isValidKey(data.linkDecoration)) { |
| 9722 | WEBPAGE_RELEASE_LOG_ERROR(ResourceLoadStatistics, "Unable to set link decoration filtering data (invalid key)"); |
| 9723 | ASSERT_NOT_REACHED()((void)0); |
| 9724 | continue; |
| 9725 | } |
| 9726 | |
| 9727 | auto it = m_internals->linkDecorationFilteringData.ensure(data.linkDecoration, [] { |
| 9728 | return Internals::LinkDecorationFilteringConditionals { }; |
| 9729 | }).iterator; |
| 9730 | |
| 9731 | if (!data.domain.isEmpty()) { |
| 9732 | if (auto& domains = it->value.domains; domains.isValidValue(data.domain)) |
| 9733 | domains.add(data.domain); |
| 9734 | else |
| 9735 | ASSERT_NOT_REACHED()((void)0); |
| 9736 | } |
| 9737 | |
| 9738 | if (!data.path.isEmpty()) |
| 9739 | it->value.paths.append(data.path); |
| 9740 | } |
| 9741 | } |
| 9742 | |
| 9743 | void WebPage::setAllowedQueryParametersForAdvancedPrivacyProtections(Vector<LinkDecorationFilteringData>&& allowStrings) |
| 9744 | { |
| 9745 | m_internals->allowedQueryParametersForAdvancedPrivacyProtections.clear(); |
| 9746 | for (auto& data : allowStrings) { |
| 9747 | if (!m_internals->allowedQueryParametersForAdvancedPrivacyProtections.isValidKey(data.domain)) |
| 9748 | continue; |
| 9749 | |
| 9750 | m_internals->allowedQueryParametersForAdvancedPrivacyProtections.ensure(data.domain, [&] { |
| 9751 | return HashSet<String> { }; |
| 9752 | }).iterator->value.add(data.linkDecoration); |
| 9753 | } |
| 9754 | } |
| 9755 | |
| 9756 | #endif // ENABLE(ADVANCED_PRIVACY_PROTECTIONS) |
| 9757 | |
| 9758 | bool WebPage::shouldSkipDecidePolicyForResponse(const WebCore::ResourceResponse& response) const |
| 9759 | { |
| 9760 | if (!m_skipDecidePolicyForResponseIfPossible) |
| 9761 | return false; |
| 9762 | |
| 9763 | auto statusCode = response.httpStatusCode(); |
| 9764 | if (statusCode == httpStatus204NoContent || statusCode >= httpStatus400BadRequest) |
| 9765 | return false; |
| 9766 | |
| 9767 | if (!equalIgnoringASCIICase(response.mimeType(), "text/html"_s)) |
| 9768 | return false; |
| 9769 | |
| 9770 | if (response.url().protocolIsFile()) |
| 9771 | return false; |
| 9772 | |
| 9773 | if (auto components = response.httpHeaderField(HTTPHeaderName::ContentDisposition).split(';'); !components.isEmpty() && equalIgnoringASCIICase(components[0].trim(isASCIIWhitespaceWithoutFF<char16_t>), "attachment"_s)) |
| 9774 | return false; |
| 9775 | |
| 9776 | return true; |
| 9777 | } |
| 9778 | |
| 9779 | const Logger& WebPage::logger() const |
| 9780 | { |
| 9781 | if (!m_logger) { |
| 9782 | m_logger = Logger::create(this); |
| 9783 | m_logger->setEnabled(this, isAlwaysOnLoggingAllowed()); |
| 9784 | } |
| 9785 | |
| 9786 | return *m_logger; |
| 9787 | } |
| 9788 | |
| 9789 | uint64_t WebPage::logIdentifier() const |
| 9790 | { |
| 9791 | return intHash(m_identifier.toUInt64()); |
| 9792 | } |
| 9793 | |
| 9794 | void WebPage::useRedirectionForCurrentNavigation(WebCore::ResourceResponse&& response) |
| 9795 | { |
| 9796 | RefPtr localMainFrame = this->localMainFrame(); |
| 9797 | if (!localMainFrame) { |
| 9798 | WEBPAGE_RELEASE_LOG_ERROR(Loading, "WebPage::useRedirectionForCurrentNavigation failed without frame"); |
| 9799 | return; |
| 9800 | } |
| 9801 | |
| 9802 | RefPtr loader = localMainFrame->loader().policyDocumentLoader(); |
| 9803 | if (!loader) |
| 9804 | loader = localMainFrame->loader().provisionalDocumentLoader(); |
| 9805 | |
| 9806 | if (!loader) { |
| 9807 | WEBPAGE_RELEASE_LOG_ERROR(Loading, "WebPage::useRedirectionForCurrentNavigation failed without loader"); |
| 9808 | return; |
| 9809 | } |
| 9810 | |
| 9811 | if (RefPtr resourceLoader = loader->mainResourceLoader()) { |
| 9812 | WEBPAGE_RELEASE_LOG(Loading, "WebPage::useRedirectionForCurrentNavigation to network process"); |
| 9813 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::UseRedirectionForCurrentNavigation(*resourceLoader->identifier(), response), 0); |
| 9814 | return; |
| 9815 | } |
| 9816 | |
| 9817 | WEBPAGE_RELEASE_LOG(Loading, "WebPage::useRedirectionForCurrentNavigation as substiute data"); |
| 9818 | loader->setRedirectionAsSubstituteData(WTF::move(response)); |
| 9819 | } |
| 9820 | |
| 9821 | void WebPage::dispatchLoadEventToFrameOwnerElement(WebCore::FrameIdentifier frameID) |
| 9822 | { |
| 9823 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 9824 | if (!frame) |
| 9825 | return; |
| 9826 | |
| 9827 | RefPtr coreRemoteFrame = frame->coreRemoteFrame(); |
| 9828 | if (!coreRemoteFrame) |
| 9829 | return; |
| 9830 | |
| 9831 | if (RefPtr ownerElement = coreRemoteFrame->ownerElement()) |
| 9832 | ownerElement->dispatchEvent(Event::create(eventNames().loadEvent, Event::CanBubble::No, Event::IsCancelable::No)); |
| 9833 | } |
| 9834 | |
| 9835 | void WebPage::elementWasFocusedInAnotherProcess(WebCore::FrameIdentifier frameID, WebCore::FocusOptions options) |
| 9836 | { |
| 9837 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 9838 | if (!frame) |
| 9839 | return; |
| 9840 | protect(corePage())->focusController().setFocusedElement(nullptr, protect(frame->coreFrame()).get(), options, WebCore::BroadcastFocusedElement::No); |
| 9841 | } |
| 9842 | |
| 9843 | void WebPage::frameWasFocusedInAnotherProcess(std::optional<WebCore::FrameIdentifier>&& frameID) |
| 9844 | { |
| 9845 | RefPtr frame = frameID ? WebProcess::singleton().webFrame(*frameID) : nullptr; |
| 9846 | RefPtr coreFrame = frame ? frame->coreFrame() : nullptr; |
| 9847 | protect(corePage())->focusController().setFocusedFrame(coreFrame.get(), WebCore::BroadcastFocusedFrame::No); |
| 9848 | } |
| 9849 | |
| 9850 | void WebPage::remotePostMessage(WebCore::FrameIdentifier source, const WebCore::SecurityOriginData& sourceOrigin, WebCore::FrameIdentifier target, std::optional<WebCore::SecurityOriginData>&& targetOrigin, const WebCore::MessageWithMessagePorts& message) |
| 9851 | { |
| 9852 | RefPtr targetFrame = WebProcess::singleton().webFrame(target); |
| 9853 | if (!targetFrame) |
| 9854 | return; |
| 9855 | |
| 9856 | if (!targetFrame->coreLocalFrame()) |
| 9857 | return; |
| 9858 | |
| 9859 | RefPtr targetWindow = protect(targetFrame->coreLocalFrame())->window(); |
| 9860 | if (!targetWindow) |
| 9861 | return; |
| 9862 | |
| 9863 | RefPtr targetCoreFrame = targetWindow->frame(); |
| 9864 | if (!targetCoreFrame) |
| 9865 | return; |
| 9866 | |
| 9867 | RefPtr sourceFrame = WebProcess::singleton().webFrame(source); |
| 9868 | RefPtr sourceWindow = sourceFrame && sourceFrame->coreFrame() ? &sourceFrame->coreFrame()->windowProxy() : nullptr; |
| 9869 | |
| 9870 | CheckedRef script = targetCoreFrame->script(); |
| 9871 | auto globalObject = script->globalObject(WebCore::mainThreadNormalWorldSingleton()); |
| 9872 | if (!globalObject) |
| 9873 | return; |
| 9874 | |
| 9875 | targetWindow->postMessageFromRemoteFrame(*globalObject, WTF::move(sourceWindow), sourceOrigin, WTF::move(targetOrigin), message); |
| 9876 | } |
| 9877 | |
| 9878 | void WebPage::renderTreeAsTextForTesting(WebCore::FrameIdentifier frameID, uint64_t baseIndent, OptionSet<WebCore::RenderAsTextFlag> behavior, CompletionHandler<void(String&&)>&& completionHandler) |
| 9879 | { |
| 9880 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 9881 | if (!webFrame) { |
| 9882 | ASSERT_NOT_REACHED()((void)0); |
| 9883 | return completionHandler("Test Error - WebFrame missing in web process"_s); |
| 9884 | } |
| 9885 | |
| 9886 | RefPtr coreLocalFrame = webFrame->coreLocalFrame(); |
| 9887 | if (!coreLocalFrame) { |
| 9888 | ASSERT_NOT_REACHED()((void)0); |
| 9889 | return completionHandler("Test Error - WebFrame missing LocalFrame in web process"_s); |
| 9890 | } |
| 9891 | |
| 9892 | CheckedPtr renderer = coreLocalFrame->contentRenderer(); |
| 9893 | if (!renderer) { |
| 9894 | ASSERT_NOT_REACHED()((void)0); |
| 9895 | return completionHandler("Test Error - WebFrame missing RenderView in web process"_s); |
| 9896 | } |
| 9897 | |
| 9898 | auto ts = WebCore::createTextStream(*renderer); |
| 9899 | ts.setIndent(baseIndent); |
| 9900 | WebCore::externalRepresentationForLocalFrame(ts, *coreLocalFrame, behavior); |
| 9901 | completionHandler(ts.release()); |
| 9902 | } |
| 9903 | |
| 9904 | void WebPage::layerTreeAsTextForTesting(WebCore::FrameIdentifier frameID, uint64_t baseIndent, OptionSet<WebCore::LayerTreeAsTextOptions> options, CompletionHandler<void(String&&)>&& completionHandler) |
| 9905 | { |
| 9906 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 9907 | if (!webFrame) { |
| 9908 | ASSERT_NOT_REACHED()((void)0); |
| 9909 | return completionHandler("Test Error - WebFrame missing in web process"_s); |
| 9910 | } |
| 9911 | |
| 9912 | RefPtr coreLocalFrame = webFrame->coreLocalFrame(); |
| 9913 | if (!coreLocalFrame) { |
| 9914 | ASSERT_NOT_REACHED()((void)0); |
| 9915 | return completionHandler("Test Error - WebFrame missing LocalFrame in web process"_s); |
| 9916 | } |
| 9917 | |
| 9918 | CheckedPtr renderer = coreLocalFrame->contentRenderer(); |
| 9919 | if (!renderer) { |
| 9920 | ASSERT_NOT_REACHED()((void)0); |
| 9921 | return completionHandler("Test Error - WebFrame missing RenderView in web process"_s); |
| 9922 | } |
| 9923 | |
| 9924 | auto ts = WebCore::createTextStream(*renderer); |
| 9925 | ts << protect(protect(coreLocalFrame->contentRenderer())->compositor())->layerTreeAsText(options, baseIndent); |
| 9926 | completionHandler(ts.release()); |
| 9927 | } |
| 9928 | |
| 9929 | void WebPage::frameTextForTesting(WebCore::FrameIdentifier frameID, CompletionHandler<void(String&&)>&& completionHandler) |
| 9930 | { |
| 9931 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 9932 | if (!webFrame) { |
| 9933 | ASSERT_NOT_REACHED()((void)0); |
| 9934 | return completionHandler("Test Error - WebFrame missing in web process"_s); |
| 9935 | } |
| 9936 | constexpr bool includeSubframes { true }; |
| 9937 | completionHandler(webFrame->frameTextForTesting(includeSubframes)); |
| 9938 | } |
| 9939 | |
| 9940 | void WebPage::requestAllTextAndRects(CompletionHandler<void(Vector<std::pair<String, WebCore::FloatRect>>&&)>&& completion) |
| 9941 | { |
| 9942 | RefPtr page = corePage(); |
| 9943 | if (!page) |
| 9944 | return completion({ }); |
| 9945 | |
| 9946 | completion(TextExtraction::extractAllTextAndRects(*page)); |
| 9947 | } |
| 9948 | |
| 9949 | void WebPage::requestTargetedElement(TargetedElementRequest&& request, CompletionHandler<void(Vector<WebCore::TargetedElementInfo>&&)>&& completion) |
| 9950 | { |
| 9951 | RefPtr page = corePage(); |
| 9952 | if (!page) |
| 9953 | return completion({ }); |
| 9954 | |
| 9955 | completion(protect(page->elementTargetingController())->findTargets(WTF::move(request))); |
| 9956 | } |
| 9957 | |
| 9958 | void WebPage::requestAllTargetableElements(float hitTestInterval, CompletionHandler<void(Vector<Vector<WebCore::TargetedElementInfo>>&&)>&& completion) |
| 9959 | { |
| 9960 | RefPtr page = corePage(); |
| 9961 | if (!page) |
| 9962 | return completion({ }); |
| 9963 | |
| 9964 | completion(protect(page->elementTargetingController())->findAllTargets(hitTestInterval)); |
| 9965 | } |
| 9966 | |
| 9967 | void WebPage::hasTextExtractionFilterRules(CompletionHandler<void(bool)>&& completion) |
| 9968 | { |
| 9969 | completion(!m_textExtractionFilterRules.isEmpty()); |
| 9970 | } |
| 9971 | |
| 9972 | void WebPage::updateTextExtractionFilterRules(Vector<WebCore::TextExtraction::FilterRuleData>&& ruleData) |
| 9973 | { |
| 9974 | m_textExtractionFilterRules = TextExtraction::extractRules(WTF::move(ruleData)); |
| 9975 | } |
| 9976 | |
| 9977 | void WebPage::applyTextExtractionFilter(const String& input, std::optional<NodeIdentifier>&& containerNodeID, CompletionHandler<void(const String&)>&& completion) |
| 9978 | { |
| 9979 | TextExtraction::applyRules(input, WTF::move(containerNodeID), m_textExtractionFilterRules, Ref { *corePage() }, WTF::move(completion)); |
| 9980 | } |
| 9981 | |
| 9982 | template<typename T> T WebPage::contentsToRootView(WebCore::FrameIdentifier frameID, T geometry) |
| 9983 | { |
| 9984 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 9985 | if (!webFrame) |
| 9986 | return geometry; |
| 9987 | |
| 9988 | RefPtr coreFrame = webFrame->coreFrame(); |
| 9989 | if (!coreFrame) { |
| 9990 | ASSERT_NOT_REACHED()((void)0); |
| 9991 | return geometry; |
| 9992 | } |
| 9993 | |
| 9994 | RefPtr view = coreFrame->virtualView(); |
| 9995 | if (!view) { |
| 9996 | ASSERT_NOT_REACHED()((void)0); |
| 9997 | return geometry; |
| 9998 | } |
| 9999 | |
| 10000 | return view->contentsToRootView(geometry); |
| 10001 | } |
| 10002 | |
| 10003 | template<typename T> T WebPage::rootViewToContents(WebCore::FrameIdentifier frameID, T geometry) |
| 10004 | { |
| 10005 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 10006 | if (!webFrame) |
| 10007 | return geometry; |
| 10008 | |
| 10009 | RefPtr coreFrame = webFrame->coreFrame(); |
| 10010 | if (!coreFrame) { |
| 10011 | ASSERT_NOT_REACHED()((void)0); |
| 10012 | return geometry; |
| 10013 | } |
| 10014 | |
| 10015 | RefPtr view = coreFrame->virtualView(); |
| 10016 | if (!view) { |
| 10017 | ASSERT_NOT_REACHED()((void)0); |
| 10018 | return geometry; |
| 10019 | } |
| 10020 | |
| 10021 | return view->rootViewToContents(geometry); |
| 10022 | } |
| 10023 | |
| 10024 | void WebPage::contentsToRootViewRect(FrameIdentifier frameID, FloatRect rect, CompletionHandler<void(FloatRect)>&& completionHandler) |
| 10025 | { |
| 10026 | completionHandler(contentsToRootView(frameID, rect)); |
| 10027 | } |
| 10028 | |
| 10029 | void WebPage::contentsToRootViewPoint(FrameIdentifier frameID, FloatPoint point, CompletionHandler<void(FloatPoint)>&& completionHandler) |
| 10030 | { |
| 10031 | completionHandler(contentsToRootView(frameID, point)); |
| 10032 | } |
| 10033 | |
| 10034 | void WebPage::remoteDictionaryPopupInfoToRootView(WebCore::FrameIdentifier frameID, WebCore::DictionaryPopupInfo popupInfo, CompletionHandler<void(WebCore::DictionaryPopupInfo)>&& completionHandler) |
| 10035 | { |
| 10036 | RefPtr textIndicator = popupInfo.textIndicator; |
| 10037 | popupInfo.origin = contentsToRootView<FloatPoint>(frameID, popupInfo.origin); |
| 10038 | if (!textIndicator) |
| 10039 | return completionHandler(popupInfo); |
| 10040 | #if PLATFORM(COCOA)(defined 1 && 1) |
| 10041 | auto textIndicatorData = textIndicator->data(); |
| 10042 | textIndicatorData.selectionRectInRootViewCoordinates = contentsToRootView<FloatRect>(frameID, popupInfo.textIndicator->selectionRectInRootViewCoordinates()); |
| 10043 | textIndicatorData.textBoundingRectInRootViewCoordinates = contentsToRootView<FloatRect>(frameID, popupInfo.textIndicator->textBoundingRectInRootViewCoordinates()); |
| 10044 | textIndicatorData.contentImageWithoutSelectionRectInRootViewCoordinates = contentsToRootView<FloatRect>(frameID, popupInfo.textIndicator->contentImageWithoutSelectionRectInRootViewCoordinates()); |
| 10045 | |
| 10046 | for (auto& textRect : textIndicatorData.textRectsInBoundingRectCoordinates) |
| 10047 | textRect = contentsToRootView<FloatRect>(frameID, textRect); |
| 10048 | #endif |
| 10049 | completionHandler(popupInfo); |
| 10050 | } |
| 10051 | |
| 10052 | void WebPage::hitTestAtPoint(WebCore::FrameIdentifier frameID, WebCore::FloatPoint point, CompletionHandler<void(NodeHitTestResult)>&& completionHandler) |
| 10053 | { |
| 10054 | RefPtr frame = WebFrame::webFrame(frameID); |
| 10055 | if (!frame) |
| 10056 | return completionHandler({ }); |
| 10057 | |
| 10058 | auto options = WebFrame::defaultHitTestRequestTypes(); |
| 10059 | options.remove(HitTestRequest::Type::AllowChildFrameContent); |
| 10060 | options.add(HitTestRequest::Type::SkipTransformToRootFrameCoordinates); |
| 10061 | RefPtr result = frame->hitTest(roundedIntPoint(point), options); |
| 10062 | if (!result) |
| 10063 | return completionHandler({ }); |
| 10064 | |
| 10065 | RefPtr node = result->coreHitTestResult().innerNonSharedNode(); |
| 10066 | if (!node) |
| 10067 | return completionHandler({ }); |
| 10068 | |
| 10069 | if (RefPtr frameOwner = dynamicDowncast<HTMLFrameOwnerElement>(node.get())) { |
| 10070 | if (RefPtr contentFrame = frameOwner->contentFrame()) { |
| 10071 | auto transformedCoordinates = rootViewToContents(contentFrame->frameID(), contentsToRootView(frameID, point)); |
| 10072 | switch (contentFrame->frameType()) { |
| 10073 | case Frame::FrameType::Remote: |
| 10074 | return completionHandler( { NodeHitTestResult::RemoteFrameInfo { contentFrame->frameID(), transformedCoordinates } }); |
| 10075 | case Frame::FrameType::Local: |
| 10076 | return hitTestAtPoint(contentFrame->frameID(), transformedCoordinates, WTF::move(completionHandler)); |
| 10077 | } |
| 10078 | } |
| 10079 | } |
| 10080 | |
| 10081 | RefPtr nodeFrame = node->document().frame(); |
| 10082 | if (!nodeFrame) |
| 10083 | return completionHandler({ }); |
| 10084 | |
| 10085 | RefPtr nodeWebFrame = WebFrame::fromCoreFrame(*nodeFrame); |
| 10086 | if (!nodeWebFrame) |
| 10087 | return completionHandler({ }); |
| 10088 | |
| 10089 | auto [handle, info] = nodeWebFrame->createAndPrepareToSendJSHandle(*node); |
| 10090 | completionHandler({ WTF::move(info) }); |
| 10091 | } |
| 10092 | |
| 10093 | void WebPage::adjustVisibilityForTargetedElements(Vector<TargetedElementAdjustment>&& adjustments, CompletionHandler<void(bool)>&& completion) |
| 10094 | { |
| 10095 | RefPtr page = corePage(); |
| 10096 | completion(page && protect(page->elementTargetingController())->adjustVisibility(WTF::move(adjustments))); |
| 10097 | } |
| 10098 | |
| 10099 | void WebPage::resetVisibilityAdjustmentsForTargetedElements(const Vector<TargetedElementIdentifiers>& identifiers, CompletionHandler<void(bool)>&& completion) |
| 10100 | { |
| 10101 | RefPtr page = corePage(); |
| 10102 | completion(page && protect(page->elementTargetingController())->resetVisibilityAdjustments(identifiers)); |
| 10103 | } |
| 10104 | |
| 10105 | void WebPage::takeSnapshotForTargetedElement(NodeIdentifier nodeID, ScriptExecutionContextIdentifier documentID, CompletionHandler<void(std::optional<ShareableBitmapHandle>&&)>&& completion) |
| 10106 | { |
| 10107 | RefPtr page = corePage(); |
| 10108 | if (!page) |
| 10109 | return completion({ }); |
| 10110 | |
| 10111 | RefPtr image = protect(page->elementTargetingController())->snapshotIgnoringVisibilityAdjustment(nodeID, documentID); |
| 10112 | if (!image) |
| 10113 | return completion({ }); |
| 10114 | |
| 10115 | auto bitmap = ShareableBitmap::create({ IntSize { image->size() } }); |
| 10116 | if (!bitmap) |
| 10117 | return completion({ }); |
| 10118 | |
| 10119 | auto context = bitmap->createGraphicsContext(); |
| 10120 | if (!context) |
| 10121 | return completion({ }); |
| 10122 | |
| 10123 | context->drawImage(*image, FloatPoint::zero()); |
| 10124 | completion(bitmap->createHandle(SharedMemory::Protection::ReadOnly)); |
| 10125 | } |
| 10126 | |
| 10127 | void WebPage::numberOfVisibilityAdjustmentRects(CompletionHandler<void(uint64_t)>&& completion) |
| 10128 | { |
| 10129 | RefPtr page = corePage(); |
| 10130 | completion(page ? protect(page->elementTargetingController())->numberOfVisibilityAdjustmentRects() : 0); |
| 10131 | } |
| 10132 | |
| 10133 | #if HAVE(SPATIAL_TRACKING_LABEL)(defined HAVE_SPATIAL_TRACKING_LABEL && HAVE_SPATIAL_TRACKING_LABEL ) |
| 10134 | void WebPage::setDefaultSpatialTrackingLabel(const String& label) |
| 10135 | { |
| 10136 | if (RefPtr page = corePage()) |
| 10137 | page->setDefaultSpatialTrackingLabel(label); |
| 10138 | } |
| 10139 | #endif |
| 10140 | |
| 10141 | void WebPage::startObservingNowPlayingMetadata() |
| 10142 | { |
| 10143 | #if ENABLE(VIDEO)(defined 1 && 1) || ENABLE(WEB_AUDIO)(defined 1 && 1) |
| 10144 | RefPtr sessionManager = mediaSessionManager(); |
| 10145 | if (!sessionManager || m_nowPlayingMetadataObserver) |
| 10146 | return; |
| 10147 | |
| 10148 | m_nowPlayingMetadataObserver = NowPlayingMetadataObserver::create([weakThis = WeakPtr { *this }](auto& metadata) { |
| 10149 | if (RefPtr protectedThis = weakThis.get()) |
| 10150 | protectedThis->send(Messages::WebPageProxy::NowPlayingMetadataChanged { metadata }); |
| 10151 | }); |
| 10152 | |
| 10153 | sessionManager->addNowPlayingMetadataObserver(Ref { *m_nowPlayingMetadataObserver }); |
| 10154 | #endif |
| 10155 | } |
| 10156 | |
| 10157 | void WebPage::stopObservingNowPlayingMetadata() |
| 10158 | { |
| 10159 | #if ENABLE(VIDEO)(defined 1 && 1) || ENABLE(WEB_AUDIO)(defined 1 && 1) |
| 10160 | RefPtr nowPlayingMetadataObserver = std::exchange(m_nowPlayingMetadataObserver, nullptr); |
| 10161 | if (!nowPlayingMetadataObserver) |
| 10162 | return; |
| 10163 | |
| 10164 | if (RefPtr sessionManager = mediaSessionManager()) |
| 10165 | sessionManager->removeNowPlayingMetadataObserver(*nowPlayingMetadataObserver); |
| 10166 | #endif |
| 10167 | } |
| 10168 | |
| 10169 | void WebPage::didAdjustVisibilityWithSelectors(Vector<String>&& selectors) |
| 10170 | { |
| 10171 | send(Messages::WebPageProxy::DidAdjustVisibilityWithSelectors(WTF::move(selectors))); |
| 10172 | } |
| 10173 | |
| 10174 | void WebPage::frameNameWasChangedInAnotherProcess(FrameIdentifier frameID, const String& frameName) |
| 10175 | { |
| 10176 | RefPtr webFrame = WebProcess::singleton().webFrame(frameID); |
| 10177 | if (!webFrame) |
| 10178 | return; |
| 10179 | if (RefPtr coreFrame = webFrame->coreFrame()) |
| 10180 | coreFrame->tree().setSpecifiedName(AtomString(frameName)); |
| 10181 | } |
| 10182 | |
| 10183 | void WebPage::updateLastNodeBeforeWritingSuggestions(const KeyboardEvent& event) |
| 10184 | { |
| 10185 | if (event.type() != eventNames().keydownEvent) |
| 10186 | return; |
| 10187 | |
| 10188 | if (RefPtr frame = corePage()->focusController().focusedOrMainFrame()) |
| 10189 | m_lastNodeBeforeWritingSuggestions = protect(frame->editor())->nodeBeforeWritingSuggestions(); |
| 10190 | } |
| 10191 | |
| 10192 | void WebPage::didAddOrRemoveViewportConstrainedObjects() |
| 10193 | { |
| 10194 | m_needsFixedContainerEdgesUpdate = true; |
| 10195 | |
| 10196 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 10197 | scheduleLayoutViewportHeightExpansionUpdate(); |
| 10198 | #endif |
| 10199 | } |
| 10200 | |
| 10201 | void WebPage::addReasonsToDisallowLayoutViewportHeightExpansion(OptionSet<DisallowLayoutViewportHeightExpansionReason> reasons) |
| 10202 | { |
| 10203 | bool wasEmpty = m_disallowLayoutViewportHeightExpansionReasons.isEmpty(); |
| 10204 | m_disallowLayoutViewportHeightExpansionReasons.add(reasons); |
| 10205 | |
| 10206 | if (!m_page->settings().layoutViewportHeightExpansionFactor()) |
| 10207 | return; |
| 10208 | |
| 10209 | if (wasEmpty && !m_disallowLayoutViewportHeightExpansionReasons.isEmpty()) |
| 10210 | send(Messages::WebPageProxy::SetAllowsLayoutViewportHeightExpansion(false)); |
| 10211 | } |
| 10212 | |
| 10213 | void WebPage::removeReasonsToDisallowLayoutViewportHeightExpansion(OptionSet<DisallowLayoutViewportHeightExpansionReason> reasons) |
| 10214 | { |
| 10215 | bool wasEmpty = m_disallowLayoutViewportHeightExpansionReasons.isEmpty(); |
| 10216 | m_disallowLayoutViewportHeightExpansionReasons.remove(reasons); |
| 10217 | |
| 10218 | if (!m_page->settings().layoutViewportHeightExpansionFactor()) |
| 10219 | return; |
| 10220 | |
| 10221 | if (!wasEmpty && m_disallowLayoutViewportHeightExpansionReasons.isEmpty()) |
| 10222 | send(Messages::WebPageProxy::SetAllowsLayoutViewportHeightExpansion(true)); |
| 10223 | } |
| 10224 | |
| 10225 | void WebPage::hasActiveNowPlayingSessionChanged(bool hasActiveNowPlayingSession) |
| 10226 | { |
| 10227 | send(Messages::WebPageProxy::HasActiveNowPlayingSessionChanged(hasActiveNowPlayingSession)); |
| 10228 | } |
| 10229 | |
| 10230 | void WebPage::simulateClickOverFirstMatchingTextInViewportWithUserInteraction(const String& targetText, CompletionHandler<void(bool)>&& completion) |
| 10231 | { |
| 10232 | ASSERT(!targetText.isEmpty())((void)0); |
| 10233 | |
| 10234 | RefPtr localMainFrame = m_mainFrame->coreLocalFrame(); |
| 10235 | if (!localMainFrame) |
| 10236 | return completion(false); |
| 10237 | |
| 10238 | RefPtr view = localMainFrame->view(); |
| 10239 | if (!view) |
| 10240 | return completion(false); |
| 10241 | |
| 10242 | RefPtr document = localMainFrame->document(); |
| 10243 | if (!document) |
| 10244 | return completion(false); |
| 10245 | |
| 10246 | RefPtr bodyElement = document->body(); |
| 10247 | if (!bodyElement) |
| 10248 | return completion(false); |
| 10249 | |
| 10250 | struct Candidate { |
| 10251 | Ref<HTMLElement> target; |
| 10252 | IntPoint location; |
| 10253 | }; |
| 10254 | |
| 10255 | Vector<Candidate> candidates; |
| 10256 | |
| 10257 | auto removeNonHitTestableCandidates = [&] { |
| 10258 | candidates.removeAllMatching([&](auto& targetAndLocation) { |
| 10259 | auto& [target, location] = targetAndLocation; |
| 10260 | auto result = localMainFrame->eventHandler().hitTestResultAtPoint(location, { |
| 10261 | HitTestRequest::Type::ReadOnly, |
| 10262 | HitTestRequest::Type::Active, |
| 10263 | }); |
| 10264 | RefPtr innerNode = result.innerNonSharedNode(); |
| 10265 | return !innerNode || !target->isShadowIncludingInclusiveAncestorOf(innerNode.get()); |
| 10266 | }); |
| 10267 | }; |
| 10268 | |
| 10269 | static constexpr OptionSet findOptions = { |
| 10270 | FindOption::CaseInsensitive, |
| 10271 | FindOption::AtWordStarts, |
| 10272 | FindOption::TreatMedialCapitalAsWordStart, |
| 10273 | FindOption::DoNotRevealSelection, |
| 10274 | FindOption::DoNotSetSelection, |
| 10275 | }; |
| 10276 | |
| 10277 | auto unobscuredContentRect = view->unobscuredContentRect(); |
| 10278 | auto searchRange = makeRangeSelectingNodeContents(*bodyElement); |
| 10279 | while (is_lt(treeOrder<ComposedTree>(searchRange.start, searchRange.end))) { |
| 10280 | auto range = findPlainText(searchRange, targetText, findOptions); |
| 10281 | |
| 10282 | if (range.collapsed()) |
| 10283 | break; |
| 10284 | |
| 10285 | searchRange.start = range.end; |
| 10286 | |
| 10287 | RefPtr target = [&] -> RefPtr<HTMLElement> { |
| 10288 | for (RefPtr ancestor = range.start.container.ptr(); ancestor; ancestor = ancestor->parentElementInComposedTree()) { |
| 10289 | RefPtr element = dynamicDowncast<HTMLElement>(*ancestor); |
| 10290 | if (!element) |
| 10291 | continue; |
| 10292 | |
| 10293 | if (element->willRespondToMouseClickEvents() || element->isLink()) |
| 10294 | return element; |
| 10295 | } |
| 10296 | return { }; |
| 10297 | }(); |
| 10298 | |
| 10299 | if (!target) |
| 10300 | continue; |
| 10301 | |
| 10302 | auto textRects = RenderObject::absoluteBorderAndTextRects(range, { |
| 10303 | RenderObject::BoundingRectBehavior::RespectClipping, |
| 10304 | RenderObject::BoundingRectBehavior::UseVisibleBounds, |
| 10305 | RenderObject::BoundingRectBehavior::IgnoreTinyRects, |
| 10306 | RenderObject::BoundingRectBehavior::IgnoreEmptyTextSelections, |
| 10307 | }); |
| 10308 | |
| 10309 | auto indexOfFirstRelevantTextRect = textRects.findIf([&](auto& textRect) { |
| 10310 | return unobscuredContentRect.intersects(enclosingIntRect(textRect)); |
| 10311 | }); |
| 10312 | |
| 10313 | if (indexOfFirstRelevantTextRect == notFound) |
| 10314 | continue; |
| 10315 | |
| 10316 | candidates.append({ target.releaseNonNull(), roundedIntPoint(textRects[indexOfFirstRelevantTextRect].center()) }); |
| 10317 | } |
| 10318 | |
| 10319 | removeNonHitTestableCandidates(); |
| 10320 | WEBPAGE_RELEASE_LOG(MouseHandling, "Simulating click - found %zu candidate(s) from visible text", candidates.size()); |
| 10321 | |
| 10322 | if (candidates.isEmpty()) { |
| 10323 | // Fall back to checking DOM attributes and accessibility labels. |
| 10324 | auto hitTestResult = HitTestResult { LayoutRect { unobscuredContentRect } }; |
| 10325 | document->hitTest({ HitTestSource::User, { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::CollectMultipleElements } }, hitTestResult); |
| 10326 | for (auto& node : hitTestResult.listBasedTestResult()) { |
| 10327 | RefPtr element = dynamicDowncast<HTMLElement>(node); |
| 10328 | if (!element) |
| 10329 | continue; |
| 10330 | |
| 10331 | bool isCandidate = false; |
| 10332 | if (auto ariaLabel = element->attributeWithoutSynchronization(HTMLNames::aria_labelAttr); !ariaLabel.isEmpty()) |
| 10333 | isCandidate = containsPlainText(ariaLabel.string(), targetText, findOptions); |
| 10334 | |
| 10335 | if (!isCandidate) { |
| 10336 | if (RefPtr input = dynamicDowncast<HTMLInputElement>(element); input && (input->isSubmitButton() || input->isTextButton())) { |
| 10337 | if (auto value = input->visibleValue(); !value.isEmpty()) |
| 10338 | isCandidate = containsPlainText(value, targetText, findOptions); |
| 10339 | } |
| 10340 | } |
| 10341 | |
| 10342 | if (!isCandidate) |
| 10343 | continue; |
| 10344 | |
| 10345 | if (auto rendererAndBounds = element->boundingAbsoluteRectWithoutLayout()) |
| 10346 | candidates.append({ element.releaseNonNull(), enclosingIntRect(rendererAndBounds->second).center() }); |
| 10347 | } |
| 10348 | |
| 10349 | removeNonHitTestableCandidates(); |
| 10350 | WEBPAGE_RELEASE_LOG(MouseHandling, "Simulating click - found %zu candidate(s) from DOM attributes", candidates.size()); |
| 10351 | } |
| 10352 | |
| 10353 | if (candidates.isEmpty()) { |
| 10354 | WEBPAGE_RELEASE_LOG(MouseHandling, "Simulating click - no matches found"); |
| 10355 | return completion(false); |
| 10356 | } |
| 10357 | |
| 10358 | if (candidates.size() > 1) { |
| 10359 | WEBPAGE_RELEASE_LOG(MouseHandling, "Simulating click - too many matches found (%zu)", candidates.size()); |
| 10360 | // FIXME: We'll want to add a way to disambiguate between multiple matches in the future. For now, just exit without |
| 10361 | // trying to simulate a click. |
| 10362 | return completion(false); |
| 10363 | } |
| 10364 | |
| 10365 | auto& [target, location] = candidates.first(); |
| 10366 | |
| 10367 | SetForScope userIsInteractingChange { m_userIsInteracting, true }; |
| 10368 | |
| 10369 | auto locationInWindow = view->contentsToWindow(location); |
| 10370 | auto makeSyntheticEvent = [&](PlatformEvent::Type type) -> PlatformMouseEvent { |
| 10371 | return { locationInWindow, locationInWindow, MouseButton::Left, type, 1, { }, MonotonicTime::now(), ForceAtClick, SyntheticClickType::OneFingerTap, MouseEventInputSource::UserDriven, mousePointerID }; |
| 10372 | }; |
| 10373 | |
| 10374 | WEBPAGE_RELEASE_LOG(MouseHandling, "Simulating click - dispatching events"); |
| 10375 | localMainFrame->eventHandler().handleMousePressEvent(makeSyntheticEvent(PlatformEvent::Type::MousePressed)).wasHandled(); |
| 10376 | if (m_isClosed) |
| 10377 | return completion(false); |
| 10378 | |
| 10379 | localMainFrame->eventHandler().handleMouseReleaseEvent(makeSyntheticEvent(PlatformEvent::Type::MouseReleased)).wasHandled(); |
| 10380 | completion(true); |
| 10381 | } |
| 10382 | |
| 10383 | #if ENABLE(MEDIA_STREAM)(defined 1 && 1) |
| 10384 | void WebPage::updateCaptureState(const WebCore::Document& document, bool isActive, WebCore::MediaProducerMediaCaptureKind kind, CompletionHandler<void(std::optional<WebCore::Exception>&&)>&& completionHandler) |
| 10385 | { |
| 10386 | RefPtr frame = document.frame(); |
| 10387 | if (!frame) { |
| 10388 | completionHandler(WebCore::Exception { ExceptionCode::InvalidStateError, "no frame available"_s }); |
| 10389 | return; |
| 10390 | } |
| 10391 | |
| 10392 | RefPtr webFrame = WebFrame::fromCoreFrame(*frame); |
| 10393 | ASSERT(webFrame)((void)0); |
| 10394 | |
| 10395 | sendWithAsyncReply(Messages::WebPageProxy::ValidateCaptureStateUpdate(UserMediaRequestIdentifier::generate(), document.clientOrigin(), webFrame->info(), isActive, kind), [weakThis = WeakPtr { *this }, isActive, kind, completionHandler = WTF::move(completionHandler)] (auto&& error) mutable { |
| 10396 | completionHandler(WTF::move(error)); |
| 10397 | if (error) |
| 10398 | return; |
| 10399 | |
| 10400 | RefPtr webPage = weakThis.get(); |
| 10401 | RefPtr page = webPage ? webPage->corePage() : nullptr; |
| 10402 | if (page) |
| 10403 | page->updateCaptureState(isActive, kind); |
| 10404 | }); |
| 10405 | } |
| 10406 | #endif |
| 10407 | |
| 10408 | void WebPage::updateOpener(WebCore::FrameIdentifier frameID, std::optional<WebCore::FrameIdentifier> newOpenerIdentifier) |
| 10409 | { |
| 10410 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 10411 | if (!frame) |
| 10412 | return; |
| 10413 | RefPtr coreFrame = frame->coreFrame(); |
| 10414 | if (!coreFrame) |
| 10415 | return; |
| 10416 | |
| 10417 | if (!newOpenerIdentifier) { |
| 10418 | coreFrame->disownOpener(WebCore::Frame::NotifyUIProcess::No); |
| 10419 | if (RefPtr provisionalFrame = frame->provisionalFrame()) |
| 10420 | provisionalFrame->disownOpener(WebCore::Frame::NotifyUIProcess::No); |
| 10421 | return; |
| 10422 | } |
| 10423 | |
| 10424 | RefPtr newOpener = WebProcess::singleton().webFrame(newOpenerIdentifier); |
| 10425 | if (!newOpener) |
| 10426 | return; |
| 10427 | RefPtr coreNewOpener = newOpener->coreFrame(); |
| 10428 | if (!coreNewOpener) |
| 10429 | return; |
| 10430 | |
| 10431 | coreFrame->updateOpener(*coreNewOpener, WebCore::Frame::NotifyUIProcess::No); |
| 10432 | if (RefPtr provisionalFrame = frame->provisionalFrame()) |
| 10433 | provisionalFrame->updateOpener(*coreNewOpener, WebCore::Frame::NotifyUIProcess::No); |
| 10434 | } |
| 10435 | |
| 10436 | void WebPage::setFramePrinting(WebCore::FrameIdentifier frameID, bool printing, FloatSize pageSize, FloatSize originalPageSize, float maximumShrinkRatio, AdjustViewSize shouldAdjustViewSize) |
| 10437 | { |
| 10438 | RefPtr frame = WebProcess::singleton().webFrame(frameID); |
| 10439 | if (!frame) |
| 10440 | return; |
| 10441 | RefPtr coreFrame = frame->coreFrame(); |
| 10442 | if (!coreFrame) |
| 10443 | return; |
| 10444 | coreFrame->setPrinting(printing, pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize, WebCore::Frame::NotifyUIProcess::No); |
| 10445 | } |
| 10446 | |
| 10447 | bool WebPage::isAlwaysOnLoggingAllowed() const |
| 10448 | { |
| 10449 | RefPtr page { protect(corePage()) }; |
| 10450 | return page && page->isAlwaysOnLoggingAllowed(); |
| 10451 | } |
| 10452 | |
| 10453 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 10454 | |
| 10455 | bool WebPage::canShowWhileLocked() const |
| 10456 | { |
| 10457 | return m_page && m_page->canShowWhileLocked(); |
| 10458 | } |
| 10459 | |
| 10460 | #else |
| 10461 | |
| 10462 | void WebPage::callAfterPendingSyntheticClick(CompletionHandler<void(SyntheticClickResult)>&& completion) |
| 10463 | { |
| 10464 | completion(SyntheticClickResult::Failed); |
| 10465 | } |
| 10466 | |
| 10467 | #endif |
| 10468 | |
| 10469 | #if HAVE(AUDIT_TOKEN)(defined 1 && 1) |
| 10470 | void WebPage::setPresentingApplicationAuditTokenAndBundleIdentifier(CoreIPCAuditToken&& auditToken, String&& bundleIdentifier) |
| 10471 | { |
| 10472 | RefPtr page = corePage(); |
| 10473 | if (!page) |
| 10474 | return; |
| 10475 | |
| 10476 | page->setPresentingApplicationAuditToken(auditToken.auditToken()); |
| 10477 | page->setPresentingApplicationBundleIdentifier(WTF::move(bundleIdentifier)); |
| 10478 | } |
| 10479 | #endif |
| 10480 | |
| 10481 | void WebPage::frameViewLayoutOrVisualViewportChanged(const LocalFrameView& frameView) |
| 10482 | { |
| 10483 | #if ENABLE(PDF_PLUGIN)(defined 1 && 1) |
| 10484 | Ref frame = frameView.frame(); |
| 10485 | if (RefPtr plugin = pluginViewForFrame(frame.ptr())) |
| 10486 | plugin->frameViewLayoutOrVisualViewportChanged(frameView.unobscuredContentRect()); |
| 10487 | #else |
| 10488 | UNUSED_PARAM(frameView)(void)frameView; |
| 10489 | #endif |
| 10490 | } |
| 10491 | |
| 10492 | RefPtr<MediaSessionManagerInterface> WebPage::mediaSessionManager() const |
| 10493 | { |
| 10494 | RefPtr page { corePage() }; |
| 10495 | return page ? page->mediaSessionManager() : nullptr; |
| 10496 | |
| 10497 | } |
| 10498 | |
| 10499 | MediaSessionManagerInterface* WebPage::mediaSessionManagerIfExists() const |
| 10500 | { |
| 10501 | RefPtr page { corePage() }; |
| 10502 | return page ? page->mediaSessionManagerIfExists() : nullptr; |
| 10503 | |
| 10504 | } |
| 10505 | |
| 10506 | #if ENABLE(MODEL_ELEMENT)(defined 1 && 1) |
| 10507 | bool WebPage::shouldDisableModelLoadDelaysForTesting() const |
| 10508 | { |
| 10509 | return m_page && m_page->shouldDisableModelLoadDelaysForTesting(); |
| 10510 | } |
| 10511 | #endif |
| 10512 | |
| 10513 | std::unique_ptr<FrameInfoData> WebPage::takeMainFrameNavigationInitiator() |
| 10514 | { |
| 10515 | return std::exchange(m_mainFrameNavigationInitiator, nullptr); |
| 10516 | } |
| 10517 | |
| 10518 | #if !PLATFORM(IOS_FAMILY)(defined 1 && 1) |
| 10519 | bool WebPage::hasAccessoryMousePointingDevice() const |
| 10520 | { |
| 10521 | return true; |
| 10522 | } |
| 10523 | #endif |
| 10524 | |
| 10525 | #if ENABLE(VIDEO)(defined 1 && 1) |
| 10526 | void WebPage::setCaptionDisplaySettingsPreviewProfileID(const String& profileID) |
| 10527 | { |
| 10528 | if (RefPtr captionPreferences = m_pageGroup->corePageGroup()->captionPreferences()) |
| 10529 | captionPreferences->setCaptionPreviewProfileID(profileID); |
| 10530 | } |
| 10531 | |
| 10532 | void WebPage::showCaptionDisplaySettingsPreview(HTMLMediaElementIdentifier identifier) |
| 10533 | { |
| 10534 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) || (PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) && ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1)) |
| 10535 | if (RefPtr mediaElement = protect(playbackSessionManager())->mediaElementWithContextId(identifier)) |
| 10536 | mediaElement->showCaptionDisplaySettingsPreview(); |
| 10537 | #else |
| 10538 | UNUSED_PARAM(identifier)(void)identifier; |
| 10539 | #endif |
| 10540 | } |
| 10541 | |
| 10542 | void WebPage::hideCaptionDisplaySettingsPreview(HTMLMediaElementIdentifier identifier) |
| 10543 | { |
| 10544 | #if PLATFORM(IOS_FAMILY)(defined 1 && 1) || (PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC) && ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1)) |
| 10545 | if (RefPtr mediaElement = protect(playbackSessionManager())->mediaElementWithContextId(identifier)) |
| 10546 | mediaElement->hideCaptionDisplaySettingsPreview(); |
| 10547 | #else |
| 10548 | UNUSED_PARAM(identifier)(void)identifier; |
| 10549 | #endif |
| 10550 | } |
| 10551 | #endif |
| 10552 | |
| 10553 | void WebPage::updateRemoteIntersectionObservers() |
| 10554 | { |
| 10555 | if (RefPtr page = m_page) { |
| 10556 | page->forEachDocument([] (Document& document) { |
| 10557 | document.updateRemoteIntersectionObservers(); |
| 10558 | }); |
| 10559 | } |
| 10560 | } |
| 10561 | |
| 10562 | } // namespace WebKit |
| 10563 | |
| 10564 | #undef WEBPAGE_RELEASE_LOG |
| 10565 | #undef WEBPAGE_RELEASE_LOG_ERROR |