Bug Summary

File:Source/WebKit/WebProcess/WebPage/WebPage.cpp
Warning:line 9230, column 14
Local variable 'cachedImage' is uncounted and unsafe

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple arm64-apple-ios26.2.0-simulator -Os -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -Werror=implicit-function-declaration -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name UnifiedSource145.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=security.insecureAPI.decodeValueOfObjCType -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -ffp-contract=on -fno-rounding-math -target-sdk-version=26.2 -fdepfile-entry=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/SDKSettings.json -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -fno-modulemap-allow-subdirectory-search -fdefine-target-os-macros -enable-tlsdesc -target-cpu apple-m1 -target-feature +v8.4a -target-feature +aes -target-feature +altnzcv -target-feature +ccdp -target-feature +ccpp -target-feature +complxnum -target-feature +crc -target-feature +dotprod -target-feature +flagm -target-feature +fp-armv8 -target-feature +fp16fml -target-feature +fptoint -target-feature +fullfp16 -target-feature +jsconv -target-feature +lse -target-feature +neon -target-feature +pauth -target-feature +perfmon -target-feature +predres -target-feature +ras -target-feature +rcpc -target-feature +rdm -target-feature +sb -target-feature +sha2 -target-feature +sha3 -target-feature +specrestrict -target-feature +ssbs -target-abi darwinpcs -dwarf-ext-refs -fmodule-format=obj -debug-info-kind=standalone -dwarf-version=5 -debugger-tuning=lldb -fdebug-compilation-dir=/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit -target-linker-version 1230.1 -fcoverage-compilation-dir=/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit -resource-dir /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21 -dependency-file /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/WebKit/WebKit/normal/arm64/UnifiedSource145.d -skip-unused-modulemap-deps -MT dependencies -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk -iquote /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/WebKit-generated-files.hmap -iquote /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/WebKit-project-headers.hmap -isystem /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/iphonesimulator26.0-additions.sdk/usr/local/include -isystem /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/SDKAdditions/usr/include -iframework /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/SDKAdditions/System/Library/Frameworks -iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/PrivateFrameworks -isystem /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/iphonesimulator26.0-additions.sdk/usr/local/include -include-pch /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/PrecompiledHeaders/SharedPrecompiledHeaders/12151610001510045616/WebKit2Prefix.h.gch -D _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D NDEBUG -D HAVE_CORE_PREDICTION -D ENABLE_LOWER_FORMATREADERBUNDLE_CODESIGNING_REQUIREMENTS -D WEBKIT_BUNDLE_VERSION="625.1.10+" -D FRAMEWORK_NAME=WebKit -D __clang_analyzer__ -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/WebKit-own-target-headers.hmap -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/WebKit-all-target-headers.hmap -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/include -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/WebCore.framework/PrivateHeaders/ForwardingHeaders -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/DerivedSources/WebKit -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/DerivedSources/WebKit/IPC -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/pal/graphics/WebGPU -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/pal/graphics/WebGPU -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/WebKitAdditions -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/WebKitAdditions -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/webrtc -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/webrtc -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/usr/local/include/webm -I /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include/webm -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/Source/WebKit -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/DerivedSources-normal/arm64 -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/DerivedSources/arm64 -I /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/WebKit.build/Release-iphonesimulator/WebKit.build/DerivedSources -F/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator -F/Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/iphonesimulator26.0-additions.sdk/System/Library/PrivateFrameworks -F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/PrivateFrameworks -D __STDC_WANT_LIB_EXT1__=1 -I/usr/local/include -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/local/include -internal-isystem /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/usr/include -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/Frameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/System/Library/SubFrameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator26.2.sdk/Library/Frameworks -Wno-trigraphs -Werror -Wno-missing-field-initializers -Wmissing-prototypes -Wunreachable-code -Wnon-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wsign-compare -Wno-shorten-64-to-32 -Wnewline-eof -Wno-c++11-extensions -Wno-implicit-fallthrough -Wdeprecated-declarations -Winvalid-offsetof -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wno-semicolon-before-method-body -Wall -Wc99-designator -Wconditional-uninitialized -Wextra -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion -Wenum-float-conversion -Wfinal-dtor-non-final-class -Wformat=2 -Wmisleading-indentation -Wpointer-to-int-cast -Wreorder-init-list -Wundef -Wunused-but-set-variable -Wvla -Werror=unguarded-availability -Wno-elaborated-enum-base -Wno-unused-parameter -Wcast-qual -Wchar-subscripts -Wextra-tokens -Winit-self -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough -Wvla -Wliteral-conversion -Wthread-safety -Wno-profile-instr-out-of-date -Wno-profile-instr-unprofiled -Wno-backend-plugin -Wunsafe-buffer-usage -Wno-unknown-warning-option -Wno-missing-field-initializers -Wno-nullability-completeness -std=c++2b -fdeprecated-macro -ferror-limit 19 -fmacro-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden -stack-protector 1 -fblocks -fencode-extended-block-signature -fno-rtti -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-cxx-modules -fno-implicit-modules -fskip-odr-check-in-gmf -fpascal-strings -fmax-type-align=16 -fdiagnostics-show-note-include-stack -vectorize-loops -vectorize-slp -fsafe-buffer-usage-suggestions -analyzer-output=html -analyzer-config report-in-main-source-file=true -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -analyzer-checker optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker security.insecureAPI.UncheckedReturn -analyzer-checker security.insecureAPI.getpw -analyzer-checker security.insecureAPI.gets -analyzer-checker security.insecureAPI.mkstemp -analyzer-checker security.insecureAPI.mktemp -analyzer-disable-checker security.insecureAPI.rand -analyzer-disable-checker security.insecureAPI.strcpy -analyzer-checker security.insecureAPI.vfork -analyzer-disable-checker alpha,apiModeling,core,cplusplus,deadcode,debug,fuchsia,nullability,optin,osx,security,unix,webkit -analyzer-checker alpha.webkit.ForwardDeclChecker,alpha.webkit.MemoryUnsafeCastChecker,alpha.webkit.NoDeleteChecker,alpha.webkit.NoUncheckedPtrMemberChecker,alpha.webkit.NoUnretainedMemberChecker,alpha.webkit.RetainPtrCtorAdoptChecker,alpha.webkit.UncheckedCallArgsChecker,alpha.webkit.UncheckedLocalVarsChecker,alpha.webkit.UncountedCallArgsChecker,alpha.webkit.UncountedLocalVarsChecker,alpha.webkit.UnretainedCallArgsChecker,alpha.webkit.UnretainedLambdaCapturesChecker,alpha.webkit.UnretainedLocalVarsChecker,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,webkit.UncountedLambdaCapturesChecker -analyzer-config max-nodes=10000000 -analyzer-config verbose-report-filename=true -fdwarf2-cfi-asm -o /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/WebKit/WebKit/normal/arm64/UnifiedSource145.plist -x c++ /Volumes/Data/worker/Apple-iOS-26-Safer-CPP-Checks-EWS/build/WebKitBuild/Release-iphonesimulator/DerivedSources/WebKit/unified-sources/UnifiedSource145.cpp
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
512namespace WebKit {
513using namespace JSC;
514using namespace WebCore;
515
516static const Seconds pageScrollHysteresisDuration { 300_ms };
517static const Seconds initialLayerVolatilityTimerInterval { 20_ms };
518static const Seconds maximumLayerVolatilityTimerInterval { 2_s };
519
520#if PLATFORM(IOS_FAMILY)(defined 1 && 1)
521static constexpr Seconds updateFocusedElementInformationDebounceInterval { 100_ms };
522static 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
529class SendStopResponsivenessTimer {
530public:
531 ~SendStopResponsivenessTimer()
532 {
533 protect(WebProcess::singleton().parentProcessConnection())->send(Messages::WebProcessProxy::StopResponsivenessTimer(), 0);
534 }
535};
536
537Ref<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
554void WebPage::ref() const
555{
556 API::ObjectImpl<API::Object::Type::BundlePage>::ref();
557}
558
559void WebPage::deref() const
560{
561 API::ObjectImpl<API::Object::Type::BundlePage>::deref();
562}
563
564static 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
575static 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
595static 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
605WebPage::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
1249void 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
1262void 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
1269void 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
1279Awaitable<std::optional<FrameTreeNodeData>> WebPage::getFrameTree()
1280{
1281 co_return m_mainFrame->frameTreeData();
1282}
1283
1284void 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
1293void 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
1305void WebPage::topDocumentSyncDataChangedInAnotherProcess(const WebCore::DocumentSyncSerializationData& data)
1306{
1307 if (RefPtr page = corePage())
1308 page->updateTopDocumentSyncData(data);
1309}
1310
1311void WebPage::allTopDocumentSyncDataChangedInAnotherProcess(Ref<WebCore::DocumentSyncData>&& data)
1312{
1313 if (RefPtr page = corePage())
1314 page->updateTopDocumentSyncData(WTF::move(data));
1315}
1316
1317void 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
1336void 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)
1352void 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
1369void 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)
1380void 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
1390void 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
1403void WebPage::pauseAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
1404{
1405 protect(corePage())->pauseAllMediaPlayback();
1406 completionHandler();
1407}
1408
1409void WebPage::suspendAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
1410{
1411 protect(corePage())->suspendAllMediaPlayback();
1412 completionHandler();
1413}
1414
1415void WebPage::resumeAllMediaPlayback(CompletionHandler<void()>&& completionHandler)
1416{
1417 protect(corePage())->resumeAllMediaPlayback();
1418 completionHandler();
1419}
1420
1421void WebPage::suspendAllMediaBuffering()
1422{
1423 protect(corePage())->suspendAllMediaBuffering();
1424}
1425
1426void WebPage::resumeAllMediaBuffering()
1427{
1428 protect(corePage())->resumeAllMediaBuffering();
1429}
1430
1431static 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
1443void 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
1496void 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
1514bool 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
1522WebPage::~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
1577IPC::Connection* WebPage::messageSenderConnection() const
1578{
1579 return WebProcess::singleton().parentProcessConnection();
1580}
1581
1582uint64_t WebPage::messageSenderDestinationID() const
1583{
1584 return identifier().toUInt64();
1585}
1586
1587#if ENABLE(CONTEXT_MENUS)(defined 0 && 0)
1588void 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
1599void 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
1609void 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
1619void 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
1635void 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
1643void 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
1653bool WebPage::hasPendingEditorStateUpdate() const
1654{
1655 return m_pendingEditorStateUpdateStatus != PendingEditorStateUpdateStatus::NotScheduled;
1656}
1657
1658EditorState 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
1723void 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
1733void 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
1743void WebPage::executeEditCommandWithCallback(const String& commandName, const String& argument, CompletionHandler<void()>&& completionHandler)
1744{
1745 executeEditCommand(commandName, argument);
1746 completionHandler();
1747}
1748
1749void WebPage::selectAll()
1750{
1751 executeEditingCommand("SelectAll"_s, { });
1752 platformDidSelectAll();
1753}
1754
1755bool 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
1763void WebPage::platformDidSelectAll()
1764{
1765}
1766
1767#endif // !PLATFORM(IOS_FAMILY)
1768
1769#if !PLATFORM(COCOA)(defined 1 && 1)
1770std::pair<URL, WebCore::DidFilterLinkDecoration> WebPage::applyLinkDecorationFilteringWithResult(const URL& url, WebCore::LinkDecorationFilteringTrigger)
1771{
1772 return { url, WebCore::DidFilterLinkDecoration::No };
1773}
1774
1775void WebPage::bindRemoteAccessibilityFrames(int, WebCore::FrameIdentifier, WebCore::AccessibilityRemoteToken, CompletionHandler<void(WebCore::AccessibilityRemoteToken, int)>&& completionHandler)
1776{
1777 completionHandler({ }, { });
1778}
1779
1780void WebPage::resolveAccessibilityHitTestForTesting(WebCore::FrameIdentifier, const WebCore::IntPoint&, CompletionHandler<void(String)>&& completionHandler)
1781{
1782 completionHandler({ });
1783}
1784
1785void WebPage::updateRemotePageAccessibilityOffset(WebCore::FrameIdentifier, WebCore::IntPoint)
1786{
1787}
1788
1789#endif
1790
1791#if ENABLE(ACCESSIBILITY_LOCAL_FRAME)(defined 1 && 1)
1792void 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
1813void 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
1823void 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
1842static 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
1862String WebPage::renderTreeExternalRepresentation(unsigned options) const
1863{
1864 return externalRepresentation(protect(m_mainFrame->coreLocalFrame()).get(), toRenderAsTextFlags(options));
1865}
1866
1867String WebPage::renderTreeExternalRepresentationForPrinting() const
1868{
1869 return externalRepresentation(protect(m_mainFrame->coreLocalFrame()).get(), { RenderAsTextFlag::PrintingMode });
1870}
1871
1872uint64_t WebPage::renderTreeSize() const
1873{
1874 if (RefPtr page = m_page)
1875 return page->renderTreeSize();
1876 return 0;
1877}
1878
1879void WebPage::setHasResourceLoadClient(bool has)
1880{
1881 if (m_page)
1882 m_page->setHasResourceLoadClient(has);
1883}
1884
1885void WebPage::setCanUseCredentialStorage(bool has)
1886{
1887 if (m_page)
1888 m_page->setCanUseCredentialStorage(has);
1889}
1890
1891bool WebPage::isTrackingRepaints() const
1892{
1893 if (RefPtr view = localMainFrameView())
1894 return view->isTrackingRepaints();
1895
1896 return false;
1897}
1898
1899Ref<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
1913PluginView* 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
1925PluginView* 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
1935PluginView* WebPage::mainFramePlugIn() const
1936{
1937 RefPtr localMainFrame = this->localMainFrame();
1938 return pluginViewForFrame(localMainFrame.get());
1939}
1940
1941#endif
1942
1943void 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
1961void 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
1977void WebPage::increaseListLevel()
1978{
1979 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
1980 if (!frame)
1981 return;
1982
1983 protect(frame->editor())->increaseSelectionListLevel();
1984}
1985
1986void WebPage::decreaseListLevel()
1987{
1988 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
1989 if (!frame)
1990 return;
1991
1992 protect(frame->editor())->decreaseSelectionListLevel();
1993}
1994
1995void WebPage::changeListType()
1996{
1997 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
1998 if (!frame)
1999 return;
2000
2001 protect(frame->editor())->changeSelectionListType();
2002}
2003
2004void 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
2013void WebPage::enterAcceleratedCompositingMode(WebCore::Frame& frame, GraphicsLayer* layer)
2014{
2015 protect(drawingArea())->setRootCompositingLayer(frame, layer);
2016}
2017
2018void WebPage::exitAcceleratedCompositingMode(WebCore::Frame& frame)
2019{
2020 protect(drawingArea())->setRootCompositingLayer(frame, nullptr);
2021}
2022
2023void 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
2142void 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
2152void WebPage::sendClose()
2153{
2154 send(Messages::WebPageProxy::ClosePage());
2155}
2156
2157void 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
2178void 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
2188void 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)
2202void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters)
2203{
2204}
2205#endif
2206
2207void 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
2216void 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
2225void 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.
2298void 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
2303void 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
2338void 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
2366void 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
2385void 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
2396void 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
2408void WebPage::stopLoadingDueToProcessSwap()
2409{
2410 SetForScope isStoppingLoadingDueToProcessSwap(m_isStoppingLoadingDueToProcessSwap, true);
2411 stopLoading();
2412}
2413
2414bool WebPage::defersLoading() const
2415{
2416 return m_page->defersLoading();
2417}
2418
2419void 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
2441void 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.
2487void 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
2492void WebPage::tryRestoreScrollPosition()
2493{
2494 if (RefPtr localMainFrame = this->localMainFrame())
2495 localMainFrame->loader().history().restoreScrollPositionAndViewState();
2496}
2497
2498WebPage* WebPage::fromCorePage(Page& page)
2499{
2500 auto& client = page.chrome().client();
2501 return client.isEmptyChromeClient() ? nullptr : downcast<WebChromeClient>(client).page();
2502}
2503
2504void 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
2524void 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
2548double 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
2561void 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
2575double 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
2590void 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
2607static 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
2641String 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
2657String WebPage::frameTextForTestingIncludingSubframes(bool includeSubframes)
2658{
2659 return m_mainFrame->frameTextForTesting(includeSubframes);
2660}
2661
2662void 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
2671void 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
2714void 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
2726void 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
2740void WebPage::platformDidScalePage()
2741{
2742}
2743
2744#endif
2745
2746void WebPage::scalePage(double scale, const IntPoint& origin)
2747{
2748 didScalePage(scale, origin);
2749 send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
2750}
2751
2752double 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
2761double WebPage::pageScaleFactor() const
2762{
2763 return totalScaleFactor() / viewScaleFactor();
2764}
2765
2766double WebPage::viewScaleFactor() const
2767{
2768 return m_page->viewScaleFactor();
2769}
2770
2771void 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
2790void WebPage::scaleView(double scale)
2791{
2792 if (scale == viewScaleFactor())
2793 return;
2794 didScaleView(scale);
2795 send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
2796}
2797
2798void 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
2825float WebPage::deviceScaleFactor() const
2826{
2827 return m_page->deviceScaleFactor();
2828}
2829
2830void WebPage::accessibilitySettingsDidChange()
2831{
2832 protect(corePage())->accessibilitySettingsDidChange();
2833}
2834
2835void WebPage::enableAccessibilityForAllProcesses()
2836{
2837 send(Messages::WebPageProxy::EnableAccessibilityForAllProcesses());
2838}
2839
2840void WebPage::enableAccessibility()
2841{
2842 if (!WebCore::AXObjectCache::accessibilityEnabled())
2843 WebCore::AXObjectCache::enableAccessibility();
2844}
2845
2846void WebPage::screenPropertiesDidChange(bool affectsStyle)
2847{
2848 protect(corePage())->screenPropertiesDidChange(affectsStyle);
2849}
2850
2851void 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
2873bool 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
2886IntSize WebPage::fixedLayoutSize() const
2887{
2888 RefPtr view = localMainFrameView();
2889 if (!view)
2890 return IntSize();
2891 return view->fixedLayoutSize();
2892}
2893
2894void WebPage::setDefaultUnobscuredSize(const FloatSize& defaultUnobscuredSize)
2895{
2896 if (defaultUnobscuredSize == m_defaultUnobscuredSize)
2897 return;
2898
2899 m_defaultUnobscuredSize = defaultUnobscuredSize;
2900
2901 updateSizeForCSSDefaultViewportUnits();
2902}
2903
2904void 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
2919void WebPage::setMinimumUnobscuredSize(const FloatSize& minimumUnobscuredSize)
2920{
2921 if (minimumUnobscuredSize == m_minimumUnobscuredSize)
2922 return;
2923
2924 m_minimumUnobscuredSize = minimumUnobscuredSize;
2925
2926 updateSizeForCSSSmallViewportUnits();
2927}
2928
2929void 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
2944void WebPage::setMaximumUnobscuredSize(const FloatSize& maximumUnobscuredSize)
2945{
2946 if (maximumUnobscuredSize == m_maximumUnobscuredSize)
2947 return;
2948
2949 m_maximumUnobscuredSize = maximumUnobscuredSize;
2950
2951 updateSizeForCSSLargeViewportUnits();
2952}
2953
2954void 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
2969void 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
2979void 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
3004FloatSize 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
3011void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones)
3012{
3013 if (RefPtr page = m_page)
3014 page->addLayoutMilestones(milestones);
3015}
3016
3017void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
3018{
3019 protect(corePage())->setShouldSuppressScrollbarAnimations(suppressAnimations);
3020}
3021
3022void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
3023{
3024 protect(corePage())->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticity::Allowed : ScrollElasticity::None);
3025}
3026
3027void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
3028{
3029 protect(corePage())->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticity::Allowed : ScrollElasticity::None);
3030}
3031
3032void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
3033{
3034 if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
3035 m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
3036}
3037
3038void 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
3046void 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
3054void 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
3062void 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
3070void 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
3080void WebPage::setUnderPageBackgroundColorOverride(WebCore::Color&& underPageBackgroundColorOverride)
3081{
3082 protect(corePage())->setUnderPageBackgroundColorOverride(WTF::move(underPageBackgroundColorOverride));
3083}
3084
3085void WebPage::setShouldSuppressHDR(bool shouldSuppressHDR)
3086{
3087 protect(corePage())->setShouldSuppressHDR(shouldSuppressHDR);
3088}
3089
3090#if !PLATFORM(IOS_FAMILY)(defined 1 && 1)
3091
3092void 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
3103PageBanner* WebPage::headerPageBanner()
3104{
3105 return m_headerBanner.get();
3106}
3107
3108void 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
3119PageBanner* WebPage::footerPageBanner()
3120{
3121 return m_footerBanner.get();
3122}
3123
3124void WebPage::hidePageBanners()
3125{
3126 if (RefPtr headerBanner = m_headerBanner)
3127 headerBanner->hide();
3128 if (RefPtr footerBanner = m_footerBanner)
3129 footerBanner->hide();
3130}
3131
3132void 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)
3143void WebPage::setHeaderBannerHeight(int height)
3144{
3145 protect(corePage())->setHeaderHeight(height);
3146}
3147
3148void WebPage::setFooterBannerHeight(int height)
3149{
3150 protect(corePage())->setFooterHeight(height);
3151}
3152#endif
3153
3154RefPtr<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
3162void 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
3207void 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
3236void 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
3244void 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
3279RefPtr<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
3304void 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
3359static 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
3382RefPtr<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
3408RefPtr<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
3461void 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
3473void 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
3480void WebPage::setHasActiveAnimatedScrolls(bool hasActiveAnimatedScrolls)
3481{
3482 send(Messages::WebPageProxy::SetHasActiveAnimatedScrolls(hasActiveAnimatedScrolls));
3483}
3484
3485#if ENABLE(CONTEXT_MENUS)(defined 0 && 0)
3486WebContextMenu& WebPage::contextMenu()
3487{
3488 if (!m_contextMenu)
3489 m_contextMenu = WebContextMenu::create(*this);
3490 return *m_contextMenu;
3491}
3492
3493RefPtr<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
3519static 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.
3524const WebEvent* WebPage::currentEvent()
3525{
3526 return g_currentEvent;
3527}
3528
3529void 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
3538void 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
3547void 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
3566void 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
3583void 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
3594void WebPage::callVolatilityCompletionHandlers(bool succeeded)
3595{
3596 auto completionHandlers = std::exchange(m_markLayersAsVolatileCompletionHandlers, { });
3597 for (auto& completionHandler : completionHandlers)
3598 completionHandler(succeeded);
3599}
3600
3601void WebPage::layerVolatilityTimerFired()
3602{
3603 m_layerVolatilityTimerInterval *= 2;
3604 markLayersVolatileOrRetry(m_layerVolatilityTimerInterval > maximumLayerVolatilityTimerInterval ? MarkLayersVolatileDontRetryReason::TimedOut : MarkLayersVolatileDontRetryReason::None);
3605}
3606
3607void 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
3621void WebPage::markLayersVolatileOrRetry(MarkLayersVolatileDontRetryReason dontRetryReason)
3622{
3623 tryMarkLayersVolatile([dontRetryReason, protectedThis = Ref { *this }](bool didSucceed) {
3624 protectedThis->tryMarkLayersVolatileCompletionHandler(dontRetryReason, didSucceed);
3625 });
3626}
3627
3628void 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
3662void WebPage::cancelMarkLayersVolatile()
3663{
3664 WEBPAGE_RELEASE_LOG(Layers, "cancelMarkLayersVolatile:");
3665 m_layerVolatilityTimer.stop();
3666 callVolatilityCompletionHandlers(false);
3667}
3668
3669class CurrentEvent {
3670public:
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
3682private:
3683 CheckedPtr<const WebEvent> m_previousCurrentEvent;
3684};
3685
3686#if ENABLE(CONTEXT_MENUS)(defined 0 && 0)
3687
3688void WebPage::didDismissContextMenu()
3689{
3690 corePage()->contextMenuController().didDismissContextMenu();
3691}
3692
3693void 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)
3704void 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
3724void 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
3806void 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
3815void WebPage::startDeferringResizeEvents()
3816{
3817 protect(corePage())->startDeferringResizeEvents();
3818}
3819
3820void WebPage::flushDeferredResizeEvents()
3821{
3822 protect(corePage())->flushDeferredResizeEvents();
3823}
3824
3825void WebPage::startDeferringScrollEvents()
3826{
3827 protect(corePage())->startDeferringScrollEvents();
3828}
3829
3830void WebPage::flushDeferredScrollEvents()
3831{
3832 protect(corePage())->flushDeferredScrollEvents();
3833}
3834
3835void WebPage::startDeferringIntersectionObservations()
3836{
3837 protect(corePage())->startDeferringIntersectionObservations();
3838}
3839
3840void WebPage::flushDeferredIntersectionObservations()
3841{
3842 protect(corePage())->flushDeferredIntersectionObservations();
3843}
3844
3845void 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
3851void 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
3869void 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
3890std::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)
3911void 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
3926void 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
3943bool 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
3961void 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
3983void WebPage::executeEditCommand(const String& commandName, const String& argument)
3984{
3985 executeEditingCommand(commandName, argument);
3986}
3987
3988void 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
3999void 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
4005void 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
4013void 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)
4022static 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
4036RefPtr<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)
4050Expected<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
4060void WebPage::didBeginTouchPoint(FloatPoint locationInRootView)
4061{
4062 m_hasAnyActiveTouchPoints = true;
4063 m_potentialTapSecurityOrigin = nullptr;
4064 m_lastTouchLocationBeforeTap = locationInRootView;
4065}
4066
4067void 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)
4103void 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
4117void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
4118{
4119 m_page->pointerCaptureController().cancelPointer(pointerId, documentPoint);
4120}
4121
4122void WebPage::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
4123{
4124 m_page->pointerCaptureController().touchWithIdentifierWasRemoved(pointerId);
4125}
4126
4127void WebPage::resetPointerCapture()
4128{
4129 m_page->pointerCaptureController().reset();
4130}
4131
4132#if ENABLE(MAC_GESTURE_EVENTS)(defined 0 && 0)
4133static 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
4145void 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
4153bool 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
4161bool 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
4169bool 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
4174void 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
4183bool WebPage::isControlledByAutomation() const
4184{
4185 return m_page->isControlledByAutomation();
4186}
4187
4188void WebPage::setControlledByAutomation(bool controlled)
4189{
4190 m_page->setControlledByAutomation(controlled);
4191}
4192
4193CheckedRef<PageInspectorTarget> WebPage::ensureInspectorTarget()
4194{
4195 if (!m_inspectorTarget)
4196 m_inspectorTarget = makeUnique<PageInspectorTarget>(*this);
4197 return *m_inspectorTarget;
4198}
4199
4200void WebPage::connectInspector(Inspector::FrontendChannel::ConnectionType connectionType)
4201{
4202 ensureInspectorTarget()->connect(connectionType);
4203}
4204
4205void WebPage::disconnectInspector()
4206{
4207 ensureInspectorTarget()->disconnect();
4208}
4209
4210void WebPage::sendMessageToTargetBackend(const String& message)
4211{
4212 ensureInspectorTarget()->sendMessageToTargetBackend(message);
4213}
4214
4215void 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)
4226void WebPage::setIndicating(bool indicating)
4227{
4228 m_page->inspectorController().setIndicating(indicating);
4229}
4230#endif
4231
4232void 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
4249void 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
)
4264void WebPage::setHasBannerViewOverlay(bool hasBannerViewOverlay)
4265{
4266 m_page->setHasBannerViewOverlay(hasBannerViewOverlay);
4267}
4268#endif
4269
4270void 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
4284void 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
4298void 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
4323void WebPage::setCanStartMediaTimerFired()
4324{
4325 if (RefPtr page = m_page)
4326 page->setCanStartMedia(true);
4327}
4328
4329void 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
4359void 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
4370void WebPage::windowActivityDidChange()
4371{
4372#if ENABLE(PDF_PLUGIN)(defined 1 && 1)
4373 for (Ref pluginView : m_pluginViews)
4374 pluginView->windowActivityDidChange();
4375#endif
4376}
4377
4378void 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
4407void 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
4441void WebPage::didCompletePageTransition()
4442{
4443 unfreezeLayerTree(LayerTreeFreezeReason::PageTransition);
4444}
4445
4446void WebPage::setMainFrameDocumentVisualUpdatesAllowed(bool allowed)
4447{
4448 if (allowed)
4449 unfreezeLayerTree(LayerTreeFreezeReason::DocumentVisualUpdatesNotAllowed);
4450 else
4451 freezeLayerTree(LayerTreeFreezeReason::DocumentVisualUpdatesNotAllowed);
4452}
4453
4454void WebPage::show()
4455{
4456 send(Messages::WebPageProxy::ShowPage());
4457}
4458
4459void 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
4467void 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
4477String 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
4485void 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
4496void WebPage::setHasCustomUserAgent(bool hasCustomUserAgent)
4497{
4498 m_hasCustomUserAgent = hasCustomUserAgent;
4499}
4500
4501void WebPage::suspendActiveDOMObjectsAndAnimations()
4502{
4503 protect(corePage())->suspendActiveDOMObjectsAndAnimations();
4504}
4505
4506void WebPage::resumeActiveDOMObjectsAndAnimations()
4507{
4508 protect(corePage())->resumeActiveDOMObjectsAndAnimations();
4509}
4510
4511void 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
4527void 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
4544IntPoint 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
4551IntPoint 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
4558IntRect 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
4565IntPoint 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
4572IntRect 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)
4580void WebPage::requestFrameScreenPosition(FrameIdentifier frameID)
4581{
4582 send(Messages::WebPageProxy::RequestFrameScreenPosition(frameID));
4583}
4584#endif
4585
4586KeyboardUIMode WebPage::keyboardUIMode()
4587{
4588 bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled();
4589 return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
4590}
4591
4592void 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
4679void 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
4698void 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)
4716void WebPage::getContentsAsMHTMLData(CompletionHandler<void(const IPC::SharedBufferReference&)>&& callback)
4717{
4718 callback(IPC::SharedBufferReference(MHTMLArchive::generateMHTMLData(m_page.get())));
4719}
4720#endif
4721
4722void WebPage::getRenderTreeExternalRepresentation(CompletionHandler<void(const String&)>&& callback)
4723{
4724 callback(renderTreeExternalRepresentation());
4725}
4726
4727static 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
4739void 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
4751void 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
4771void 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
4780void 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
4799static 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
4812void 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
4823void 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
4837void 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
4862void WebPage::updateRenderingWithForcedRepaintWithoutCallback()
4863{
4864 protect(drawingArea())->updateRenderingWithForcedRepaint();
4865}
4866
4867void WebPage::updateRenderingWithForcedRepaint(CompletionHandler<void()>&& completionHandler)
4868{
4869 protect(drawingArea())->updateRenderingWithForcedRepaintAsync(*this, WTF::move(completionHandler));
4870}
4871
4872void 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
4889bool WebPage::isParentProcessAWebBrowser() const
4890{
4891#if HAVE(AUDIT_TOKEN)(defined 1 && 1)
4892 return isParentProcessAFullWebBrowser(WebProcess::singleton());
4893#endif
4894 return false;
4895}
4896
4897void 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
4933void 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
5086void WebPage::setDataDetectionResults(NSArray *detectionResults)
5087{
5088 DataDetectionResult dataDetectionResult;
5089 dataDetectionResult.setResults(detectionResults);
5090 send(Messages::WebPageProxy::SetDataDetectionResult(dataDetectionResult));
5091}
5092
5093void 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
5114static 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
5137void 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
5145void WebPage::layoutIfNeeded()
5146{
5147 protect(corePage())->layoutIfNeeded();
5148}
5149
5150void 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
5160bool 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
5170String 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
5191void 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
5211bool 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
5226void 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
5244void WebPage::willStartRenderingUpdateDisplay()
5245{
5246 if (m_isClosed)
5247 return;
5248 protect(corePage())->willStartRenderingUpdateDisplay();
5249}
5250
5251void WebPage::didCompleteRenderingUpdateDisplay()
5252{
5253 if (m_isClosed)
5254 return;
5255 protect(corePage())->didCompleteRenderingUpdateDisplay();
5256}
5257
5258void WebPage::didCompleteRenderingFrame()
5259{
5260 if (m_isClosed)
5261 return;
5262 protect(corePage())->didCompleteRenderingFrame();
5263}
5264
5265void 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
5275void WebPage::willDestroyDecodedDataForAllImages()
5276{
5277}
5278
5279unsigned 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
5288WebInspectorBackend* 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
5297WebInspectorUI* 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
5306RemoteWebInspectorUI* 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
5315void WebPage::inspectorFrontendCountChanged(unsigned count)
5316{
5317 send(Messages::WebPageProxy::DidChangeInspectorFrontendCount(count));
5318}
5319
5320#if ENABLE(VIDEO_PRESENTATION_MODE)(defined 1 && 1)
5321PlaybackSessionManager& WebPage::playbackSessionManager()
5322{
5323 if (!m_playbackSessionManager)
5324 m_playbackSessionManager = PlaybackSessionManager::create(*this);
5325 return *m_playbackSessionManager;
5326}
5327
5328VideoPresentationManager& WebPage::videoPresentationManager()
5329{
5330 if (!m_videoPresentationManager)
5331 m_videoPresentationManager = VideoPresentationManager::create(*this, protect(playbackSessionManager()));
5332 return *m_videoPresentationManager;
5333}
5334
5335void WebPage::videoControlsManagerDidChange()
5336{
5337#if ENABLE(FULLSCREEN_API)(defined 1 && 1)
5338 protect(fullScreenManager())->videoControlsManagerDidChange();
5339#endif
5340}
5341
5342void 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)
5417void WebPage::setSceneIdentifier(String&& sceneIdentifier)
5418{
5419 AudioSession::singleton().setSceneIdentifier(sceneIdentifier);
5420 protect(m_page)->setSceneIdentifier(WTF::move(sceneIdentifier));
5421}
5422
5423void WebPage::setAllowsMediaDocumentInlinePlayback(bool allows)
5424{
5425 protect(m_page)->setAllowsMediaDocumentInlinePlayback(allows);
5426}
5427#endif
5428
5429#if ENABLE(FULLSCREEN_API)(defined 1 && 1)
5430WebFullScreenManager& WebPage::fullScreenManager()
5431{
5432 if (!m_fullScreenManager)
5433 m_fullScreenManager = WebFullScreenManager::create(*this);
5434 return *m_fullScreenManager;
5435}
5436
5437void 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
5448void WebPage::closeFullScreen()
5449{
5450 removeReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen);
5451
5452 send(Messages::WebFullScreenManagerProxy::Close());
5453}
5454
5455void WebPage::prepareToEnterElementFullScreen()
5456{
5457 addReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen);
5458}
5459
5460void WebPage::prepareToExitElementFullScreen()
5461{
5462 removeReasonsToDisallowLayoutViewportHeightExpansion(DisallowLayoutViewportHeightExpansionReason::ElementFullScreen);
5463}
5464
5465#endif // ENABLE(FULLSCREEN_API)
5466
5467void 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
5473void 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
5485void 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
5497void 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
5520NotificationPermissionRequestManager* 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)
5532void 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
5563void 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
5598void 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
5636void 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
5662void 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
5668void 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
5681void 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
5691void 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)
5699void 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)
5716void 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
5725void 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
5731void 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
5738WebUndoStep* WebPage::webUndoStep(WebUndoStepID stepID)
5739{
5740 return m_undoStepMap.get(stepID);
5741}
5742
5743void 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
5749void WebPage::removeWebEditCommand(WebUndoStepID stepID)
5750{
5751 if (auto undoStep = m_undoStepMap.take(stepID))
5752 undoStep->didRemoveFromUndoManager();
5753}
5754
5755void 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
5770void 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
5787void WebPage::didRemoveEditCommand(WebUndoStepID commandID)
5788{
5789 removeWebEditCommand(commandID);
5790}
5791
5792void 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
5802void WebPage::setActivePopupMenu(WebPopupMenu* menu)
5803{
5804 m_activePopupMenu = menu;
5805}
5806
5807WebColorChooser* WebPage::activeColorChooser() const
5808{
5809 return m_activeColorChooser.get();
5810}
5811
5812void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
5813{
5814 m_activeColorChooser = colorChooser;
5815}
5816
5817void WebPage::didEndColorPicker()
5818{
5819 if (RefPtr activeColorChooser = m_activeColorChooser.get())
5820 activeColorChooser->didEndChooser();
5821}
5822
5823void WebPage::didChooseColor(const WebCore::Color& color)
5824{
5825 if (RefPtr activeColorChooser = m_activeColorChooser.get())
5826 activeColorChooser->didChooseColor(color);
5827}
5828
5829void WebPage::setActiveDataListSuggestionPicker(WebDataListSuggestionPicker& dataListSuggestionPicker)
5830{
5831 m_activeDataListSuggestionPicker = dataListSuggestionPicker;
5832}
5833
5834void WebPage::didSelectDataListOption(const String& selectedOption)
5835{
5836 if (RefPtr activeDataListSuggestionPicker = m_activeDataListSuggestionPicker.get())
5837 activeDataListSuggestionPicker->didSelectOption(selectedOption);
5838}
5839
5840void WebPage::didCloseSuggestions()
5841{
5842 if (RefPtr picker = std::exchange(m_activeDataListSuggestionPicker, nullptr).get())
5843 picker->didCloseSuggestions();
5844}
5845
5846void WebPage::setActiveDateTimeChooser(WebDateTimeChooser& dateTimeChooser)
5847{
5848 m_activeDateTimeChooser = dateTimeChooser;
5849}
5850
5851void WebPage::didChooseDate(const String& date)
5852{
5853 if (RefPtr activeDateTimeChooser = m_activeDateTimeChooser.get())
5854 activeDateTimeChooser->didChooseDate(date);
5855}
5856
5857void WebPage::didEndDateTimePicker()
5858{
5859 if (auto chooser = std::exchange(m_activeDateTimeChooser, nullptr))
5860 chooser->didEndChooser();
5861}
5862
5863void WebPage::setActiveOpenPanelResultListener(Ref<WebOpenPanelResultListener>&& openPanelResultListener)
5864{
5865 m_activeOpenPanelResultListener = WTF::move(openPanelResultListener);
5866}
5867
5868void WebPage::setTextIndicator(RefPtr<WebCore::TextIndicator>&& textIndicator)
5869{
5870 send(Messages::WebPageProxy::SetTextIndicatorFromFrame(m_mainFrame->frameID(), WTF::move(textIndicator), WebCore::TextIndicatorLifetime::Temporary));
5871}
5872
5873void WebPage::updateTextIndicator(RefPtr<WebCore::TextIndicator>&& textIndicator)
5874{
5875 send(Messages::WebPageProxy::UpdateTextIndicatorFromFrame(m_mainFrame->frameID(), WTF::move(textIndicator)));
5876}
5877
5878void WebPage::replaceStringMatchesFromInjectedBundle(const Vector<uint32_t>& matchIndices, const String& replacementText, bool selectionOnly)
5879{
5880 findController().replaceMatches(matchIndices, replacementText, selectionOnly);
5881}
5882
5883void 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)
5889void 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
5895void 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
5900void 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
5905void WebPage::replaceFoundTextRangeWithString(const WebFoundTextRange& range, const String& string)
5906{
5907 foundTextRangeController().replaceFoundTextRangeWithString(range, string);
5908}
5909
5910void WebPage::decorateTextRangeWithStyle(const WebFoundTextRange& range, WebKit::FindDecorationStyle style)
5911{
5912 foundTextRangeController().decorateTextRangeWithStyle(range, style);
5913}
5914
5915void WebPage::scrollTextRangeToVisible(const WebFoundTextRange& range)
5916{
5917 foundTextRangeController().scrollTextRangeToVisible(range);
5918}
5919
5920void WebPage::clearAllDecoratedFoundText()
5921{
5922 hideFindUI();
5923 foundTextRangeController().clearAllDecoratedFoundText();
5924}
5925
5926void WebPage::didBeginTextSearchOperation()
5927{
5928 foundTextRangeController().didBeginTextSearchOperation();
5929}
5930
5931void WebPage::requestRectForFoundTextRange(const WebFoundTextRange& range, CompletionHandler<void(WebCore::FloatRect)>&& completionHandler)
5932{
5933 foundTextRangeController().requestRectForFoundTextRange(range, WTF::move(completionHandler));
5934}
5935
5936void WebPage::addLayerForFindOverlay(CompletionHandler<void(std::optional<WebCore::PlatformLayerIdentifier>)>&& completionHandler)
5937{
5938 foundTextRangeController().addLayerForFindOverlay(WTF::move(completionHandler));
5939}
5940
5941void WebPage::removeLayerForFindOverlay(CompletionHandler<void()>&& completionHandler)
5942{
5943 foundTextRangeController().removeLayerForFindOverlay();
5944 completionHandler();
5945}
5946
5947void WebPage::getImageForFindMatch(uint32_t matchIndex)
5948{
5949 findController().getImageForFindMatch(matchIndex);
5950}
5951
5952void WebPage::selectFindMatch(uint32_t matchIndex)
5953{
5954 findController().selectFindMatch(matchIndex);
5955}
5956
5957void WebPage::indicateFindMatch(uint32_t matchIndex)
5958{
5959 findController().indicateFindMatch(matchIndex);
5960}
5961
5962void WebPage::hideFindUI()
5963{
5964 findController().hideFindUI();
5965}
5966
5967void 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
5972void 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)
5979void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
5980{
5981 changeSelectedIndex(newIndex);
5982 m_activePopupMenu = nullptr;
5983}
5984
5985void 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)
5993void 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
6014void 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
6020void 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)
6027void 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)
6038void 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
6046void 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
6053void 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
6058void WebPage::captureDevicesChanged()
6059{
6060 m_userMediaPermissionRequestManager->captureDevicesChanged();
6061}
6062
6063void WebPage::voiceActivityDetected()
6064{
6065 protect(corePage())->voiceActivityDetected();
6066}
6067
6068#if USE(GSTREAMER)(defined USE_GSTREAMER && USE_GSTREAMER)
6069void WebPage::setOrientationForMediaCapture(uint64_t rotation)
6070{
6071 m_page->forEachDocument([&](auto& document) {
6072 document.orientationChanged(rotation);
6073 });
6074}
6075
6076void WebPage::setMockCaptureDevicesInterrupted(bool isCameraInterrupted, bool isMicrophoneInterrupted)
6077{
6078 MockRealtimeMediaSourceCenter::setMockCaptureDevicesInterrupted(isCameraInterrupted, isMicrophoneInterrupted);
6079}
6080
6081void 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)
6090void WebPage::mediaKeySystemWasGranted(MediaKeySystemRequestIdentifier mediaKeySystemID, String&& mediaKeysHashSalt)
6091{
6092 m_mediaKeySystemPermissionRequestManager->mediaKeySystemWasGranted(mediaKeySystemID, WTF::move(mediaKeysHashSalt));
6093}
6094
6095void 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)
6102void 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
6112bool 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
6124void WebPage::changeSpellingToWord(const String& word)
6125{
6126 replaceSelectionWithText(protect(corePage()->focusController().focusedOrMainFrame()).get(), word);
6127}
6128
6129void 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
6140void 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)
6152void 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
6165void 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
6178void 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
6192void 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
6205void 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)
6220void 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)
6228void 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)
6238void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
6239{
6240 if (auto contextMenu = std::exchange(m_contextMenu, nullptr))
6241 contextMenu->itemSelected(item);
6242}
6243#endif
6244
6245void 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)
6251void WebPage::clearSelection()
6252{
6253 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
6254 if (!frame)
6255 return;
6256
6257 protect(frame->selection())->clear();
6258}
6259#endif
6260
6261void 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
6276bool 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
6287void 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
6300void 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
6326void WebPage::addPluginView(PluginView& pluginView)
6327{
6328 ASSERT(!m_pluginViews.contains(pluginView))((void)0);
6329 m_pluginViews.add(pluginView);
6330}
6331
6332void 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
6340void 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
6350void 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
6367void 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
6379void 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
6390bool WebPage::windowIsFocused() const
6391{
6392 return m_page->focusController().isActive();
6393}
6394
6395bool WebPage::windowAndWebPageAreFocused() const
6396{
6397 return isVisible() && m_page->focusController().isFocused() && m_page->focusController().isActive();
6398}
6399
6400bool 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)
6430ScrollingCoordinator* WebPage::scrollingCoordinator() const
6431{
6432 return protect(corePage())->scrollingCoordinator();
6433}
6434
6435#endif
6436
6437WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
6438{
6439 invalidate();
6440}
6441
6442void 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
6453void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(RefPtr<SandboxExtension>&& pendingDropSandboxExtension)
6454{
6455 setPendingProvisionalSandboxExtension(WTF::move(pendingDropSandboxExtension));
6456}
6457
6458void WebPage::SandboxExtensionTracker::beginLoad(SandboxExtension::Handle&& handle)
6459{
6460 setPendingProvisionalSandboxExtension(SandboxExtension::create(WTF::move(handle)));
6461}
6462
6463void 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
6473void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(RefPtr<SandboxExtension>&& pendingProvisionalSandboxExtension)
6474{
6475 m_pendingProvisionalSandboxExtension = WTF::move(pendingProvisionalSandboxExtension);
6476}
6477
6478bool 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
6503void 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
6520void 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
6534void 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
6547void WebPage::setCustomTextEncodingName(const String& encoding)
6548{
6549 if (RefPtr localMainFrame = this->localMainFrame())
6550 localMainFrame->loader().reloadWithOverrideEncoding(encoding);
6551}
6552
6553void WebPage::didRemoveBackForwardItem(BackForwardFrameItemIdentifier frameItemID)
6554{
6555 WebBackForwardListProxy::removeItem(frameItemID);
6556}
6557
6558#if PLATFORM(MAC)(defined WTF_PLATFORM_MAC && WTF_PLATFORM_MAC)
6559void 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
6568void 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
6579void 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
6592void WebPage::swipeAnimationDidStart()
6593{
6594 freezeLayerTree(LayerTreeFreezeReason::SwipeAnimation);
6595 corePage()->setIsInSwipeAnimation(true);
6596}
6597
6598void WebPage::swipeAnimationDidEnd()
6599{
6600 unfreezeLayerTree(LayerTreeFreezeReason::SwipeAnimation);
6601 corePage()->setIsInSwipeAnimation(false);
6602}
6603
6604void 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
6653void 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
6666void 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
6679void 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
6689void 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
6712void 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
6727void 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
6764void 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
6810void 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
6837void 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)
6868void 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
6887void 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
6918void 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
6935void WebPage::setMediaVolume(float volume)
6936{
6937 protect(corePage())->setMediaVolume(volume);
6938}
6939
6940void WebPage::setMuted(MediaProducerMutedStateFlags state, CompletionHandler<void()>&& completionHandler)
6941{
6942 protect(corePage())->setMuted(state);
6943 completionHandler();
6944}
6945
6946void 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
6954void WebPage::processWillSuspend()
6955{
6956 if (RefPtr manager = mediaSessionManagerIfExists())
6957 manager->processWillSuspend();
6958}
6959
6960void WebPage::processDidResume()
6961{
6962 if (RefPtr manager = mediaSessionManagerIfExists())
6963 manager->processDidResume();
6964}
6965
6966void WebPage::didReceiveRemoteCommand(PlatformMediaSession::RemoteControlCommandType type, const PlatformMediaSession::RemoteCommandArgument& argument)
6967{
6968 if (RefPtr manager = mediaSessionManagerIfExists())
6969 manager->processDidReceiveRemoteControlCommand(type, argument);
6970}
6971
6972void 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
6982void 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
6997bool 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
7008void 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
7025bool WebPage::hasCompositionForTesting()
7026{
7027 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
7028 if (!frame)
7029 return false;
7030
7031 return frame->editor().hasComposition();
7032}
7033
7034void 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
7049void WebPage::wheelEventHandlersChanged(bool hasHandlers)
7050{
7051 if (m_hasWheelEventHandlers == hasHandlers)
7052 return;
7053
7054 m_hasWheelEventHandlers = hasHandlers;
7055 recomputeShortCircuitHorizontalWheelEventsState();
7056}
7057
7058static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea)
7059{
7060 RefPtr scrollbar = scrollableArea->horizontalScrollbar();
7061 return scrollbar && scrollbar->enabled();
7062}
7063
7064static 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
7099void 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
7116Frame* WebPage::mainFrame() const
7117{
7118 return m_page ? &m_page->mainFrame() : nullptr;
7119}
7120
7121RefPtr<WebCore::LocalFrame> WebPage::localMainFrame() const
7122{
7123 if (RefPtr page = m_page)
7124 return page->localMainFrame();
7125 return nullptr;
7126}
7127
7128RefPtr<WebCore::Document> WebPage::localTopDocument() const
7129{
7130 if (RefPtr page = m_page)
7131 return page->localTopDocument();
7132 return nullptr;
7133}
7134
7135FrameView* WebPage::mainFrameView() const
7136{
7137 if (RefPtr frame = mainFrame())
7138 return frame->virtualView();
7139 return nullptr;
7140}
7141
7142LocalFrameView* WebPage::localMainFrameView() const
7143{
7144 return dynamicDowncast<LocalFrameView>(mainFrameView());
7145}
7146
7147bool 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
7158static 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
7181void WebPage::cancelComposition(const String& compositionString)
7182{
7183 if (RefPtr targetFrame = targetFrameForEditing(*this))
7184 protect(targetFrame->editor())->confirmComposition(compositionString);
7185}
7186
7187void 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
7215void WebPage::didApplyStyle()
7216{
7217 sendEditorStateUpdate();
7218}
7219
7220void WebPage::didChangeContents()
7221{
7222 sendEditorStateUpdate();
7223}
7224
7225void WebPage::didScrollSelection()
7226{
7227 didChangeSelectionOrOverflowScrollPosition();
7228}
7229
7230void 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
7256void 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
7309void 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
7330void WebPage::elementDidRefocus(Element& element, const FocusOptions& options)
7331{
7332 elementDidFocus(element, options);
7333
7334 if (m_userIsInteracting)
7335 scheduleFullEditorStateUpdate();
7336}
7337
7338bool 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
7350static 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)
7356static 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
7368void 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
7424void 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
7445void 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
7463void 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
7475void WebPage::didUpdateComposition()
7476{
7477 sendEditorStateUpdate();
7478}
7479
7480void WebPage::didEndUserTriggeredSelectionChanges()
7481{
7482 RefPtr frame = corePage()->focusController().focusedOrMainFrame();
7483 if (!frame)
7484 return;
7485
7486 if (!frame->editor().ignoreSelectionChanges())
7487 sendEditorStateUpdate();
7488}
7489
7490void WebPage::discardedComposition(const Document& document)
7491{
7492 send(Messages::WebPageProxy::CompositionWasCanceled());
7493 if (!document.hasLivingRenderTree())
7494 return;
7495
7496 sendEditorStateUpdate();
7497}
7498
7499void WebPage::canceledComposition()
7500{
7501 send(Messages::WebPageProxy::CompositionWasCanceled());
7502 sendEditorStateUpdate();
7503}
7504
7505void 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
7515void 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
7528void 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
7541void 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
7561void 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
7581void 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
7592void 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
7604bool WebPage::isIOSurfaceLosslessCompressionEnabled() const
7605{
7606 return m_page->settings().iOSurfaceLosslessCompressionEnabled();
7607}
7608
7609bool WebPage::isSmartInsertDeleteEnabled()
7610{
7611 return m_page->settings().smartInsertDeleteEnabled();
7612}
7613
7614void WebPage::setSmartInsertDeleteEnabled(bool enabled)
7615{
7616 if (m_page->settings().smartInsertDeleteEnabled() != enabled) {
7617 m_page->settings().setSmartInsertDeleteEnabled(enabled);
7618 setSelectTrailingWhitespaceEnabled(!enabled);
7619 }
7620}
7621
7622bool WebPage::isSelectTrailingWhitespaceEnabled() const
7623{
7624 return m_page->settings().selectTrailingWhitespaceEnabled();
7625}
7626
7627void WebPage::setSelectTrailingWhitespaceEnabled(bool enabled)
7628{
7629 if (m_page->settings().selectTrailingWhitespaceEnabled() != enabled) {
7630 m_page->settings().setSelectTrailingWhitespaceEnabled(enabled);
7631 setSmartInsertDeleteEnabled(!enabled);
7632 }
7633}
7634
7635bool 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
7642bool 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
7649bool 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
7669void WebPage::addTextCheckingRequest(TextCheckerRequestID requestID, Ref<TextCheckingRequest>&& request)
7670{
7671 m_pendingTextCheckingRequestMap.add(requestID, WTF::move(request));
7672}
7673
7674void 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
7683void WebPage::didCancelCheckingText(TextCheckerRequestID requestID)
7684{
7685 RefPtr<TextCheckingRequest> request = m_pendingTextCheckingRequestMap.take(requestID);
7686 if (!request)
7687 return;
7688
7689 request->didCancel();
7690}
7691
7692void 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
7702void 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)
7715static 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
7721static 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
7728void 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
7891void 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
7901void 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
7917void 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
7938void WebPage::didNavigateWithinPageForFrame(WebFrame& frame)
7939{
7940 if (frame.isMainFrame())
7941 m_pendingNavigationID = std::nullopt;
7942}
7943
7944void 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
7950std::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
7959void WebPage::reportUsedFeatures()
7960{
7961 Vector<String> namedFeatures;
7962 m_loaderClient->featuresUsedInPage(*this, namedFeatures);
7963}
7964
7965void 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
7987void 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
8005void 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)
8041void 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
8052void 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
8062void 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
)
8073void 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
)
8082void WebPage::allowImmersiveElement(CompletionHandler<void(bool)>&& completion)
8083{
8084 sendWithAsyncReply(Messages::WebPageProxy::AllowImmersiveElement(), WTF::move(completion));
8085}
8086
8087void WebPage::presentImmersiveElement(const LayerHostingContextIdentifier contextID, CompletionHandler<void(bool)>&& completion)
8088{
8089 sendWithAsyncReply(Messages::WebPageProxy::PresentImmersiveElement(contextID), WTF::move(completion));
8090}
8091
8092void WebPage::dismissImmersiveElement(CompletionHandler<void()>&& completion)
8093{
8094 sendWithAsyncReply(Messages::WebPageProxy::DismissImmersiveElement(), WTF::move(completion));
8095}
8096
8097void WebPage::exitImmersive() const
8098{
8099 if (RefPtr localTopDocument = this->localTopDocument(); RefPtr protectedImmersive = localTopDocument->immersiveIfExists())
8100 protectedImmersive->exitImmersive();
8101}
8102
8103bool WebPage::allowsImmersiveEnvironments() const
8104{
8105 return m_allowsImmersiveEnvironments;
8106}
8107#endif
8108
8109void 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
8124void 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
8153unsigned 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
8168void 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
8177WebCore::ScrollPinningBehavior WebPage::scrollPinningBehavior()
8178{
8179 return m_internals->scrollPinningBehavior;
8180}
8181
8182void 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
8189void 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
8197Ref<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
8218Ref<DocumentLoader> WebPage::createDocumentLoader(LocalFrame& frame, ResourceRequest&& request, SubstituteData&& substituteData)
8219{
8220 return createDocumentLoader(frame, WTF::move(request), WTF::move(substituteData), { });
8221}
8222
8223void 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
8231void 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
8241void 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
8257void 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
8270void WebPage::postMessage(const String& messageName, API::Object* messageBody)
8271{
8272 send(Messages::WebPageProxy::HandleMessage(messageName, UserData(WebProcess::singleton().transformObjectsToHandles(messageBody))));
8273}
8274
8275void 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
8280void 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
8292void WebPage::setShouldScaleViewToFitDocument(bool shouldScaleViewToFitDocument)
8293{
8294 if (RefPtr drawingArea = m_drawingArea)
8295 drawingArea->setShouldScaleViewToFitDocument(shouldScaleViewToFitDocument);
8296}
8297
8298void WebPage::imageOrMediaDocumentSizeChanged(const IntSize& newSize)
8299{
8300 send(Messages::WebPageProxy::ImageOrMediaDocumentSizeChanged(newSize));
8301}
8302
8303void 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
8310void 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
8317void WebPage::removeAllUserContent()
8318{
8319 Ref { m_userContentController }->removeAllUserContent();
8320}
8321
8322void 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
8336void WebPage::flushPendingIntrinsicContentSizeUpdate()
8337{
8338 if (auto pendingSize = std::exchange(m_pendingIntrinsicContentSize, std::nullopt))
8339 updateIntrinsicContentSizeIfNeeded(*pendingSize);
8340}
8341
8342void 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
8352void 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
8375void WebPage::didRestoreScrollPosition()
8376{
8377 send(Messages::WebPageProxy::DidRestoreScrollPosition());
8378}
8379
8380void 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
8388void WebPage::gamepadActivity(const Vector<std::optional<GamepadData>>& gamepadDatas, EventMakesGamepadsVisible eventVisibilty)
8389{
8390 WebGamepadProvider::singleton().gamepadActivity(gamepadDatas, eventVisibilty);
8391}
8392
8393void WebPage::gamepadsRecentlyAccessed()
8394{
8395 send(Messages::WebPageProxy::GamepadsRecentlyAccessed());
8396}
8397
8398#if PLATFORM(VISION)(defined WTF_PLATFORM_VISION && WTF_PLATFORM_VISION)
8399void WebPage::allowGamepadAccess()
8400{
8401 corePage()->allowGamepadAccess();
8402}
8403#endif
8404
8405#endif // ENABLE(GAMEPAD)
8406
8407#if ENABLE(POINTER_LOCK)(defined 1 && 1)
8408void WebPage::didAcquirePointerLock()
8409{
8410 corePage()->pointerLockController().didAcquirePointerLock();
8411}
8412
8413void WebPage::didNotAcquirePointerLock()
8414{
8415 corePage()->pointerLockController().didNotAcquirePointerLock();
8416}
8417
8418void WebPage::didLosePointerLock()
8419{
8420 corePage()->pointerLockController().didLosePointerLock();
8421}
8422#endif
8423
8424void 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
8438WebURLSchemeHandlerProxy* WebPage::urlSchemeHandlerForScheme(StringView scheme)
8439{
8440 return m_schemeToURLSchemeHandlerProxyMap.get<StringViewHashTranslator>(scheme);
8441}
8442
8443void 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
8453void 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
8462void 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
8471void 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
8479void 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
8487void 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
8495void 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
8503void 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
8525void 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
8535void 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
8553void 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
8562void 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
8567void 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
8576bool 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
8582void WebPage::clearPageLevelStorageAccess()
8583{
8584 m_internals->domainsWithPageLevelStorageAccess.clear();
8585}
8586
8587void 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
8598void WebPage::wasLoadedWithDataTransferFromPrevalentResource()
8599{
8600 if (RefPtr localTopDocument = this->localTopDocument())
8601 localTopDocument->wasLoadedWithDataTransferFromPrevalentResource();
8602}
8603
8604void WebPage::didLoadFromRegistrableDomain(RegistrableDomain&& targetDomain)
8605{
8606 if (targetDomain != RegistrableDomain(m_mainFrame->url()))
8607 m_internals->loadedSubresourceDomains.add(targetDomain);
8608}
8609
8610void WebPage::getLoadedSubresourceDomains(CompletionHandler<void(Vector<RegistrableDomain>)>&& completionHandler)
8611{
8612 completionHandler(copyToVector(m_internals->loadedSubresourceDomains));
8613}
8614
8615void WebPage::clearLoadedSubresourceDomains()
8616{
8617 m_internals->loadedSubresourceDomains.clear();
8618}
8619
8620const HashSet<WebCore::RegistrableDomain>& WebPage::loadedSubresourceDomains() const
8621{
8622 return m_internals->loadedSubresourceDomains;
8623}
8624
8625#if ENABLE(DEVICE_ORIENTATION)(defined 1 && 1)
8626void 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
8632void WebPage::showShareSheet(ShareDataWithParsedURL&& shareData, WTF::CompletionHandler<void(bool)>&& callback)
8633{
8634 sendWithAsyncReply(Messages::WebPageProxy::ShowShareSheet(WTF::move(shareData)), WTF::move(callback));
8635}
8636
8637void 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)
8643void 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
8648void WebPage::dismissDigitalCredentialsPicker(CompletionHandler<void(bool)>&& completionHandler)
8649{
8650 sendWithAsyncReply(Messages::WebPageProxy::DismissDigitalCredentialsPicker(), WTF::move(completionHandler));
8651}
8652#endif
8653
8654WebCore::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
8671void 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
8685void 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)
8700void 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)
8715void WebPage::speakingErrorOccurred()
8716{
8717 if (auto observer = protect(corePage())->speechSynthesisClient()->observer())
8718 observer->speakingErrorOccurred();
8719}
8720
8721void 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
8727void 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
8736void 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
8746void 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
8756void 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
8779void 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
8789RefPtr<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
8802void 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
8814void 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
8848void WebPage::updateCurrentModifierState(OptionSet<PlatformEvent::Modifier> modifiers)
8849{
8850 PlatformKeyboardEvent::setCurrentModifierState(modifiers);
8851}
8852
8853#if !PLATFORM(IOS_FAMILY)(defined 1 && 1)
8854
8855WebCore::IntRect WebPage::rectForElementAtInteractionLocation() const
8856{
8857 return { };
8858}
8859
8860void WebPage::updateInputContextAfterBlurringAndRefocusingElementIfNeeded(Element&)
8861{
8862}
8863
8864#endif // !PLATFORM(IOS_FAMILY)
8865
8866void 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
8873RefPtr<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
8888std::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
8901void 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
8918void 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
8939void 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
9007PAL::SessionID WebPage::sessionID() const
9008{
9009 return WebProcess::singleton().sessionID();
9010}
9011
9012bool WebPage::usesEphemeralSession() const
9013{
9014 return sessionID().isEphemeral();
9015}
9016
9017void 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
9034void WebPage::getPDFFirstPageSize(WebCore::FrameIdentifier, CompletionHandler<void(WebCore::FloatSize)>&& completionHandler)
9035{
9036 completionHandler({ });
9037}
9038
9039void WebPage::getProcessDisplayName(CompletionHandler<void(String&&)>&& completionHandler)
9040{
9041 completionHandler({ });
9042}
9043
9044void WebPage::updateMockAccessibilityElementAfterCommittingLoad()
9045{
9046}
9047
9048#endif
9049
9050#if !PLATFORM(IOS_FAMILY)(defined 1 && 1) || !ENABLE(DRAG_SUPPORT)(defined 1 && 1)
9051
9052void WebPage::didFinishLoadingImageForElement(WebCore::HTMLImageElement&)
9053{
9054}
9055
9056#endif
9057
9058#if ENABLE(MODEL_PROCESS)(defined 0 && 0)
9059void WebPage::setHasModelElement(bool hasModelElement)
9060{
9061 send(Messages::WebPageProxy::SetHasModelElement(hasModelElement));
9062}
9063#endif
9064
9065#if ENABLE(TEXT_AUTOSIZING)(defined 1 && 1)
9066void WebPage::textAutoSizingAdjustmentTimerFired()
9067{
9068 protect(corePage())->recomputeTextAutoSizingInAllFrames();
9069}
9070
9071void 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)
9079PlatformXRSystemProxy& WebPage::xrSystemProxy()
9080{
9081 if (!m_xrSystemProxy)
9082 lazyInitialize(m_xrSystemProxy, makeUniqueWithoutRefCountedCheck<PlatformXRSystemProxy>(*this));
9083 return *m_xrSystemProxy;
9084}
9085#endif
9086
9087void 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
9096void 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
9107void 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)
9114void WebPage::isAnyAnimationAllowedToPlayDidChange(bool anyAnimationCanPlay)
9115{
9116 send(Messages::WebPageProxy::IsAnyAnimationAllowedToPlayDidChange(anyAnimationCanPlay));
9117}
9118#endif
9119
9120void 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)
9126void WebPage::addMediaUsageManagerSession(MediaSessionIdentifier identifier, const String& bundleIdentifier, const URL& pageURL)
9127{
9128 send(Messages::WebPageProxy::AddMediaUsageManagerSession(identifier, bundleIdentifier, pageURL));
9129}
9130
9131void WebPage::updateMediaUsageManagerSessionState(MediaSessionIdentifier identifier, const MediaUsageInfo& usage)
9132{
9133 send(Messages::WebPageProxy::UpdateMediaUsageManagerSessionState(identifier, usage));
9134}
9135
9136void 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
9144void 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();
Local variable 'cachedImage' is uncounted and unsafe
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
9261void 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
9302void 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
9313void 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()) {
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)
9349void 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
9363void WebPage::animationDidFinishForElement(const WebCore::Element&)
9364{
9365}
9366
9367#endif
9368
9369#if ENABLE(APP_BOUND_DOMAINS)(defined 1 && 1)
9370void WebPage::setIsNavigatingToAppBoundDomain(std::optional<NavigatingToAppBoundDomain> isNavigatingToAppBoundDomain, WebFrame& frame)
9371{
9372 frame.setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain);
9373
9374 m_navigationHasOccured = true;
9375}
9376
9377void 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)
9385RemoteRenderingBackendProxy& WebPage::ensureRemoteRenderingBackendProxy()
9386{
9387 if (!m_remoteRenderingBackendProxy)
9388 m_remoteRenderingBackendProxy = RemoteRenderingBackendProxy::create(*this);
9389 return *m_remoteRenderingBackendProxy;
9390}
9391#endif
9392
9393Vector<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
9405void WebPage::revokeSandboxExtensions(Vector<Ref<SandboxExtension>>& sandboxExtensions)
9406{
9407 for (auto& sandboxExtension : sandboxExtensions)
9408 sandboxExtension->revoke();
9409 sandboxExtensions.clear();
9410}
9411
9412void WebPage::createTextFragmentDirectiveFromSelection(CompletionHandler<void(URL&&)>&& completionHandler)
9413{
9414 auto url = protect(corePage())->fragmentDirectiveURLForSelectedText();
9415 completionHandler(WTF::move(url));
9416}
9417
9418void 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)
9447WebCore::CreateNewGroupForHighlight WebPage::highlightIsNewGroup() const
9448{
9449 return m_internals->highlightIsNewGroup;
9450}
9451
9452WebCore::HighlightRequestOriginatedInApp WebPage::highlightRequestOriginatedInApp() const
9453{
9454 return m_internals->highlightRequestOriginatedInApp;
9455}
9456
9457void 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
9483void 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
9501void 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
)
9516void 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
9529void 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
9539void WebPage::handleContextMenuTranslation(const TranslationContextMenuInfo& info)
9540{
9541 send(Messages::WebPageProxy::HandleContextMenuTranslation(info));
9542}
9543#endif
9544
9545void 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
9553void 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
9565void 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)
9578void 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
9601void 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)
9609void WebPage::modelInlinePreviewDidLoad(WebCore::PlatformLayerIdentifier layerID)
9610{
9611 ARKitInlinePreviewModelPlayerIOS::pageLoadedModelInlinePreview(*this, layerID);
9612}
9613
9614void 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
9622void 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
9632void 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
9645void 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
9656bool 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
9666void 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)
9673void WebPage::updateImageAnimationEnabled()
9674{
9675 protect(corePage())->setImageAnimationEnabled(WebProcess::singleton().imageAnimationEnabled());
9676}
9677
9678void WebPage::pauseAllAnimations(CompletionHandler<void()>&& completionHandler)
9679{
9680 protect(corePage())->setImageAnimationEnabled(false);
9681 completionHandler();
9682}
9683
9684void 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)
9692void 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
9703bool 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
9716void 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
9743void 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
9758bool 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
9779const 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
9789uint64_t WebPage::logIdentifier() const
9790{
9791 return intHash(m_identifier.toUInt64());
9792}
9793
9794void 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
9821void 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
9835void 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
9843void 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
9850void 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
9878void 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
9904void 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
9929void 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
9940void 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
9949void 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
9958void 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
9967void WebPage::hasTextExtractionFilterRules(CompletionHandler<void(bool)>&& completion)
9968{
9969 completion(!m_textExtractionFilterRules.isEmpty());
9970}
9971
9972void WebPage::updateTextExtractionFilterRules(Vector<WebCore::TextExtraction::FilterRuleData>&& ruleData)
9973{
9974 m_textExtractionFilterRules = TextExtraction::extractRules(WTF::move(ruleData));
9975}
9976
9977void 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
9982template<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
10003template<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
10024void WebPage::contentsToRootViewRect(FrameIdentifier frameID, FloatRect rect, CompletionHandler<void(FloatRect)>&& completionHandler)
10025{
10026 completionHandler(contentsToRootView(frameID, rect));
10027}
10028
10029void WebPage::contentsToRootViewPoint(FrameIdentifier frameID, FloatPoint point, CompletionHandler<void(FloatPoint)>&& completionHandler)
10030{
10031 completionHandler(contentsToRootView(frameID, point));
10032}
10033
10034void 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
10052void 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
10093void 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
10099void 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
10105void 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
10127void 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
)
10134void WebPage::setDefaultSpatialTrackingLabel(const String& label)
10135{
10136 if (RefPtr page = corePage())
10137 page->setDefaultSpatialTrackingLabel(label);
10138}
10139#endif
10140
10141void 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
10157void 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
10169void WebPage::didAdjustVisibilityWithSelectors(Vector<String>&& selectors)
10170{
10171 send(Messages::WebPageProxy::DidAdjustVisibilityWithSelectors(WTF::move(selectors)));
10172}
10173
10174void 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
10183void 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
10192void WebPage::didAddOrRemoveViewportConstrainedObjects()
10193{
10194 m_needsFixedContainerEdgesUpdate = true;
10195
10196#if PLATFORM(IOS_FAMILY)(defined 1 && 1)
10197 scheduleLayoutViewportHeightExpansionUpdate();
10198#endif
10199}
10200
10201void 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
10213void 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
10225void WebPage::hasActiveNowPlayingSessionChanged(bool hasActiveNowPlayingSession)
10226{
10227 send(Messages::WebPageProxy::HasActiveNowPlayingSessionChanged(hasActiveNowPlayingSession));
10228}
10229
10230void 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)
10384void 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
10408void 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
10436void 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
10447bool 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
10455bool WebPage::canShowWhileLocked() const
10456{
10457 return m_page && m_page->canShowWhileLocked();
10458}
10459
10460#else
10461
10462void WebPage::callAfterPendingSyntheticClick(CompletionHandler<void(SyntheticClickResult)>&& completion)
10463{
10464 completion(SyntheticClickResult::Failed);
10465}
10466
10467#endif
10468
10469#if HAVE(AUDIT_TOKEN)(defined 1 && 1)
10470void 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
10481void 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
10492RefPtr<MediaSessionManagerInterface> WebPage::mediaSessionManager() const
10493{
10494 RefPtr page { corePage() };
10495 return page ? page->mediaSessionManager() : nullptr;
10496
10497}
10498
10499MediaSessionManagerInterface* 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)
10507bool WebPage::shouldDisableModelLoadDelaysForTesting() const
10508{
10509 return m_page && m_page->shouldDisableModelLoadDelaysForTesting();
10510}
10511#endif
10512
10513std::unique_ptr<FrameInfoData> WebPage::takeMainFrameNavigationInitiator()
10514{
10515 return std::exchange(m_mainFrameNavigationInitiator, nullptr);
10516}
10517
10518#if !PLATFORM(IOS_FAMILY)(defined 1 && 1)
10519bool WebPage::hasAccessoryMousePointingDevice() const
10520{
10521 return true;
10522}
10523#endif
10524
10525#if ENABLE(VIDEO)(defined 1 && 1)
10526void WebPage::setCaptionDisplaySettingsPreviewProfileID(const String& profileID)
10527{
10528 if (RefPtr captionPreferences = m_pageGroup->corePageGroup()->captionPreferences())
10529 captionPreferences->setCaptionPreviewProfileID(profileID);
10530}
10531
10532void 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
10542void 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
10553void 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