032867bda75a40818e10206bde789a1936a8cdf3
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010-2020 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 "DataReference.h"
34 #include "DragControllerAction.h"
35 #include "DrawingArea.h"
36 #include "DrawingAreaMessages.h"
37 #include "EditorState.h"
38 #include "EventDispatcher.h"
39 #include "FindController.h"
40 #include "FormDataReference.h"
41 #include "FrameTreeNodeData.h"
42 #include "GeolocationPermissionRequestManager.h"
43 #include "InjectUserScriptImmediately.h"
44 #include "InjectedBundle.h"
45 #include "InjectedBundleScriptWorld.h"
46 #include "LibWebRTCProvider.h"
47 #include "LoadParameters.h"
48 #include "Logging.h"
49 #include "MediaRecorderProvider.h"
50 #include "NetscapePlugin.h"
51 #include "NetworkConnectionToWebProcessMessages.h"
52 #include "NetworkProcessConnection.h"
53 #include "NotificationPermissionRequestManager.h"
54 #include "PageBanner.h"
55 #include "PluginProcessAttributes.h"
56 #include "PluginProxy.h"
57 #include "PluginView.h"
58 #include "PrintInfo.h"
59 #include "RemoteWebInspectorUI.h"
60 #include "RemoteWebInspectorUIMessages.h"
61 #include "SessionState.h"
62 #include "SessionStateConversion.h"
63 #include "ShareSheetCallbackID.h"
64 #include "ShareableBitmap.h"
65 #include "SharedBufferDataReference.h"
66 #include "UserMediaPermissionRequestManager.h"
67 #include "ViewGestureGeometryCollector.h"
68 #include "VisitedLinkTableController.h"
69 #include "WKBundleAPICast.h"
70 #include "WKRetainPtr.h"
71 #include "WKSharedAPICast.h"
72 #include "WebAlternativeTextClient.h"
73 #include "WebBackForwardListItem.h"
74 #include "WebBackForwardListProxy.h"
75 #include "WebCacheStorageProvider.h"
76 #include "WebChromeClient.h"
77 #include "WebColorChooser.h"
78 #include "WebContextMenu.h"
79 #include "WebContextMenuClient.h"
80 #include "WebCookieJar.h"
81 #include "WebCoreArgumentCoders.h"
82 #include "WebDataListSuggestionPicker.h"
83 #include "WebDatabaseProvider.h"
84 #include "WebDiagnosticLoggingClient.h"
85 #include "WebDocumentLoader.h"
86 #include "WebDragClient.h"
87 #include "WebEditorClient.h"
88 #include "WebEvent.h"
89 #include "WebEventConversion.h"
90 #include "WebEventFactory.h"
91 #include "WebFrame.h"
92 #include "WebFrameLoaderClient.h"
93 #include "WebFullScreenManager.h"
94 #include "WebFullScreenManagerMessages.h"
95 #include "WebGamepadProvider.h"
96 #include "WebGeolocationClient.h"
97 #include "WebImage.h"
98 #include "WebInspector.h"
99 #include "WebInspectorClient.h"
100 #include "WebInspectorMessages.h"
101 #include "WebInspectorUI.h"
102 #include "WebInspectorUIMessages.h"
103 #include "WebLoaderStrategy.h"
104 #include "WebMediaKeyStorageManager.h"
105 #include "WebMediaStrategy.h"
106 #include "WebNotificationClient.h"
107 #include "WebOpenPanelResultListener.h"
108 #include "WebPageCreationParameters.h"
109 #include "WebPageGroupProxy.h"
110 #include "WebPageInspectorTargetController.h"
111 #include "WebPageMessages.h"
112 #include "WebPageOverlay.h"
113 #include "WebPageProxyMessages.h"
114 #include "WebPaymentCoordinator.h"
115 #include "WebPerformanceLoggingClient.h"
116 #include "WebPlugInClient.h"
117 #include "WebPluginInfoProvider.h"
118 #include "WebPopupMenu.h"
119 #include "WebPreferencesDefinitions.h"
120 #include "WebPreferencesKeys.h"
121 #include "WebPreferencesStore.h"
122 #include "WebProcess.h"
123 #include "WebProcessPoolMessages.h"
124 #include "WebProcessProxyMessages.h"
125 #include "WebProgressTrackerClient.h"
126 #include "WebServiceWorkerProvider.h"
127 #include "WebSocketProvider.h"
128 #include "WebSpeechSynthesisClient.h"
129 #include "WebStorageNamespaceProvider.h"
130 #include "WebURLSchemeHandlerProxy.h"
131 #include "WebUndoStep.h"
132 #include "WebUserContentController.h"
133 #include "WebUserMediaClient.h"
134 #include "WebValidationMessageClient.h"
135 #include "WebsiteDataStoreParameters.h"
136 #include <JavaScriptCore/APICast.h>
137 #include <JavaScriptCore/JSCInlines.h>
138 #include <JavaScriptCore/JSCJSValue.h>
139 #include <JavaScriptCore/JSLock.h>
140 #include <JavaScriptCore/ProfilerDatabase.h>
141 #include <JavaScriptCore/SamplingProfiler.h>
142 #include <WebCore/ApplicationCacheStorage.h>
143 #include <WebCore/ArchiveResource.h>
144 #include <WebCore/BackForwardCache.h>
145 #include <WebCore/BackForwardController.h>
146 #include <WebCore/Chrome.h>
147 #include <WebCore/CommonVM.h>
148 #include <WebCore/ContextMenuController.h>
149 #include <WebCore/DOMPasteAccess.h>
150 #include <WebCore/DataTransfer.h>
151 #include <WebCore/DatabaseManager.h>
152 #include <WebCore/DeprecatedGlobalSettings.h>
153 #include <WebCore/DocumentFragment.h>
154 #include <WebCore/DocumentLoader.h>
155 #include <WebCore/DocumentMarkerController.h>
156 #include <WebCore/DocumentStorageAccess.h>
157 #include <WebCore/DragController.h>
158 #include <WebCore/DragData.h>
159 #include <WebCore/Editing.h>
160 #include <WebCore/Editor.h>
161 #include <WebCore/ElementIterator.h>
162 #include <WebCore/EventHandler.h>
163 #include <WebCore/EventNames.h>
164 #include <WebCore/File.h>
165 #include <WebCore/FocusController.h>
166 #include <WebCore/FontAttributeChanges.h>
167 #include <WebCore/FontAttributes.h>
168 #include <WebCore/FormState.h>
169 #include <WebCore/Frame.h>
170 #include <WebCore/FrameLoadRequest.h>
171 #include <WebCore/FrameLoaderTypes.h>
172 #include <WebCore/FrameView.h>
173 #include <WebCore/FullscreenManager.h>
174 #include <WebCore/GraphicsContextGLOpenGL.h>
175 #include <WebCore/HTMLAttachmentElement.h>
176 #include <WebCore/HTMLFormElement.h>
177 #include <WebCore/HTMLImageElement.h>
178 #include <WebCore/HTMLInputElement.h>
179 #include <WebCore/HTMLMenuElement.h>
180 #include <WebCore/HTMLMenuItemElement.h>
181 #include <WebCore/HTMLOListElement.h>
182 #include <WebCore/HTMLPlugInElement.h>
183 #include <WebCore/HTMLPlugInImageElement.h>
184 #include <WebCore/HTMLSelectElement.h>
185 #include <WebCore/HTMLTextFormControlElement.h>
186 #include <WebCore/HTMLUListElement.h>
187 #include <WebCore/HistoryController.h>
188 #include <WebCore/HistoryItem.h>
189 #include <WebCore/HitTestResult.h>
190 #include <WebCore/InspectorController.h>
191 #include <WebCore/JSDOMExceptionHandling.h>
192 #include <WebCore/JSDOMWindow.h>
193 #include <WebCore/KeyboardEvent.h>
194 #include <WebCore/LegacySchemeRegistry.h>
195 #include <WebCore/LocalizedStrings.h>
196 #include <WebCore/MIMETypeRegistry.h>
197 #include <WebCore/MouseEvent.h>
198 #include <WebCore/NotImplemented.h>
199 #include <WebCore/Page.h>
200 #include <WebCore/PageConfiguration.h>
201 #include <WebCore/PingLoader.h>
202 #include <WebCore/PlatformKeyboardEvent.h>
203 #include <WebCore/PlatformMediaSessionManager.h>
204 #include <WebCore/PlatformStrategies.h>
205 #include <WebCore/PluginDocument.h>
206 #include <WebCore/PointerCaptureController.h>
207 #include <WebCore/PrintContext.h>
208 #include <WebCore/PromisedAttachmentInfo.h>
209 #include <WebCore/Quirks.h>
210 #include <WebCore/Range.h>
211 #include <WebCore/RegistrableDomain.h>
212 #include <WebCore/RemoteDOMWindow.h>
213 #include <WebCore/RemoteFrame.h>
214 #include <WebCore/RenderLayer.h>
215 #include <WebCore/RenderTheme.h>
216 #include <WebCore/RenderTreeAsText.h>
217 #include <WebCore/RenderView.h>
218 #include <WebCore/ResourceLoadStatistics.h>
219 #include <WebCore/ResourceRequest.h>
220 #include <WebCore/ResourceResponse.h>
221 #include <WebCore/RunJavaScriptParameters.h>
222 #include <WebCore/RuntimeEnabledFeatures.h>
223 #include <WebCore/SWClientConnection.h>
224 #include <WebCore/ScriptController.h>
225 #include <WebCore/SerializedScriptValue.h>
226 #include <WebCore/Settings.h>
227 #include <WebCore/ShadowRoot.h>
228 #include <WebCore/SharedBuffer.h>
229 #include <WebCore/StyleProperties.h>
230 #include <WebCore/SubframeLoader.h>
231 #include <WebCore/SubstituteData.h>
232 #include <WebCore/TextIterator.h>
233 #include <WebCore/UserGestureIndicator.h>
234 #include <WebCore/UserInputBridge.h>
235 #include <WebCore/UserScript.h>
236 #include <WebCore/UserStyleSheet.h>
237 #include <WebCore/UserTypingGestureIndicator.h>
238 #include <WebCore/VisiblePosition.h>
239 #include <WebCore/VisibleUnits.h>
240 #include <WebCore/WebGLStateTracker.h>
241 #include <WebCore/WritingDirection.h>
242 #include <WebCore/markup.h>
243 #include <pal/SessionID.h>
244 #include <wtf/ProcessID.h>
245 #include <wtf/RunLoop.h>
246 #include <wtf/SetForScope.h>
247 #include <wtf/text/TextStream.h>
248
249 #if ENABLE(DATA_DETECTION)
250 #include "DataDetectionResult.h"
251 #endif
252
253 #if ENABLE(MHTML)
254 #include <WebCore/MHTMLArchive.h>
255 #endif
256
257 #if ENABLE(POINTER_LOCK)
258 #include <WebCore/PointerLockController.h>
259 #endif
260
261 #if PLATFORM(COCOA)
262 #include "InsertTextOptions.h"
263 #include "PDFPlugin.h"
264 #include "PlaybackSessionManager.h"
265 #include "RemoteLayerTreeTransaction.h"
266 #include "RemoteObjectRegistryMessages.h"
267 #include "TextCheckingControllerProxy.h"
268 #include "UserMediaCaptureManager.h"
269 #include "VideoFullscreenManager.h"
270 #include "WKStringCF.h"
271 #include "WebRemoteObjectRegistry.h"
272 #include <WebCore/LegacyWebArchive.h>
273 #include <WebCore/UTIRegistry.h>
274 #include <wtf/MachSendRight.h>
275 #endif
276
277 #if HAVE(TOUCH_BAR)
278 #include "TouchBarMenuData.h"
279 #include "TouchBarMenuItemData.h"
280 #endif
281
282 #if PLATFORM(GTK)
283 #include "WebPrintOperationGtk.h"
284 #include "WebSelectionData.h"
285 #include <gtk/gtk.h>
286 #endif
287
288 #if PLATFORM(IOS_FAMILY)
289 #include "InteractionInformationAtPosition.h"
290 #include "InteractionInformationRequest.h"
291 #include "RemoteLayerTreeDrawingArea.h"
292 #include "WebAutocorrectionContext.h"
293 #include <CoreGraphics/CoreGraphics.h>
294 #include <WebCore/Icon.h>
295 #include <pal/spi/cocoa/CoreTextSPI.h>
296 #endif
297
298 #if PLATFORM(MAC)
299 #include <WebCore/LocalDefaultSystemAppearance.h>
300 #include <pal/spi/cf/CFUtilitiesSPI.h>
301 #endif
302
303 #ifndef NDEBUG
304 #include <wtf/RefCountedLeakCounter.h>
305 #endif
306
307 #if ENABLE(DATA_DETECTION)
308 #include <WebCore/DataDetection.h>
309 #endif
310
311 #if ENABLE(VIDEO) && USE(GSTREAMER)
312 #include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
313 #endif
314
315 #if ENABLE(WEB_AUTHN)
316 #include "WebAuthenticatorCoordinator.h"
317 #include <WebCore/AuthenticatorCoordinator.h>
318 #endif
319
320 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
321 #include "WebDeviceOrientationUpdateProvider.h"
322 #endif
323
324 #if ENABLE(GPU_PROCESS)
325 #include "RemoteMediaPlayerManager.h"
326 #if ENABLE(ENCRYPTED_MEDIA)
327 #include "RemoteCDMFactory.h"
328 #endif
329 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
330 #include "RemoteLegacyCDMFactory.h"
331 #endif
332 #endif
333
334 namespace WebKit {
335 using namespace JSC;
336 using namespace WebCore;
337
338 static const Seconds pageScrollHysteresisDuration { 300_ms };
339 static const Seconds initialLayerVolatilityTimerInterval { 20_ms };
340 static const Seconds maximumLayerVolatilityTimerInterval { 2_s };
341
342 #define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [webPageID=%" PRIu64 "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__)
343 #define RELEASE_LOG_ERROR_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_ERROR_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [webPageID=%" PRIu64 "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__)
344
345 class SendStopResponsivenessTimer {
346 public:
347     ~SendStopResponsivenessTimer()
348     {
349         WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopResponsivenessTimer(), 0);
350     }
351 };
352
353 class DeferredPageDestructor {
354 public:
355     static void createDeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
356     {
357         new DeferredPageDestructor(WTFMove(page), webPage);
358     }
359
360 private:
361     DeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
362         : m_page(WTFMove(page))
363         , m_webPage(webPage)
364     {
365         tryDestruction();
366     }
367
368     void tryDestruction()
369     {
370         if (m_page->insideNestedRunLoop()) {
371             m_page->whenUnnested([this] { tryDestruction(); });
372             return;
373         }
374
375         m_page = nullptr;
376         m_webPage = nullptr;
377         delete this;
378     }
379
380     std::unique_ptr<Page> m_page;
381     RefPtr<WebPage> m_webPage;
382 };
383
384 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
385
386 Ref<WebPage> WebPage::create(PageIdentifier pageID, WebPageCreationParameters&& parameters)
387 {
388     Ref<WebPage> page = adoptRef(*new WebPage(pageID, WTFMove(parameters)));
389
390     if (WebProcess::singleton().injectedBundle())
391         WebProcess::singleton().injectedBundle()->didCreatePage(page.ptr());
392
393     return page;
394 }
395
396 WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
397     : m_identifier(pageID)
398     , m_mainFrame(WebFrame::create())
399     , m_viewSize(parameters.viewSize)
400     , m_alwaysShowsHorizontalScroller { parameters.alwaysShowsHorizontalScroller }
401     , m_alwaysShowsVerticalScroller { parameters.alwaysShowsVerticalScroller }
402     , m_shouldRenderCanvasInGPUProcess { parameters.shouldRenderCanvasInGPUProcess }
403     , m_needsInAppBrowserPrivacyQuirks { parameters.needsInAppBrowserPrivacyQuirks }
404 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
405     , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
406 #endif
407     , m_layerHostingMode(parameters.layerHostingMode)
408 #if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
409     , m_textCheckingControllerProxy(makeUniqueRef<TextCheckingControllerProxy>(*this))
410 #endif
411 #if PLATFORM(COCOA) || PLATFORM(GTK)
412     , m_viewGestureGeometryCollector(makeUnique<ViewGestureGeometryCollector>(*this))
413 #elif ENABLE(ACCESSIBILITY) && PLATFORM(GTK)
414     , m_accessibilityObject(nullptr)
415 #endif
416     , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
417 #if ENABLE(CONTEXT_MENUS)
418     , m_contextMenuClient(makeUnique<API::InjectedBundle::PageContextMenuClient>())
419 #endif
420     , m_editorClient { makeUnique<API::InjectedBundle::EditorClient>() }
421     , m_formClient(makeUnique<API::InjectedBundle::FormClient>())
422     , m_loaderClient(makeUnique<API::InjectedBundle::PageLoaderClient>())
423     , m_resourceLoadClient(makeUnique<API::InjectedBundle::ResourceLoadClient>())
424     , m_uiClient(makeUnique<API::InjectedBundle::PageUIClient>())
425     , m_findController(makeUniqueRef<FindController>(this))
426     , m_inspectorTargetController(makeUnique<WebPageInspectorTargetController>(*this))
427     , m_userContentController(WebUserContentController::getOrCreate(parameters.userContentControllerID))
428 #if ENABLE(GEOLOCATION)
429     , m_geolocationPermissionRequestManager(makeUniqueRef<GeolocationPermissionRequestManager>(*this))
430 #endif
431 #if ENABLE(MEDIA_STREAM)
432     , m_userMediaPermissionRequestManager { makeUniqueRef<UserMediaPermissionRequestManager>(*this) }
433 #endif
434     , m_pageScrolledHysteresis([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) pageStoppedScrolling(); }, pageScrollHysteresisDuration)
435     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
436     , m_canRunModal(parameters.canRunModal)
437 #if ENABLE(META_VIEWPORT)
438     , m_forceAlwaysUserScalable(parameters.ignoresViewportScaleLimits)
439 #endif
440 #if PLATFORM(IOS_FAMILY)
441     , m_screenSize(parameters.screenSize)
442     , m_availableScreenSize(parameters.availableScreenSize)
443     , m_overrideScreenSize(parameters.overrideScreenSize)
444     , m_deviceOrientation(parameters.deviceOrientation)
445     , m_keyboardIsAttached(parameters.keyboardIsAttached)
446     , m_canShowWhileLocked(parameters.canShowWhileLocked)
447 #endif
448     , m_layerVolatilityTimer(*this, &WebPage::layerVolatilityTimerFired)
449     , m_activityState(parameters.activityState)
450     , m_userActivity("App nap disabled for page due to user activity")
451     , m_userInterfaceLayoutDirection(parameters.userInterfaceLayoutDirection)
452     , m_overrideContentSecurityPolicy { parameters.overrideContentSecurityPolicy }
453     , m_cpuLimit(parameters.cpuLimit)
454 #if USE(WPE_RENDERER)
455     , m_hostFileDescriptor(WTFMove(parameters.hostFileDescriptor))
456 #endif
457     , m_webPageProxyIdentifier(parameters.webPageProxyIdentifier)
458 #if ENABLE(TEXT_AUTOSIZING)
459     , m_textAutoSizingAdjustmentTimer(*this, &WebPage::textAutoSizingAdjustmentTimerFired)
460 #endif
461     , m_overriddenMediaType(parameters.overriddenMediaType)
462     , m_processDisplayName(parameters.processDisplayName)
463 {
464     ASSERT(m_identifier);
465
466     m_pageGroup = WebProcess::singleton().webPageGroup(parameters.pageGroupData);
467
468     PageConfiguration pageConfiguration(
469         WebProcess::singleton().sessionID(),
470         makeUniqueRef<WebEditorClient>(this),
471         WebSocketProvider::create(),
472         makeUniqueRef<WebKit::LibWebRTCProvider>(),
473         WebProcess::singleton().cacheStorageProvider(),
474         WebBackForwardListProxy::create(*this),
475         WebProcess::singleton().cookieJar(),
476         makeUniqueRef<WebProgressTrackerClient>(*this),
477         makeUniqueRef<WebFrameLoaderClient>(m_mainFrame.copyRef()),
478         makeUniqueRef<MediaRecorderProvider>()
479     );
480     pageConfiguration.chromeClient = new WebChromeClient(*this);
481 #if ENABLE(CONTEXT_MENUS)
482     pageConfiguration.contextMenuClient = new WebContextMenuClient(this);
483 #endif
484 #if ENABLE(DRAG_SUPPORT)
485     pageConfiguration.dragClient = makeUnique<WebDragClient>(this);
486 #endif
487     pageConfiguration.inspectorClient = new WebInspectorClient(this);
488 #if USE(AUTOCORRECTION_PANEL)
489     pageConfiguration.alternativeTextClient = makeUnique<WebAlternativeTextClient>(this);
490 #endif
491
492     pageConfiguration.plugInClient = makeUnique<WebPlugInClient>(*this);
493     pageConfiguration.diagnosticLoggingClient = makeUnique<WebDiagnosticLoggingClient>(*this);
494     pageConfiguration.performanceLoggingClient = makeUnique<WebPerformanceLoggingClient>(*this);
495
496 #if ENABLE(WEBGL)
497     pageConfiguration.webGLStateTracker = makeUnique<WebGLStateTracker>([this](bool isUsingHighPerformanceWebGL) {
498         send(Messages::WebPageProxy::SetIsUsingHighPerformanceWebGL(isUsingHighPerformanceWebGL));
499     });
500 #endif
501
502 #if ENABLE(SPEECH_SYNTHESIS)
503     pageConfiguration.speechSynthesisClient = makeUnique<WebSpeechSynthesisClient>(*this);
504 #endif
505
506 #if PLATFORM(COCOA)
507     pageConfiguration.validationMessageClient = makeUnique<WebValidationMessageClient>(*this);
508 #endif
509
510     pageConfiguration.applicationCacheStorage = &WebProcess::singleton().applicationCacheStorage();
511     pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID());
512     pageConfiguration.pluginInfoProvider = &WebPluginInfoProvider::singleton();
513     pageConfiguration.storageNamespaceProvider = WebStorageNamespaceProvider::getOrCreate(*m_pageGroup);
514     pageConfiguration.userContentProvider = m_userContentController.ptr();
515     pageConfiguration.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID);
516
517 #if ENABLE(APPLE_PAY)
518     pageConfiguration.paymentCoordinatorClient = new WebPaymentCoordinator(*this);
519 #endif
520
521 #if ENABLE(WEB_AUTHN)
522     pageConfiguration.authenticatorCoordinatorClient = makeUnique<WebAuthenticatorCoordinator>(*this);
523 #endif
524
525 #if ENABLE(APPLICATION_MANIFEST)
526     pageConfiguration.applicationManifest = parameters.applicationManifest;
527 #endif
528     
529 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
530     pageConfiguration.deviceOrientationUpdateProvider = WebDeviceOrientationUpdateProvider::create(*this);
531 #endif
532
533     pageConfiguration.corsDisablingPatterns = WTFMove(parameters.corsDisablingPatterns);
534     if (!parameters.crossOriginAccessControlCheckEnabled)
535         CrossOriginAccessControlCheckDisabler::singleton().setCrossOriginAccessControlCheckEnabled(false);
536
537 #if ENABLE(ATTACHMENT_ELEMENT) && PLATFORM(IOS_FAMILY)
538     if (parameters.frontboardExtensionHandle)
539         SandboxExtension::consumePermanently(*parameters.frontboardExtensionHandle);
540     if (parameters.iconServicesExtensionHandle)
541         SandboxExtension::consumePermanently(*parameters.iconServicesExtensionHandle);
542 #endif
543
544     m_page = makeUnique<Page>(WTFMove(pageConfiguration));
545
546     updatePreferences(parameters.store);
547
548 #if PLATFORM(IOS_FAMILY)
549     if (!m_page->settings().useGPUProcessForMedia())
550         DeprecatedGlobalSettings::setShouldManageAudioSessionCategory(true);
551 #endif
552
553     m_backgroundColor = parameters.backgroundColor;
554
555     m_drawingArea = DrawingArea::create(*this, parameters);
556     m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
557
558     if (parameters.isProcessSwap)
559         freezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
560
561 #if ENABLE(ASYNC_SCROLLING)
562     m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
563     if (!m_drawingArea->supportsAsyncScrolling())
564         m_useAsyncScrolling = false;
565     m_page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling);
566 #endif
567
568     // Disable Back/Forward cache expiration in the WebContent process since management happens in the UIProcess
569     // in modern WebKit.
570     m_page->settings().setBackForwardCacheExpirationInterval(Seconds::infinity());
571
572     m_mainFrame->initWithCoreMainFrame(*this, m_page->mainFrame());
573
574     m_drawingArea->updatePreferences(parameters.store);
575
576     setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage);
577     setPageAndTextZoomFactors(parameters.pageZoomFactor, parameters.textZoomFactor);
578
579 #if ENABLE(GEOLOCATION)
580     WebCore::provideGeolocationTo(m_page.get(), *new WebGeolocationClient(*this));
581 #endif
582 #if ENABLE(NOTIFICATIONS)
583     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
584 #endif
585 #if ENABLE(MEDIA_STREAM)
586     WebCore::provideUserMediaTo(m_page.get(), new WebUserMediaClient(*this));
587 #endif
588
589     m_page->setControlledByAutomation(parameters.controlledByAutomation);
590     m_page->setHasResourceLoadClient(parameters.hasResourceLoadClient);
591
592     m_page->setCanStartMedia(false);
593     m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
594     if (parameters.mediaPlaybackIsSuspended)
595         m_page->suspendAllMediaPlayback();
596
597     m_page->setGroupName(m_pageGroup->identifier());
598     m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
599     m_page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection);
600 #if PLATFORM(IOS_FAMILY)
601     m_page->setTextAutosizingWidth(parameters.textAutosizingWidth);
602     setOverrideViewportArguments(parameters.overrideViewportArguments);
603 #endif
604
605     platformInitialize();
606
607     setUseFixedLayout(parameters.useFixedLayout);
608
609     setUnderlayColor(parameters.underlayColor);
610
611     setPaginationMode(parameters.paginationMode);
612     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
613     setPageLength(parameters.pageLength);
614     setGapBetweenPages(parameters.gapBetweenPages);
615     setPaginationLineGridEnabled(parameters.paginationLineGridEnabled);
616
617 #if PLATFORM(GTK)
618     themeDidChange(WTFMove(parameters.themeName));
619 #endif
620
621     effectiveAppearanceDidChange(parameters.useDarkAppearance, parameters.useElevatedUserInterfaceLevel);
622
623     if (parameters.isEditable)
624         setEditable(true);
625
626 #if PLATFORM(MAC)
627     setUseSystemAppearance(parameters.useSystemAppearance);
628 #endif
629
630     // If the page is created off-screen, its visibilityState should be prerender.
631     m_page->setActivityState(m_activityState);
632     if (!isVisible())
633         m_page->setIsPrerender();
634
635     updateIsInWindow(true);
636
637     setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout);
638     setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
639     setViewportSizeForCSSViewportUnits(parameters.viewportSizeForCSSViewportUnits);
640     
641     setScrollPinningBehavior(parameters.scrollPinningBehavior);
642     if (parameters.scrollbarOverlayStyle)
643         m_scrollbarOverlayStyle = static_cast<ScrollbarOverlayStyle>(parameters.scrollbarOverlayStyle.value());
644     else
645         m_scrollbarOverlayStyle = Optional<ScrollbarOverlayStyle>();
646
647     setTopContentInset(parameters.topContentInset);
648
649     m_userAgent = parameters.userAgent;
650     
651     if (!parameters.itemStates.isEmpty())
652         restoreSessionInternal(parameters.itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
653
654     m_drawingArea->enablePainting();
655     
656     setMediaVolume(parameters.mediaVolume);
657
658     setMuted(parameters.muted);
659
660     // We use the DidFirstVisuallyNonEmptyLayout milestone to determine when to unfreeze the layer tree.
661     m_page->addLayoutMilestones({ DidFirstLayout, DidFirstVisuallyNonEmptyLayout });
662
663     auto& webProcess = WebProcess::singleton();
664     webProcess.addMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier, *this);
665
666     // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
667     webProcess.addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_identifier, *this);
668     webProcess.addMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier, *this);
669     webProcess.addMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier, *this);
670 #if ENABLE(FULLSCREEN_API)
671     webProcess.addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier, *this);
672 #endif
673
674 #ifndef NDEBUG
675     webPageCounter.increment();
676 #endif
677
678 #if ENABLE(SCROLLING_THREAD)
679     if (m_useAsyncScrolling)
680         webProcess.eventDispatcher().addScrollingTreeForPage(this);
681 #endif
682
683     for (auto& mimeType : parameters.mimeTypesWithCustomContentProviders)
684         m_mimeTypesWithCustomContentProviders.add(mimeType);
685
686
687 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
688     if (WebMediaKeyStorageManager* manager = webProcess.supplement<WebMediaKeyStorageManager>())
689         m_page->settings().setMediaKeysStorageDirectory(manager->mediaKeyStorageDirectory());
690 #endif
691     m_page->settings().setAppleMailPaginationQuirkEnabled(parameters.appleMailPaginationQuirkEnabled);
692     
693     if (parameters.viewScaleFactor != 1)
694         scaleView(parameters.viewScaleFactor);
695
696     m_page->addLayoutMilestones(parameters.observedLayoutMilestones);
697
698 #if PLATFORM(COCOA)
699     m_page->settings().setContentDispositionAttachmentSandboxEnabled(true);
700     setSmartInsertDeleteEnabled(parameters.smartInsertDeleteEnabled);
701     WebCore::setAdditionalSupportedImageTypes(parameters.additionalSupportedImageTypes);
702 #endif
703
704     m_needsFontAttributes = parameters.needsFontAttributes;
705
706 #if ENABLE(WEB_RTC)
707     if (!parameters.iceCandidateFilteringEnabled)
708         m_page->disableICECandidateFiltering();
709 #if USE(LIBWEBRTC)
710     if (parameters.enumeratingAllNetworkInterfacesEnabled)
711         m_page->libWebRTCProvider().enableEnumeratingAllNetworkInterfaces();
712 #endif
713 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
714     if (auto* captureManager = WebProcess::singleton().supplement<UserMediaCaptureManager>())
715         captureManager->setupCaptureProcesses(parameters.shouldCaptureAudioInUIProcess, parameters.shouldCaptureAudioInGPUProcess, parameters.shouldCaptureVideoInUIProcess, parameters.shouldCaptureVideoInGPUProcess, parameters.shouldCaptureDisplayInUIProcess);
716 #endif
717 #endif
718
719     for (const auto& iterator : parameters.urlSchemeHandlers)
720         registerURLSchemeHandler(iterator.value, iterator.key);
721
722     m_userContentController->addContentWorlds(parameters.userContentWorlds);
723     m_userContentController->addUserScripts(WTFMove(parameters.userScripts), InjectUserScriptImmediately::No);
724     m_userContentController->addUserStyleSheets(parameters.userStyleSheets);
725     m_userContentController->addUserScriptMessageHandlers(parameters.messageHandlers);
726 #if ENABLE(CONTENT_EXTENSIONS)
727     m_userContentController->addContentRuleLists(WTFMove(parameters.contentRuleLists));
728 #endif
729
730 #if PLATFORM(IOS_FAMILY)
731     setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize, parameters.viewportConfigurationLayoutSizeScaleFactor, parameters.viewportConfigurationMinimumEffectiveDeviceWidth);
732     setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
733 #endif
734
735 #if USE(AUDIO_SESSION)
736     PlatformMediaSessionManager::setShouldDeactivateAudioSession(true);
737 #endif
738
739 #if HAVE(VISIBILITY_PROPAGATION_VIEW)
740     m_contextForVisibilityPropagation = LayerHostingContext::createForExternalHostingProcess({
741         m_canShowWhileLocked
742     });
743     RELEASE_LOG_IF_ALLOWED(Process, "WebPage: Created context with ID %d for visibility propagation from UIProcess", m_contextForVisibilityPropagation->contextID());
744     send(Messages::WebPageProxy::DidCreateContextForVisibilityPropagation(m_contextForVisibilityPropagation->contextID()));
745 #endif
746
747     updateThrottleState();
748 }
749
750 void WebPage::stopAllMediaPlayback()
751 {
752     m_page->stopAllMediaPlayback();
753 }
754
755 void WebPage::suspendAllMediaPlayback()
756 {
757     m_page->suspendAllMediaPlayback();
758 }
759
760 void WebPage::resumeAllMediaPlayback()
761 {
762     m_page->resumeAllMediaPlayback();
763 }
764
765 void WebPage::suspendAllMediaBuffering()
766 {
767     m_page->suspendAllMediaBuffering();
768 }
769
770 void WebPage::resumeAllMediaBuffering()
771 {
772     m_page->resumeAllMediaBuffering();
773 }
774
775
776 void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
777 {
778     ASSERT(m_drawingArea);
779
780     setSize(parameters.viewSize);
781
782     // If the UIProcess created a new DrawingArea, then we need to do the same.
783     if (m_drawingArea->identifier() != parameters.drawingAreaIdentifier) {
784         auto oldDrawingArea = std::exchange(m_drawingArea, nullptr);
785         oldDrawingArea->removeMessageReceiverIfNeeded();
786
787         m_drawingArea = DrawingArea::create(*this, parameters);
788         m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
789         m_drawingArea->updatePreferences(parameters.store);
790         m_drawingArea->enablePainting();
791
792         m_drawingArea->adoptLayersFromDrawingArea(*oldDrawingArea);
793         m_drawingArea->adoptDisplayRefreshMonitorsFromDrawingArea(*oldDrawingArea);
794
795         unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended);
796     }
797
798     setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout);
799
800     if (m_activityState != parameters.activityState)
801         setActivityState(parameters.activityState, ActivityStateChangeAsynchronous, Vector<CallbackID>());
802     if (m_layerHostingMode != parameters.layerHostingMode)
803         setLayerHostingMode(parameters.layerHostingMode);
804
805     platformReinitialize();
806 }
807
808 void WebPage::updateThrottleState()
809 {
810     bool isThrottleable = this->isThrottleable();
811
812     // The UserActivity prevents App Nap. So if we want to allow App Nap of the page, stop the activity.
813     // If the page should not be app nap'd, start it.
814     if (isThrottleable)
815         m_userActivity.stop();
816     else
817         m_userActivity.start();
818
819 #if ENABLE(SERVICE_WORKER)
820     if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled()) {
821         RunLoop::main().dispatch([isThrottleable] {
822             WebServiceWorkerProvider::singleton().updateThrottleState(isThrottleable);
823         });
824     }
825 #endif
826 }
827
828 bool WebPage::isThrottleable() const
829 {
830     bool isActive = m_activityState.containsAny({ ActivityState::IsLoading, ActivityState::IsAudible, ActivityState::IsCapturingMedia, ActivityState::WindowIsActive });
831     bool isVisuallyIdle = m_activityState.contains(ActivityState::IsVisuallyIdle);
832
833     return m_isAppNapEnabled && !isActive && isVisuallyIdle;
834 }
835
836 WebPage::~WebPage()
837 {
838     ASSERT(!m_page);
839
840     platformDetach();
841     
842     m_sandboxExtensionTracker.invalidate();
843
844     for (auto* pluginView : m_pluginViews)
845         pluginView->webPageDestroyed();
846
847 #if !PLATFORM(IOS_FAMILY)
848     if (m_headerBanner)
849         m_headerBanner->detachFromPage();
850     if (m_footerBanner)
851         m_footerBanner->detachFromPage();
852 #endif // !PLATFORM(IOS_FAMILY)
853
854 #ifndef NDEBUG
855     webPageCounter.decrement();
856 #endif
857     
858 #if (PLATFORM(IOS_FAMILY) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
859     if (m_playbackSessionManager)
860         m_playbackSessionManager->invalidate();
861
862     if (m_videoFullscreenManager)
863         m_videoFullscreenManager->invalidate();
864 #endif
865 }
866
867 IPC::Connection* WebPage::messageSenderConnection() const
868 {
869     return WebProcess::singleton().parentProcessConnection();
870 }
871
872 uint64_t WebPage::messageSenderDestinationID() const
873 {
874     return identifier().toUInt64();
875 }
876
877 #if ENABLE(CONTEXT_MENUS)
878 void WebPage::setInjectedBundleContextMenuClient(std::unique_ptr<API::InjectedBundle::PageContextMenuClient>&& contextMenuClient)
879 {
880     if (!contextMenuClient) {
881         m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>();
882         return;
883     }
884
885     m_contextMenuClient = WTFMove(contextMenuClient);
886 }
887 #endif
888
889 void WebPage::setInjectedBundleEditorClient(std::unique_ptr<API::InjectedBundle::EditorClient>&& editorClient)
890 {
891     if (!editorClient) {
892         m_editorClient = makeUnique<API::InjectedBundle::EditorClient>();
893         return;
894     }
895
896     m_editorClient = WTFMove(editorClient);
897 }
898
899 void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient>&& formClient)
900 {
901     if (!formClient) {
902         m_formClient = makeUnique<API::InjectedBundle::FormClient>();
903         return;
904     }
905
906     m_formClient = WTFMove(formClient);
907 }
908
909 void WebPage::setInjectedBundlePageLoaderClient(std::unique_ptr<API::InjectedBundle::PageLoaderClient>&& loaderClient)
910 {
911     if (!loaderClient) {
912         m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>();
913         return;
914     }
915
916     m_loaderClient = WTFMove(loaderClient);
917
918     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
919     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
920     // for backwards compatibility.
921     if (auto milestones = m_loaderClient->layoutMilestones())
922         listenForLayoutMilestones(milestones);
923 }
924
925 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClientBase* client)
926 {
927     m_policyClient.initialize(client);
928 }
929
930 void WebPage::setInjectedBundleResourceLoadClient(std::unique_ptr<API::InjectedBundle::ResourceLoadClient>&& client)
931 {
932     if (!m_resourceLoadClient)
933         m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>();
934     else
935         m_resourceLoadClient = WTFMove(client);
936 }
937
938 void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient>&& uiClient)
939 {
940     if (!uiClient) {
941         m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>();
942         return;
943     }
944
945     m_uiClient = WTFMove(uiClient);
946 }
947
948 #if ENABLE(FULLSCREEN_API)
949 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClientBase* client)
950 {
951     m_fullScreenClient.initialize(client);
952 }
953 #endif
954
955 #if ENABLE(NETSCAPE_PLUGIN_API)
956
957 constexpr int smallPluginDimensionThreshold = 5;
958
959 static bool pluginIsSmall(WebCore::HTMLPlugInElement& pluginElement)
960 {
961     auto* renderer = pluginElement.renderer();
962     if (!is<RenderEmbeddedObject>(*renderer))
963         return false;
964
965     auto& box = downcast<RenderBox>(*renderer);
966     return box.contentWidth() <= smallPluginDimensionThreshold && box.contentHeight() <= smallPluginDimensionThreshold;
967 }
968
969 RefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
970 {
971     String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
972     String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
973
974 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
975     HTMLPlugInImageElement& pluginImageElement = downcast<HTMLPlugInImageElement>(*pluginElement);
976     unsigned pluginArea = 0;
977     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot && !(plugInIsPrimarySize(pluginImageElement, pluginArea) && !plugInIntersectsSearchRect(pluginImageElement)) ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
978 #else
979     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
980 #endif
981
982     bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins();
983
984     uint64_t pluginProcessToken;
985     uint32_t pluginLoadPolicy;
986     String unavailabilityDescription;
987     bool isUnsupported;
988     if (!sendSync(Messages::WebPageProxy::FindPlugin(parameters.mimeType, static_cast<uint32_t>(processType), parameters.url.string(), frameURLString, pageURLString, allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription, isUnsupported)))
989         return nullptr;
990
991     PluginModuleLoadPolicy loadPolicy = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy);
992     bool isBlockedPlugin = (loadPolicy == PluginModuleBlockedForSecurity) || (loadPolicy == PluginModuleBlockedForCompatibility);
993
994     if (isUnsupported || isBlockedPlugin || !pluginProcessToken) {
995 #if ENABLE(PDFKIT_PLUGIN)
996         auto path = parameters.url.path();
997         if (shouldUsePDFPlugin() && (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWithIgnoringASCIICase(".pdf") || path.endsWithIgnoringASCIICase(".ps")))))
998             return PDFPlugin::create(*frame);
999 #endif
1000     }
1001
1002     if (isUnsupported) {
1003         pluginElement->setReplacement(RenderEmbeddedObject::UnsupportedPlugin, unavailabilityDescription);
1004         return nullptr;
1005     }
1006
1007     if (isBlockedPlugin) {
1008         bool isReplacementObscured = pluginElement->setReplacement(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
1009         send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, isReplacementObscured));
1010         return nullptr;
1011     }
1012
1013     if (!pluginProcessToken)
1014         return nullptr;
1015
1016     if (m_page->settings().blockingOfSmallPluginsEnabled() && pluginIsSmall(*pluginElement)) {
1017         RELEASE_LOG_IF_ALLOWED(Plugins, "createPlugin: Blocking a plugin because it is too small");
1018         pluginElement->setReplacement(RenderEmbeddedObject::PluginTooSmall, pluginTooSmallText());
1019         return nullptr;
1020     }
1021
1022     bool isRestartedProcess = (pluginElement->displayState() == HTMLPlugInElement::Restarting || pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick);
1023     return PluginProxy::create(pluginProcessToken, isRestartedProcess);
1024 }
1025 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1026
1027 #if ENABLE(WEBGL) && !PLATFORM(MAC)
1028 WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const URL&)
1029 {
1030     return WebGLAllowCreation;
1031 }
1032
1033 WebCore::WebGLLoadPolicy WebPage::resolveWebGLPolicyForURL(WebFrame*, const URL&)
1034 {
1035     return WebGLAllowCreation;
1036 }
1037 #endif
1038
1039 EditorState WebPage::editorState(IncludePostLayoutDataHint shouldIncludePostLayoutData) const
1040 {
1041     Frame& frame = m_page->focusController().focusedOrMainFrame();
1042
1043     EditorState result;
1044
1045     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
1046         if (!pluginView->getSelectionString().isNull()) {
1047             result.selectionIsNone = false;
1048             result.selectionIsRange = true;
1049             result.isInPlugin = true;
1050             return result;
1051         }
1052     }
1053
1054     const VisibleSelection& selection = frame.selection().selection();
1055     const Editor& editor = frame.editor();
1056
1057     result.selectionIsNone = selection.isNone();
1058     result.selectionIsRange = selection.isRange();
1059     result.isContentEditable = selection.isContentEditable();
1060     result.isContentRichlyEditable = selection.isContentRichlyEditable();
1061     result.isInPasswordField = selection.isInPasswordField();
1062     result.hasComposition = editor.hasComposition();
1063     result.shouldIgnoreSelectionChanges = editor.ignoreSelectionChanges() || (editor.client() && !editor.client()->shouldRevealCurrentSelectionAfterInsertion());
1064
1065     if (auto* document = frame.document())
1066         result.originIdentifierForPasteboard = document->originIdentifierForPasteboard();
1067
1068     bool canIncludePostLayoutData = frame.view() && !frame.view()->needsLayout();
1069     if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::Yes && canIncludePostLayoutData) {
1070         auto& postLayoutData = result.postLayoutData();
1071         postLayoutData.canCut = editor.canCut();
1072         postLayoutData.canCopy = editor.canCopy();
1073         postLayoutData.canPaste = editor.canPaste();
1074
1075         if (m_needsFontAttributes)
1076             postLayoutData.fontAttributes = editor.fontAttributesAtSelectionStart();
1077
1078 #if PLATFORM(COCOA)
1079         if (result.isContentEditable && !selection.isNone()) {
1080             if (auto editingStyle = EditingStyle::styleAtSelectionStart(selection)) {
1081                 if (editingStyle->hasStyle(CSSPropertyFontWeight, "bold"))
1082                     postLayoutData.typingAttributes |= AttributeBold;
1083
1084                 if (editingStyle->hasStyle(CSSPropertyFontStyle, "italic") || editingStyle->hasStyle(CSSPropertyFontStyle, "oblique"))
1085                     postLayoutData.typingAttributes |= AttributeItalics;
1086
1087                 if (editingStyle->hasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline"))
1088                     postLayoutData.typingAttributes |= AttributeUnderline;
1089
1090                 if (auto* styleProperties = editingStyle->style()) {
1091                     bool isLeftToRight = styleProperties->propertyAsValueID(CSSPropertyDirection) == CSSValueLtr;
1092                     switch (styleProperties->propertyAsValueID(CSSPropertyTextAlign)) {
1093                     case CSSValueRight:
1094                     case CSSValueWebkitRight:
1095                         postLayoutData.textAlignment = RightAlignment;
1096                         break;
1097                     case CSSValueLeft:
1098                     case CSSValueWebkitLeft:
1099                         postLayoutData.textAlignment = LeftAlignment;
1100                         break;
1101                     case CSSValueCenter:
1102                     case CSSValueWebkitCenter:
1103                         postLayoutData.textAlignment = CenterAlignment;
1104                         break;
1105                     case CSSValueJustify:
1106                         postLayoutData.textAlignment = JustifiedAlignment;
1107                         break;
1108                     case CSSValueStart:
1109                         postLayoutData.textAlignment = isLeftToRight ? LeftAlignment : RightAlignment;
1110                         break;
1111                     case CSSValueEnd:
1112                         postLayoutData.textAlignment = isLeftToRight ? RightAlignment : LeftAlignment;
1113                         break;
1114                     default:
1115                         break;
1116                     }
1117                     if (auto textColor = styleProperties->propertyAsColor(CSSPropertyColor))
1118                         postLayoutData.textColor = *textColor;
1119                 }
1120             }
1121
1122             if (auto* enclosingListElement = enclosingList(selection.start().containerNode())) {
1123                 if (is<HTMLUListElement>(*enclosingListElement))
1124                     postLayoutData.enclosingListType = UnorderedList;
1125                 else if (is<HTMLOListElement>(*enclosingListElement))
1126                     postLayoutData.enclosingListType = OrderedList;
1127                 else
1128                     ASSERT_NOT_REACHED();
1129             }
1130
1131             postLayoutData.baseWritingDirection = editor.baseWritingDirectionForSelectionStart();
1132         }
1133 #endif
1134     }
1135
1136     platformEditorState(frame, result, shouldIncludePostLayoutData);
1137
1138     m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
1139
1140     return result;
1141 }
1142
1143 void WebPage::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
1144 {
1145     auto& frame = m_page->focusController().focusedOrMainFrame();
1146     if (frame.selection().selection().isContentEditable())
1147         frame.editor().applyStyleToSelection(changes.createEditingStyle(), changes.editAction(), Editor::ColorFilterMode::InvertColor);
1148 }
1149
1150 void WebPage::changeFont(WebCore::FontChanges&& changes)
1151 {
1152     auto& frame = m_page->focusController().focusedOrMainFrame();
1153     if (frame.selection().selection().isContentEditable())
1154         frame.editor().applyStyleToSelection(changes.createEditingStyle(), EditAction::SetFont, Editor::ColorFilterMode::InvertColor);
1155 }
1156
1157 void WebPage::executeEditCommandWithCallback(const String& commandName, const String& argument, CallbackID callbackID)
1158 {
1159     executeEditCommand(commandName, argument);
1160     send(Messages::WebPageProxy::VoidCallback(callbackID));
1161 }
1162
1163 void WebPage::selectAll()
1164 {
1165     executeEditingCommand("SelectAll"_s, { });
1166     platformDidSelectAll();
1167 }
1168
1169 bool WebPage::shouldDispatchSyntheticMouseEventsWhenModifyingSelection() const
1170 {
1171     auto* document = m_page->mainFrame().document();
1172     return document && document->quirks().shouldDispatchSyntheticMouseEventsWhenModifyingSelection();
1173 }
1174
1175 #if !PLATFORM(IOS_FAMILY)
1176
1177 void WebPage::platformDidSelectAll()
1178 {
1179 }
1180
1181 #endif // !PLATFORM(IOS_FAMILY)
1182
1183 void WebPage::updateEditorStateAfterLayoutIfEditabilityChanged()
1184 {
1185     // FIXME: We should update EditorStateIsContentEditable to track whether the state is richly
1186     // editable or plainttext-only.
1187     if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset)
1188         return;
1189
1190     Frame& frame = m_page->focusController().focusedOrMainFrame();
1191     EditorStateIsContentEditable editorStateIsContentEditable = frame.selection().selection().isContentEditable() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
1192     if (m_lastEditorStateWasContentEditable != editorStateIsContentEditable)
1193         scheduleFullEditorStateUpdate();
1194 }
1195
1196 static OptionSet<RenderAsTextFlag> toRenderAsTextFlags(unsigned options)
1197 {
1198     OptionSet<RenderAsTextFlag> flags;
1199
1200     if (options & RenderTreeShowAllLayers)
1201         flags.add(RenderAsTextFlag::ShowAllLayers);
1202     if (options & RenderTreeShowLayerNesting)
1203         flags.add(RenderAsTextFlag::ShowLayerNesting);
1204     if (options & RenderTreeShowCompositedLayers)
1205         flags.add(RenderAsTextFlag::ShowCompositedLayers);
1206     if (options & RenderTreeShowOverflow)
1207         flags.add(RenderAsTextFlag::ShowOverflow);
1208     if (options & RenderTreeShowSVGGeometry)
1209         flags.add(RenderAsTextFlag::ShowSVGGeometry);
1210     if (options & RenderTreeShowLayerFragments)
1211         flags.add(RenderAsTextFlag::ShowLayerFragments);
1212
1213     return flags;
1214 }
1215
1216 String WebPage::renderTreeExternalRepresentation(unsigned options) const
1217 {
1218     return externalRepresentation(m_mainFrame->coreFrame(), toRenderAsTextFlags(options));
1219 }
1220
1221 String WebPage::renderTreeExternalRepresentationForPrinting() const
1222 {
1223     return externalRepresentation(m_mainFrame->coreFrame(), { RenderAsTextFlag::PrintingMode });
1224 }
1225
1226 uint64_t WebPage::renderTreeSize() const
1227 {
1228     if (!m_page)
1229         return 0;
1230     return m_page->renderTreeSize();
1231 }
1232
1233 void WebPage::setHasResourceLoadClient(bool has)
1234 {
1235     if (m_page)
1236         m_page->setHasResourceLoadClient(has);
1237 }
1238
1239 void WebPage::setTracksRepaints(bool trackRepaints)
1240 {
1241     if (FrameView* view = mainFrameView())
1242         view->setTracksRepaints(trackRepaints);
1243 }
1244
1245 bool WebPage::isTrackingRepaints() const
1246 {
1247     if (FrameView* view = mainFrameView())
1248         return view->isTrackingRepaints();
1249
1250     return false;
1251 }
1252
1253 void WebPage::resetTrackedRepaints()
1254 {
1255     if (FrameView* view = mainFrameView())
1256         view->resetTrackedRepaints();
1257 }
1258
1259 Ref<API::Array> WebPage::trackedRepaintRects()
1260 {
1261     FrameView* view = mainFrameView();
1262     if (!view)
1263         return API::Array::create();
1264
1265     Vector<RefPtr<API::Object>> repaintRects;
1266     repaintRects.reserveInitialCapacity(view->trackedRepaintRects().size());
1267
1268     for (const auto& repaintRect : view->trackedRepaintRects())
1269         repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
1270
1271     return API::Array::create(WTFMove(repaintRects));
1272 }
1273
1274 PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
1275 {
1276     if (!is<PluginDocument>(frame.document()))
1277         return nullptr;
1278
1279     auto& pluginDocument = downcast<PluginDocument>(*frame.document());
1280     if (pluginDocument.focusedElement() != pluginDocument.pluginElement())
1281         return nullptr;
1282
1283     return pluginViewForFrame(&frame);
1284 }
1285
1286 PluginView* WebPage::pluginViewForFrame(Frame* frame)
1287 {
1288     if (!frame || !is<PluginDocument>(frame->document()))
1289         return nullptr;
1290
1291     auto& document = downcast<PluginDocument>(*frame->document());
1292     return static_cast<PluginView*>(document.pluginWidget());
1293 }
1294
1295 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
1296 {
1297     platformWillPerformEditingCommand();
1298
1299     auto& frame = m_page->focusController().focusedOrMainFrame();
1300
1301     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
1302         pluginView->handleEditingCommand(commandName, argument);
1303         return;
1304     }
1305     
1306     frame.editor().command(commandName).execute(argument);
1307 }
1308
1309 void WebPage::setEditable(bool editable)
1310 {
1311     m_page->setEditable(editable);
1312     m_page->setTabKeyCyclesThroughElements(!editable);
1313     Frame& frame = m_page->focusController().focusedOrMainFrame();
1314     if (editable) {
1315         frame.editor().applyEditingStyleToBodyElement();
1316         // If the page is made editable and the selection is empty, set it to something.
1317         if (frame.selection().isNone())
1318             frame.selection().setSelectionFromNone();
1319     }
1320 }
1321
1322 void WebPage::increaseListLevel()
1323 {
1324     m_page->focusController().focusedOrMainFrame().editor().increaseSelectionListLevel();
1325 }
1326
1327 void WebPage::decreaseListLevel()
1328 {
1329     m_page->focusController().focusedOrMainFrame().editor().decreaseSelectionListLevel();
1330 }
1331
1332 void WebPage::changeListType()
1333 {
1334     m_page->focusController().focusedOrMainFrame().editor().changeSelectionListType();
1335 }
1336
1337 void WebPage::setBaseWritingDirection(WritingDirection direction)
1338 {
1339     m_page->focusController().focusedOrMainFrame().editor().setBaseWritingDirection(direction);
1340 }
1341
1342 bool WebPage::isEditingCommandEnabled(const String& commandName)
1343 {
1344     Frame& frame = m_page->focusController().focusedOrMainFrame();
1345
1346     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
1347         return pluginView->isEditingCommandEnabled(commandName);
1348     
1349     Editor::Command command = frame.editor().command(commandName);
1350     return command.isSupported() && command.isEnabled();
1351 }
1352     
1353 void WebPage::clearMainFrameName()
1354 {
1355     if (Frame* frame = mainFrame())
1356         frame->tree().clearName();
1357 }
1358
1359 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
1360 {
1361     m_drawingArea->setRootCompositingLayer(layer);
1362 }
1363
1364 void WebPage::exitAcceleratedCompositingMode()
1365 {
1366     m_drawingArea->setRootCompositingLayer(nullptr);
1367 }
1368
1369 void WebPage::close()
1370 {
1371     if (m_isClosed)
1372         return;
1373
1374 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1375     WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ClearPageSpecificDataForResourceLoadStatistics(m_identifier), 0);
1376 #endif
1377
1378     m_isClosed = true;
1379
1380     // If there is still no URL, then we never loaded anything in this page, so nothing to report.
1381     if (!mainWebFrame().url().isEmpty())
1382         reportUsedFeatures();
1383
1384     if (WebProcess::singleton().injectedBundle())
1385         WebProcess::singleton().injectedBundle()->willDestroyPage(this);
1386
1387     if (m_inspector) {
1388         m_inspector->disconnectFromPage();
1389         m_inspector = nullptr;
1390     }
1391
1392     m_page->inspectorController().disconnectAllFrontends();
1393
1394 #if ENABLE(FULLSCREEN_API)
1395     m_fullScreenManager = nullptr;
1396 #endif
1397
1398     if (m_activePopupMenu) {
1399         m_activePopupMenu->disconnectFromPage();
1400         m_activePopupMenu = nullptr;
1401     }
1402
1403     if (m_activeOpenPanelResultListener) {
1404         m_activeOpenPanelResultListener->disconnectFromPage();
1405         m_activeOpenPanelResultListener = nullptr;
1406     }
1407
1408 #if ENABLE(INPUT_TYPE_COLOR)
1409     if (m_activeColorChooser) {
1410         m_activeColorChooser->disconnectFromPage();
1411         m_activeColorChooser = nullptr;
1412     }
1413 #endif
1414
1415 #if PLATFORM(GTK)
1416     if (m_printOperation) {
1417         m_printOperation->disconnectFromPage();
1418         m_printOperation = nullptr;
1419     }
1420 #endif
1421
1422 #if ENABLE(VIDEO) && USE(GSTREAMER)
1423     if (m_installMediaPluginsCallback) {
1424         m_installMediaPluginsCallback->invalidate();
1425         m_installMediaPluginsCallback = nullptr;
1426     }
1427 #endif
1428
1429     m_sandboxExtensionTracker.invalidate();
1430
1431 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
1432     m_determinePrimarySnapshottedPlugInTimer.stop();
1433 #endif
1434
1435 #if ENABLE(TEXT_AUTOSIZING)
1436     m_textAutoSizingAdjustmentTimer.stop();
1437 #endif
1438
1439 #if ENABLE(CONTEXT_MENUS)
1440     m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>();
1441 #endif
1442     m_editorClient = makeUnique<API::InjectedBundle::EditorClient>();
1443     m_formClient = makeUnique<API::InjectedBundle::FormClient>();
1444     m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>();
1445     m_policyClient.initialize(0);
1446     m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>();
1447     m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>();
1448 #if ENABLE(FULLSCREEN_API)
1449     m_fullScreenClient.initialize(0);
1450 #endif
1451
1452     m_printContext = nullptr;
1453     m_mainFrame->coreFrame()->loader().detachFromParent();
1454     m_drawingArea = nullptr;
1455
1456     DeferredPageDestructor::createDeferredPageDestructor(WTFMove(m_page), this);
1457
1458     bool isRunningModal = m_isRunningModal;
1459     m_isRunningModal = false;
1460
1461     auto& webProcess = WebProcess::singleton();
1462 #if PLATFORM(COCOA)
1463     if (m_remoteObjectRegistry)
1464         m_remoteObjectRegistry->close();
1465     ASSERT(!m_remoteObjectRegistry);
1466 #endif
1467 #if ENABLE(SCROLLING_THREAD)
1468     if (m_useAsyncScrolling)
1469         webProcess.eventDispatcher().removeScrollingTreeForPage(this);
1470 #endif
1471     webProcess.removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier);
1472     // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
1473     webProcess.removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_identifier);
1474     webProcess.removeMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier);
1475     webProcess.removeMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier);
1476 #if ENABLE(FULLSCREEN_API)
1477     webProcess.removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier);
1478 #endif
1479 #if PLATFORM(COCOA) || PLATFORM(GTK)
1480     m_viewGestureGeometryCollector = nullptr;
1481 #endif
1482
1483     // The WebPage can be destroyed by this call.
1484     WebProcess::singleton().removeWebPage(m_identifier);
1485
1486     WebProcess::singleton().updateActivePages(m_processDisplayName);
1487
1488     if (isRunningModal)
1489         RunLoop::main().stop();
1490 }
1491
1492 void WebPage::tryClose(CompletionHandler<void(bool)>&& completionHandler)
1493 {
1494     bool shouldClose = corePage()->userInputBridge().tryClosePage();
1495     completionHandler(shouldClose);
1496 }
1497
1498 void WebPage::sendClose()
1499 {
1500     send(Messages::WebPageProxy::ClosePage());
1501 }
1502
1503 void WebPage::suspendForProcessSwap()
1504 {
1505     auto failedToSuspend = [this, protectedThis = makeRef(*this)] {
1506         send(Messages::WebPageProxy::DidFailToSuspendAfterProcessSwap());
1507     };
1508
1509     auto* currentHistoryItem = m_mainFrame->coreFrame()->loader().history().currentItem();
1510     if (!currentHistoryItem) {
1511         failedToSuspend();
1512         return;
1513     }
1514
1515     if (!BackForwardCache::singleton().addIfCacheable(*currentHistoryItem, corePage())) {
1516         failedToSuspend();
1517         return;
1518     }
1519
1520     // Back/forward cache does not break the opener link for the main frame (only does so for the subframes) because the
1521     // main frame is normally re-used for the navigation. However, in the case of process-swapping, the main frame
1522     // is now hosted in another process and the one in this process is in the cache.
1523     if (m_mainFrame->coreFrame())
1524         m_mainFrame->coreFrame()->loader().detachFromAllOpenedFrames();
1525
1526     send(Messages::WebPageProxy::DidSuspendAfterProcessSwap());
1527 }
1528
1529 void WebPage::loadURLInFrame(URL&& url, const String& referrer, FrameIdentifier frameID)
1530 {
1531     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1532     if (!frame)
1533         return;
1534
1535     frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(url, referrer), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
1536 }
1537
1538 void WebPage::loadDataInFrame(IPC::DataReference&& data, String&& MIMEType, String&& encodingName, URL&& baseURL, FrameIdentifier frameID)
1539 {
1540     auto* frame = WebProcess::singleton().webFrame(frameID);
1541     if (!frame)
1542         return;
1543     ASSERT(&mainWebFrame() != frame);
1544
1545     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size());
1546     ResourceResponse response(baseURL, MIMEType, sharedBuffer->size(), encodingName);
1547     SubstituteData substituteData(WTFMove(sharedBuffer), baseURL, WTFMove(response), SubstituteData::SessionHistoryVisibility::Hidden);
1548     frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(baseURL), ShouldOpenExternalURLsPolicy::ShouldNotAllow, WTFMove(substituteData)));
1549 }
1550
1551 #if !PLATFORM(COCOA)
1552 void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters)
1553 {
1554 }
1555 #endif
1556
1557 void WebPage::loadRequest(LoadParameters&& loadParameters)
1558 {
1559     setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain);
1560     setHasNavigatedAwayFromAppBoundDomain(loadParameters.hasNavigatedAwayFromAppBoundDomain);
1561
1562     SendStopResponsivenessTimer stopper;
1563
1564     m_pendingNavigationID = loadParameters.navigationID;
1565     m_pendingWebsitePolicies = WTFMove(loadParameters.websitePolicies);
1566
1567     m_sandboxExtensionTracker.beginLoad(m_mainFrame.ptr(), WTFMove(loadParameters.sandboxExtensionHandle));
1568
1569     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1570     // to all the client to set up any needed state.
1571     m_loaderClient->willLoadURLRequest(*this, loadParameters.request, WebProcess::singleton().transformHandlesToObjects(loadParameters.userData.object()).get());
1572
1573     platformDidReceiveLoadParameters(loadParameters);
1574
1575     // Initate the load in WebCore.
1576     FrameLoadRequest frameLoadRequest { *m_mainFrame->coreFrame(), loadParameters.request, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
1577     frameLoadRequest.setShouldOpenExternalURLsPolicy(loadParameters.shouldOpenExternalURLsPolicy);
1578     frameLoadRequest.setShouldTreatAsContinuingLoad(loadParameters.shouldTreatAsContinuingLoad);
1579     frameLoadRequest.setLockHistory(loadParameters.lockHistory);
1580     frameLoadRequest.setlockBackForwardList(loadParameters.lockBackForwardList);
1581     frameLoadRequest.setClientRedirectSourceForHistory(loadParameters.clientRedirectSourceForHistory);
1582     frameLoadRequest.setIsRequestFromClientOrUserInput();
1583
1584     corePage()->userInputBridge().loadRequest(WTFMove(frameLoadRequest));
1585
1586     ASSERT(!m_pendingNavigationID);
1587     ASSERT(!m_pendingWebsitePolicies);
1588 }
1589
1590 // LoadRequestWaitingForProcessLaunch should never be sent to the WebProcess. It must always be converted to a LoadRequest message.
1591 NO_RETURN void WebPage::loadRequestWaitingForProcessLaunch(LoadParameters&&, URL&&, WebPageProxyIdentifier, bool)
1592 {
1593     RELEASE_ASSERT_NOT_REACHED();
1594 }
1595
1596 void WebPage::loadDataImpl(uint64_t navigationID, bool shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData, NavigatingToAppBoundDomain isNavigatingToAppBoundDomain, NavigatedAwayFromAppBoundDomain hasNavigatedAwayFromAppBoundDomain, ShouldOpenExternalURLsPolicy shouldOpenExternalURLsPolicy)
1597 {
1598     setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain);
1599     setHasNavigatedAwayFromAppBoundDomain(hasNavigatedAwayFromAppBoundDomain);
1600
1601     SendStopResponsivenessTimer stopper;
1602
1603     m_pendingNavigationID = navigationID;
1604     m_pendingWebsitePolicies = WTFMove(websitePolicies);
1605
1606     ResourceRequest request(baseURL);
1607     ResourceResponse response(URL(), MIMEType, sharedBuffer->size(), encodingName);
1608     SubstituteData substituteData(WTFMove(sharedBuffer), unreachableURL, response, SubstituteData::SessionHistoryVisibility::Hidden);
1609
1610     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1611     // to all the client to set up any needed state.
1612     m_loaderClient->willLoadDataRequest(*this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
1613
1614     // Initate the load in WebCore.
1615     FrameLoadRequest frameLoadRequest(*m_mainFrame->coreFrame(), request, shouldOpenExternalURLsPolicy, substituteData);
1616     frameLoadRequest.setShouldTreatAsContinuingLoad(shouldTreatAsContinuingLoad);
1617     frameLoadRequest.setIsRequestFromClientOrUserInput();
1618     m_mainFrame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
1619 }
1620
1621 void WebPage::loadData(LoadParameters&& loadParameters)
1622 {
1623     platformDidReceiveLoadParameters(loadParameters);
1624
1625     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
1626     URL baseURL = loadParameters.baseURLString.isEmpty() ? aboutBlankURL() : URL(URL(), loadParameters.baseURLString);
1627     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
1628 }
1629
1630 void WebPage::loadAlternateHTML(LoadParameters&& loadParameters)
1631 {
1632     platformDidReceiveLoadParameters(loadParameters);
1633
1634     URL baseURL = loadParameters.baseURLString.isEmpty() ? aboutBlankURL() : URL(URL(), loadParameters.baseURLString);
1635     URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL(URL(), loadParameters.unreachableURLString);
1636     URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString);
1637     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
1638     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);    
1639     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain);
1640     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
1641 }
1642
1643 void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
1644 {
1645     Frame* mainFrame = m_mainFrame->coreFrame();
1646     Document* mainFrameDocument = mainFrame->document();
1647     if (!mainFrameDocument)
1648         return;
1649
1650     const int singleClick = 1;
1651     // FIXME: Set modifier keys.
1652     // FIXME: This should probably set IsSimulated::Yes.
1653     auto mouseEvent = MouseEvent::create(eventNames().clickEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes, Event::IsComposed::Yes,
1654         MonotonicTime::now(), nullptr, singleClick, screenPoint, documentPoint, { }, { }, 0, 0, nullptr, 0, WebCore::NoTap);
1655
1656     mainFrame->loader().changeLocation(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.ptr(), LockHistory::No, LockBackForwardList::No, ReferrerPolicy::NoReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
1657 }
1658
1659 void WebPage::stopLoadingFrame(FrameIdentifier frameID)
1660 {
1661     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1662     if (!frame)
1663         return;
1664
1665     corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
1666 }
1667
1668 void WebPage::stopLoading()
1669 {
1670     SendStopResponsivenessTimer stopper;
1671
1672     corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
1673 }
1674
1675 bool WebPage::defersLoading() const
1676 {
1677     return m_page->defersLoading();
1678 }
1679
1680 void WebPage::setDefersLoading(bool defersLoading)
1681 {
1682     m_page->setDefersLoading(defersLoading);
1683 }
1684
1685 void WebPage::reload(uint64_t navigationID, uint32_t reloadOptions, SandboxExtension::Handle&& sandboxExtensionHandle)
1686 {
1687     SendStopResponsivenessTimer stopper;
1688
1689     ASSERT(!m_mainFrame->coreFrame()->loader().frameHasLoaded() || !m_pendingNavigationID);
1690     m_pendingNavigationID = navigationID;
1691
1692     m_sandboxExtensionTracker.beginReload(m_mainFrame.ptr(), WTFMove(sandboxExtensionHandle));
1693     corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), OptionSet<ReloadOption>::fromRaw(reloadOptions));
1694
1695     if (m_pendingNavigationID) {
1696         // This can happen if FrameLoader::reload() returns early because the document URL is empty.
1697         // The reload does nothing so we need to reset the pending navigation. See webkit.org/b/153210.
1698         m_pendingNavigationID = 0;
1699     }
1700 }
1701
1702 void WebPage::goToBackForwardItem(uint64_t navigationID, const BackForwardItemIdentifier& backForwardItemID, FrameLoadType backForwardType, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies)
1703 {
1704     SendStopResponsivenessTimer stopper;
1705
1706     ASSERT(isBackForwardLoadType(backForwardType));
1707
1708     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1709     ASSERT(item);
1710     if (!item)
1711         return;
1712
1713     LOG(Loading, "In WebProcess pid %i, WebPage %" PRIu64 " is navigating to back/forward URL %s", getCurrentProcessID(), m_identifier.toUInt64(), item->url().string().utf8().data());
1714
1715     ASSERT(!m_pendingNavigationID);
1716     m_pendingNavigationID = navigationID;
1717     m_pendingWebsitePolicies = WTFMove(websitePolicies);
1718
1719     m_page->goToItem(*item, backForwardType, shouldTreatAsContinuingLoad);
1720 }
1721
1722 void WebPage::tryRestoreScrollPosition()
1723 {
1724     m_page->mainFrame().loader().history().restoreScrollPositionAndViewState();
1725 }
1726
1727 WebPage& WebPage::fromCorePage(Page& page)
1728 {
1729     return static_cast<WebChromeClient&>(page.chrome().client()).page();
1730 }
1731
1732 static Optional<FrameTreeNodeData> frameTreeNodeData(Frame& frame)
1733 {
1734     Optional<FrameTreeNodeData> info;
1735     if (auto* webFrame = WebFrame::fromCoreFrame(frame)) {
1736         Vector<FrameTreeNodeData> children;
1737         for (auto* childFrame = frame.tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling()) {
1738             if (auto childInfo = frameTreeNodeData(*childFrame))
1739                 children.append(WTFMove(*childInfo));
1740         }
1741         info = FrameTreeNodeData {
1742             webFrame->info(),
1743             WTFMove(children)
1744         };
1745     }
1746     return info;
1747 }
1748
1749 void WebPage::getAllFrames(CompletionHandler<void(FrameTreeNodeData&&)>&& completionHandler)
1750 {
1751     completionHandler(*frameTreeNodeData(m_page->mainFrame()));
1752 }
1753
1754 void WebPage::setSize(const WebCore::IntSize& viewSize)
1755 {
1756     if (m_viewSize == viewSize)
1757         return;
1758
1759     m_viewSize = viewSize;
1760     FrameView* view = m_page->mainFrame().view();
1761     view->resize(viewSize);
1762     m_drawingArea->setNeedsDisplay();
1763
1764 #if USE(COORDINATED_GRAPHICS)
1765     if (view->useFixedLayout())
1766         sendViewportAttributesChanged(m_page->viewportArguments());
1767 #endif
1768 }
1769
1770 #if USE(COORDINATED_GRAPHICS)
1771 void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
1772 {
1773     FrameView* view = m_page->mainFrame().view();
1774     ASSERT(view && view->useFixedLayout());
1775
1776     // Viewport properties have no impact on zero sized fixed viewports.
1777     if (m_viewSize.isEmpty())
1778         return;
1779
1780     // Recalculate the recommended layout size, when the available size (device pixel) changes.
1781     Settings& settings = m_page->settings();
1782
1783     int minimumLayoutFallbackWidth = std::max(settings.layoutFallbackWidth(), m_viewSize.width());
1784
1785     // If unset  we use the viewport dimensions. This fits with the behavior of desktop browsers.
1786     int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
1787     int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
1788
1789     ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
1790
1791     // If no layout was done yet set contentFixedOrigin to (0,0).
1792     IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
1793
1794     // Put the width and height to the viewport width and height. In css units however.
1795     // Use FloatSize to avoid truncated values during scale.
1796     FloatSize contentFixedSize = m_viewSize;
1797
1798     contentFixedSize.scale(1 / attr.initialScale);
1799     view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
1800
1801     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
1802
1803     // This also takes care of the relayout.
1804     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
1805
1806 #if USE(COORDINATED_GRAPHICS)
1807     m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
1808 #else
1809     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
1810 #endif
1811 }
1812 #endif
1813
1814 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
1815 {
1816     FrameView* frameView = m_page->mainFrame().view();
1817
1818     ScrollPosition scrollPosition = frameView->scrollPosition();
1819     ScrollPosition maximumScrollPosition = frameView->maximumScrollPosition();
1820
1821     // If the current scroll position in a direction is the max scroll position 
1822     // we don't want to scroll at all.
1823     IntSize newScrollOffset;
1824     if (scrollPosition.x() < maximumScrollPosition.x())
1825         newScrollOffset.setWidth(scrollOffset.width());
1826     if (scrollPosition.y() < maximumScrollPosition.y())
1827         newScrollOffset.setHeight(scrollOffset.height());
1828
1829     if (newScrollOffset.isZero())
1830         return;
1831
1832     frameView->setScrollPosition(frameView->scrollPosition() + newScrollOffset);
1833 }
1834
1835 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
1836 {
1837 #if PLATFORM(MAC)
1838     FrameView* mainFrameView = m_page->mainFrame().view();
1839     LocalDefaultSystemAppearance localAppearance(mainFrameView ? mainFrameView->useDarkAppearance() : false);
1840 #endif
1841
1842     GraphicsContextStateSaver stateSaver(graphicsContext);
1843     graphicsContext.clip(rect);
1844
1845     m_mainFrame->coreFrame()->view()->paint(graphicsContext, rect);
1846 }
1847
1848 double WebPage::textZoomFactor() const
1849 {
1850     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1851     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1852         if (pluginView->handlesPageScaleFactor())
1853             return pluginView->pageScaleFactor();
1854         return pageScaleFactor();
1855     }
1856
1857     Frame* frame = m_mainFrame->coreFrame();
1858     if (!frame)
1859         return 1;
1860     return frame->textZoomFactor();
1861 }
1862
1863 void WebPage::setTextZoomFactor(double zoomFactor)
1864 {
1865     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1866     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1867         if (pluginView->handlesPageScaleFactor())
1868             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1869         else
1870             scalePage(zoomFactor, IntPoint());
1871         return;
1872     }
1873
1874     Frame* frame = m_mainFrame->coreFrame();
1875     if (!frame)
1876         return;
1877     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
1878 }
1879
1880 double WebPage::pageZoomFactor() const
1881 {
1882     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1883     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1884         if (pluginView->handlesPageScaleFactor())
1885             return pluginView->pageScaleFactor();
1886         return pageScaleFactor();
1887     }
1888
1889     Frame* frame = m_mainFrame->coreFrame();
1890     if (!frame)
1891         return 1;
1892     return frame->pageZoomFactor();
1893 }
1894
1895 void WebPage::setPageZoomFactor(double zoomFactor)
1896 {
1897     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1898     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1899         if (pluginView->handlesPageScaleFactor())
1900             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1901         else
1902             scalePage(zoomFactor, IntPoint());
1903         return;
1904     }
1905
1906     Frame* frame = m_mainFrame->coreFrame();
1907     if (!frame)
1908         return;
1909     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
1910 }
1911
1912 static void dumpHistoryItem(HistoryItem& item, size_t indent, bool isCurrentItem, StringBuilder& stringBuilder, const String& directoryName)
1913 {
1914     if (isCurrentItem)
1915         stringBuilder.appendLiteral("curr->  ");
1916     else {
1917         for (size_t i = 0; i < indent; ++i)
1918             stringBuilder.append(' ');
1919     }
1920
1921     auto url = item.url();
1922     if (url.protocolIs("file")) {
1923         size_t start = url.string().find(directoryName);
1924         if (start == WTF::notFound)
1925             start = 0;
1926         else
1927             start += directoryName.length();
1928         stringBuilder.appendLiteral("(file test):");
1929         stringBuilder.append(url.string().substring(start));
1930     } else
1931         stringBuilder.append(url.string());
1932     
1933     auto& target = item.target();
1934     if (target.length()) {
1935         stringBuilder.appendLiteral(" (in frame \"");
1936         stringBuilder.append(target);
1937         stringBuilder.appendLiteral("\")");
1938     }
1939     
1940     if (item.isTargetItem())
1941         stringBuilder.appendLiteral("  **nav target**");
1942     
1943     stringBuilder.append('\n');
1944     
1945     Vector<Ref<HistoryItem>> children;
1946     children.reserveInitialCapacity(item.children().size());
1947     for (auto& child : item.children())
1948         children.uncheckedAppend(child.copyRef());
1949     std::stable_sort(children.begin(), children.end(), [] (auto& a, auto& b) {
1950         return codePointCompare(a->target(), b->target()) < 0;
1951     });
1952     for (auto& child : children)
1953         dumpHistoryItem(child, indent + 4, false, stringBuilder, directoryName);
1954 }
1955
1956 String WebPage::dumpHistoryForTesting(const String& directory)
1957 {
1958     if (!m_page)
1959         return { };
1960
1961     auto& list = m_page->backForward();
1962     
1963     StringBuilder builder;
1964     int begin = -list.backCount();
1965     if (list.itemAtIndex(begin)->url() == aboutBlankURL())
1966         ++begin;
1967     for (int i = begin; i <= static_cast<int>(list.forwardCount()); ++i)
1968         dumpHistoryItem(*list.itemAtIndex(i), 8, !i, builder, directory);
1969     return builder.toString();
1970 }
1971
1972 void WebPage::clearHistory()
1973 {
1974     if (!m_page)
1975         return;
1976
1977     static_cast<WebBackForwardListProxy&>(m_page->backForward().client()).clear();
1978 }
1979
1980 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1981 {
1982     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1983     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1984         if (pluginView->handlesPageScaleFactor())
1985             pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
1986         else
1987             scalePage(pageZoomFactor, IntPoint());
1988         return;
1989     }
1990
1991     Frame* frame = m_mainFrame->coreFrame();
1992     if (!frame)
1993         return;
1994     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
1995 }
1996
1997 void WebPage::windowScreenDidChange(uint32_t displayID)
1998 {
1999     m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
2000
2001 #if PLATFORM(MAC)
2002     WebProcess::singleton().updatePageScreenProperties();
2003 #endif
2004 }
2005
2006 void WebPage::scalePage(double scale, const IntPoint& origin)
2007 {
2008     double totalScale = scale * viewScaleFactor();
2009     bool willChangeScaleFactor = totalScale != totalScaleFactor();
2010
2011 #if PLATFORM(IOS_FAMILY)
2012     if (willChangeScaleFactor) {
2013         if (!m_inDynamicSizeUpdate)
2014             m_dynamicSizeUpdateHistory.clear();
2015         m_scaleWasSetByUIProcess = false;
2016     }
2017 #endif
2018     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
2019     if (pluginView && pluginView->handlesPageScaleFactor()) {
2020         // If the main-frame plugin wants to handle the page scale factor, make sure to reset WebCore's page scale.
2021         // Otherwise, we can end up with an immutable but non-1 page scale applied by WebCore on top of whatever the plugin does.
2022         if (m_page->pageScaleFactor() != 1) {
2023             m_page->setPageScaleFactor(1, origin);
2024             for (auto* pluginView : m_pluginViews)
2025                 pluginView->pageScaleFactorDidChange();
2026         }
2027
2028         pluginView->setPageScaleFactor(totalScale, origin);
2029         return;
2030     }
2031
2032     m_page->setPageScaleFactor(totalScale, origin);
2033
2034     // We can't early return before setPageScaleFactor because the origin might be different.
2035     if (!willChangeScaleFactor)
2036         return;
2037
2038     for (auto* pluginView : m_pluginViews)
2039         pluginView->pageScaleFactorDidChange();
2040
2041 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
2042     m_drawingArea->deviceOrPageScaleFactorChanged();
2043 #endif
2044
2045     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
2046     platformDidScalePage();
2047 }
2048
2049 #if !PLATFORM(IOS_FAMILY)
2050
2051 void WebPage::platformDidScalePage()
2052 {
2053 }
2054
2055 #endif
2056
2057 void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
2058 {
2059     double totalScale = scale * viewScaleFactor();
2060     if (totalScale == totalScaleFactor())
2061         return;
2062
2063     IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
2064     double scaleRatio = scale / pageScaleFactor();
2065     scrollPositionAtNewScale.scale(scaleRatio);
2066     scalePage(scale, scrollPositionAtNewScale);
2067 }
2068
2069 double WebPage::totalScaleFactor() const
2070 {
2071     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
2072     if (pluginView && pluginView->handlesPageScaleFactor())
2073         return pluginView->pageScaleFactor();
2074
2075     return m_page->pageScaleFactor();
2076 }
2077
2078 double WebPage::pageScaleFactor() const
2079 {
2080     return totalScaleFactor() / viewScaleFactor();
2081 }
2082
2083 double WebPage::viewScaleFactor() const
2084 {
2085     return m_page->viewScaleFactor();
2086 }
2087
2088 void WebPage::scaleView(double scale)
2089 {
2090     if (viewScaleFactor() == scale)
2091         return;
2092
2093     float pageScale = pageScaleFactor();
2094
2095     IntPoint scrollPositionAtNewScale;
2096     if (FrameView* mainFrameView = m_page->mainFrame().view()) {
2097         double scaleRatio = scale / viewScaleFactor();
2098         scrollPositionAtNewScale = mainFrameView->scrollPosition();
2099         scrollPositionAtNewScale.scale(scaleRatio);
2100     }
2101
2102     m_page->setViewScaleFactor(scale);
2103     scalePage(pageScale, scrollPositionAtNewScale);
2104 }
2105
2106 void WebPage::setDeviceScaleFactor(float scaleFactor)
2107 {
2108     if (scaleFactor == m_page->deviceScaleFactor())
2109         return;
2110
2111     m_page->setDeviceScaleFactor(scaleFactor);
2112
2113     // Tell all our plug-in views that the device scale factor changed.
2114 #if PLATFORM(MAC)
2115     for (auto* pluginView : m_pluginViews)
2116         pluginView->setDeviceScaleFactor(scaleFactor);
2117
2118     updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor);
2119 #endif
2120
2121     if (findController().isShowingOverlay()) {
2122         // We must have updated layout to get the selection rects right.
2123         layoutIfNeeded();
2124         findController().deviceScaleFactorDidChange();
2125     }
2126
2127 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
2128     m_drawingArea->deviceOrPageScaleFactorChanged();
2129 #endif
2130 }
2131
2132 float WebPage::deviceScaleFactor() const
2133 {
2134     return m_page->deviceScaleFactor();
2135 }
2136
2137 void WebPage::accessibilitySettingsDidChange()
2138 {
2139     m_page->accessibilitySettingsDidChange();
2140 }
2141
2142 void WebPage::screenPropertiesDidChange()
2143 {
2144     m_page->setNeedsRecalcStyleInAllFrames();
2145 }
2146
2147 void WebPage::setUseFixedLayout(bool fixed)
2148 {
2149     // Do not overwrite current settings if initially setting it to false.
2150     if (m_useFixedLayout == fixed)
2151         return;
2152     m_useFixedLayout = fixed;
2153
2154 #if !PLATFORM(IOS_FAMILY)
2155     m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
2156 #endif
2157
2158     FrameView* view = mainFrameView();
2159     if (!view)
2160         return;
2161
2162     view->setUseFixedLayout(fixed);
2163     if (!fixed)
2164         setFixedLayoutSize(IntSize());
2165
2166     send(Messages::WebPageProxy::UseFixedLayoutDidChange(fixed));
2167 }
2168
2169 bool WebPage::setFixedLayoutSize(const IntSize& size)
2170 {
2171     FrameView* view = mainFrameView();
2172     if (!view || view->fixedLayoutSize() == size)
2173         return false;
2174
2175     LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier.toUInt64() << " setFixedLayoutSize " << size);
2176     view->setFixedLayoutSize(size);
2177
2178     send(Messages::WebPageProxy::FixedLayoutSizeDidChange(size));
2179     return true;
2180 }
2181
2182 IntSize WebPage::fixedLayoutSize() const
2183 {
2184     FrameView* view = mainFrameView();
2185     if (!view)
2186         return IntSize();
2187     return view->fixedLayoutSize();
2188 }
2189
2190 void WebPage::disabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations)
2191 {
2192 #if PLATFORM(IOS_FAMILY)
2193     if (m_viewportConfiguration.setDisabledAdaptations(disabledAdaptations))
2194         viewportConfigurationChanged();
2195 #else
2196     UNUSED_PARAM(disabledAdaptations);
2197 #endif
2198 }
2199
2200 void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments)
2201 {
2202 #if PLATFORM(IOS_FAMILY)
2203     if (m_viewportConfiguration.setViewportArguments(viewportArguments))
2204         viewportConfigurationChanged();
2205 #endif
2206
2207 #if USE(COORDINATED_GRAPHICS)
2208     FrameView* view = m_page->mainFrame().view();
2209     if (view && view->useFixedLayout())
2210         sendViewportAttributesChanged(viewportArguments);
2211     else
2212         m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
2213 #endif
2214
2215 #if !PLATFORM(IOS_FAMILY) && !USE(COORDINATED_GRAPHICS)
2216     UNUSED_PARAM(viewportArguments);
2217 #endif
2218 }
2219
2220 void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones)
2221 {
2222     if (!m_page)
2223         return;
2224     m_page->addLayoutMilestones(milestones);
2225 }
2226
2227 void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
2228 {
2229     m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
2230 }
2231     
2232 void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2233 {
2234     m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
2235 }
2236     
2237 void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2238 {
2239     m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
2240 }
2241
2242 void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2243 {
2244     if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
2245         m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
2246 }
2247
2248 void WebPage::setPaginationMode(uint32_t mode)
2249 {
2250     Pagination pagination = m_page->pagination();
2251     pagination.mode = static_cast<Pagination::Mode>(mode);
2252     m_page->setPagination(pagination);
2253 }
2254
2255 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2256 {
2257     Pagination pagination = m_page->pagination();
2258     pagination.behavesLikeColumns = behavesLikeColumns;
2259     m_page->setPagination(pagination);
2260 }
2261
2262 void WebPage::setPageLength(double pageLength)
2263 {
2264     Pagination pagination = m_page->pagination();
2265     pagination.pageLength = pageLength;
2266     m_page->setPagination(pagination);
2267 }
2268
2269 void WebPage::setGapBetweenPages(double gap)
2270 {
2271     Pagination pagination = m_page->pagination();
2272     pagination.gap = gap;
2273     m_page->setPagination(pagination);
2274 }
2275
2276 void WebPage::setPaginationLineGridEnabled(bool lineGridEnabled)
2277 {
2278     m_page->setPaginationLineGridEnabled(lineGridEnabled);
2279 }
2280
2281 void WebPage::postInjectedBundleMessage(const String& messageName, const UserData& userData)
2282 {
2283     auto& webProcess = WebProcess::singleton();
2284     InjectedBundle* injectedBundle = webProcess.injectedBundle();
2285     if (!injectedBundle)
2286         return;
2287
2288     injectedBundle->didReceiveMessageToPage(this, messageName, webProcess.transformHandlesToObjects(userData.object()).get());
2289 }
2290
2291 #if !PLATFORM(IOS_FAMILY)
2292
2293 void WebPage::setHeaderPageBanner(PageBanner* pageBanner)
2294 {
2295     if (m_headerBanner)
2296         m_headerBanner->detachFromPage();
2297
2298     m_headerBanner = pageBanner;
2299
2300     if (m_headerBanner)
2301         m_headerBanner->addToPage(PageBanner::Header, this);
2302 }
2303
2304 PageBanner* WebPage::headerPageBanner()
2305 {
2306     return m_headerBanner.get();
2307 }
2308
2309 void WebPage::setFooterPageBanner(PageBanner* pageBanner)
2310 {
2311     if (m_footerBanner)
2312         m_footerBanner->detachFromPage();
2313
2314     m_footerBanner = pageBanner;
2315
2316     if (m_footerBanner)
2317         m_footerBanner->addToPage(PageBanner::Footer, this);
2318 }
2319
2320 PageBanner* WebPage::footerPageBanner()
2321 {
2322     return m_footerBanner.get();
2323 }
2324
2325 void WebPage::hidePageBanners()
2326 {
2327     if (m_headerBanner)
2328         m_headerBanner->hide();
2329     if (m_footerBanner)
2330         m_footerBanner->hide();
2331 }
2332
2333 void WebPage::showPageBanners()
2334 {
2335     if (m_headerBanner)
2336         m_headerBanner->showIfHidden();
2337     if (m_footerBanner)
2338         m_footerBanner->showIfHidden();
2339 }
2340
2341 void WebPage::setHeaderBannerHeightForTesting(int height)
2342 {
2343     corePage()->setHeaderHeight(height);
2344 }
2345
2346 void WebPage::setFooterBannerHeightForTesting(int height)
2347 {
2348     corePage()->setFooterHeight(height);
2349 }
2350
2351 #endif // !PLATFORM(IOS_FAMILY)
2352
2353 void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, CallbackID callbackID)
2354 {
2355     SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
2356     snapshotOptions |= SnapshotOptionsShareable;
2357
2358     RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
2359
2360     ShareableBitmap::Handle handle;
2361     if (image)
2362         image->bitmap().createHandle(handle, SharedMemory::Protection::ReadOnly);
2363
2364     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
2365 }
2366
2367 RefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
2368 {
2369     IntRect snapshotRect = rect;
2370     IntSize bitmapSize = snapshotRect.size();
2371     if (options & SnapshotOptionsPrinting) {
2372         ASSERT(additionalScaleFactor == 1);
2373         Frame* coreFrame = m_mainFrame->coreFrame();
2374         if (!coreFrame)
2375             return nullptr;
2376         bitmapSize.setHeight(PrintContext::numberOfPages(*coreFrame, bitmapSize) * (bitmapSize.height() + 1) - 1);
2377     } else {
2378         double scaleFactor = additionalScaleFactor;
2379         if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
2380             scaleFactor *= corePage()->deviceScaleFactor();
2381         bitmapSize.scale(scaleFactor);
2382     }
2383
2384     return snapshotAtSize(rect, bitmapSize, options);
2385 }
2386
2387 void WebPage::paintSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, Frame& frame, FrameView& frameView, GraphicsContext& graphicsContext)
2388 {
2389     IntRect snapshotRect = rect;
2390     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
2391     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
2392     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
2393
2394     if (options & SnapshotOptionsPrinting) {
2395         PrintContext::spoolAllPagesWithBoundaries(frame, graphicsContext, snapshotRect.size());
2396         return;
2397     }
2398
2399     Color documentBackgroundColor = frameView.documentBackgroundColor();
2400     Color backgroundColor = (frame.settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView.baseBackgroundColor();
2401     graphicsContext.fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
2402
2403     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
2404         double deviceScaleFactor = frame.page()->deviceScaleFactor();
2405         graphicsContext.applyDeviceScaleFactor(deviceScaleFactor);
2406         scaleFactor /= deviceScaleFactor;
2407     }
2408
2409     graphicsContext.scale(scaleFactor);
2410     graphicsContext.translate(-snapshotRect.location());
2411
2412     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
2413     if (options & SnapshotOptionsExcludeSelectionHighlighting)
2414         shouldPaintSelection = FrameView::ExcludeSelection;
2415
2416     FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates;
2417     if (options & SnapshotOptionsInViewCoordinates)
2418         coordinateSpace = FrameView::ViewCoordinates;
2419
2420     frameView.paintContentsForSnapshot(graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
2421
2422     if (options & SnapshotOptionsPaintSelectionRectangle) {
2423         FloatRect selectionRectangle = frame.selection().selectionBounds();
2424         graphicsContext.setStrokeColor(Color(0xFF, 0, 0));
2425         graphicsContext.strokeRect(selectionRectangle, 1);
2426     }
2427 }
2428
2429 static ShareableBitmap::Configuration snapshotOptionsToBitmapConfiguration(SnapshotOptions options, WebPage& page)
2430 {
2431     ShareableBitmap::Configuration configuration;
2432 #if USE(CG)
2433     if (options & SnapshotOptionsUseScreenColorSpace)
2434         configuration.colorSpace.cgColorSpace = screenColorSpace(page.corePage()->mainFrame().view());
2435 #endif
2436     return configuration;
2437 }
2438
2439 RefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
2440 {
2441     Frame* coreFrame = m_mainFrame->coreFrame();
2442     if (!coreFrame)
2443         return nullptr;
2444
2445     FrameView* frameView = coreFrame->view();
2446     if (!frameView)
2447         return nullptr;
2448
2449     auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options), snapshotOptionsToBitmapConfiguration(options, *this));
2450     if (!snapshot)
2451         return nullptr;
2452     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2453     if (!graphicsContext)
2454         return nullptr;
2455
2456     paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, *graphicsContext);
2457
2458     return snapshot;
2459 }
2460
2461 RefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
2462 {
2463     Frame* coreFrame = m_mainFrame->coreFrame();
2464     if (!coreFrame)
2465         return nullptr;
2466
2467     FrameView* frameView = coreFrame->view();
2468     if (!frameView)
2469         return nullptr;
2470
2471     if (!node.renderer())
2472         return nullptr;
2473
2474     LayoutRect topLevelRect;
2475     IntRect snapshotRect = snappedIntRect(node.renderer()->paintingRootRect(topLevelRect));
2476     if (snapshotRect.isEmpty())
2477         return nullptr;
2478
2479     double scaleFactor = 1;
2480     IntSize snapshotSize = snapshotRect.size();
2481     unsigned maximumHeight = maximumPixelCount / snapshotSize.width();
2482     if (maximumHeight < static_cast<unsigned>(snapshotSize.height())) {
2483         scaleFactor = static_cast<double>(maximumHeight) / snapshotSize.height();
2484         snapshotSize = IntSize(snapshotSize.width() * scaleFactor, maximumHeight);
2485     }
2486
2487     auto snapshot = WebImage::create(snapshotSize, snapshotOptionsToImageOptions(options), snapshotOptionsToBitmapConfiguration(options, *this));
2488     if (!snapshot)
2489         return nullptr;
2490     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2491     if (!graphicsContext)
2492         return nullptr;
2493
2494     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
2495         double deviceScaleFactor = corePage()->deviceScaleFactor();
2496         graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
2497         scaleFactor /= deviceScaleFactor;
2498     }
2499
2500     graphicsContext->scale(scaleFactor);
2501     graphicsContext->translate(-snapshotRect.location());
2502
2503     Color savedBackgroundColor = frameView->baseBackgroundColor();
2504     frameView->setBaseBackgroundColor(Color::transparent);
2505     frameView->setNodeToDraw(&node);
2506
2507     frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, FrameView::ExcludeSelection, FrameView::DocumentCoordinates);
2508
2509     frameView->setBaseBackgroundColor(savedBackgroundColor);
2510     frameView->setNodeToDraw(nullptr);
2511
2512     return snapshot;
2513 }
2514
2515 void WebPage::pageDidScroll()
2516 {
2517 #if PLATFORM(IOS_FAMILY)
2518     if (!m_inDynamicSizeUpdate)
2519         m_dynamicSizeUpdateHistory.clear();
2520 #endif
2521     m_uiClient->pageDidScroll(this);
2522
2523     m_pageScrolledHysteresis.impulse();
2524
2525     send(Messages::WebPageProxy::PageDidScroll());
2526 }
2527
2528 void WebPage::pageStoppedScrolling()
2529 {
2530     // Maintain the current history item's scroll position up-to-date.
2531     if (Frame* frame = m_mainFrame->coreFrame())
2532         frame->loader().history().saveScrollPositionAndViewStateToItem(frame->loader().history().currentItem());
2533 }
2534
2535 #if ENABLE(CONTEXT_MENUS)
2536 WebContextMenu* WebPage::contextMenu()
2537 {
2538     if (!m_contextMenu)
2539         m_contextMenu = WebContextMenu::create(this);
2540     return m_contextMenu.get();
2541 }
2542
2543 WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
2544 {
2545     corePage()->contextMenuController().clearContextMenu();
2546
2547     // Simulate a mouse click to generate the correct menu.
2548     PlatformMouseEvent mousePressEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
2549     corePage()->userInputBridge().handleMousePressEvent(mousePressEvent);
2550     bool handled = corePage()->userInputBridge().handleContextMenuEvent(mousePressEvent, corePage()->mainFrame());
2551     auto* menu = handled ? contextMenu() : nullptr;
2552     PlatformMouseEvent mouseReleaseEvent(point, point, RightButton, PlatformEvent::MouseReleased, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
2553     corePage()->userInputBridge().handleMouseReleaseEvent(mouseReleaseEvent);
2554
2555     return menu;
2556 }
2557 #endif
2558
2559 // Events 
2560
2561 static const WebEvent* g_currentEvent = 0;
2562
2563 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
2564 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
2565 // platform events passed to the event handler code.
2566 const WebEvent* WebPage::currentEvent()
2567 {
2568     return g_currentEvent;
2569 }
2570
2571 void WebPage::freezeLayerTree(LayerTreeFreezeReason reason)
2572 {
2573     auto oldReasons = m_layerTreeFreezeReasons.toRaw();
2574     UNUSED_PARAM(oldReasons);
2575     m_layerTreeFreezeReasons.add(reason);
2576     RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "freezeLayerTree: Adding a reason to freeze layer tree (reason=%d, new=%d, old=%d)", static_cast<unsigned>(reason), m_layerTreeFreezeReasons.toRaw(), oldReasons);
2577     updateDrawingAreaLayerTreeFreezeState();
2578 }
2579
2580 void WebPage::unfreezeLayerTree(LayerTreeFreezeReason reason)
2581 {
2582     auto oldReasons = m_layerTreeFreezeReasons.toRaw();
2583     UNUSED_PARAM(oldReasons);
2584     m_layerTreeFreezeReasons.remove(reason);
2585     RELEASE_LOG_IF_ALLOWED(ProcessSuspension, "unfreezeLayerTree: Removing a reason to freeze layer tree (reason=%d, new=%d, old=%d)", static_cast<unsigned>(reason), m_layerTreeFreezeReasons.toRaw(), oldReasons);
2586     updateDrawingAreaLayerTreeFreezeState();
2587 }
2588
2589 void WebPage::updateDrawingAreaLayerTreeFreezeState()
2590 {
2591     if (!m_drawingArea)
2592         return;
2593     m_drawingArea->setLayerTreeStateIsFrozen(!!m_layerTreeFreezeReasons);
2594 }
2595
2596 void WebPage::callVolatilityCompletionHandlers(bool succeeded)
2597 {
2598     auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
2599     for (auto& completionHandler : completionHandlers)
2600         completionHandler(succeeded);
2601 }
2602
2603 void WebPage::layerVolatilityTimerFired()
2604 {
2605     Seconds newInterval = m_layerVolatilityTimer.repeatInterval() * 2.;
2606     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2607     if (didSucceed || newInterval > maximumLayerVolatilityTimerInterval) {
2608         m_layerVolatilityTimer.stop();
2609         if (didSucceed)
2610             RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Succeeded in marking layers as volatile");
2611         else
2612             RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark layers as volatile within %gms", maximumLayerVolatilityTimerInterval.milliseconds());
2613         callVolatilityCompletionHandlers(didSucceed);
2614         return;
2615     }
2616
2617     RELEASE_LOG_ERROR_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark all layers as volatile, will retry in %g ms", newInterval.milliseconds());
2618     m_layerVolatilityTimer.startRepeating(newInterval);
2619 }
2620
2621 bool WebPage::markLayersVolatileImmediatelyIfPossible()
2622 {
2623     return !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
2624 }
2625
2626 void WebPage::markLayersVolatile(WTF::Function<void (bool)>&& completionHandler)
2627 {
2628     RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile:");
2629
2630     if (m_layerVolatilityTimer.isActive())
2631         m_layerVolatilityTimer.stop();
2632
2633     if (completionHandler)
2634         m_markLayersAsVolatileCompletionHandlers.append(WTFMove(completionHandler));
2635
2636     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2637     if (didSucceed || m_isSuspendedUnderLock) {
2638         if (didSucceed)
2639             RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Successfully marked layers as volatile");
2640         else {
2641             // If we get suspended when locking the screen, it is expected that some IOSurfaces cannot be marked as purgeable so we do not keep retrying.
2642             RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Did what we could to mark IOSurfaces as purgeable after locking the screen");
2643         }
2644         callVolatilityCompletionHandlers(didSucceed);
2645         return;
2646     }
2647
2648     RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms", initialLayerVolatilityTimerInterval.milliseconds());
2649     m_layerVolatilityTimer.startRepeating(initialLayerVolatilityTimerInterval);
2650 }
2651
2652 void WebPage::cancelMarkLayersVolatile()
2653 {
2654     RELEASE_LOG_IF_ALLOWED(Layers, "cancelMarkLayersVolatile:");
2655     m_layerVolatilityTimer.stop();
2656     m_markLayersAsVolatileCompletionHandlers.clear();
2657 }
2658
2659 class CurrentEvent {
2660 public:
2661     explicit CurrentEvent(const WebEvent& event)
2662         : m_previousCurrentEvent(g_currentEvent)
2663     {
2664         g_currentEvent = &event;
2665     }
2666
2667     ~CurrentEvent()
2668     {
2669         g_currentEvent = m_previousCurrentEvent;
2670     }
2671
2672 private:
2673     const WebEvent* m_previousCurrentEvent;
2674 };
2675
2676 #if ENABLE(CONTEXT_MENU_EVENT)
2677 static bool isContextClick(const PlatformMouseEvent& event)
2678 {
2679 #if USE(APPKIT)
2680     return WebEventFactory::shouldBeHandledAsContextClick(event);
2681 #else
2682     return event.button() == WebCore::RightButton;
2683 #endif
2684 }
2685
2686 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
2687 {
2688     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
2689     constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent,  HitTestRequest::AllowChildFrameContent };
2690     HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point, hitType);
2691
2692     Frame* frame = &page->corePage()->mainFrame();
2693     if (result.innerNonSharedNode())
2694         frame = result.innerNonSharedNode()->document().frame();
2695
2696     bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, *frame);
2697 #if ENABLE(CONTEXT_MENUS)
2698     if (handled)
2699         page->contextMenu()->show();
2700 #endif
2701     return handled;
2702 }
2703
2704 void WebPage::contextMenuForKeyEvent()
2705 {
2706 #if ENABLE(CONTEXT_MENUS)
2707     corePage()->contextMenuController().clearContextMenu();
2708 #endif
2709
2710     Frame& frame = m_page->focusController().focusedOrMainFrame();
2711     bool handled = frame.eventHandler().sendContextMenuEventForKey();
2712 #if ENABLE(CONTEXT_MENUS)
2713     if (handled)
2714         contextMenu()->show();
2715 #else
2716     UNUSED_PARAM(handled);
2717 #endif
2718 }
2719 #endif
2720
2721 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page)
2722 {
2723     Frame& frame = page->corePage()->mainFrame();
2724     if (!frame.view())
2725         return false;
2726
2727     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
2728
2729     switch (platformMouseEvent.type()) {
2730         case PlatformEvent::MousePressed: {
2731 #if ENABLE(CONTEXT_MENUS)
2732             if (isContextClick(platformMouseEvent))
2733                 page->corePage()->contextMenuController().clearContextMenu();
2734 #endif
2735
2736             bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
2737 #if ENABLE(CONTEXT_MENU_EVENT)
2738             if (isContextClick(platformMouseEvent))
2739                 handled = handleContextMenuEvent(platformMouseEvent, page);
2740 #endif
2741             return handled;
2742         }
2743         case PlatformEvent::MouseReleased:
2744             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
2745
2746         case PlatformEvent::MouseMoved:
2747 #if PLATFORM(COCOA)
2748             // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
2749             // button is currently pressed. It is possible that neither of those things will be true since on
2750             // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
2751             // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
2752             // efficient scrollbars-only version of the event.
2753             if (!(page->corePage()->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)))
2754                 return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
2755 #endif
2756             return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
2757
2758         case PlatformEvent::MouseForceChanged:
2759         case PlatformEvent::MouseForceDown:
2760         case PlatformEvent::MouseForceUp:
2761             return page->corePage()->userInputBridge().handleMouseForceEvent(platformMouseEvent);
2762
2763         default:
2764             ASSERT_NOT_REACHED();
2765             return false;
2766     }
2767 }
2768
2769 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
2770 {
2771     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2772
2773     m_userActivity.impulse();
2774
2775     bool shouldHandleEvent = true;
2776
2777 #if ENABLE(CONTEXT_MENUS)
2778     // Don't try to handle any pending mouse events if a context menu is showing.
2779     if (m_isShowingContextMenu)
2780         shouldHandleEvent = false;
2781 #endif
2782 #if ENABLE(DRAG_SUPPORT)
2783     if (m_isStartingDrag)
2784         shouldHandleEvent = false;
2785 #endif
2786
2787     if (!shouldHandleEvent) {
2788         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
2789         return;
2790     }
2791
2792     bool handled = false;
2793
2794 #if !PLATFORM(IOS_FAMILY)
2795     if (!handled && m_headerBanner)
2796         handled = m_headerBanner->mouseEvent(mouseEvent);
2797     if (!handled && m_footerBanner)
2798         handled = m_footerBanner->mouseEvent(mouseEvent);
2799 #endif // !PLATFORM(IOS_FAMILY)
2800
2801     if (!handled) {
2802         CurrentEvent currentEvent(mouseEvent);
2803         handled = handleMouseEvent(mouseEvent, this);
2804     }
2805
2806     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
2807 }
2808
2809 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
2810 {
2811     Frame& frame = page->mainFrame();
2812     if (!frame.view())
2813         return false;
2814
2815     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
2816     return page->userInputBridge().handleWheelEvent(platformWheelEvent);
2817 }
2818
2819 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
2820 {
2821     m_userActivity.impulse();
2822
2823     CurrentEvent currentEvent(wheelEvent);
2824
2825     bool handled = handleWheelEvent(wheelEvent, m_page.get());
2826
2827     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
2828 }
2829
2830 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
2831 {
2832     if (!page->mainFrame().view())
2833         return false;
2834
2835     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
2836         return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
2837     return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
2838 }
2839
2840 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
2841 {
2842     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2843
2844     m_userActivity.impulse();
2845
2846     PlatformKeyboardEvent::setCurrentModifierState(platform(keyboardEvent).modifiers());
2847
2848     CurrentEvent currentEvent(keyboardEvent);
2849
2850     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
2851     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
2852     if (!handled)
2853         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
2854
2855     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
2856 }
2857
2858 void WebPage::validateCommand(const String& commandName, CallbackID callbackID)
2859 {
2860     bool isEnabled = false;
2861     int32_t state = 0;
2862     Frame& frame = m_page->focusController().focusedOrMainFrame();
2863     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
2864         isEnabled = pluginView->isEditingCommandEnabled(commandName);
2865     else {
2866         Editor::Command command = frame.editor().command(commandName);
2867         state = command.state();
2868         isEnabled = command.isSupported() && command.isEnabled();
2869     }
2870
2871     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
2872 }
2873
2874 void WebPage::executeEditCommand(const String& commandName, const String& argument)
2875 {
2876     executeEditingCommand(commandName, argument);
2877 }
2878
2879 void WebPage::setNeedsFontAttributes(bool needsFontAttributes)
2880 {
2881     if (m_needsFontAttributes == needsFontAttributes)
2882         return;
2883
2884     m_needsFontAttributes = needsFontAttributes;
2885
2886     if (m_needsFontAttributes)
2887         scheduleFullEditorStateUpdate();
2888 }
2889
2890 void WebPage::restoreSessionInternal(const Vector<BackForwardListItemState>& itemStates, WasRestoredByAPIRequest restoredByAPIRequest, WebBackForwardListProxy::OverwriteExistingItem overwrite)
2891 {
2892     // Since we're merely restoring HistoryItems from the UIProcess, there is no need to send HistoryItem update notifications back to the UIProcess.
2893     // Also, with process-swap on navigation, these updates may actually overwrite important state in the UIProcess such as the scroll position.
2894     SetForScope<void (*)(WebCore::HistoryItem&)> bypassHistoryItemUpdateNotifications(WebCore::notifyHistoryItemChanged, [](WebCore::HistoryItem&){});
2895     for (const auto& itemState : itemStates) {
2896         auto historyItem = toHistoryItem(itemState);
2897         historyItem->setWasRestoredFromSession(restoredByAPIRequest == WasRestoredByAPIRequest::Yes);
2898         static_cast<WebBackForwardListProxy&>(corePage()->backForward().client()).addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_identifier, overwrite);
2899     }
2900 }
2901
2902 void WebPage::restoreSession(const Vector<BackForwardListItemState>& itemStates)
2903 {
2904     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::Yes, WebBackForwardListProxy::OverwriteExistingItem::No);
2905 }
2906
2907 void WebPage::updateBackForwardListForReattach(const Vector<WebKit::BackForwardListItemState>& itemStates)
2908 {
2909     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
2910 }
2911
2912 void WebPage::setCurrentHistoryItemForReattach(WebKit::BackForwardListItemState&& itemState)
2913 {
2914     auto historyItem = toHistoryItem(itemState);
2915     auto& historyItemRef = historyItem.get();
2916     static_cast<WebBackForwardListProxy&>(corePage()->backForward().client()).addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_identifier, WebBackForwardListProxy::OverwriteExistingItem::Yes);
2917     corePage()->mainFrame().loader().history().setCurrentItem(historyItemRef);
2918 }
2919
2920 void WebPage::requestFontAttributesAtSelectionStart(CallbackID callbackID)
2921 {
2922     auto attributes = m_page->focusController().focusedOrMainFrame().editor().fontAttributesAtSelectionStart();
2923     send(Messages::WebPageProxy::FontAttributesCallback(attributes, callbackID));
2924 }
2925
2926 void WebPage::cancelGesturesBlockedOnSynchronousReplies()
2927 {
2928 #if ENABLE(IOS_TOUCH_EVENTS)
2929     if (auto reply = WTFMove(m_pendingSynchronousTouchEventReply))
2930         reply(true);
2931 #endif
2932
2933 #if PLATFORM(IOS_FAMILY)
2934     if (auto reply = WTFMove(m_pendingSynchronousPositionInformationReply))
2935         reply(InteractionInformationAtPosition::invalidInformation());
2936 #endif
2937 }
2938
2939 #if ENABLE(TOUCH_EVENTS)
2940 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
2941 {
2942     if (!page->mainFrame().view())
2943         return false;
2944
2945     return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
2946 }
2947 #endif
2948
2949 #if ENABLE(IOS_TOUCH_EVENTS)
2950 void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
2951 {
2952     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2953     m_lastInteractionLocation = touchEvent.position();
2954     CurrentEvent currentEvent(touchEvent);
2955     handled = handleTouchEvent(touchEvent, m_page.get());
2956     updatePotentialTapSecurityOrigin(touchEvent, handled);
2957 }
2958
2959 void WebPage::touchEventSync(const WebTouchEvent& touchEvent, CompletionHandler<void(bool)>&& reply)
2960 {
2961     // Avoid UIProcess hangs when the WebContent process is stuck on a sync IPC.
2962     if (IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC()) {
2963         RELEASE_LOG_ERROR_IF_ALLOWED(Process, "touchEventSync: Not processing because the process is stuck on unbounded sync IPC");
2964         return reply(true);
2965     }
2966
2967     m_pendingSynchronousTouchEventReply = WTFMove(reply);
2968
2969     EventDispatcher::TouchEventQueue queuedEvents;
2970     WebProcess::singleton().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
2971     dispatchAsynchronousTouchEvents(queuedEvents);
2972
2973     bool handled = true;
2974     dispatchTouchEvent(touchEvent, handled);
2975
2976     if (auto reply = WTFMove(m_pendingSynchronousTouchEventReply))
2977         reply(handled);
2978 }
2979
2980 void WebPage::resetPotentialTapSecurityOrigin()
2981 {
2982     m_potentialTapSecurityOrigin = nullptr;
2983 }
2984
2985 void WebPage::updatePotentialTapSecurityOrigin(const WebTouchEvent& touchEvent, bool wasHandled)
2986 {
2987     if (wasHandled)
2988         return;
2989
2990     if (!touchEvent.isPotentialTap())
2991         return;
2992
2993     if (touchEvent.type() != WebEvent::TouchStart)
2994         return;
2995
2996     auto& mainFrame = m_page->mainFrame();
2997     auto document = mainFrame.document();
2998     if (!document)
2999         return;
3000
3001     if (!document->handlingTouchEvent())
3002         return;
3003
3004     Frame* touchEventTargetFrame = &mainFrame;
3005     while (auto subframe = touchEventTargetFrame->eventHandler().touchEventTargetSubframe())
3006         touchEventTargetFrame = subframe;
3007
3008     auto& touches = touchEventTargetFrame->eventHandler().touches();
3009     if (touches.isEmpty())
3010         return;
3011
3012     ASSERT(touches.size() == 1);
3013
3014     if (auto targetDocument = touchEventTargetFrame->document())
3015         m_potentialTapSecurityOrigin = &targetDocument->securityOrigin();
3016 }
3017 #elif ENABLE(TOUCH_EVENTS)
3018 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
3019 {
3020     CurrentEvent currentEvent(touchEvent);
3021
3022     bool handled = handleTouchEvent(touchEvent, m_page.get());
3023
3024     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
3025 }
3026 #endif
3027
3028 void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
3029 {
3030     m_page->pointerCaptureController().cancelPointer(pointerId, documentPoint);
3031 }
3032
3033 void WebPage::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
3034 {
3035     m_page->pointerCaptureController().touchWithIdentifierWasRemoved(pointerId);
3036 }
3037
3038 #if ENABLE(MAC_GESTURE_EVENTS)
3039 static bool handleGestureEvent(const WebGestureEvent& event, Page* page)
3040 {
3041     if (!page->mainFrame().view())
3042         return false;
3043
3044     return page->mainFrame().eventHandler().handleGestureEvent(platform(event));
3045 }
3046
3047 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
3048 {
3049     CurrentEvent currentEvent(gestureEvent);
3050     bool handled = handleGestureEvent(gestureEvent, m_page.get());
3051     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
3052 }
3053 #endif
3054
3055 bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
3056 {
3057     return page->userInputBridge().scrollRecursively(direction, granularity);
3058 }
3059
3060 bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
3061 {
3062     return page->userInputBridge().logicalScrollRecursively(direction, granularity);
3063 }
3064
3065 bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
3066 {
3067     return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
3068 }
3069
3070 void WebPage::centerSelectionInVisibleArea()
3071 {
3072     Frame& frame = m_page->focusController().focusedOrMainFrame();
3073     frame.selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
3074     findController().showFindIndicatorInSelection();
3075 }
3076
3077 bool WebPage::isControlledByAutomation() const
3078 {
3079     return m_page->isControlledByAutomation();
3080 }
3081
3082 void WebPage::setControlledByAutomation(bool controlled)
3083 {
3084     m_page->setControlledByAutomation(controlled);
3085 }
3086
3087 void WebPage::connectInspector(const String& targetId, Inspector::FrontendChannel::ConnectionType connectionType)
3088 {
3089     m_inspectorTargetController->connectInspector(targetId, connectionType);
3090 }
3091
3092 void WebPage::disconnectInspector(const String& targetId)
3093 {
3094     m_inspectorTargetController->disconnectInspector(targetId);
3095 }
3096
3097 void WebPage::sendMessageToTargetBackend(const String& targetId, const String& message)
3098 {
3099     m_inspectorTargetController->sendMessageToTargetBackend(targetId, message);
3100 }
3101
3102 void WebPage::insertNewlineInQuotedContent()
3103 {
3104     Frame& frame = m_page->focusController().focusedOrMainFrame();
3105     if (frame.selection().isNone())
3106         return;
3107     frame.editor().insertParagraphSeparatorInQuotedContent();
3108 }
3109
3110 #if ENABLE(REMOTE_INSPECTOR)
3111 void WebPage::setIndicating(bool indicating)
3112 {
3113     m_page->inspectorController().setIndicating(indicating);
3114 }
3115 #endif
3116
3117 void WebPage::setBackgroundColor(const Optional<WebCore::Color>& backgroundColor)
3118 {
3119     if (m_backgroundColor == backgroundColor)
3120         return;
3121
3122     m_backgroundColor = backgroundColor;
3123
3124     if (FrameView* frameView = mainFrameView())
3125         frameView->updateBackgroundRecursively(backgroundColor);
3126
3127     m_drawingArea->setNeedsDisplay();
3128 }
3129
3130 #if PLATFORM(COCOA)
3131 void WebPage::setTopContentInsetFenced(float contentInset, IPC::Attachment fencePort)
3132 {
3133     if (fencePort.disposition() != MACH_MSG_TYPE_MOVE_SEND) {
3134         LOG(Layers, "WebPage::setTopContentInsetFenced(%g, fencePort) Received an invalid fence port: %d, disposition: %d", contentInset, fencePort.port(), fencePort.disposition());
3135         return;
3136     }
3137
3138     m_drawingArea->addFence(MachSendRight::create(fencePort.port()));
3139
3140     setTopContentInset(contentInset);
3141
3142     deallocateSendRightSafely(fencePort.port());
3143 }
3144 #endif
3145
3146 void WebPage::setTopContentInset(float contentInset)
3147 {
3148     if (contentInset == m_page->topContentInset())
3149         return;
3150
3151     m_page->setTopContentInset(contentInset);
3152
3153     for (auto* pluginView : m_pluginViews)
3154         pluginView->topContentInsetDidChange();
3155 }
3156
3157 void WebPage::viewWillStartLiveResize()
3158 {
3159     if (!m_page)
3160         return;
3161
3162     // FIXME: This should propagate to all ScrollableAreas.
3163     Frame& frame = m_page->focusController().focusedOrMainFrame();
3164     if (FrameView* view = frame.view())
3165         view->willStartLiveResize();
3166 }
3167
3168 void WebPage::viewWillEndLiveResize()
3169 {
3170     if (!m_page)
3171         return;
3172
3173     // FIXME: This should propagate to all ScrollableAreas.
3174     Frame& frame = m_page->focusController().focusedOrMainFrame();
3175     if (FrameView* view = frame.view())
3176         view->willEndLiveResize();
3177 }
3178
3179 void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event, CallbackID callbackID)
3180 {
3181     if (!m_page)
3182         return;
3183
3184     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
3185
3186     Frame& frame = m_page->focusController().focusedOrMainFrame();
3187     frame.document()->setFocusedElement(0);
3188
3189     if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
3190         PlatformKeyboardEvent platformEvent(platform(event));
3191         platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
3192         m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, &KeyboardEvent::create(platformEvent, &frame.windowProxy()).get());
3193
3194         send(Messages::WebPageProxy::VoidCallback(callbackID));
3195         return;
3196     }
3197
3198     m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, nullptr);
3199     send(Messages::WebPageProxy::VoidCallback(callbackID));
3200 }
3201
3202 void WebPage::setCanStartMediaTimerFired()
3203 {
3204     if (m_page)
3205         m_page->setCanStartMedia(true);
3206 }
3207
3208 void WebPage::updateIsInWindow(bool isInitialState)
3209 {
3210     bool isInWindow = m_activityState.contains(WebCore::ActivityState::IsInWindow);
3211
3212     if (!isInWindow) {
3213         m_setCanStartMediaTimer.stop();
3214         m_page->setCanStartMedia(false);
3215         
3216         // The WebProcess does not yet know about this page; no need to tell it we're leaving the window.
3217         if (!isInitialState)
3218             WebProcess::singleton().pageWillLeaveWindow(m_identifier);
3219     } else {
3220         // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process
3221         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
3222         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
3223         if (m_mayStartMediaWhenInWindow)
3224             m_setCanStartMediaTimer.startOneShot(0_s);
3225
3226         WebProcess::singleton().pageDidEnterWindow(m_identifier);
3227     }
3228
3229     if (isInWindow)
3230         layoutIfNeeded();
3231 }
3232
3233 void WebPage::visibilityDidChange()
3234 {
3235     bool isVisible = m_activityState.contains(ActivityState::IsVisible);
3236     if (!isVisible) {
3237         // We save the document / scroll state when backgrounding a tab so that we are able to restore it
3238         // if it gets terminated while in the background.
3239         if (auto* frame = m_mainFrame->coreFrame())
3240             frame->loader().history().saveDocumentAndScrollState();
3241     }
3242 }
3243
3244 void WebPage::setActivityState(OptionSet<ActivityState::Flag> activityState, ActivityStateChangeID activityStateChangeID, const Vector<CallbackID>& callbackIDs)
3245 {
3246     LOG_WITH_STREAM(ActivityState, stream << "WebPage " << identifier().toUInt64() << " setActivityState to " << activityState);
3247
3248     auto changed = m_activityState ^ activityState;
3249     m_activityState = activityState;
3250
3251     if (changed)
3252         updateThrottleState();
3253
3254     ASSERT_WITH_MESSAGE(m_page, "setActivityState called on %" PRIu64 " but WebCore page was null", identifier().toUInt64());
3255     if (m_page) {
3256         SetForScope<OptionSet<ActivityState::Flag>> currentlyChangingActivityState { m_lastActivityStateChanges, changed };
3257         m_page->setActivityState(activityState);
3258     }
3259     
3260     for (auto* pluginView : m_pluginViews)
3261         pluginView->activityStateDidChange(changed);
3262
3263     m_drawingArea->activityStateDidChange(changed, activityStateChangeID, callbackIDs);
3264     WebProcess::singleton().pageActivityStateDidChange(m_identifier, changed);
3265
3266     if (changed & ActivityState::IsInWindow)
3267         updateIsInWindow();
3268
3269     if (changed & ActivityState::IsVisible)
3270         visibilityDidChange();
3271 }
3272
3273 void WebPage::setLayerHostingMode(LayerHostingMode layerHostingMode)
3274 {
3275     m_layerHostingMode = layerHostingMode;
3276
3277     m_drawingArea->setLayerHostingMode(m_layerHostingMode);
3278
3279     for (auto* pluginView : m_pluginViews)
3280         pluginView->setLayerHostingMode(m_layerHostingMode);
3281 }
3282
3283 void WebPage::didReceivePolicyDecision(FrameIdentifier frameID, uint64_t listenerID, PolicyDecision&& policyDecision)
3284 {
3285     setIsNavigatingToAppBoundDomain(policyDecision.isNavigatingToAppBoundDomain);
3286     setHasNavigatedAwayFromAppBoundDomain(policyDecision.hasNavigatedAwayFromAppBoundDomain);
3287
3288     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
3289     if (!frame)
3290         return;
3291     frame->didReceivePolicyDecision(listenerID, WTFMove(policyDecision));
3292 }
3293
3294 void WebPage::continueWillSubmitForm(FrameIdentifier frameID, uint64_t listenerID)
3295 {
3296     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
3297     if (!frame)
3298         return;
3299     frame->continueWillSubmitForm(listenerID);
3300 }
3301
3302 void WebPage::didStartPageTransition()
3303 {
3304     freezeLayerTree(LayerTreeFreezeReason::PageTransition);
3305
3306 #if PLATFORM(MAC)
3307     bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
3308 #endif
3309     m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
3310     m_lastEditorStateWasContentEditable = EditorStateIsContentEditable::Unset;
3311
3312 #if PLATFORM(MAC)
3313     if (hasPreviouslyFocusedDueToUserInteraction)
3314         send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
3315 #endif
3316
3317 #if HAVE(TOUCH_BAR)
3318     if (m_isTouchBarUpdateSupressedForHiddenContentEditable) {
3319         m_isTouchBarUpdateSupressedForHiddenContentEditable = false;
3320         send(Messages::WebPageProxy::SetIsTouchBarUpdateSupressedForHiddenContentEditable(m_isTouchBarUpdateSupressedForHiddenContentEditable));
3321     }
3322
3323     if (m_isNeverRichlyEditableForTouchBar) {
3324         m_isNeverRichlyEditableForTouchBar = false;
3325         send(Messages::WebPageProxy::SetIsNeverRichlyEditableForTouchBar(m_isNeverRichlyEditableForTouchBar));
3326     }
3327 #endif
3328
3329 #if PLATFORM(IOS_FAMILY)
3330     m_isShowingInputViewForFocusedElement = false;
3331 #endif
3332 }
3333
3334 void WebPage::didCompletePageTransition()
3335 {
3336     unfreezeLayerTree(LayerTreeFreezeReason::PageTransition);
3337 }
3338
3339 void WebPage::show()
3340 {
3341     send(Messages::WebPageProxy::ShowPage());
3342 }
3343
3344 void WebPage::setShouldFireResizeEvents(bool shouldFireResizeEvents)
3345 {
3346     RELEASE_LOG_IF_ALLOWED(Resize, "setShouldFireResizeEvents(%d)", shouldFireResizeEvents);
3347
3348     if (m_page)
3349         m_page->setShouldFireResizeEvents(shouldFireResizeEvents);
3350 }
3351
3352 String WebPage::userAgent(const URL& webCoreURL) const
3353 {
3354     String userAgent = platformUserAgent(webCoreURL);
3355     if (!userAgent.isEmpty())
3356         return userAgent;
3357     return m_userAgent;
3358 }
3359
3360 void WebPage::setUserAgent(const String& userAgent)
3361 {
3362     if (m_userAgent == userAgent)
3363         return;
3364
3365     m_userAgent = userAgent;
3366
3367     if (m_page)
3368         m_page->userAgentChanged();
3369 }
3370
3371 void WebPage::suspendActiveDOMObjectsAndAnimations()
3372 {
3373     m_page->suspendActiveDOMObjectsAndAnimations();
3374 }
3375
3376 void WebPage::resumeActiveDOMObjectsAndAnimations()
3377 {
3378     m_page->resumeActiveDOMObjectsAndAnimations();
3379 }
3380
3381 IntPoint WebPage::screenToRootView(const IntPoint& point)
3382 {
3383     IntPoint windowPoint;
3384     sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
3385     return windowPoint;
3386 }
3387     
3388 IntRect WebPage::rootViewToScreen(const IntRect& rect)
3389 {
3390     IntRect screenRect;
3391     sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
3392     return screenRect;
3393 }
3394     
3395 IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
3396 {
3397     IntPoint windowPoint;
3398     sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point), Messages::WebPageProxy::AccessibilityScreenToRootView::Reply(windowPoint));
3399     return windowPoint;
3400 }
3401
3402 IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
3403 {
3404     IntRect screenRect;
3405     sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
3406     return screenRect;
3407 }
3408
3409 KeyboardUIMode WebPage::keyboardUIMode()
3410 {
3411     bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled();
3412     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
3413 }
3414
3415 void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, ContentWorldIdentifier worldIdentifier, CallbackID callbackID)
3416 {
3417     // NOTE: We need to be careful when running scripts that the objects we depend on don't
3418     // disappear during script execution.
3419
3420     if (!frame || !frame->coreFrame()) {
3421         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript: Page is in invalid state"_s }, callbackID));
3422         return;
3423     }
3424
3425     auto* world = m_userContentController->worldForIdentifier(worldIdentifier);
3426     if (!world) {
3427         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript: Cannot find specified content world"_s }, callbackID));
3428         return;
3429     }
3430
3431     auto resolveFunction = [protectedThis = makeRef(*this), this, world = makeRef(*world), frame = makeRef(*frame), callbackID](ValueOrException result) {
3432         RefPtr<SerializedScriptValue> serializedResultValue;
3433         if (result) {
3434             serializedResultValue = SerializedScriptValue::create(frame->jsContextForWorld(world.ptr()),
3435                 toRef(frame->coreFrame()->script().globalObject(world->coreWorld()), result.value()), nullptr);
3436         }
3437
3438         IPC::DataReference dataReference;
3439         if (serializedResultValue)
3440             dataReference = serializedResultValue->data();
3441
3442         Optional<ExceptionDetails> details;
3443         if (!result)
3444             details = result.error();
3445
3446         send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID));
3447     };
3448     
3449     if (hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes && !m_needsInAppBrowserPrivacyQuirks) {
3450         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript"_s }, callbackID));
3451         if (auto* document = m_page->mainFrame().document())
3452             document->addConsoleMessage(MessageSource::Security, MessageLevel::Warning, "Ignoring user script injection for non-app bound domain.");
3453         RELEASE_LOG_ERROR_IF_ALLOWED(Loading, "runJavaScript: Ignoring user script injection for non app-bound domain");
3454         return;
3455     }
3456
3457     JSLockHolder lock(commonVM());
3458     frame->coreFrame()->script().executeAsynchronousUserAgentScriptInWorld(world->coreWorld(), WTFMove(parameters), WTFMove(resolveFunction));
3459 }
3460
3461 void WebPage::runJavaScriptInFrameInScriptWorld(RunJavaScriptParameters&& parameters, Optional<WebCore::FrameIdentifier> frameID, const std::pair<ContentWorldIdentifier, String>& worldData, CallbackID callbackID)
3462 {
3463     auto* webFrame = frameID ? WebProcess::singleton().webFrame(*frameID) : &mainWebFrame();
3464
3465     if (auto* newWorld = m_userContentController->addContentWorld(worldData)) {
3466         auto& coreWorld = newWorld->coreWorld();
3467         for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree().traverseNext())
3468             frame->loader().client().dispatchGlobalObjectAvailable(coreWorld);
3469     }
3470
3471     runJavaScript(webFrame, WTFMove(parameters), worldData.first, callbackID);
3472 }
3473
3474 void WebPage::getContentsAsString(ContentAsStringIncludesChildFrames includeChildFrames, CallbackID callbackID)
3475 {
3476     switch (includeChildFrames) {
3477     case ContentAsStringIncludesChildFrames::No: {
3478         String resultString = m_mainFrame->contentsAsString();
3479         send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3480         break;
3481     }
3482     case ContentAsStringIncludesChildFrames::Yes: {
3483         StringBuilder builder;
3484         for (RefPtr<Frame> frame = m_mainFrame->coreFrame(); frame; frame = frame->tree().traverseNextRendered()) {
3485             if (auto* webFrame = WebFrame::fromCoreFrame(*frame)) {
3486                 if (!builder.isEmpty())
3487                     builder.appendLiteral("\n\n");
3488
3489                 builder.append(webFrame->contentsAsString());
3490             }
3491         }
3492
3493         send(Messages::WebPageProxy::StringCallback(builder.toString(), callbackID));
3494         break;
3495     }
3496     }
3497 }
3498
3499 #if ENABLE(MHTML)
3500 void WebPage::getContentsAsMHTMLData(CallbackID callbackID)
3501 {
3502     send(Messages::WebPageProxy::DataCallback({ MHTMLArchive::generateMHTMLData(m_page.get()) }, callbackID));
3503 }
3504 #endif
3505
3506 void WebPage::getRenderTreeExternalRepresentation(CallbackID callbackID)
3507 {
3508     String resultString = renderTreeExternalRepresentation();
3509     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3510 }
3511
3512 static Frame* frameWithSelection(Page* page)
3513 {
3514     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3515         if (frame->selection().isRange())
3516             return frame;
3517     }
3518
3519     return 0;
3520 }
3521
3522 void WebPage::getSelectionAsWebArchiveData(CallbackID callbackID)
3523 {
3524 #if PLATFORM(COCOA)
3525     RetainPtr<CFDataRef> data;
3526     if (Frame* frame = frameWithSelection(m_page.get()))
3527         data = LegacyWebArchive::createFromSelection(frame)->rawDataRepresentation();
3528 #endif
3529
3530     IPC::SharedBufferDataReference dataReference;
3531 #if PLATFORM(COCOA)
3532     if (data)
3533         dataReference = SharedBuffer::create(data.get());
3534 #endif
3535     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
3536 }
3537
3538 void WebPage::getSelectionOrContentsAsString(CallbackID callbackID)
3539 {
3540     WebFrame* focusedOrMainFrame = WebFrame::fromCoreFrame(m_page->focusController().focusedOrMainFrame());
3541     String resultString = focusedOrMainFrame->selectionAsString();
3542     if (resultString.isEmpty())
3543         resultString = focusedOrMainFrame->contentsAsString();
3544     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3545 }
3546
3547 void WebPage::getSourceForFrame(FrameIdentifier frameID, CallbackID callbackID)
3548 {
3549     String resultString;
3550     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
3551        resultString = frame->source();
3552
3553     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3554 }
3555
3556 void WebPage::getMainResourceDataOfFrame(FrameIdentifier frameID, CallbackID callbackID)
3557 {
3558     RefPtr<SharedBuffer> buffer;
3559     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID)) {
3560         if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame()))
3561             buffer = pluginView->liveResourceData();
3562         if (!buffer) {
3563             if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader())
3564                 buffer = loader->mainResourceData();
3565         }
3566     }
3567
3568     IPC::SharedBufferDataReference dataReference;
3569     if (buffer)
3570         dataReference = { *buffer };
3571     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
3572 }
3573
3574 static RefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
3575 {
3576     DocumentLoader* loader = frame->loader().documentLoader();
3577     if (!loader)
3578         return nullptr;
3579
3580     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
3581     if (!subresource)
3582         return nullptr;
3583
3584     return &subresource->data();
3585 }
3586
3587 void WebPage::getResourceDataFromFrame(FrameIdentifier frameID, const String& resourceURLString, CallbackID callbackID)
3588 {
3589     RefPtr<SharedBuffer> buffer;
3590     if (auto* frame = WebProcess::singleton().webFrame(frameID)) {
3591         URL resourceURL(URL(), resourceURLString);
3592         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
3593     }
3594
3595     IPC::SharedBufferDataReference dataReference;
3596     if (buffer)
3597         dataReference = { *buffer };
3598     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
3599 }
3600
3601 void WebPage::getWebArchiveOfFrame(FrameIdentifier frameID, CallbackID callbackID)
3602 {
3603 #if PLATFORM(COCOA)
3604     RetainPtr<CFDataRef> data;
3605     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
3606         data = frame->webArchiveData(nullptr, nullptr);
3607 #else
3608     UNUSED_PARAM(frameID);
3609 #endif
3610
3611     IPC::SharedBufferDataReference dataReference;
3612 #if PLATFORM(COCOA)
3613     if (data)
3614         dataReference = SharedBuffer::create(data.get());
3615 #endif
3616     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
3617 }
3618
3619 void WebPage::forceRepaintWithoutCallback()
3620 {
3621     m_drawingArea->forceRepaint();
3622 }
3623
3624 void WebPage::forceRepaint(CallbackID callbackID)
3625 {
3626     if (m_drawingArea->forceRepaintAsync(callbackID))
3627         return;
3628
3629     forceRepaintWithoutCallback();
3630     send(Messages::WebPageProxy::VoidCallback(callbackID));
3631 }
3632
3633 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
3634 {
3635     WebPreferencesStore::removeTestRunnerOverrides();
3636     updatePreferences(store);
3637 }
3638
3639 void WebPage::updatePreferences(const WebPreferencesStore& store)
3640 {
3641     updatePreferencesGenerated(store);
3642
3643     Settings& settings = m_page->settings();
3644
3645 #if !PLATFORM(GTK) && !PLATFORM(WIN)
3646     if (!settings.acceleratedCompositingEnabled()) {
3647         RELEASE_LOG_IF_ALLOWED(Layers, "updatePreferences: acceleratedCompositingEnabled setting was false. WebKit cannot function in this mode; changing setting to true");
3648         settings.setAcceleratedCompositingEnabled(true);
3649     }
3650 #endif
3651
3652     bool requiresUserGestureForMedia = store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForMediaPlaybackKey());
3653     settings.setVideoPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForVideoPlaybackKey()));
3654     settings.setAudioPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForAudioPlaybackKey()));
3655     settings.setUserInterfaceDirectionPolicy(static_cast<WebCore::UserInterfaceDirectionPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionPolicyKey())));
3656     settings.setSystemLayoutDirection(static_cast<TextDirection>(store.getUInt32ValueForKey(WebPreferencesKey::systemLayoutDirectionKey())));
3657     settings.setJavaScriptRuntimeFlags(static_cast<RuntimeFlags>(store.getUInt32ValueForKey(WebPreferencesKey::javaScriptRuntimeFlagsKey())));
3658     settings.setStorageBlockingPolicy(static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey())));
3659     settings.setFrameFlattening(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()) ? WebCore::FrameFlattening::FullyEnabled : WebCore::FrameFlattening::Disabled);
3660     settings.setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
3661 #if ENABLE(DATA_DETECTION)
3662     settings.setDataDetectorTypes(static_cast<DataDetectorTypes>(store.getUInt32ValueForKey(WebPreferencesKey::dataDetectorTypesKey())));
3663 #endif
3664
3665     DatabaseManager::singleton().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
3666
3667     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
3668     m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey());
3669     m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey());
3670     m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey());
3671
3672     m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey());
3673     settings.setScrollingPerformanceLoggingEnabled(m_scrollingPerformanceLoggingEnabled);
3674
3675     bool isAppNapEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
3676     if (m_isAppNapEnabled != isAppNapEnabled) {
3677         m_isAppNapEnabled = isAppNapEnabled;
3678         updateThrottleState();
3679     }
3680
3681 #if PLATFORM(COCOA)
3682     m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey());
3683 #endif
3684 #if ENABLE(PAYMENT_REQUEST)
3685     settings.setPaymentRequestEnabled(store.getBoolValueForKey(WebPreferencesKey::applePayEnabledKey()));
3686 #endif
3687
3688     // FIXME: This is both a RuntimeEnabledFeatures (generated) and a setting. It should pick one.
3689     settings.setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
3690
3691 #if PLATFORM(IOS_FAMILY)
3692     m_ignoreViewportScalingConstraints = store.getBoolValueForKey(WebPreferencesKey::ignoreViewportScalingConstraintsKey());
3693     m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints);
3694     setForceAlwaysUserScalable(m_forceAlwaysUserScalable || store.getBoolValueForKey(WebPreferencesKey::forceAlwaysUserScalableKey()));
3695
3696     settings.setUseImageDocumentForSubframePDF(true);
3697 #if HAVE(AVKIT)
3698     DeprecatedGlobalSettings::setAVKitEnabled(true);
3699 #endif
3700 #endif
3701
3702 #if ENABLE(SERVICE_WORKER)
3703     if (store.getBoolValueForKey(WebPreferencesKey::serviceWorkersEnabledKey())) {
3704         ASSERT(parentProcessHasServiceWorkerEntitlement());
3705         if (!parentProcessHasServiceWorkerEntitlement())
3706             RuntimeEnabledFeatures::sharedFeatures().setServiceWorkerEnabled(false);
3707     }
3708 #endif
3709
3710     settings.setLayoutViewportHeightExpansionFactor(store.getDoubleValueForKey(WebPreferencesKey::layoutViewportHeightExpansionFactorKey()));
3711
3712     m_needsInAppBrowserPrivacyQuirks = store.getBoolValueForKey(WebPreferencesKey::needsInAppBrowserPrivacyQuirksKey());
3713
3714     if (m_drawingArea)
3715         m_drawingArea->updatePreferences(store);
3716
3717 #if ENABLE(GPU_PROCESS)
3718     // FIXME: useGPUProcessForMedia should be a RuntimeEnabledFeature since it's global.
3719     static_cast<WebMediaStrategy&>(platformStrategies()->mediaStrategy()).setUseGPUProcess(settings.useGPUProcessForMedia());
3720     WebProcess::singleton().supplement<RemoteMediaPlayerManager>()->updatePreferences(settings);
3721     WebProcess::singleton().setUseGPUProcessForMedia(settings.useGPUProcessForMedia());
3722 #endif
3723 }
3724
3725 #if ENABLE(DATA_DETECTION)
3726
3727 void WebPage::setDataDetectionResults(NSArray *detectionResults)
3728 {
3729     DataDetectionResult dataDetectionResult;
3730     dataDetectionResult.results = detectionResults;
3731     send(Messages::WebPageProxy::SetDataDetectionResult(dataDetectionResult));
3732 }
3733
3734 void WebPage::removeDataDetectedLinks(CompletionHandler<void(const DataDetectionResult&)>&& completionHandler)
3735 {
3736     for (auto frame = makeRefPtr(&m_page->mainFrame()); frame; frame = frame->tree().traverseNext()) {
3737         auto document = makeRefPtr(frame->document());
3738         if (!document)
3739             continue;
3740
3741         DataDetection::removeDataDetectedLinksInDocument(*document);
3742         frame->setDataDetectionResults(nullptr);
3743     }
3744     completionHandler({ m_page->mainFrame().dataDetectionResults() });
3745 }
3746
3747 void WebPage::detectDataInAllFrames(uint64_t types, CompletionHandler<void(const DataDetectionResult&)>&& completionHandler)
3748 {
3749     auto dataDetectorTypes = static_cast<WebCore::DataDetectorTypes>(types);
3750     for (auto frame = makeRefPtr(&m_page->mainFrame()); frame; frame = frame->tree().traverseNext()) {
3751         auto document = makeRefPtr(frame->document());
3752         if (!document)
3753             continue;
3754
3755         RefPtr<Range> range = Range::create(*document, Position { document.get(), Position::PositionIsBeforeChildren }, Position { document.get(), Position::PositionIsAfterChildren });
3756         frame->setDataDetectionResults(DataDetection::detectContentInRange(range, dataDetectorTypes, m_dataDetectionContext.get()));
3757     }
3758     completionHandler({ m_page->mainFrame().dataDetectionResults() });
3759 }
3760
3761 #endif // ENABLE(DATA_DETECTION)
3762
3763 #if PLATFORM(COCOA)
3764 void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
3765 {
3766     FrameView* frameView = corePage()->mainFrame().view();
3767     if (!frameView)
3768         return;
3769
3770     layerTransaction.setContentsSize(frameView->contentsSize());
3771     layerTransaction.setScrollOrigin(frameView->scrollOrigin());
3772     layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
3773     layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
3774     layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
3775
3776     layerTransaction.setBaseLayoutViewportSize(frameView->baseLayoutViewportSize());
3777     layerTransaction.setMinStableLayoutViewportOrigin(frameView->minStableLayoutViewportOrigin());
3778     layerTransaction.setMaxStableLayoutViewportOrigin(frameView->maxStableLayoutViewportOrigin());
3779
3780 #if PLATFORM(IOS_FAMILY)
3781     layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
3782     layerTransaction.setMinimumScaleFactor(m_viewportConfiguration.minimumScale());
3783     layerTransaction.setMaximumScaleFactor(m_viewportConfiguration.maximumScale());
3784     layerTransaction.setInitialScaleFactor(m_viewportConfiguration.initialScale());
3785     layerTransaction.setViewportMetaTagWidth(m_viewportConfiguration.viewportArguments().width);
3786     layerTransaction.setViewportMetaTagWidthWasExplicit(m_viewportConfiguration.viewportArguments().widthWasExplicit);
3787     layerTransaction.setViewportMetaTagCameFromImageDocument(m_viewportConfiguration.viewportArguments().type == ViewportArguments::ImageDocument);
3788     layerTransaction.setAvoidsUnsafeArea(m_viewportConfiguration.avoidsUnsafeArea());
3789     layerTransaction.setIsInStableState(m_isInStableState);
3790     layerTransaction.setAllowsUserScaling(allowsUserScaling());
3791     if (m_pendingDynamicViewportSizeUpdateID) {
3792         layerTransaction.setDynamicViewportSizeUpdateID(*m_pendingDynamicViewportSizeUpdateID);
3793         m_pendingDynamicViewportSizeUpdateID = WTF::nullopt;
3794     }
3795     if (m_lastTransactionPageScaleFactor != layerTransaction.pageScaleFactor()) {
3796         m_lastTransactionPageScaleFactor = layerTransaction.pageScaleFactor();
3797         m_lastTransactionIDWithScaleChange = layerTransaction.transactionID();
3798     }
3799 #endif
3800
3801     layerTransaction.setScrollPosition(frameView->scrollPosition());
3802
3803     if (m_hasPendingEditorStateUpdate) {
3804         layerTransaction.setEditorState(editorState());
3805         m_hasPendingEditorStateUpdate = false;
3806     }
3807 }
3808
3809 void WebPage::didFlushLayerTreeAtTime(MonotonicTime timestamp)
3810 {
3811 #if PLATFORM(IOS_FAMILY)
3812     if (m_oldestNonStableUpdateVisibleContentRectsTimestamp != MonotonicTime()) {
3813         Seconds elapsed = timestamp - m_oldestNonStableUpdateVisibleContentRectsTimestamp;
3814         m_oldestNonStableUpdateVisibleContentRectsTimestamp = MonotonicTime();
3815
3816         m_estimatedLatency = m_estimatedLatency * 0.80 + elapsed * 0.20;
3817     }
3818 #else
3819     UNUSED_PARAM(timestamp);
3820 #endif
3821 }
3822 #endif
3823
3824 void WebPage::layoutIfNeeded()
3825 {
3826     m_page->layoutIfNeeded();
3827 }
3828     
3829 void WebPage::updateRendering()
3830 {
3831     m_page->updateRendering();
3832 }
3833
3834 WebInspector* WebPage::inspector(LazyCreationPolicy behavior)
3835 {
3836     if (m_isClosed)
3837         return nullptr;
3838     if (!m_inspector && behavior == LazyCreationPolicy::CreateIfNeeded)
3839         m_inspector = WebInspector::create(this);
3840     return m_inspector.get();
3841 }
3842
3843 WebInspectorUI* WebPage::inspectorUI()
3844 {
3845     if (m_isClosed)
3846         return nullptr;
3847     if (!m_inspectorUI)
3848         m_inspectorUI = WebInspectorUI::create(*this);
3849     return m_inspectorUI.get();
3850 }
3851
3852 RemoteWebInspectorUI* WebPage::remoteInspectorUI()
3853 {
3854     if (m_isClosed)
3855         return nullptr;
3856     if (!m_remoteInspectorUI)
3857         m_remoteInspectorUI = RemoteWebInspectorUI::create(*this);
3858     return m_remoteInspectorUI.get();
3859 }
3860
3861 void WebPage::inspectorFrontendCountChanged(unsigned count)
3862 {
3863     send(Messages::WebPageProxy::DidChangeInspectorFrontendCount(count));
3864 }
3865
3866 #if (PLATFORM(IOS_FAMILY) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
3867 PlaybackSessionManager& WebPage::playbackSessionManager()
3868 {
3869     if (!m_playbackSessionManager)
3870         m_playbackSessionManager = PlaybackSessionManager::create(*this);
3871     return *m_playbackSessionManager;
3872 }
3873
3874 VideoFullscreenManager& WebPage::videoFullscreenManager()
3875 {
3876     if (!m_videoFullscreenManager)
3877         m_videoFullscreenManager = VideoFullscreenManager::create(*this, playbackSessionManager());
3878     return *m_videoFullscreenManager;
3879 }
3880
3881 void WebPage::videoControlsManagerDidChange()
3882 {
3883 #if ENABLE(FULLSCREEN_API)
3884     if (auto* manager = fullScreenManager())
3885         manager->videoControlsManagerDidChange();
3886 #endif
3887 }
3888
3889 #endif
3890
3891 #if PLATFORM(IOS_FAMILY)
3892 void WebPage::setAllowsMediaDocumentInlinePlayback(bool allows)
3893 {
3894     m_page->setAllowsMediaDocumentInlinePlayback(allows);
3895 }
3896 #endif
3897
3898 #if ENABLE(FULLSCREEN_API)
3899 WebFullScreenManager* WebPage::fullScreenManager()
3900 {
3901     if (!m_fullScreenManager)
3902         m_fullScreenManager = WebFullScreenManager::create(this);
3903     return m_fullScreenManager.get();
3904 }
3905 #endif
3906
3907 void WebPage::addConsoleMessage(FrameIdentifier frameID, MessageSource messageSource, MessageLevel messageLevel, const String& message, uint64_t requestID)
3908 {
3909     if (auto* frame = WebProcess::singleton().webFrame(frameID))
3910         frame->addConsoleMessage(messageSource, messageLevel, message, requestID);
3911 }
3912
3913 void WebPage::sendCSPViolationReport(FrameIdentifier frameID, const URL& reportURL, IPC::FormDataReference&& reportData)
3914 {
3915     auto report = reportData.takeData();
3916     if (!report)
3917         return;
3918     if (auto* frame = WebProcess::singleton().webFrame(frameID))
3919         PingLoader::sendViolationReport(*frame->coreFrame(), reportURL, report.releaseNonNull(), ViolationReportType::ContentSecurityPolicy);
3920 }
3921
3922 void WebPage::enqueueSecurityPolicyViolationEvent(FrameIdentifier frameID, SecurityPolicyViolationEvent::Init&& eventInit)
3923 {
3924     auto* frame = WebProcess::singleton().webFrame(frameID);
3925     if (!frame)
3926         return;
3927     auto* coreFrame = frame->coreFrame();
3928     if (!coreFrame)
3929         return;
3930     if (auto* document = coreFrame->document())
3931         document->enqueueSecurityPolicyViolationEvent(WTFMove(eventInit));
3932 }
3933
3934 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
3935 {
3936     if (m_notificationPermissionRequestManager)
3937         return m_notificationPermissionRequestManager.get();
3938
3939     m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
3940     return m_notificationPermissionRequestManager.get();
3941 }
3942
3943 #if ENABLE(DRAG_SUPPORT)
3944
3945 #if PLATFORM(GTK)
3946 void WebPage::performDragControllerAction(DragControllerAction action, const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t draggingSourceOperationMask, WebSelectionData&& selection, uint32_t flags)
3947 {
3948     if (!m_page) {
3949         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, DragHandlingMethod::None, false, 0, { }, { }));
3950         return;
3951     }
3952
3953     DragData dragData(selection.selectionData.ptr(), clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
3954     switch (action) {
3955     case DragControllerAction::Entered: {
3956         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3957         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }, { }));
3958         return;
3959     }
3960     case DragControllerAction::Updated: {
3961         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3962         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }, { }));
3963         return;
3964     }
3965     case DragControllerAction::Exited:
3966         m_page->dragController().dragExited(dragData);
3967         return;
3968
3969     case DragControllerAction::PerformDragOperation: {
3970         m_page->dragController().performDragOperation(dragData);
3971         return;
3972     }
3973     }
3974     ASSERT_NOT_REACHED();
3975 }
3976 #else
3977 void WebPage::performDragControllerAction(DragControllerAction action, const WebCore::DragData& dragData, SandboxExtension::Handle&& sandboxExtensionHandle, SandboxExtension::HandleArray&& sandboxExtensionsHandleArray)
3978 {
3979     if (!m_page) {
3980         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, DragHandlingMethod::None, false, 0, { }, { }));
3981         return;
3982     }
3983
3984     switch (action) {
3985     case DragControllerAction::Entered: {
3986         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3987         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), m_page->dragCaretController().caretRectInRootViewCoordinates(), m_page->dragCaretController().editableElementRectInRootViewCoordinates()));
3988         return;
3989     }
3990     case DragControllerAction::Updated: {
3991         DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
3992         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().dragHandlingMethod(), m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), m_page->dragCaretController().caretRectInRootViewCoordinates(), m_page->dragCaretController().editableElementRectInRootViewCoordinates()));
3993         return;
3994     }
3995     case DragControllerAction::Exited:
3996         m_page->dragController().dragExited(dragData);
3997         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, DragHandlingMethod::None, false, 0, { }, { }));
3998         return;
3999         
4000     case DragControllerAction::PerformDragOperation: {
4001         ASSERT(!m_pendingDropSandboxExtension);
4002
4003         m_pendingDropSandboxExtension = SandboxExtension::create(WTFMove(sandboxExtensionHandle));
4004         for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
4005             if (auto extension = SandboxExtension::create(WTFMove(sandboxExtensionsHandleArray[i])))
4006                 m_pendingDropExtensionsForFileUpload.append(extension);
4007         }
4008
4009         bool handled = m_page->dragController().performDragOperation(dragData);
4010
4011         // If we started loading a local file, the sandbox extension tracker would have adopted this
4012         // pending drop sandbox extension. If not, we'll play it safe and clear it.
4013         m_pendingDropSandboxExtension = nullptr;
4014
4015         m_pendingDropExtensionsForFileUpload.clear();
4016         send(Messages::WebPageProxy::DidPerformDragOperation(handled));
4017         return;
4018     }
4019     }
4020     ASSERT_NOT_REACHED();
4021 }
4022 #endif
4023
4024 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
4025 {
4026     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController().dragOffset().x(), clientPosition.y() + m_page->dragController().dragOffset().y());
4027     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController().dragOffset().x(), globalPosition.y() + m_page->dragController().dragOffset().y());
4028
4029     m_page->dragController().dragEnded();
4030     FrameView* view = m_page->mainFrame().view();
4031     if (!view)
4032         return;
4033     // FIXME: These are fake modifier keys here, but they should be real ones instead.
4034     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, WallTime::now(), 0, WebCore::NoTap);
4035     m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
4036
4037     send(Messages::WebPageProxy::DidEndDragging());
4038
4039     m_isStartingDrag = false;
4040 }
4041
4042 void WebPage::willPerformLoadDragDestinationAction()
4043 {
4044     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(WTFMove(m_pendingDropSandboxExtension));
4045 }
4046
4047 void WebPage::mayPerformUploadDragDestinationAction()
4048 {
4049     for (size_t i = 0; i < m_pendingDropExtensionsForFileUpload.size(); i++)
4050         m_pendingDropExtensionsForFileUpload[i]->consumePermanently();
4051     m_pendingDropExtensionsForFileUpload.clear();
4052 }
4053
4054 void WebPage::didStartDrag()
4055 {
4056     m_isStartingDrag = false;
4057     m_page->mainFrame().eventHandler().didStartDrag();
4058 }
4059
4060 void WebPage::dragCancelled()
4061 {
4062     m_isStartingDrag = false;
4063     m_page->mainFrame().eventHandler().dragCancelled();
4064 }
4065     
4066 #endif // ENABLE(DRAG_SUPPORT)
4067
4068 WebUndoStep* WebPage::webUndoStep(WebUndoStepID stepID)
4069 {
4070     return m_undoStepMap.get(stepID);
4071 }
4072
4073 void WebPage::addWebUndoStep(WebUndoStepID stepID, Ref<WebUndoStep>&& entry)
4074 {
4075     auto addResult = m_undoStepMap.set(stepID, WTFMove(entry));
4076     ASSERT_UNUSED(addResult, addResult.isNewEntry);
4077 }
4078
4079 void WebPage::removeWebEditCommand(WebUndoStepID stepID)
4080 {
4081     if (auto undoStep = m_undoStepMap.take(stepID))
4082         undoStep->didRemoveFromUndoManager();
4083 }
4084
4085 bool WebPage::isAlwaysOnLoggingAllowed() const
4086 {
4087     return corePage() && corePage()->isAlwaysOnLoggingAllowed();
4088 }
4089
4090 void WebPage::unapplyEditCommand(WebUndoStepID stepID)
4091 {
4092     auto* step = webUndoStep(stepID);
4093     if (!step)
4094         return;
4095
4096     step->step().unapply();
4097 }
4098
4099 void WebPage::reapplyEditCommand(WebUndoStepID stepID)
4100 {
4101     auto* step = webUndoStep(stepID);
4102     if (!step)
4103         return;
4104
4105     m_isInRedo = true;
4106     step->step().reapply();
4107     m_isInRedo = false;
4108 }
4109
4110 void WebPage::didRemoveEditCommand(WebUndoStepID commandID)
4111 {
4112     removeWebEditCommand(commandID);
4113 }
4114
4115 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
4116 {
4117     m_activePopupMenu = menu;
4118 }
4119
4120 #if ENABLE(INPUT_TYPE_COLOR)
4121
4122 void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
4123 {
4124     m_activeColorChooser = colorChooser;
4125 }
4126
4127 void WebPage::didEndColorPicker()
4128 {
4129     m_activeColorChooser->didEndChooser();
4130 }
4131
4132 void WebPage::didChooseColor(const WebCore::Color& color)
4133 {
4134     m_activeColorChooser->didChooseColor(color);
4135 }
4136
4137 #endif
4138
4139 #if ENABLE(DATALIST_ELEMENT)
4140
4141 void WebPage::setActiveDataListSuggestionPicker(WebDataListSuggestionPicker& dataListSuggestionPicker)
4142 {
4143     m_activeDataListSuggestionPicker = makeWeakPtr(&dataListSuggestionPicker);
4144 }
4145
4146 void WebPage::didSelectDataListOption(const String& selectedOption)
4147 {
4148     if (m_activeDataListSuggestionPicker)
4149         m_activeDataListSuggestionPicker->didSelectOption(selectedOption);
4150 }
4151
4152 void WebPage::didCloseSuggestions()
4153 {
4154     if (auto picker = std::exchange(m_activeDataListSuggestionPicker, nullptr))
4155         picker->didCloseSuggestions();
4156 }
4157
4158 #endif