Check for navigation to app-bound domain during script evaluation
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010-2019 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 "GeolocationPermissionRequestManager.h"
42 #include "InjectUserScriptImmediately.h"
43 #include "InjectedBundle.h"
44 #include "InjectedBundleScriptWorld.h"
45 #include "LibWebRTCProvider.h"
46 #include "LoadParameters.h"
47 #include "Logging.h"
48 #include "MediaRecorderProvider.h"
49 #include "NetscapePlugin.h"
50 #include "NetworkConnectionToWebProcessMessages.h"
51 #include "NetworkProcessConnection.h"
52 #include "NotificationPermissionRequestManager.h"
53 #include "PageBanner.h"
54 #include "PluginProcessAttributes.h"
55 #include "PluginProxy.h"
56 #include "PluginView.h"
57 #include "PrintInfo.h"
58 #include "RemoteWebInspectorUI.h"
59 #include "RemoteWebInspectorUIMessages.h"
60 #include "SessionState.h"
61 #include "SessionStateConversion.h"
62 #include "ShareSheetCallbackID.h"
63 #include "ShareableBitmap.h"
64 #include "SharedBufferDataReference.h"
65 #include "UserMediaPermissionRequestManager.h"
66 #include "ViewGestureGeometryCollector.h"
67 #include "VisitedLinkTableController.h"
68 #include "WKBundleAPICast.h"
69 #include "WKRetainPtr.h"
70 #include "WKSharedAPICast.h"
71 #include "WebAlternativeTextClient.h"
72 #include "WebBackForwardListItem.h"
73 #include "WebBackForwardListProxy.h"
74 #include "WebCacheStorageProvider.h"
75 #include "WebChromeClient.h"
76 #include "WebColorChooser.h"
77 #include "WebContextMenu.h"
78 #include "WebContextMenuClient.h"
79 #include "WebCookieJar.h"
80 #include "WebCoreArgumentCoders.h"
81 #include "WebDataListSuggestionPicker.h"
82 #include "WebDatabaseProvider.h"
83 #include "WebDiagnosticLoggingClient.h"
84 #include "WebDocumentLoader.h"
85 #include "WebDragClient.h"
86 #include "WebEditorClient.h"
87 #include "WebEvent.h"
88 #include "WebEventConversion.h"
89 #include "WebEventFactory.h"
90 #include "WebFrame.h"
91 #include "WebFrameLoaderClient.h"
92 #include "WebFullScreenManager.h"
93 #include "WebFullScreenManagerMessages.h"
94 #include "WebGamepadProvider.h"
95 #include "WebGeolocationClient.h"
96 #include "WebImage.h"
97 #include "WebInspector.h"
98 #include "WebInspectorClient.h"
99 #include "WebInspectorMessages.h"
100 #include "WebInspectorUI.h"
101 #include "WebInspectorUIMessages.h"
102 #include "WebLoaderStrategy.h"
103 #include "WebMediaKeyStorageManager.h"
104 #include "WebMediaStrategy.h"
105 #include "WebNotificationClient.h"
106 #include "WebOpenPanelResultListener.h"
107 #include "WebPageCreationParameters.h"
108 #include "WebPageGroupProxy.h"
109 #include "WebPageInspectorTargetController.h"
110 #include "WebPageMessages.h"
111 #include "WebPageOverlay.h"
112 #include "WebPageProxyMessages.h"
113 #include "WebPaymentCoordinator.h"
114 #include "WebPerformanceLoggingClient.h"
115 #include "WebPlugInClient.h"
116 #include "WebPluginInfoProvider.h"
117 #include "WebPopupMenu.h"
118 #include "WebPreferencesDefinitions.h"
119 #include "WebPreferencesKeys.h"
120 #include "WebPreferencesStore.h"
121 #include "WebProcess.h"
122 #include "WebProcessPoolMessages.h"
123 #include "WebProcessProxyMessages.h"
124 #include "WebProgressTrackerClient.h"
125 #include "WebServiceWorkerProvider.h"
126 #include "WebSocketProvider.h"
127 #include "WebSpeechSynthesisClient.h"
128 #include "WebStorageNamespaceProvider.h"
129 #include "WebURLSchemeHandlerProxy.h"
130 #include "WebUndoStep.h"
131 #include "WebUserContentController.h"
132 #include "WebUserMediaClient.h"
133 #include "WebValidationMessageClient.h"
134 #include "WebsiteDataStoreParameters.h"
135 #include <JavaScriptCore/APICast.h>
136 #include <JavaScriptCore/JSCInlines.h>
137 #include <JavaScriptCore/JSCJSValue.h>
138 #include <JavaScriptCore/JSLock.h>
139 #include <JavaScriptCore/ProfilerDatabase.h>
140 #include <JavaScriptCore/SamplingProfiler.h>
141 #include <WebCore/ApplicationCacheStorage.h>
142 #include <WebCore/ArchiveResource.h>
143 #include <WebCore/BackForwardCache.h>
144 #include <WebCore/BackForwardController.h>
145 #include <WebCore/Chrome.h>
146 #include <WebCore/CommonVM.h>
147 #include <WebCore/ContextMenuController.h>
148 #include <WebCore/DOMPasteAccess.h>
149 #include <WebCore/DataTransfer.h>
150 #include <WebCore/DatabaseManager.h>
151 #include <WebCore/DeprecatedGlobalSettings.h>
152 #include <WebCore/DocumentFragment.h>
153 #include <WebCore/DocumentLoader.h>
154 #include <WebCore/DocumentMarkerController.h>
155 #include <WebCore/DocumentStorageAccess.h>
156 #include <WebCore/DragController.h>
157 #include <WebCore/DragData.h>
158 #include <WebCore/Editing.h>
159 #include <WebCore/Editor.h>
160 #include <WebCore/ElementIterator.h>
161 #include <WebCore/EventHandler.h>
162 #include <WebCore/EventNames.h>
163 #include <WebCore/File.h>
164 #include <WebCore/FocusController.h>
165 #include <WebCore/FontAttributeChanges.h>
166 #include <WebCore/FontAttributes.h>
167 #include <WebCore/FormState.h>
168 #include <WebCore/Frame.h>
169 #include <WebCore/FrameLoadRequest.h>
170 #include <WebCore/FrameLoaderTypes.h>
171 #include <WebCore/FrameView.h>
172 #include <WebCore/FullscreenManager.h>
173 #include <WebCore/GraphicsContextGLOpenGL.h>
174 #include <WebCore/HTMLAttachmentElement.h>
175 #include <WebCore/HTMLFormElement.h>
176 #include <WebCore/HTMLImageElement.h>
177 #include <WebCore/HTMLInputElement.h>
178 #include <WebCore/HTMLMenuElement.h>
179 #include <WebCore/HTMLMenuItemElement.h>
180 #include <WebCore/HTMLOListElement.h>
181 #include <WebCore/HTMLPlugInElement.h>
182 #include <WebCore/HTMLPlugInImageElement.h>
183 #include <WebCore/HTMLSelectElement.h>
184 #include <WebCore/HTMLTextFormControlElement.h>
185 #include <WebCore/HTMLUListElement.h>
186 #include <WebCore/HistoryController.h>
187 #include <WebCore/HistoryItem.h>
188 #include <WebCore/HitTestResult.h>
189 #include <WebCore/InspectorController.h>
190 #include <WebCore/JSDOMExceptionHandling.h>
191 #include <WebCore/JSDOMWindow.h>
192 #include <WebCore/KeyboardEvent.h>
193 #include <WebCore/LegacySchemeRegistry.h>
194 #include <WebCore/LocalizedStrings.h>
195 #include <WebCore/MIMETypeRegistry.h>
196 #include <WebCore/MouseEvent.h>
197 #include <WebCore/NotImplemented.h>
198 #include <WebCore/Page.h>
199 #include <WebCore/PageConfiguration.h>
200 #include <WebCore/PingLoader.h>
201 #include <WebCore/PlatformKeyboardEvent.h>
202 #include <WebCore/PlatformMediaSessionManager.h>
203 #include <WebCore/PlatformStrategies.h>
204 #include <WebCore/PluginDocument.h>
205 #include <WebCore/PointerCaptureController.h>
206 #include <WebCore/PrintContext.h>
207 #include <WebCore/PromisedAttachmentInfo.h>
208 #include <WebCore/Quirks.h>
209 #include <WebCore/Range.h>
210 #include <WebCore/RegistrableDomain.h>
211 #include <WebCore/RemoteDOMWindow.h>
212 #include <WebCore/RemoteFrame.h>
213 #include <WebCore/RenderLayer.h>
214 #include <WebCore/RenderTheme.h>
215 #include <WebCore/RenderTreeAsText.h>
216 #include <WebCore/RenderView.h>
217 #include <WebCore/ResourceLoadStatistics.h>
218 #include <WebCore/ResourceRequest.h>
219 #include <WebCore/ResourceResponse.h>
220 #include <WebCore/RunJavaScriptParameters.h>
221 #include <WebCore/RuntimeEnabledFeatures.h>
222 #include <WebCore/SWClientConnection.h>
223 #include <WebCore/ScriptController.h>
224 #include <WebCore/SerializedScriptValue.h>
225 #include <WebCore/Settings.h>
226 #include <WebCore/ShadowRoot.h>
227 #include <WebCore/SharedBuffer.h>
228 #include <WebCore/StyleProperties.h>
229 #include <WebCore/SubframeLoader.h>
230 #include <WebCore/SubstituteData.h>
231 #include <WebCore/TextIterator.h>
232 #include <WebCore/UserGestureIndicator.h>
233 #include <WebCore/UserInputBridge.h>
234 #include <WebCore/UserScript.h>
235 #include <WebCore/UserStyleSheet.h>
236 #include <WebCore/UserTypingGestureIndicator.h>
237 #include <WebCore/VisiblePosition.h>
238 #include <WebCore/VisibleUnits.h>
239 #include <WebCore/WebGLStateTracker.h>
240 #include <WebCore/WritingDirection.h>
241 #include <WebCore/markup.h>
242 #include <pal/SessionID.h>
243 #include <wtf/ProcessID.h>
244 #include <wtf/RunLoop.h>
245 #include <wtf/SetForScope.h>
246 #include <wtf/text/TextStream.h>
247
248 #if ENABLE(DATA_DETECTION)
249 #include "DataDetectionResult.h"
250 #endif
251
252 #if ENABLE(MHTML)
253 #include <WebCore/MHTMLArchive.h>
254 #endif
255
256 #if ENABLE(POINTER_LOCK)
257 #include <WebCore/PointerLockController.h>
258 #endif
259
260 #if PLATFORM(COCOA)
261 #include "InsertTextOptions.h"
262 #include "PDFPlugin.h"
263 #include "PlaybackSessionManager.h"
264 #include "RemoteLayerTreeTransaction.h"
265 #include "RemoteObjectRegistryMessages.h"
266 #include "TextCheckingControllerProxy.h"
267 #include "UserMediaCaptureManager.h"
268 #include "VideoFullscreenManager.h"
269 #include "WKStringCF.h"
270 #include "WebRemoteObjectRegistry.h"
271 #include <WebCore/LegacyWebArchive.h>
272 #include <WebCore/UTIRegistry.h>
273 #include <wtf/MachSendRight.h>
274 #endif
275
276 #if HAVE(TOUCH_BAR)
277 #include "TouchBarMenuData.h"
278 #include "TouchBarMenuItemData.h"
279 #endif
280
281 #if PLATFORM(GTK)
282 #include "WebPrintOperationGtk.h"
283 #include "WebSelectionData.h"
284 #include <gtk/gtk.h>
285 #endif
286
287 #if PLATFORM(IOS_FAMILY)
288 #include "InteractionInformationAtPosition.h"
289 #include "InteractionInformationRequest.h"
290 #include "RemoteLayerTreeDrawingArea.h"
291 #include "WebAutocorrectionContext.h"
292 #include <CoreGraphics/CoreGraphics.h>
293 #include <WebCore/Icon.h>
294 #include <pal/spi/cocoa/CoreTextSPI.h>
295 #endif
296
297 #if PLATFORM(MAC)
298 #include <WebCore/LocalDefaultSystemAppearance.h>
299 #include <pal/spi/cf/CFUtilitiesSPI.h>
300 #endif
301
302 #ifndef NDEBUG
303 #include <wtf/RefCountedLeakCounter.h>
304 #endif
305
306 #if ENABLE(DATA_DETECTION)
307 #include <WebCore/DataDetection.h>
308 #endif
309
310 #if ENABLE(VIDEO) && USE(GSTREAMER)
311 #include <WebCore/MediaPlayerRequestInstallMissingPluginsCallback.h>
312 #endif
313
314 #if ENABLE(WEB_AUTHN)
315 #include "WebAuthenticatorCoordinator.h"
316 #include <WebCore/AuthenticatorCoordinator.h>
317 #endif
318
319 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
320 #include "WebDeviceOrientationUpdateProvider.h"
321 #endif
322
323 #if ENABLE(GPU_PROCESS)
324 #include "RemoteMediaPlayerManager.h"
325 #endif
326
327 namespace WebKit {
328 using namespace JSC;
329 using namespace WebCore;
330
331 static const Seconds pageScrollHysteresisDuration { 300_ms };
332 static const Seconds initialLayerVolatilityTimerInterval { 20_ms };
333 static const Seconds maximumLayerVolatilityTimerInterval { 2_s };
334
335 #define RELEASE_LOG_IF_ALLOWED(channel, fmt, ...) RELEASE_LOG_IF(isAlwaysOnLoggingAllowed(), channel, "%p - [webPageID=%" PRIu64 "] WebPage::" fmt, this, m_identifier.toUInt64(), ##__VA_ARGS__)
336 #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__)
337
338 class SendStopResponsivenessTimer {
339 public:
340     ~SendStopResponsivenessTimer()
341     {
342         WebProcess::singleton().parentProcessConnection()->send(Messages::WebProcessProxy::StopResponsivenessTimer(), 0);
343     }
344 };
345
346 class DeferredPageDestructor {
347 public:
348     static void createDeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
349     {
350         new DeferredPageDestructor(WTFMove(page), webPage);
351     }
352
353 private:
354     DeferredPageDestructor(std::unique_ptr<Page> page, WebPage* webPage)
355         : m_page(WTFMove(page))
356         , m_webPage(webPage)
357     {
358         tryDestruction();
359     }
360
361     void tryDestruction()
362     {
363         if (m_page->insideNestedRunLoop()) {
364             m_page->whenUnnested([this] { tryDestruction(); });
365             return;
366         }
367
368         m_page = nullptr;
369         m_webPage = nullptr;
370         delete this;
371     }
372
373     std::unique_ptr<Page> m_page;
374     RefPtr<WebPage> m_webPage;
375 };
376
377 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
378
379 Ref<WebPage> WebPage::create(PageIdentifier pageID, WebPageCreationParameters&& parameters)
380 {
381     Ref<WebPage> page = adoptRef(*new WebPage(pageID, WTFMove(parameters)));
382
383     if (WebProcess::singleton().injectedBundle())
384         WebProcess::singleton().injectedBundle()->didCreatePage(page.ptr());
385
386     return page;
387 }
388
389 WebPage::WebPage(PageIdentifier pageID, WebPageCreationParameters&& parameters)
390     : m_identifier(pageID)
391     , m_viewSize(parameters.viewSize)
392     , m_alwaysShowsHorizontalScroller { parameters.alwaysShowsHorizontalScroller }
393     , m_alwaysShowsVerticalScroller { parameters.alwaysShowsVerticalScroller }
394     , m_shouldRenderCanvasInGPUProcess { parameters.shouldRenderCanvasInGPUProcess }
395 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
396     , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
397 #endif
398     , m_layerHostingMode(parameters.layerHostingMode)
399 #if ENABLE(PLATFORM_DRIVEN_TEXT_CHECKING)
400     , m_textCheckingControllerProxy(makeUniqueRef<TextCheckingControllerProxy>(*this))
401 #endif
402 #if PLATFORM(COCOA) || PLATFORM(GTK)
403     , m_viewGestureGeometryCollector(makeUnique<ViewGestureGeometryCollector>(*this))
404 #elif ENABLE(ACCESSIBILITY) && PLATFORM(GTK)
405     , m_accessibilityObject(nullptr)
406 #endif
407     , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
408 #if ENABLE(CONTEXT_MENUS)
409     , m_contextMenuClient(makeUnique<API::InjectedBundle::PageContextMenuClient>())
410 #endif
411     , m_editorClient { makeUnique<API::InjectedBundle::EditorClient>() }
412     , m_formClient(makeUnique<API::InjectedBundle::FormClient>())
413     , m_loaderClient(makeUnique<API::InjectedBundle::PageLoaderClient>())
414     , m_resourceLoadClient(makeUnique<API::InjectedBundle::ResourceLoadClient>())
415     , m_uiClient(makeUnique<API::InjectedBundle::PageUIClient>())
416     , m_findController(makeUniqueRef<FindController>(this))
417     , m_inspectorTargetController(makeUnique<WebPageInspectorTargetController>(*this))
418     , m_userContentController(WebUserContentController::getOrCreate(parameters.userContentControllerID))
419 #if ENABLE(GEOLOCATION)
420     , m_geolocationPermissionRequestManager(makeUniqueRef<GeolocationPermissionRequestManager>(*this))
421 #endif
422 #if ENABLE(MEDIA_STREAM)
423     , m_userMediaPermissionRequestManager { makeUniqueRef<UserMediaPermissionRequestManager>(*this) }
424 #endif
425     , m_pageScrolledHysteresis([this](PAL::HysteresisState state) { if (state == PAL::HysteresisState::Stopped) pageStoppedScrolling(); }, pageScrollHysteresisDuration)
426     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
427     , m_canRunModal(parameters.canRunModal)
428 #if ENABLE(META_VIEWPORT)
429     , m_forceAlwaysUserScalable(parameters.ignoresViewportScaleLimits)
430 #endif
431 #if PLATFORM(IOS_FAMILY)
432     , m_screenSize(parameters.screenSize)
433     , m_availableScreenSize(parameters.availableScreenSize)
434     , m_overrideScreenSize(parameters.overrideScreenSize)
435     , m_deviceOrientation(parameters.deviceOrientation)
436     , m_keyboardIsAttached(parameters.keyboardIsAttached)
437     , m_canShowWhileLocked(parameters.canShowWhileLocked)
438 #endif
439     , m_layerVolatilityTimer(*this, &WebPage::layerVolatilityTimerFired)
440     , m_activityState(parameters.activityState)
441     , m_userActivity("App nap disabled for page due to user activity")
442     , m_userInterfaceLayoutDirection(parameters.userInterfaceLayoutDirection)
443     , m_overrideContentSecurityPolicy { parameters.overrideContentSecurityPolicy }
444     , m_cpuLimit(parameters.cpuLimit)
445 #if USE(WPE_RENDERER)
446     , m_hostFileDescriptor(WTFMove(parameters.hostFileDescriptor))
447 #endif
448     , m_webPageProxyIdentifier(parameters.webPageProxyIdentifier)
449 #if ENABLE(VIEWPORT_RESIZING)
450     , m_shrinkToFitContentTimer(*this, &WebPage::shrinkToFitContentTimerFired, 0_s)
451 #endif
452 #if ENABLE(TEXT_AUTOSIZING)
453     , m_textAutoSizingAdjustmentTimer(*this, &WebPage::textAutoSizingAdjustmentTimerFired)
454 #endif
455     , m_overriddenMediaType(parameters.overriddenMediaType)
456     , m_processDisplayName(parameters.processDisplayName)
457 {
458     ASSERT(m_identifier);
459
460     m_pageGroup = WebProcess::singleton().webPageGroup(parameters.pageGroupData);
461
462     PageConfiguration pageConfiguration(
463         WebProcess::singleton().sessionID(),
464         makeUniqueRef<WebEditorClient>(this),
465         WebSocketProvider::create(),
466         makeUniqueRef<WebKit::LibWebRTCProvider>(),
467         WebProcess::singleton().cacheStorageProvider(),
468         WebBackForwardListProxy::create(*this),
469         WebProcess::singleton().cookieJar(),
470         makeUniqueRef<WebProgressTrackerClient>(*this),
471         makeUniqueRef<MediaRecorderProvider>()
472     );
473     pageConfiguration.chromeClient = new WebChromeClient(*this);
474 #if ENABLE(CONTEXT_MENUS)
475     pageConfiguration.contextMenuClient = new WebContextMenuClient(this);
476 #endif
477 #if ENABLE(DRAG_SUPPORT)
478     pageConfiguration.dragClient = makeUnique<WebDragClient>(this);
479 #endif
480     pageConfiguration.inspectorClient = new WebInspectorClient(this);
481 #if USE(AUTOCORRECTION_PANEL)
482     pageConfiguration.alternativeTextClient = makeUnique<WebAlternativeTextClient>(this);
483 #endif
484
485     pageConfiguration.plugInClient = makeUnique<WebPlugInClient>(*this);
486     pageConfiguration.loaderClientForMainFrame = new WebFrameLoaderClient;
487     pageConfiguration.diagnosticLoggingClient = makeUnique<WebDiagnosticLoggingClient>(*this);
488     pageConfiguration.performanceLoggingClient = makeUnique<WebPerformanceLoggingClient>(*this);
489
490 #if ENABLE(WEBGL)
491     pageConfiguration.webGLStateTracker = makeUnique<WebGLStateTracker>([this](bool isUsingHighPerformanceWebGL) {
492         send(Messages::WebPageProxy::SetIsUsingHighPerformanceWebGL(isUsingHighPerformanceWebGL));
493     });
494 #endif
495
496 #if ENABLE(SPEECH_SYNTHESIS)
497     pageConfiguration.speechSynthesisClient = makeUnique<WebSpeechSynthesisClient>(*this);
498 #endif
499
500 #if PLATFORM(COCOA)
501     pageConfiguration.validationMessageClient = makeUnique<WebValidationMessageClient>(*this);
502 #endif
503
504     pageConfiguration.applicationCacheStorage = &WebProcess::singleton().applicationCacheStorage();
505     pageConfiguration.databaseProvider = WebDatabaseProvider::getOrCreate(m_pageGroup->pageGroupID());
506     pageConfiguration.pluginInfoProvider = &WebPluginInfoProvider::singleton();
507     pageConfiguration.storageNamespaceProvider = WebStorageNamespaceProvider::getOrCreate(*m_pageGroup);
508     pageConfiguration.userContentProvider = m_userContentController.ptr();
509     pageConfiguration.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID);
510
511 #if ENABLE(APPLE_PAY)
512     pageConfiguration.paymentCoordinatorClient = new WebPaymentCoordinator(*this);
513 #endif
514
515 #if ENABLE(WEB_AUTHN)
516     pageConfiguration.authenticatorCoordinatorClient = makeUnique<WebAuthenticatorCoordinator>(*this);
517 #endif
518
519 #if ENABLE(APPLICATION_MANIFEST)
520     pageConfiguration.applicationManifest = parameters.applicationManifest;
521 #endif
522     
523 #if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)
524     pageConfiguration.deviceOrientationUpdateProvider = WebDeviceOrientationUpdateProvider::create(*this);
525 #endif
526
527     pageConfiguration.corsDisablingPatterns = WTFMove(parameters.corsDisablingPatterns);
528
529 #if ENABLE(ATTACHMENT_ELEMENT) && PLATFORM(IOS_FAMILY)
530     if (parameters.frontboardExtensionHandle)
531         SandboxExtension::consumePermanently(*parameters.frontboardExtensionHandle);
532     if (parameters.iconServicesExtensionHandle)
533         SandboxExtension::consumePermanently(*parameters.iconServicesExtensionHandle);
534 #endif
535
536     m_page = makeUnique<Page>(WTFMove(pageConfiguration));
537
538     updatePreferences(parameters.store);
539
540 #if PLATFORM(IOS_FAMILY)
541     if (!m_page->settings().useGPUProcessForMedia())
542         DeprecatedGlobalSettings::setShouldManageAudioSessionCategory(true);
543 #endif
544
545     m_backgroundColor = parameters.backgroundColor;
546
547     m_drawingArea = DrawingArea::create(*this, parameters);
548     m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
549
550     if (parameters.isProcessSwap)
551         freezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
552
553 #if ENABLE(ASYNC_SCROLLING)
554     m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
555     if (!m_drawingArea->supportsAsyncScrolling())
556         m_useAsyncScrolling = false;
557     m_page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling);
558 #endif
559
560     // Disable Back/Forward cache expiration in the WebContent process since management happens in the UIProcess
561     // in modern WebKit.
562     m_page->settings().setBackForwardCacheExpirationInterval(Seconds::infinity());
563
564     m_mainFrame = WebFrame::createWithCoreMainFrame(this, &m_page->mainFrame());
565     m_drawingArea->updatePreferences(parameters.store);
566
567     setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage);
568     setPageAndTextZoomFactors(parameters.pageZoomFactor, parameters.textZoomFactor);
569
570 #if ENABLE(GEOLOCATION)
571     WebCore::provideGeolocationTo(m_page.get(), *new WebGeolocationClient(*this));
572 #endif
573 #if ENABLE(NOTIFICATIONS)
574     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
575 #endif
576 #if ENABLE(MEDIA_STREAM)
577     WebCore::provideUserMediaTo(m_page.get(), new WebUserMediaClient(*this));
578 #endif
579
580     m_page->setControlledByAutomation(parameters.controlledByAutomation);
581     m_page->setHasResourceLoadClient(parameters.hasResourceLoadClient);
582
583     m_page->setCanStartMedia(false);
584     m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
585     if (parameters.mediaPlaybackIsSuspended)
586         m_page->suspendAllMediaPlayback();
587
588     m_page->setGroupName(m_pageGroup->identifier());
589     m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
590     m_page->setUserInterfaceLayoutDirection(m_userInterfaceLayoutDirection);
591 #if PLATFORM(IOS_FAMILY)
592     m_page->setTextAutosizingWidth(parameters.textAutosizingWidth);
593     setOverrideViewportArguments(parameters.overrideViewportArguments);
594 #endif
595
596     platformInitialize();
597
598     setUseFixedLayout(parameters.useFixedLayout);
599
600     setUnderlayColor(parameters.underlayColor);
601
602     setPaginationMode(parameters.paginationMode);
603     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
604     setPageLength(parameters.pageLength);
605     setGapBetweenPages(parameters.gapBetweenPages);
606     setPaginationLineGridEnabled(parameters.paginationLineGridEnabled);
607
608 #if PLATFORM(GTK)
609     themeDidChange(WTFMove(parameters.themeName));
610 #endif
611
612     effectiveAppearanceDidChange(parameters.useDarkAppearance, parameters.useElevatedUserInterfaceLevel);
613
614     if (parameters.isEditable)
615         setEditable(true);
616
617 #if PLATFORM(MAC)
618     setUseSystemAppearance(parameters.useSystemAppearance);
619 #endif
620
621     // If the page is created off-screen, its visibilityState should be prerender.
622     m_page->setActivityState(m_activityState);
623     if (!isVisible())
624         m_page->setIsPrerender();
625
626     updateIsInWindow(true);
627
628     setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout);
629     setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
630     setViewportSizeForCSSViewportUnits(parameters.viewportSizeForCSSViewportUnits);
631     
632     setScrollPinningBehavior(parameters.scrollPinningBehavior);
633     if (parameters.scrollbarOverlayStyle)
634         m_scrollbarOverlayStyle = static_cast<ScrollbarOverlayStyle>(parameters.scrollbarOverlayStyle.value());
635     else
636         m_scrollbarOverlayStyle = Optional<ScrollbarOverlayStyle>();
637
638     setTopContentInset(parameters.topContentInset);
639
640     m_userAgent = parameters.userAgent;
641     
642     if (!parameters.itemStates.isEmpty())
643         restoreSessionInternal(parameters.itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
644
645     m_drawingArea->enablePainting();
646     
647     setMediaVolume(parameters.mediaVolume);
648
649     setMuted(parameters.muted);
650
651     // We use the DidFirstVisuallyNonEmptyLayout milestone to determine when to unfreeze the layer tree.
652     m_page->addLayoutMilestones({ DidFirstLayout, DidFirstVisuallyNonEmptyLayout });
653
654     auto& webProcess = WebProcess::singleton();
655     webProcess.addMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier, *this);
656
657     // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
658     webProcess.addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_identifier, *this);
659     webProcess.addMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier, *this);
660     webProcess.addMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier, *this);
661 #if ENABLE(FULLSCREEN_API)
662     webProcess.addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier, *this);
663 #endif
664
665 #ifndef NDEBUG
666     webPageCounter.increment();
667 #endif
668
669 #if ENABLE(SCROLLING_THREAD)
670     if (m_useAsyncScrolling)
671         webProcess.eventDispatcher().addScrollingTreeForPage(this);
672 #endif
673
674     for (auto& mimeType : parameters.mimeTypesWithCustomContentProviders)
675         m_mimeTypesWithCustomContentProviders.add(mimeType);
676
677
678 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
679     if (WebMediaKeyStorageManager* manager = webProcess.supplement<WebMediaKeyStorageManager>())
680         m_page->settings().setMediaKeysStorageDirectory(manager->mediaKeyStorageDirectory());
681 #endif
682     m_page->settings().setAppleMailPaginationQuirkEnabled(parameters.appleMailPaginationQuirkEnabled);
683     
684     if (parameters.viewScaleFactor != 1)
685         scaleView(parameters.viewScaleFactor);
686
687     m_page->addLayoutMilestones(parameters.observedLayoutMilestones);
688
689 #if PLATFORM(COCOA)
690     m_page->settings().setContentDispositionAttachmentSandboxEnabled(true);
691     setSmartInsertDeleteEnabled(parameters.smartInsertDeleteEnabled);
692     WebCore::setAdditionalSupportedImageTypes(parameters.additionalSupportedImageTypes);
693 #endif
694
695     m_needsFontAttributes = parameters.needsFontAttributes;
696
697 #if ENABLE(WEB_RTC)
698     if (!parameters.iceCandidateFilteringEnabled)
699         disableICECandidateFiltering();
700 #if USE(LIBWEBRTC)
701     if (parameters.enumeratingAllNetworkInterfacesEnabled)
702         enableEnumeratingAllNetworkInterfaces();
703 #endif
704 #if PLATFORM(COCOA) && ENABLE(MEDIA_STREAM)
705     if (auto* captureManager = WebProcess::singleton().supplement<UserMediaCaptureManager>())
706         captureManager->setupCaptureProcesses(parameters.shouldCaptureAudioInUIProcess, parameters.shouldCaptureAudioInGPUProcess, parameters.shouldCaptureVideoInUIProcess, parameters.shouldCaptureVideoInGPUProcess, parameters.shouldCaptureDisplayInUIProcess);
707 #endif
708 #endif
709
710     for (const auto& iterator : parameters.urlSchemeHandlers)
711         registerURLSchemeHandler(iterator.value, iterator.key);
712
713     m_userContentController->addContentWorlds(parameters.userContentWorlds);
714     m_userContentController->addUserScripts(WTFMove(parameters.userScripts), InjectUserScriptImmediately::No);
715     m_userContentController->addUserStyleSheets(parameters.userStyleSheets);
716     m_userContentController->addUserScriptMessageHandlers(parameters.messageHandlers);
717 #if ENABLE(CONTENT_EXTENSIONS)
718     m_userContentController->addContentRuleLists(WTFMove(parameters.contentRuleLists));
719 #endif
720
721 #if PLATFORM(IOS_FAMILY)
722     setViewportConfigurationViewLayoutSize(parameters.viewportConfigurationViewLayoutSize, parameters.viewportConfigurationLayoutSizeScaleFactor, parameters.viewportConfigurationMinimumEffectiveDeviceWidth);
723     setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
724 #endif
725
726 #if USE(AUDIO_SESSION)
727     PlatformMediaSessionManager::setShouldDeactivateAudioSession(true);
728 #endif
729
730 #if HAVE(VISIBILITY_PROPAGATION_VIEW)
731     m_contextForVisibilityPropagation = LayerHostingContext::createForExternalHostingProcess({
732         m_canShowWhileLocked
733     });
734     RELEASE_LOG_IF_ALLOWED(Process, "WebPage: Created context with ID %d for visibility propagation from UIProcess", m_contextForVisibilityPropagation->contextID());
735     send(Messages::WebPageProxy::DidCreateContextForVisibilityPropagation(m_contextForVisibilityPropagation->contextID()));
736 #endif
737
738     updateThrottleState();
739 }
740
741 #if ENABLE(WEB_RTC)
742 void WebPage::disableICECandidateFiltering()
743 {
744     m_page->disableICECandidateFiltering();
745 }
746
747 void WebPage::enableICECandidateFiltering()
748 {
749     m_page->enableICECandidateFiltering();
750 }
751
752 #if USE(LIBWEBRTC)
753 void WebPage::disableEnumeratingAllNetworkInterfaces()
754 {
755     m_page->libWebRTCProvider().disableEnumeratingAllNetworkInterfaces();
756 }
757
758 void WebPage::enableEnumeratingAllNetworkInterfaces()
759 {
760     m_page->libWebRTCProvider().enableEnumeratingAllNetworkInterfaces();
761 }
762 #endif
763 #endif
764
765 void WebPage::stopAllMediaPlayback()
766 {
767     m_page->stopAllMediaPlayback();
768 }
769
770 void WebPage::suspendAllMediaPlayback()
771 {
772     m_page->suspendAllMediaPlayback();
773 }
774
775 void WebPage::resumeAllMediaPlayback()
776 {
777     m_page->resumeAllMediaPlayback();
778 }
779
780 void WebPage::suspendAllMediaBuffering()
781 {
782     m_page->suspendAllMediaBuffering();
783 }
784
785 void WebPage::resumeAllMediaBuffering()
786 {
787     m_page->resumeAllMediaBuffering();
788 }
789
790
791 void WebPage::reinitializeWebPage(WebPageCreationParameters&& parameters)
792 {
793     ASSERT(m_drawingArea);
794
795     setSize(parameters.viewSize);
796
797     // If the UIProcess created a new DrawingArea, then we need to do the same.
798     if (m_drawingArea->identifier() != parameters.drawingAreaIdentifier) {
799         auto oldDrawingArea = std::exchange(m_drawingArea, nullptr);
800         oldDrawingArea->removeMessageReceiverIfNeeded();
801
802         m_drawingArea = DrawingArea::create(*this, parameters);
803         m_drawingArea->setShouldScaleViewToFitDocument(parameters.shouldScaleViewToFitDocument);
804         m_drawingArea->updatePreferences(parameters.store);
805         m_drawingArea->enablePainting();
806
807         m_drawingArea->adoptLayersFromDrawingArea(*oldDrawingArea);
808         m_drawingArea->adoptDisplayRefreshMonitorsFromDrawingArea(*oldDrawingArea);
809
810         unfreezeLayerTree(LayerTreeFreezeReason::PageSuspended);
811     }
812
813     setMinimumSizeForAutoLayout(parameters.minimumSizeForAutoLayout);
814
815     if (m_activityState != parameters.activityState)
816         setActivityState(parameters.activityState, ActivityStateChangeAsynchronous, Vector<CallbackID>());
817     if (m_layerHostingMode != parameters.layerHostingMode)
818         setLayerHostingMode(parameters.layerHostingMode);
819
820     platformReinitialize();
821 }
822
823 void WebPage::updateThrottleState()
824 {
825     bool isThrottleable = this->isThrottleable();
826
827     // The UserActivity prevents App Nap. So if we want to allow App Nap of the page, stop the activity.
828     // If the page should not be app nap'd, start it.
829     if (isThrottleable)
830         m_userActivity.stop();
831     else
832         m_userActivity.start();
833
834 #if ENABLE(SERVICE_WORKER)
835     if (RuntimeEnabledFeatures::sharedFeatures().serviceWorkerEnabled()) {
836         RunLoop::main().dispatch([isThrottleable] {
837             WebServiceWorkerProvider::singleton().updateThrottleState(isThrottleable);
838         });
839     }
840 #endif
841 }
842
843 bool WebPage::isThrottleable() const
844 {
845     bool isActive = m_activityState.containsAny({ ActivityState::IsLoading, ActivityState::IsAudible, ActivityState::IsCapturingMedia, ActivityState::WindowIsActive });
846     bool isVisuallyIdle = m_activityState.contains(ActivityState::IsVisuallyIdle);
847
848     return m_isAppNapEnabled && !isActive && isVisuallyIdle;
849 }
850
851 WebPage::~WebPage()
852 {
853     ASSERT(!m_page);
854
855     platformDetach();
856     
857     m_sandboxExtensionTracker.invalidate();
858
859     for (auto* pluginView : m_pluginViews)
860         pluginView->webPageDestroyed();
861
862 #if !PLATFORM(IOS_FAMILY)
863     if (m_headerBanner)
864         m_headerBanner->detachFromPage();
865     if (m_footerBanner)
866         m_footerBanner->detachFromPage();
867 #endif // !PLATFORM(IOS_FAMILY)
868
869 #ifndef NDEBUG
870     webPageCounter.decrement();
871 #endif
872     
873 #if (PLATFORM(IOS_FAMILY) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
874     if (m_playbackSessionManager)
875         m_playbackSessionManager->invalidate();
876
877     if (m_videoFullscreenManager)
878         m_videoFullscreenManager->invalidate();
879 #endif
880 }
881
882 IPC::Connection* WebPage::messageSenderConnection() const
883 {
884     return WebProcess::singleton().parentProcessConnection();
885 }
886
887 uint64_t WebPage::messageSenderDestinationID() const
888 {
889     return identifier().toUInt64();
890 }
891
892 #if ENABLE(CONTEXT_MENUS)
893 void WebPage::setInjectedBundleContextMenuClient(std::unique_ptr<API::InjectedBundle::PageContextMenuClient>&& contextMenuClient)
894 {
895     if (!contextMenuClient) {
896         m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>();
897         return;
898     }
899
900     m_contextMenuClient = WTFMove(contextMenuClient);
901 }
902 #endif
903
904 void WebPage::setInjectedBundleEditorClient(std::unique_ptr<API::InjectedBundle::EditorClient>&& editorClient)
905 {
906     if (!editorClient) {
907         m_editorClient = makeUnique<API::InjectedBundle::EditorClient>();
908         return;
909     }
910
911     m_editorClient = WTFMove(editorClient);
912 }
913
914 void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient>&& formClient)
915 {
916     if (!formClient) {
917         m_formClient = makeUnique<API::InjectedBundle::FormClient>();
918         return;
919     }
920
921     m_formClient = WTFMove(formClient);
922 }
923
924 void WebPage::setInjectedBundlePageLoaderClient(std::unique_ptr<API::InjectedBundle::PageLoaderClient>&& loaderClient)
925 {
926     if (!loaderClient) {
927         m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>();
928         return;
929     }
930
931     m_loaderClient = WTFMove(loaderClient);
932
933     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
934     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
935     // for backwards compatibility.
936     if (auto milestones = m_loaderClient->layoutMilestones())
937         listenForLayoutMilestones(milestones);
938 }
939
940 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClientBase* client)
941 {
942     m_policyClient.initialize(client);
943 }
944
945 void WebPage::setInjectedBundleResourceLoadClient(std::unique_ptr<API::InjectedBundle::ResourceLoadClient>&& client)
946 {
947     if (!m_resourceLoadClient)
948         m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>();
949     else
950         m_resourceLoadClient = WTFMove(client);
951 }
952
953 void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient>&& uiClient)
954 {
955     if (!uiClient) {
956         m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>();
957         return;
958     }
959
960     m_uiClient = WTFMove(uiClient);
961 }
962
963 #if ENABLE(FULLSCREEN_API)
964 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClientBase* client)
965 {
966     m_fullScreenClient.initialize(client);
967 }
968 #endif
969
970 #if ENABLE(NETSCAPE_PLUGIN_API)
971
972 constexpr int smallPluginDimensionThreshold = 5;
973
974 static bool pluginIsSmall(WebCore::HTMLPlugInElement& pluginElement)
975 {
976     auto* renderer = pluginElement.renderer();
977     if (!is<RenderEmbeddedObject>(*renderer))
978         return false;
979
980     auto& box = downcast<RenderBox>(*renderer);
981     return box.contentWidth() <= smallPluginDimensionThreshold && box.contentHeight() <= smallPluginDimensionThreshold;
982 }
983
984 RefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
985 {
986     String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
987     String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
988
989 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
990     HTMLPlugInImageElement& pluginImageElement = downcast<HTMLPlugInImageElement>(*pluginElement);
991     unsigned pluginArea = 0;
992     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot && !(plugInIsPrimarySize(pluginImageElement, pluginArea) && !plugInIntersectsSearchRect(pluginImageElement)) ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
993 #else
994     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
995 #endif
996
997     bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins();
998
999     uint64_t pluginProcessToken;
1000     uint32_t pluginLoadPolicy;
1001     String unavailabilityDescription;
1002     bool isUnsupported;
1003     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)))
1004         return nullptr;
1005
1006     PluginModuleLoadPolicy loadPolicy = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy);
1007     bool isBlockedPlugin = (loadPolicy == PluginModuleBlockedForSecurity) || (loadPolicy == PluginModuleBlockedForCompatibility);
1008
1009     if (isUnsupported || isBlockedPlugin || !pluginProcessToken) {
1010 #if ENABLE(PDFKIT_PLUGIN)
1011         String path = parameters.url.path();
1012         if (shouldUsePDFPlugin() && (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWithIgnoringASCIICase(".pdf") || path.endsWithIgnoringASCIICase(".ps")))))
1013             return PDFPlugin::create(*frame);
1014 #endif
1015     }
1016
1017     if (isUnsupported) {
1018         pluginElement->setReplacement(RenderEmbeddedObject::UnsupportedPlugin, unavailabilityDescription);
1019         return nullptr;
1020     }
1021
1022     if (isBlockedPlugin) {
1023         bool isReplacementObscured = pluginElement->setReplacement(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
1024         send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, isReplacementObscured));
1025         return nullptr;
1026     }
1027
1028     if (!pluginProcessToken)
1029         return nullptr;
1030
1031     if (m_page->settings().blockingOfSmallPluginsEnabled() && pluginIsSmall(*pluginElement)) {
1032         RELEASE_LOG_IF_ALLOWED(Plugins, "createPlugin: Blocking a plugin because it is too small");
1033         pluginElement->setReplacement(RenderEmbeddedObject::PluginTooSmall, pluginTooSmallText());
1034         return nullptr;
1035     }
1036
1037     bool isRestartedProcess = (pluginElement->displayState() == HTMLPlugInElement::Restarting || pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick);
1038     return PluginProxy::create(pluginProcessToken, isRestartedProcess);
1039 }
1040 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1041
1042 #if ENABLE(WEBGL) && !PLATFORM(MAC)
1043 WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const URL&)
1044 {
1045     return WebGLAllowCreation;
1046 }
1047
1048 WebCore::WebGLLoadPolicy WebPage::resolveWebGLPolicyForURL(WebFrame*, const URL&)
1049 {
1050     return WebGLAllowCreation;
1051 }
1052 #endif
1053
1054 EditorState WebPage::editorState(IncludePostLayoutDataHint shouldIncludePostLayoutData) const
1055 {
1056     Frame& frame = m_page->focusController().focusedOrMainFrame();
1057
1058     EditorState result;
1059
1060     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
1061         if (!pluginView->getSelectionString().isNull()) {
1062             result.selectionIsNone = false;
1063             result.selectionIsRange = true;
1064             result.isInPlugin = true;
1065             return result;
1066         }
1067     }
1068
1069     const VisibleSelection& selection = frame.selection().selection();
1070     const Editor& editor = frame.editor();
1071
1072     result.selectionIsNone = selection.isNone();
1073     result.selectionIsRange = selection.isRange();
1074     result.isContentEditable = selection.isContentEditable();
1075     result.isContentRichlyEditable = selection.isContentRichlyEditable();
1076     result.isInPasswordField = selection.isInPasswordField();
1077     result.hasComposition = editor.hasComposition();
1078     result.shouldIgnoreSelectionChanges = editor.ignoreSelectionChanges() || (editor.client() && !editor.client()->shouldRevealCurrentSelectionAfterInsertion());
1079
1080     if (auto* document = frame.document())
1081         result.originIdentifierForPasteboard = document->originIdentifierForPasteboard();
1082
1083     bool canIncludePostLayoutData = frame.view() && !frame.view()->needsLayout();
1084     if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::Yes && canIncludePostLayoutData) {
1085         auto& postLayoutData = result.postLayoutData();
1086         postLayoutData.canCut = editor.canCut();
1087         postLayoutData.canCopy = editor.canCopy();
1088         postLayoutData.canPaste = editor.canPaste();
1089
1090         if (m_needsFontAttributes)
1091             postLayoutData.fontAttributes = editor.fontAttributesAtSelectionStart();
1092
1093 #if PLATFORM(COCOA)
1094         if (result.isContentEditable && !selection.isNone()) {
1095             if (auto editingStyle = EditingStyle::styleAtSelectionStart(selection)) {
1096                 if (editingStyle->hasStyle(CSSPropertyFontWeight, "bold"))
1097                     postLayoutData.typingAttributes |= AttributeBold;
1098
1099                 if (editingStyle->hasStyle(CSSPropertyFontStyle, "italic") || editingStyle->hasStyle(CSSPropertyFontStyle, "oblique"))
1100                     postLayoutData.typingAttributes |= AttributeItalics;
1101
1102                 if (editingStyle->hasStyle(CSSPropertyWebkitTextDecorationsInEffect, "underline"))
1103                     postLayoutData.typingAttributes |= AttributeUnderline;
1104
1105                 if (auto* styleProperties = editingStyle->style()) {
1106                     bool isLeftToRight = styleProperties->propertyAsValueID(CSSPropertyDirection) == CSSValueLtr;
1107                     switch (styleProperties->propertyAsValueID(CSSPropertyTextAlign)) {
1108                     case CSSValueRight:
1109                     case CSSValueWebkitRight:
1110                         postLayoutData.textAlignment = RightAlignment;
1111                         break;
1112                     case CSSValueLeft:
1113                     case CSSValueWebkitLeft:
1114                         postLayoutData.textAlignment = LeftAlignment;
1115                         break;
1116                     case CSSValueCenter:
1117                     case CSSValueWebkitCenter:
1118                         postLayoutData.textAlignment = CenterAlignment;
1119                         break;
1120                     case CSSValueJustify:
1121                         postLayoutData.textAlignment = JustifiedAlignment;
1122                         break;
1123                     case CSSValueStart:
1124                         postLayoutData.textAlignment = isLeftToRight ? LeftAlignment : RightAlignment;
1125                         break;
1126                     case CSSValueEnd:
1127                         postLayoutData.textAlignment = isLeftToRight ? RightAlignment : LeftAlignment;
1128                         break;
1129                     default:
1130                         break;
1131                     }
1132                     if (auto textColor = styleProperties->propertyAsColor(CSSPropertyColor))
1133                         postLayoutData.textColor = *textColor;
1134                 }
1135             }
1136
1137             if (auto* enclosingListElement = enclosingList(selection.start().containerNode())) {
1138                 if (is<HTMLUListElement>(*enclosingListElement))
1139                     postLayoutData.enclosingListType = UnorderedList;
1140                 else if (is<HTMLOListElement>(*enclosingListElement))
1141                     postLayoutData.enclosingListType = OrderedList;
1142                 else
1143                     ASSERT_NOT_REACHED();
1144             }
1145
1146             postLayoutData.baseWritingDirection = editor.baseWritingDirectionForSelectionStart();
1147         }
1148 #endif
1149     }
1150
1151     platformEditorState(frame, result, shouldIncludePostLayoutData);
1152
1153     m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
1154
1155     return result;
1156 }
1157
1158 void WebPage::changeFontAttributes(WebCore::FontAttributeChanges&& changes)
1159 {
1160     auto& frame = m_page->focusController().focusedOrMainFrame();
1161     if (frame.selection().selection().isContentEditable())
1162         frame.editor().applyStyleToSelection(changes.createEditingStyle(), changes.editAction(), Editor::ColorFilterMode::InvertColor);
1163 }
1164
1165 void WebPage::changeFont(WebCore::FontChanges&& changes)
1166 {
1167     auto& frame = m_page->focusController().focusedOrMainFrame();
1168     if (frame.selection().selection().isContentEditable())
1169         frame.editor().applyStyleToSelection(changes.createEditingStyle(), EditAction::SetFont, Editor::ColorFilterMode::InvertColor);
1170 }
1171
1172 void WebPage::executeEditCommandWithCallback(const String& commandName, const String& argument, CallbackID callbackID)
1173 {
1174     executeEditCommand(commandName, argument);
1175     send(Messages::WebPageProxy::VoidCallback(callbackID));
1176 }
1177
1178 void WebPage::selectAll()
1179 {
1180     executeEditingCommand("SelectAll"_s, { });
1181     platformDidSelectAll();
1182 }
1183
1184 bool WebPage::shouldDispatchSyntheticMouseEventsWhenModifyingSelection() const
1185 {
1186     auto* document = m_page->mainFrame().document();
1187     return document && document->quirks().shouldDispatchSyntheticMouseEventsWhenModifyingSelection();
1188 }
1189
1190 #if !PLATFORM(IOS_FAMILY)
1191
1192 void WebPage::platformDidSelectAll()
1193 {
1194 }
1195
1196 #endif // !PLATFORM(IOS_FAMILY)
1197
1198 void WebPage::updateEditorStateAfterLayoutIfEditabilityChanged()
1199 {
1200     // FIXME: We should update EditorStateIsContentEditable to track whether the state is richly
1201     // editable or plainttext-only.
1202     if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset)
1203         return;
1204
1205     Frame& frame = m_page->focusController().focusedOrMainFrame();
1206     EditorStateIsContentEditable editorStateIsContentEditable = frame.selection().selection().isContentEditable() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
1207     if (m_lastEditorStateWasContentEditable != editorStateIsContentEditable)
1208         scheduleFullEditorStateUpdate();
1209 }
1210
1211 static OptionSet<RenderAsTextFlag> toRenderAsTextFlags(unsigned options)
1212 {
1213     OptionSet<RenderAsTextFlag> flags;
1214
1215     if (options & RenderTreeShowAllLayers)
1216         flags.add(RenderAsTextFlag::ShowAllLayers);
1217     if (options & RenderTreeShowLayerNesting)
1218         flags.add(RenderAsTextFlag::ShowLayerNesting);
1219     if (options & RenderTreeShowCompositedLayers)
1220         flags.add(RenderAsTextFlag::ShowCompositedLayers);
1221     if (options & RenderTreeShowOverflow)
1222         flags.add(RenderAsTextFlag::ShowOverflow);
1223     if (options & RenderTreeShowSVGGeometry)
1224         flags.add(RenderAsTextFlag::ShowSVGGeometry);
1225     if (options & RenderTreeShowLayerFragments)
1226         flags.add(RenderAsTextFlag::ShowLayerFragments);
1227
1228     return flags;
1229 }
1230
1231 String WebPage::renderTreeExternalRepresentation(unsigned options) const
1232 {
1233     return externalRepresentation(m_mainFrame->coreFrame(), toRenderAsTextFlags(options));
1234 }
1235
1236 String WebPage::renderTreeExternalRepresentationForPrinting() const
1237 {
1238     return externalRepresentation(m_mainFrame->coreFrame(), { RenderAsTextFlag::PrintingMode });
1239 }
1240
1241 uint64_t WebPage::renderTreeSize() const
1242 {
1243     if (!m_page)
1244         return 0;
1245     return m_page->renderTreeSize();
1246 }
1247
1248 void WebPage::setHasResourceLoadClient(bool has)
1249 {
1250     if (m_page)
1251         m_page->setHasResourceLoadClient(has);
1252 }
1253
1254 void WebPage::setTracksRepaints(bool trackRepaints)
1255 {
1256     if (FrameView* view = mainFrameView())
1257         view->setTracksRepaints(trackRepaints);
1258 }
1259
1260 bool WebPage::isTrackingRepaints() const
1261 {
1262     if (FrameView* view = mainFrameView())
1263         return view->isTrackingRepaints();
1264
1265     return false;
1266 }
1267
1268 void WebPage::resetTrackedRepaints()
1269 {
1270     if (FrameView* view = mainFrameView())
1271         view->resetTrackedRepaints();
1272 }
1273
1274 Ref<API::Array> WebPage::trackedRepaintRects()
1275 {
1276     FrameView* view = mainFrameView();
1277     if (!view)
1278         return API::Array::create();
1279
1280     Vector<RefPtr<API::Object>> repaintRects;
1281     repaintRects.reserveInitialCapacity(view->trackedRepaintRects().size());
1282
1283     for (const auto& repaintRect : view->trackedRepaintRects())
1284         repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
1285
1286     return API::Array::create(WTFMove(repaintRects));
1287 }
1288
1289 PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
1290 {
1291     if (!is<PluginDocument>(frame.document()))
1292         return nullptr;
1293
1294     auto& pluginDocument = downcast<PluginDocument>(*frame.document());
1295     if (pluginDocument.focusedElement() != pluginDocument.pluginElement())
1296         return nullptr;
1297
1298     return pluginViewForFrame(&frame);
1299 }
1300
1301 PluginView* WebPage::pluginViewForFrame(Frame* frame)
1302 {
1303     if (!frame || !is<PluginDocument>(frame->document()))
1304         return nullptr;
1305
1306     auto& document = downcast<PluginDocument>(*frame->document());
1307     return static_cast<PluginView*>(document.pluginWidget());
1308 }
1309
1310 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
1311 {
1312     platformWillPerformEditingCommand();
1313
1314     auto& frame = m_page->focusController().focusedOrMainFrame();
1315
1316     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
1317         pluginView->handleEditingCommand(commandName, argument);
1318         return;
1319     }
1320     
1321     frame.editor().command(commandName).execute(argument);
1322 }
1323
1324 void WebPage::setEditable(bool editable)
1325 {
1326     m_page->setEditable(editable);
1327     m_page->setTabKeyCyclesThroughElements(!editable);
1328     Frame& frame = m_page->focusController().focusedOrMainFrame();
1329     if (editable) {
1330         frame.editor().applyEditingStyleToBodyElement();
1331         // If the page is made editable and the selection is empty, set it to something.
1332         if (frame.selection().isNone())
1333             frame.selection().setSelectionFromNone();
1334     }
1335 }
1336
1337 void WebPage::increaseListLevel()
1338 {
1339     m_page->focusController().focusedOrMainFrame().editor().increaseSelectionListLevel();
1340 }
1341
1342 void WebPage::decreaseListLevel()
1343 {
1344     m_page->focusController().focusedOrMainFrame().editor().decreaseSelectionListLevel();
1345 }
1346
1347 void WebPage::changeListType()
1348 {
1349     m_page->focusController().focusedOrMainFrame().editor().changeSelectionListType();
1350 }
1351
1352 void WebPage::setBaseWritingDirection(WritingDirection direction)
1353 {
1354     m_page->focusController().focusedOrMainFrame().editor().setBaseWritingDirection(direction);
1355 }
1356
1357 bool WebPage::isEditingCommandEnabled(const String& commandName)
1358 {
1359     Frame& frame = m_page->focusController().focusedOrMainFrame();
1360
1361     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
1362         return pluginView->isEditingCommandEnabled(commandName);
1363     
1364     Editor::Command command = frame.editor().command(commandName);
1365     return command.isSupported() && command.isEnabled();
1366 }
1367     
1368 void WebPage::clearMainFrameName()
1369 {
1370     if (Frame* frame = mainFrame())
1371         frame->tree().clearName();
1372 }
1373
1374 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
1375 {
1376     m_drawingArea->setRootCompositingLayer(layer);
1377 }
1378
1379 void WebPage::exitAcceleratedCompositingMode()
1380 {
1381     m_drawingArea->setRootCompositingLayer(nullptr);
1382 }
1383
1384 void WebPage::close()
1385 {
1386     if (m_isClosed)
1387         return;
1388
1389 #if ENABLE(RESOURCE_LOAD_STATISTICS)
1390     WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::ClearPageSpecificDataForResourceLoadStatistics(m_identifier), 0);
1391 #endif
1392
1393     m_isClosed = true;
1394
1395     // If there is still no URL, then we never loaded anything in this page, so nothing to report.
1396     if (!mainWebFrame()->url().isEmpty())
1397         reportUsedFeatures();
1398
1399     if (WebProcess::singleton().injectedBundle())
1400         WebProcess::singleton().injectedBundle()->willDestroyPage(this);
1401
1402     if (m_inspector) {
1403         m_inspector->disconnectFromPage();
1404         m_inspector = nullptr;
1405     }
1406
1407     m_page->inspectorController().disconnectAllFrontends();
1408
1409 #if ENABLE(FULLSCREEN_API)
1410     m_fullScreenManager = nullptr;
1411 #endif
1412
1413     if (m_activePopupMenu) {
1414         m_activePopupMenu->disconnectFromPage();
1415         m_activePopupMenu = nullptr;
1416     }
1417
1418     if (m_activeOpenPanelResultListener) {
1419         m_activeOpenPanelResultListener->disconnectFromPage();
1420         m_activeOpenPanelResultListener = nullptr;
1421     }
1422
1423 #if ENABLE(INPUT_TYPE_COLOR)
1424     if (m_activeColorChooser) {
1425         m_activeColorChooser->disconnectFromPage();
1426         m_activeColorChooser = nullptr;
1427     }
1428 #endif
1429
1430 #if PLATFORM(GTK)
1431     if (m_printOperation) {
1432         m_printOperation->disconnectFromPage();
1433         m_printOperation = nullptr;
1434     }
1435 #endif
1436
1437 #if ENABLE(VIDEO) && USE(GSTREAMER)
1438     if (m_installMediaPluginsCallback) {
1439         m_installMediaPluginsCallback->invalidate();
1440         m_installMediaPluginsCallback = nullptr;
1441     }
1442 #endif
1443
1444     m_sandboxExtensionTracker.invalidate();
1445
1446 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
1447     m_determinePrimarySnapshottedPlugInTimer.stop();
1448 #endif
1449
1450 #if ENABLE(VIEWPORT_RESIZING)
1451     m_shrinkToFitContentTimer.stop();
1452 #endif
1453
1454 #if ENABLE(TEXT_AUTOSIZING)
1455     m_textAutoSizingAdjustmentTimer.stop();
1456 #endif
1457
1458 #if ENABLE(CONTEXT_MENUS)
1459     m_contextMenuClient = makeUnique<API::InjectedBundle::PageContextMenuClient>();
1460 #endif
1461     m_editorClient = makeUnique<API::InjectedBundle::EditorClient>();
1462     m_formClient = makeUnique<API::InjectedBundle::FormClient>();
1463     m_loaderClient = makeUnique<API::InjectedBundle::PageLoaderClient>();
1464     m_policyClient.initialize(0);
1465     m_resourceLoadClient = makeUnique<API::InjectedBundle::ResourceLoadClient>();
1466     m_uiClient = makeUnique<API::InjectedBundle::PageUIClient>();
1467 #if ENABLE(FULLSCREEN_API)
1468     m_fullScreenClient.initialize(0);
1469 #endif
1470
1471     m_printContext = nullptr;
1472     m_mainFrame->coreFrame()->loader().detachFromParent();
1473     m_drawingArea = nullptr;
1474
1475     DeferredPageDestructor::createDeferredPageDestructor(WTFMove(m_page), this);
1476
1477     bool isRunningModal = m_isRunningModal;
1478     m_isRunningModal = false;
1479
1480     auto& webProcess = WebProcess::singleton();
1481 #if PLATFORM(COCOA)
1482     if (m_remoteObjectRegistry)
1483         m_remoteObjectRegistry->close();
1484     ASSERT(!m_remoteObjectRegistry);
1485 #endif
1486 #if ENABLE(SCROLLING_THREAD)
1487     if (m_useAsyncScrolling)
1488         webProcess.eventDispatcher().removeScrollingTreeForPage(this);
1489 #endif
1490     webProcess.removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_identifier);
1491     // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
1492     webProcess.removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_identifier);
1493     webProcess.removeMessageReceiver(Messages::WebInspectorUI::messageReceiverName(), m_identifier);
1494     webProcess.removeMessageReceiver(Messages::RemoteWebInspectorUI::messageReceiverName(), m_identifier);
1495 #if ENABLE(FULLSCREEN_API)
1496     webProcess.removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_identifier);
1497 #endif
1498 #if PLATFORM(COCOA) || PLATFORM(GTK)
1499     m_viewGestureGeometryCollector = nullptr;
1500 #endif
1501
1502     // The WebPage can be destroyed by this call.
1503     WebProcess::singleton().removeWebPage(m_identifier);
1504
1505     WebProcess::singleton().updateActivePages(m_processDisplayName);
1506
1507     if (isRunningModal)
1508         RunLoop::main().stop();
1509 }
1510
1511 void WebPage::tryClose(CompletionHandler<void(bool)>&& completionHandler)
1512 {
1513     bool shouldClose = corePage()->userInputBridge().tryClosePage();
1514     completionHandler(shouldClose);
1515 }
1516
1517 void WebPage::sendClose()
1518 {
1519     send(Messages::WebPageProxy::ClosePage());
1520 }
1521
1522 void WebPage::suspendForProcessSwap()
1523 {
1524     auto failedToSuspend = [this, protectedThis = makeRef(*this)] {
1525         send(Messages::WebPageProxy::DidFailToSuspendAfterProcessSwap());
1526     };
1527
1528     auto* currentHistoryItem = m_mainFrame->coreFrame()->loader().history().currentItem();
1529     if (!currentHistoryItem) {
1530         failedToSuspend();
1531         return;
1532     }
1533
1534     if (!BackForwardCache::singleton().addIfCacheable(*currentHistoryItem, corePage())) {
1535         failedToSuspend();
1536         return;
1537     }
1538
1539     // Back/forward cache does not break the opener link for the main frame (only does so for the subframes) because the
1540     // main frame is normally re-used for the navigation. However, in the case of process-swapping, the main frame
1541     // is now hosted in another process and the one in this process is in the cache.
1542     if (m_mainFrame && m_mainFrame->coreFrame())
1543         m_mainFrame->coreFrame()->loader().detachFromAllOpenedFrames();
1544
1545     send(Messages::WebPageProxy::DidSuspendAfterProcessSwap());
1546 }
1547
1548 void WebPage::loadURLInFrame(URL&& url, const String& referrer, FrameIdentifier frameID)
1549 {
1550     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1551     if (!frame)
1552         return;
1553
1554     frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(url, referrer), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
1555 }
1556
1557 void WebPage::loadDataInFrame(IPC::DataReference&& data, String&& MIMEType, String&& encodingName, URL&& baseURL, FrameIdentifier frameID)
1558 {
1559     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1560     if (!frame)
1561         return;
1562     ASSERT(mainWebFrame() != frame);
1563
1564     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size());
1565     ResourceResponse response(baseURL, MIMEType, sharedBuffer->size(), encodingName);
1566     SubstituteData substituteData(WTFMove(sharedBuffer), baseURL, WTFMove(response), SubstituteData::SessionHistoryVisibility::Hidden);
1567     frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(baseURL), ShouldOpenExternalURLsPolicy::ShouldNotAllow, WTFMove(substituteData)));
1568 }
1569
1570 #if !PLATFORM(COCOA)
1571 void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters)
1572 {
1573 }
1574 #endif
1575
1576 void WebPage::loadRequest(LoadParameters&& loadParameters)
1577 {
1578     setIsNavigatingToAppBoundDomain(loadParameters.isNavigatingToAppBoundDomain);
1579     setHasNavigatedAwayFromAppBoundDomain(loadParameters.hasNavigatedAwayFromAppBoundDomain);
1580
1581     SendStopResponsivenessTimer stopper;
1582
1583     m_pendingNavigationID = loadParameters.navigationID;
1584     m_pendingWebsitePolicies = WTFMove(loadParameters.websitePolicies);
1585
1586     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), WTFMove(loadParameters.sandboxExtensionHandle));
1587
1588     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1589     // to all the client to set up any needed state.
1590     m_loaderClient->willLoadURLRequest(*this, loadParameters.request, WebProcess::singleton().transformHandlesToObjects(loadParameters.userData.object()).get());
1591
1592     platformDidReceiveLoadParameters(loadParameters);
1593
1594     // Initate the load in WebCore.
1595     FrameLoadRequest frameLoadRequest { *m_mainFrame->coreFrame(), loadParameters.request, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
1596     frameLoadRequest.setShouldOpenExternalURLsPolicy(loadParameters.shouldOpenExternalURLsPolicy);
1597     frameLoadRequest.setShouldTreatAsContinuingLoad(loadParameters.shouldTreatAsContinuingLoad);
1598     frameLoadRequest.setLockHistory(loadParameters.lockHistory);
1599     frameLoadRequest.setlockBackForwardList(loadParameters.lockBackForwardList);
1600     frameLoadRequest.setClientRedirectSourceForHistory(loadParameters.clientRedirectSourceForHistory);
1601     frameLoadRequest.setIsRequestFromClientOrUserInput();
1602
1603     corePage()->userInputBridge().loadRequest(WTFMove(frameLoadRequest));
1604
1605     ASSERT(!m_pendingNavigationID);
1606     ASSERT(!m_pendingWebsitePolicies);
1607 }
1608
1609 // LoadRequestWaitingForProcessLaunch should never be sent to the WebProcess. It must always be converted to a LoadRequest message.
1610 NO_RETURN void WebPage::loadRequestWaitingForProcessLaunch(LoadParameters&&, URL&&, WebPageProxyIdentifier, bool)
1611 {
1612     RELEASE_ASSERT_NOT_REACHED();
1613 }
1614
1615 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)
1616 {
1617     setIsNavigatingToAppBoundDomain(isNavigatingToAppBoundDomain);
1618     setHasNavigatedAwayFromAppBoundDomain(hasNavigatedAwayFromAppBoundDomain);
1619
1620     SendStopResponsivenessTimer stopper;
1621
1622     m_pendingNavigationID = navigationID;
1623     m_pendingWebsitePolicies = WTFMove(websitePolicies);
1624
1625     ResourceRequest request(baseURL);
1626     ResourceResponse response(URL(), MIMEType, sharedBuffer->size(), encodingName);
1627     SubstituteData substituteData(WTFMove(sharedBuffer), unreachableURL, response, SubstituteData::SessionHistoryVisibility::Hidden);
1628
1629     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1630     // to all the client to set up any needed state.
1631     m_loaderClient->willLoadDataRequest(*this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
1632
1633     // Initate the load in WebCore.
1634     FrameLoadRequest frameLoadRequest(*m_mainFrame->coreFrame(), request, shouldOpenExternalURLsPolicy, substituteData);
1635     frameLoadRequest.setShouldTreatAsContinuingLoad(shouldTreatAsContinuingLoad);
1636     frameLoadRequest.setIsRequestFromClientOrUserInput();
1637     m_mainFrame->coreFrame()->loader().load(WTFMove(frameLoadRequest));
1638 }
1639
1640 void WebPage::loadData(LoadParameters&& loadParameters)
1641 {
1642     platformDidReceiveLoadParameters(loadParameters);
1643
1644     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
1645     URL baseURL = loadParameters.baseURLString.isEmpty() ? WTF::blankURL() : URL(URL(), loadParameters.baseURLString);
1646     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain, loadParameters.shouldOpenExternalURLsPolicy);
1647 }
1648
1649 void WebPage::loadAlternateHTML(LoadParameters&& loadParameters)
1650 {
1651     platformDidReceiveLoadParameters(loadParameters);
1652
1653     URL baseURL = loadParameters.baseURLString.isEmpty() ? WTF::blankURL() : URL(URL(), loadParameters.baseURLString);
1654     URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL(URL(), loadParameters.unreachableURLString);
1655     URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString);
1656     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
1657     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);    
1658     loadDataImpl(loadParameters.navigationID, loadParameters.shouldTreatAsContinuingLoad, WTFMove(loadParameters.websitePolicies), WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, unreachableURL, loadParameters.userData, loadParameters.isNavigatingToAppBoundDomain, loadParameters.hasNavigatedAwayFromAppBoundDomain);
1659     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
1660 }
1661
1662 void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
1663 {
1664     Frame* mainFrame = m_mainFrame->coreFrame();
1665     Document* mainFrameDocument = mainFrame->document();
1666     if (!mainFrameDocument)
1667         return;
1668
1669     const int singleClick = 1;
1670     // FIXME: Set modifier keys.
1671     // FIXME: This should probably set IsSimulated::Yes.
1672     auto mouseEvent = MouseEvent::create(eventNames().clickEvent, Event::CanBubble::Yes, Event::IsCancelable::Yes, Event::IsComposed::Yes,
1673         MonotonicTime::now(), nullptr, singleClick, screenPoint, documentPoint, { }, { }, 0, 0, nullptr, 0, WebCore::NoTap);
1674
1675     mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.ptr(), LockHistory::No, LockBackForwardList::No, ReferrerPolicy::NoReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
1676 }
1677
1678 void WebPage::stopLoadingFrame(FrameIdentifier frameID)
1679 {
1680     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1681     if (!frame)
1682         return;
1683
1684     corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
1685 }
1686
1687 void WebPage::stopLoading()
1688 {
1689     SendStopResponsivenessTimer stopper;
1690
1691     corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
1692 }
1693
1694 bool WebPage::defersLoading() const
1695 {
1696     return m_page->defersLoading();
1697 }
1698
1699 void WebPage::setDefersLoading(bool defersLoading)
1700 {
1701     m_page->setDefersLoading(defersLoading);
1702 }
1703
1704 void WebPage::reload(uint64_t navigationID, uint32_t reloadOptions, SandboxExtension::Handle&& sandboxExtensionHandle)
1705 {
1706     SendStopResponsivenessTimer stopper;
1707
1708     ASSERT(!m_mainFrame->coreFrame()->loader().frameHasLoaded() || !m_pendingNavigationID);
1709     m_pendingNavigationID = navigationID;
1710
1711     m_sandboxExtensionTracker.beginReload(m_mainFrame.get(), WTFMove(sandboxExtensionHandle));
1712     corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), OptionSet<ReloadOption>::fromRaw(reloadOptions));
1713
1714     if (m_pendingNavigationID) {
1715         // This can happen if FrameLoader::reload() returns early because the document URL is empty.
1716         // The reload does nothing so we need to reset the pending navigation. See webkit.org/b/153210.
1717         m_pendingNavigationID = 0;
1718     }
1719 }
1720
1721 void WebPage::goToBackForwardItem(uint64_t navigationID, const BackForwardItemIdentifier& backForwardItemID, FrameLoadType backForwardType, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, Optional<WebsitePoliciesData>&& websitePolicies)
1722 {
1723     SendStopResponsivenessTimer stopper;
1724
1725     ASSERT(isBackForwardLoadType(backForwardType));
1726
1727     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1728     ASSERT(item);
1729     if (!item)
1730         return;
1731
1732     LOG(Loading, "In WebProcess pid %i, WebPage %" PRIu64 " is navigating to back/forward URL %s", getCurrentProcessID(), m_identifier.toUInt64(), item->url().string().utf8().data());
1733
1734     ASSERT(!m_pendingNavigationID);
1735     m_pendingNavigationID = navigationID;
1736     m_pendingWebsitePolicies = WTFMove(websitePolicies);
1737
1738     m_page->goToItem(*item, backForwardType, shouldTreatAsContinuingLoad);
1739 }
1740
1741 void WebPage::tryRestoreScrollPosition()
1742 {
1743     m_page->mainFrame().loader().history().restoreScrollPositionAndViewState();
1744 }
1745
1746 WebPage& WebPage::fromCorePage(Page& page)
1747 {
1748     return static_cast<WebChromeClient&>(page.chrome().client()).page();
1749 }
1750
1751 void WebPage::getAllFrames(CompletionHandler<void(Vector<FrameInfoData>&&)>&& completionHandler)
1752 {
1753     Vector<FrameInfoData> data;
1754     for (auto* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
1755         if (auto* webFrame = WebFrame::fromCoreFrame(*frame))
1756             data.append(webFrame->info());
1757     }
1758     completionHandler(WTFMove(data));
1759 }
1760
1761 void WebPage::setSize(const WebCore::IntSize& viewSize)
1762 {
1763     if (m_viewSize == viewSize)
1764         return;
1765
1766     m_viewSize = viewSize;
1767     FrameView* view = m_page->mainFrame().view();
1768     view->resize(viewSize);
1769     m_drawingArea->setNeedsDisplay();
1770
1771 #if USE(COORDINATED_GRAPHICS)
1772     if (view->useFixedLayout())
1773         sendViewportAttributesChanged(m_page->viewportArguments());
1774 #endif
1775 }
1776
1777 #if USE(COORDINATED_GRAPHICS)
1778 void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
1779 {
1780     FrameView* view = m_page->mainFrame().view();
1781     ASSERT(view && view->useFixedLayout());
1782
1783     // Viewport properties have no impact on zero sized fixed viewports.
1784     if (m_viewSize.isEmpty())
1785         return;
1786
1787     // Recalculate the recommended layout size, when the available size (device pixel) changes.
1788     Settings& settings = m_page->settings();
1789
1790     int minimumLayoutFallbackWidth = std::max(settings.layoutFallbackWidth(), m_viewSize.width());
1791
1792     // If unset  we use the viewport dimensions. This fits with the behavior of desktop browsers.
1793     int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
1794     int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
1795
1796     ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
1797
1798     // If no layout was done yet set contentFixedOrigin to (0,0).
1799     IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
1800
1801     // Put the width and height to the viewport width and height. In css units however.
1802     // Use FloatSize to avoid truncated values during scale.
1803     FloatSize contentFixedSize = m_viewSize;
1804
1805     contentFixedSize.scale(1 / attr.initialScale);
1806     view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
1807
1808     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
1809
1810     // This also takes care of the relayout.
1811     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
1812
1813 #if USE(COORDINATED_GRAPHICS)
1814     m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
1815 #else
1816     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
1817 #endif
1818 }
1819 #endif
1820
1821 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
1822 {
1823     FrameView* frameView = m_page->mainFrame().view();
1824
1825     ScrollPosition scrollPosition = frameView->scrollPosition();
1826     ScrollPosition maximumScrollPosition = frameView->maximumScrollPosition();
1827
1828     // If the current scroll position in a direction is the max scroll position 
1829     // we don't want to scroll at all.
1830     IntSize newScrollOffset;
1831     if (scrollPosition.x() < maximumScrollPosition.x())
1832         newScrollOffset.setWidth(scrollOffset.width());
1833     if (scrollPosition.y() < maximumScrollPosition.y())
1834         newScrollOffset.setHeight(scrollOffset.height());
1835
1836     if (newScrollOffset.isZero())
1837         return;
1838
1839     frameView->setScrollPosition(frameView->scrollPosition() + newScrollOffset);
1840 }
1841
1842 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
1843 {
1844 #if PLATFORM(MAC)
1845     FrameView* mainFrameView = m_page->mainFrame().view();
1846     LocalDefaultSystemAppearance localAppearance(mainFrameView ? mainFrameView->useDarkAppearance() : false);
1847 #endif
1848
1849     GraphicsContextStateSaver stateSaver(graphicsContext);
1850     graphicsContext.clip(rect);
1851
1852     m_mainFrame->coreFrame()->view()->paint(graphicsContext, rect);
1853 }
1854
1855 double WebPage::textZoomFactor() const
1856 {
1857     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1858     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1859         if (pluginView->handlesPageScaleFactor())
1860             return pluginView->pageScaleFactor();
1861         return pageScaleFactor();
1862     }
1863
1864     Frame* frame = m_mainFrame->coreFrame();
1865     if (!frame)
1866         return 1;
1867     return frame->textZoomFactor();
1868 }
1869
1870 void WebPage::setTextZoomFactor(double zoomFactor)
1871 {
1872     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1873     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1874         if (pluginView->handlesPageScaleFactor())
1875             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1876         else
1877             scalePage(zoomFactor, IntPoint());
1878         return;
1879     }
1880
1881     Frame* frame = m_mainFrame->coreFrame();
1882     if (!frame)
1883         return;
1884     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
1885 }
1886
1887 double WebPage::pageZoomFactor() const
1888 {
1889     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1890     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1891         if (pluginView->handlesPageScaleFactor())
1892             return pluginView->pageScaleFactor();
1893         return pageScaleFactor();
1894     }
1895
1896     Frame* frame = m_mainFrame->coreFrame();
1897     if (!frame)
1898         return 1;
1899     return frame->pageZoomFactor();
1900 }
1901
1902 void WebPage::setPageZoomFactor(double zoomFactor)
1903 {
1904     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1905     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1906         if (pluginView->handlesPageScaleFactor())
1907             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1908         else
1909             scalePage(zoomFactor, IntPoint());
1910         return;
1911     }
1912
1913     Frame* frame = m_mainFrame->coreFrame();
1914     if (!frame)
1915         return;
1916     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
1917 }
1918
1919 static void dumpHistoryItem(HistoryItem& item, size_t indent, bool isCurrentItem, StringBuilder& stringBuilder, const String& directoryName)
1920 {
1921     if (isCurrentItem)
1922         stringBuilder.appendLiteral("curr->  ");
1923     else {
1924         for (size_t i = 0; i < indent; ++i)
1925             stringBuilder.append(' ');
1926     }
1927
1928     auto url = item.url();
1929     if (url.protocolIs("file")) {
1930         size_t start = url.string().find(directoryName);
1931         if (start == WTF::notFound)
1932             start = 0;
1933         else
1934             start += directoryName.length();
1935         stringBuilder.appendLiteral("(file test):");
1936         stringBuilder.append(url.string().substring(start));
1937     } else
1938         stringBuilder.append(url.string());
1939     
1940     auto& target = item.target();
1941     if (target.length()) {
1942         stringBuilder.appendLiteral(" (in frame \"");
1943         stringBuilder.append(target);
1944         stringBuilder.appendLiteral("\")");
1945     }
1946     
1947     if (item.isTargetItem())
1948         stringBuilder.appendLiteral("  **nav target**");
1949     
1950     stringBuilder.append('\n');
1951     
1952     Vector<Ref<HistoryItem>> children;
1953     children.reserveInitialCapacity(item.children().size());
1954     for (auto& child : item.children())
1955         children.uncheckedAppend(child.copyRef());
1956     std::stable_sort(children.begin(), children.end(), [] (auto& a, auto& b) {
1957         return codePointCompare(a->target(), b->target()) < 0;
1958     });
1959     for (auto& child : children)
1960         dumpHistoryItem(child, indent + 4, false, stringBuilder, directoryName);
1961 }
1962
1963 String WebPage::dumpHistoryForTesting(const String& directory)
1964 {
1965     if (!m_page)
1966         return { };
1967
1968     auto& list = m_page->backForward();
1969     
1970     StringBuilder builder;
1971     int begin = -list.backCount();
1972     if (list.itemAtIndex(begin)->url() == WTF::blankURL())
1973         ++begin;
1974     for (int i = begin; i <= static_cast<int>(list.forwardCount()); ++i)
1975         dumpHistoryItem(*list.itemAtIndex(i), 8, !i, builder, directory);
1976     return builder.toString();
1977 }
1978
1979 void WebPage::clearHistory()
1980 {
1981     if (!m_page)
1982         return;
1983
1984     static_cast<WebBackForwardListProxy&>(m_page->backForward().client()).clear();
1985 }
1986
1987 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1988 {
1989     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1990     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1991         if (pluginView->handlesPageScaleFactor())
1992             pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
1993         else
1994             scalePage(pageZoomFactor, IntPoint());
1995         return;
1996     }
1997
1998     Frame* frame = m_mainFrame->coreFrame();
1999     if (!frame)
2000         return;
2001     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
2002 }
2003
2004 void WebPage::windowScreenDidChange(uint32_t displayID)
2005 {
2006     m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
2007
2008 #if PLATFORM(MAC)
2009     WebProcess::singleton().updatePageScreenProperties();
2010 #endif
2011 }
2012
2013 void WebPage::scalePage(double scale, const IntPoint& origin)
2014 {
2015     double totalScale = scale * viewScaleFactor();
2016     bool willChangeScaleFactor = totalScale != totalScaleFactor();
2017
2018 #if PLATFORM(IOS_FAMILY)
2019     if (willChangeScaleFactor) {
2020         if (!m_inDynamicSizeUpdate)
2021             m_dynamicSizeUpdateHistory.clear();
2022         m_scaleWasSetByUIProcess = false;
2023     }
2024 #endif
2025     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
2026     if (pluginView && pluginView->handlesPageScaleFactor()) {
2027         // If the main-frame plugin wants to handle the page scale factor, make sure to reset WebCore's page scale.
2028         // Otherwise, we can end up with an immutable but non-1 page scale applied by WebCore on top of whatever the plugin does.
2029         if (m_page->pageScaleFactor() != 1) {
2030             m_page->setPageScaleFactor(1, origin);
2031             for (auto* pluginView : m_pluginViews)
2032                 pluginView->pageScaleFactorDidChange();
2033         }
2034
2035         pluginView->setPageScaleFactor(totalScale, origin);
2036         return;
2037     }
2038
2039     m_page->setPageScaleFactor(totalScale, origin);
2040
2041     // We can't early return before setPageScaleFactor because the origin might be different.
2042     if (!willChangeScaleFactor)
2043         return;
2044
2045     for (auto* pluginView : m_pluginViews)
2046         pluginView->pageScaleFactorDidChange();
2047
2048 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
2049     m_drawingArea->deviceOrPageScaleFactorChanged();
2050 #endif
2051
2052     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
2053 }
2054
2055 void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
2056 {
2057     double totalScale = scale * viewScaleFactor();
2058     if (totalScale == totalScaleFactor())
2059         return;
2060
2061     IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
2062     double scaleRatio = scale / pageScaleFactor();
2063     scrollPositionAtNewScale.scale(scaleRatio);
2064     scalePage(scale, scrollPositionAtNewScale);
2065 }
2066
2067 double WebPage::totalScaleFactor() const
2068 {
2069     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
2070     if (pluginView && pluginView->handlesPageScaleFactor())
2071         return pluginView->pageScaleFactor();
2072
2073     return m_page->pageScaleFactor();
2074 }
2075
2076 double WebPage::pageScaleFactor() const
2077 {
2078     return totalScaleFactor() / viewScaleFactor();
2079 }
2080
2081 double WebPage::viewScaleFactor() const
2082 {
2083     return m_page->viewScaleFactor();
2084 }
2085
2086 void WebPage::scaleView(double scale)
2087 {
2088     if (viewScaleFactor() == scale)
2089         return;
2090
2091     float pageScale = pageScaleFactor();
2092
2093     IntPoint scrollPositionAtNewScale;
2094     if (FrameView* mainFrameView = m_page->mainFrame().view()) {
2095         double scaleRatio = scale / viewScaleFactor();
2096         scrollPositionAtNewScale = mainFrameView->scrollPosition();
2097         scrollPositionAtNewScale.scale(scaleRatio);
2098     }
2099
2100     m_page->setViewScaleFactor(scale);
2101     scalePage(pageScale, scrollPositionAtNewScale);
2102 }
2103
2104 void WebPage::setDeviceScaleFactor(float scaleFactor)
2105 {
2106     if (scaleFactor == m_page->deviceScaleFactor())
2107         return;
2108
2109     m_page->setDeviceScaleFactor(scaleFactor);
2110
2111     // Tell all our plug-in views that the device scale factor changed.
2112 #if PLATFORM(MAC)
2113     for (auto* pluginView : m_pluginViews)
2114         pluginView->setDeviceScaleFactor(scaleFactor);
2115
2116     updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor);
2117 #endif
2118
2119     if (findController().isShowingOverlay()) {
2120         // We must have updated layout to get the selection rects right.
2121         layoutIfNeeded();
2122         findController().deviceScaleFactorDidChange();
2123     }
2124
2125 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
2126     m_drawingArea->deviceOrPageScaleFactorChanged();
2127 #endif
2128 }
2129
2130 float WebPage::deviceScaleFactor() const
2131 {
2132     return m_page->deviceScaleFactor();
2133 }
2134
2135 void WebPage::accessibilitySettingsDidChange()
2136 {
2137     m_page->accessibilitySettingsDidChange();
2138 }
2139
2140 void WebPage::screenPropertiesDidChange()
2141 {
2142     m_page->setNeedsRecalcStyleInAllFrames();
2143 }
2144
2145 void WebPage::setUseFixedLayout(bool fixed)
2146 {
2147     // Do not overwrite current settings if initially setting it to false.
2148     if (m_useFixedLayout == fixed)
2149         return;
2150     m_useFixedLayout = fixed;
2151
2152 #if !PLATFORM(IOS_FAMILY)
2153     m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
2154 #endif
2155
2156     FrameView* view = mainFrameView();
2157     if (!view)
2158         return;
2159
2160     view->setUseFixedLayout(fixed);
2161     if (!fixed)
2162         setFixedLayoutSize(IntSize());
2163
2164     send(Messages::WebPageProxy::UseFixedLayoutDidChange(fixed));
2165 }
2166
2167 bool WebPage::setFixedLayoutSize(const IntSize& size)
2168 {
2169     FrameView* view = mainFrameView();
2170     if (!view || view->fixedLayoutSize() == size)
2171         return false;
2172
2173     LOG_WITH_STREAM(VisibleRects, stream << "WebPage " << m_identifier.toUInt64() << " setFixedLayoutSize " << size);
2174     view->setFixedLayoutSize(size);
2175
2176     send(Messages::WebPageProxy::FixedLayoutSizeDidChange(size));
2177     return true;
2178 }
2179
2180 IntSize WebPage::fixedLayoutSize() const
2181 {
2182     FrameView* view = mainFrameView();
2183     if (!view)
2184         return IntSize();
2185     return view->fixedLayoutSize();
2186 }
2187
2188 void WebPage::disabledAdaptationsDidChange(const OptionSet<DisabledAdaptations>& disabledAdaptations)
2189 {
2190 #if PLATFORM(IOS_FAMILY)
2191     if (m_viewportConfiguration.setDisabledAdaptations(disabledAdaptations))
2192         viewportConfigurationChanged();
2193 #else
2194     UNUSED_PARAM(disabledAdaptations);
2195 #endif
2196 }
2197
2198 void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments)
2199 {
2200 #if PLATFORM(IOS_FAMILY)
2201     if (m_viewportConfiguration.setViewportArguments(viewportArguments))
2202         viewportConfigurationChanged();
2203 #endif
2204
2205 #if USE(COORDINATED_GRAPHICS)
2206     FrameView* view = m_page->mainFrame().view();
2207     if (view && view->useFixedLayout())
2208         sendViewportAttributesChanged(viewportArguments);
2209     else
2210         m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
2211 #endif
2212
2213 #if !PLATFORM(IOS_FAMILY) && !USE(COORDINATED_GRAPHICS)
2214     UNUSED_PARAM(viewportArguments);
2215 #endif
2216 }
2217
2218 void WebPage::listenForLayoutMilestones(OptionSet<WebCore::LayoutMilestone> milestones)
2219 {
2220     if (!m_page)
2221         return;
2222     m_page->addLayoutMilestones(milestones);
2223 }
2224
2225 void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
2226 {
2227     m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
2228 }
2229     
2230 void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
2231 {
2232     m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
2233 }
2234     
2235 void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
2236 {
2237     m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
2238 }
2239
2240 void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
2241 {
2242     if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
2243         m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
2244 }
2245
2246 void WebPage::setPaginationMode(uint32_t mode)
2247 {
2248     Pagination pagination = m_page->pagination();
2249     pagination.mode = static_cast<Pagination::Mode>(mode);
2250     m_page->setPagination(pagination);
2251 }
2252
2253 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
2254 {
2255     Pagination pagination = m_page->pagination();
2256     pagination.behavesLikeColumns = behavesLikeColumns;
2257     m_page->setPagination(pagination);
2258 }
2259
2260 void WebPage::setPageLength(double pageLength)
2261 {
2262     Pagination pagination = m_page->pagination();
2263     pagination.pageLength = pageLength;
2264     m_page->setPagination(pagination);
2265 }
2266
2267 void WebPage::setGapBetweenPages(double gap)
2268 {
2269     Pagination pagination = m_page->pagination();
2270     pagination.gap = gap;
2271     m_page->setPagination(pagination);
2272 }
2273
2274 void WebPage::setPaginationLineGridEnabled(bool lineGridEnabled)
2275 {
2276     m_page->setPaginationLineGridEnabled(lineGridEnabled);
2277 }
2278
2279 void WebPage::postInjectedBundleMessage(const String& messageName, const UserData& userData)
2280 {
2281     auto& webProcess = WebProcess::singleton();
2282     InjectedBundle* injectedBundle = webProcess.injectedBundle();
2283     if (!injectedBundle)
2284         return;
2285
2286     injectedBundle->didReceiveMessageToPage(this, messageName, webProcess.transformHandlesToObjects(userData.object()).get());
2287 }
2288
2289 #if !PLATFORM(IOS_FAMILY)
2290
2291 void WebPage::setHeaderPageBanner(PageBanner* pageBanner)
2292 {
2293     if (m_headerBanner)
2294         m_headerBanner->detachFromPage();
2295
2296     m_headerBanner = pageBanner;
2297
2298     if (m_headerBanner)
2299         m_headerBanner->addToPage(PageBanner::Header, this);
2300 }
2301
2302 PageBanner* WebPage::headerPageBanner()
2303 {
2304     return m_headerBanner.get();
2305 }
2306
2307 void WebPage::setFooterPageBanner(PageBanner* pageBanner)
2308 {
2309     if (m_footerBanner)
2310         m_footerBanner->detachFromPage();
2311
2312     m_footerBanner = pageBanner;
2313
2314     if (m_footerBanner)
2315         m_footerBanner->addToPage(PageBanner::Footer, this);
2316 }
2317
2318 PageBanner* WebPage::footerPageBanner()
2319 {
2320     return m_footerBanner.get();
2321 }
2322
2323 void WebPage::hidePageBanners()
2324 {
2325     if (m_headerBanner)
2326         m_headerBanner->hide();
2327     if (m_footerBanner)
2328         m_footerBanner->hide();
2329 }
2330
2331 void WebPage::showPageBanners()
2332 {
2333     if (m_headerBanner)
2334         m_headerBanner->showIfHidden();
2335     if (m_footerBanner)
2336         m_footerBanner->showIfHidden();
2337 }
2338
2339 void WebPage::setHeaderBannerHeightForTesting(int height)
2340 {
2341     corePage()->setHeaderHeight(height);
2342 }
2343
2344 void WebPage::setFooterBannerHeightForTesting(int height)
2345 {
2346     corePage()->setFooterHeight(height);
2347 }
2348
2349 #endif // !PLATFORM(IOS_FAMILY)
2350
2351 void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, CallbackID callbackID)
2352 {
2353     SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
2354     snapshotOptions |= SnapshotOptionsShareable;
2355
2356     RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
2357
2358     ShareableBitmap::Handle handle;
2359     if (image)
2360         image->bitmap().createHandle(handle, SharedMemory::Protection::ReadOnly);
2361
2362     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
2363 }
2364
2365 RefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
2366 {
2367     IntRect snapshotRect = rect;
2368     IntSize bitmapSize = snapshotRect.size();
2369     if (options & SnapshotOptionsPrinting) {
2370         ASSERT(additionalScaleFactor == 1);
2371         Frame* coreFrame = m_mainFrame->coreFrame();
2372         if (!coreFrame)
2373             return nullptr;
2374         bitmapSize.setHeight(PrintContext::numberOfPages(*coreFrame, bitmapSize) * (bitmapSize.height() + 1) - 1);
2375     } else {
2376         double scaleFactor = additionalScaleFactor;
2377         if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
2378             scaleFactor *= corePage()->deviceScaleFactor();
2379         bitmapSize.scale(scaleFactor);
2380     }
2381
2382     return snapshotAtSize(rect, bitmapSize, options);
2383 }
2384
2385 void WebPage::paintSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, Frame& frame, FrameView& frameView, GraphicsContext& graphicsContext)
2386 {
2387     IntRect snapshotRect = rect;
2388     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
2389     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
2390     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
2391
2392     if (options & SnapshotOptionsPrinting) {
2393         PrintContext::spoolAllPagesWithBoundaries(frame, graphicsContext, snapshotRect.size());
2394         return;
2395     }
2396
2397     Color documentBackgroundColor = frameView.documentBackgroundColor();
2398     Color backgroundColor = (frame.settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView.baseBackgroundColor();
2399     graphicsContext.fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
2400
2401     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
2402         double deviceScaleFactor = frame.page()->deviceScaleFactor();
2403         graphicsContext.applyDeviceScaleFactor(deviceScaleFactor);
2404         scaleFactor /= deviceScaleFactor;
2405     }
2406
2407     graphicsContext.scale(scaleFactor);
2408     graphicsContext.translate(-snapshotRect.location());
2409
2410     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
2411     if (options & SnapshotOptionsExcludeSelectionHighlighting)
2412         shouldPaintSelection = FrameView::ExcludeSelection;
2413
2414     FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates;
2415     if (options & SnapshotOptionsInViewCoordinates)
2416         coordinateSpace = FrameView::ViewCoordinates;
2417
2418     frameView.paintContentsForSnapshot(graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
2419
2420     if (options & SnapshotOptionsPaintSelectionRectangle) {
2421         FloatRect selectionRectangle = frame.selection().selectionBounds();
2422         graphicsContext.setStrokeColor(Color(0xFF, 0, 0));
2423         graphicsContext.strokeRect(selectionRectangle, 1);
2424     }
2425 }
2426
2427 static ShareableBitmap::Configuration snapshotOptionsToBitmapConfiguration(SnapshotOptions options, WebPage& page)
2428 {
2429     ShareableBitmap::Configuration configuration;
2430 #if USE(CG)
2431     if (options & SnapshotOptionsUseScreenColorSpace)
2432         configuration.colorSpace.cgColorSpace = screenColorSpace(page.corePage()->mainFrame().view());
2433 #endif
2434     return configuration;
2435 }
2436
2437 RefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
2438 {
2439     Frame* coreFrame = m_mainFrame->coreFrame();
2440     if (!coreFrame)
2441         return nullptr;
2442
2443     FrameView* frameView = coreFrame->view();
2444     if (!frameView)
2445         return nullptr;
2446
2447     auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options), snapshotOptionsToBitmapConfiguration(options, *this));
2448     if (!snapshot)
2449         return nullptr;
2450     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2451     if (!graphicsContext)
2452         return nullptr;
2453
2454     paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, *graphicsContext);
2455
2456     return snapshot;
2457 }
2458
2459 RefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
2460 {
2461     Frame* coreFrame = m_mainFrame->coreFrame();
2462     if (!coreFrame)
2463         return nullptr;
2464
2465     FrameView* frameView = coreFrame->view();
2466     if (!frameView)
2467         return nullptr;
2468
2469     if (!node.renderer())
2470         return nullptr;
2471
2472     LayoutRect topLevelRect;
2473     IntRect snapshotRect = snappedIntRect(node.renderer()->paintingRootRect(topLevelRect));
2474     if (snapshotRect.isEmpty())
2475         return nullptr;
2476
2477     double scaleFactor = 1;
2478     IntSize snapshotSize = snapshotRect.size();
2479     unsigned maximumHeight = maximumPixelCount / snapshotSize.width();
2480     if (maximumHeight < static_cast<unsigned>(snapshotSize.height())) {
2481         scaleFactor = static_cast<double>(maximumHeight) / snapshotSize.height();
2482         snapshotSize = IntSize(snapshotSize.width() * scaleFactor, maximumHeight);
2483     }
2484
2485     auto snapshot = WebImage::create(snapshotSize, snapshotOptionsToImageOptions(options), snapshotOptionsToBitmapConfiguration(options, *this));
2486     if (!snapshot)
2487         return nullptr;
2488     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2489     if (!graphicsContext)
2490         return nullptr;
2491
2492     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
2493         double deviceScaleFactor = corePage()->deviceScaleFactor();
2494         graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
2495         scaleFactor /= deviceScaleFactor;
2496     }
2497
2498     graphicsContext->scale(scaleFactor);
2499     graphicsContext->translate(-snapshotRect.location());
2500
2501     Color savedBackgroundColor = frameView->baseBackgroundColor();
2502     frameView->setBaseBackgroundColor(Color::transparent);
2503     frameView->setNodeToDraw(&node);
2504
2505     frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, FrameView::ExcludeSelection, FrameView::DocumentCoordinates);
2506
2507     frameView->setBaseBackgroundColor(savedBackgroundColor);
2508     frameView->setNodeToDraw(nullptr);
2509
2510     return snapshot;
2511 }
2512
2513 void WebPage::pageDidScroll()
2514 {
2515 #if PLATFORM(IOS_FAMILY)
2516     if (!m_inDynamicSizeUpdate)
2517         m_dynamicSizeUpdateHistory.clear();
2518 #endif
2519     m_uiClient->pageDidScroll(this);
2520
2521     m_pageScrolledHysteresis.impulse();
2522
2523     send(Messages::WebPageProxy::PageDidScroll());
2524 }
2525
2526 void WebPage::pageStoppedScrolling()
2527 {
2528     // Maintain the current history item's scroll position up-to-date.
2529     if (Frame* frame = m_mainFrame->coreFrame())
2530         frame->loader().history().saveScrollPositionAndViewStateToItem(frame->loader().history().currentItem());
2531 }
2532
2533 #if ENABLE(CONTEXT_MENUS)
2534 WebContextMenu* WebPage::contextMenu()
2535 {
2536     if (!m_contextMenu)
2537         m_contextMenu = WebContextMenu::create(this);
2538     return m_contextMenu.get();
2539 }
2540
2541 WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
2542 {
2543     corePage()->contextMenuController().clearContextMenu();
2544
2545     // Simulate a mouse click to generate the correct menu.
2546     PlatformMouseEvent mousePressEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
2547     corePage()->userInputBridge().handleMousePressEvent(mousePressEvent);
2548     bool handled = corePage()->userInputBridge().handleContextMenuEvent(mousePressEvent, corePage()->mainFrame());
2549     auto* menu = handled ? contextMenu() : nullptr;
2550     PlatformMouseEvent mouseReleaseEvent(point, point, RightButton, PlatformEvent::MouseReleased, 1, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
2551     corePage()->userInputBridge().handleMouseReleaseEvent(mouseReleaseEvent);
2552
2553     return menu;
2554 }
2555 #endif
2556
2557 // Events 
2558
2559 static const WebEvent* g_currentEvent = 0;
2560
2561 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
2562 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
2563 // platform events passed to the event handler code.
2564 const WebEvent* WebPage::currentEvent()
2565 {
2566     return g_currentEvent;
2567 }
2568
2569 void WebPage::freezeLayerTree(LayerTreeFreezeReason reason)
2570 {
2571     auto oldReasons = m_layerTreeFreezeReasons.toRaw();
2572     UNUSED_PARAM(oldReasons);
2573     m_layerTreeFreezeReasons.add(reason);
2574     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);
2575     updateDrawingAreaLayerTreeFreezeState();
2576 }
2577
2578 void WebPage::unfreezeLayerTree(LayerTreeFreezeReason reason)
2579 {
2580     auto oldReasons = m_layerTreeFreezeReasons.toRaw();
2581     UNUSED_PARAM(oldReasons);
2582     m_layerTreeFreezeReasons.remove(reason);
2583     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);
2584     updateDrawingAreaLayerTreeFreezeState();
2585 }
2586
2587 void WebPage::updateDrawingAreaLayerTreeFreezeState()
2588 {
2589     if (!m_drawingArea)
2590         return;
2591     m_drawingArea->setLayerTreeStateIsFrozen(!!m_layerTreeFreezeReasons);
2592 }
2593
2594 void WebPage::callVolatilityCompletionHandlers(bool succeeded)
2595 {
2596     auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
2597     for (auto& completionHandler : completionHandlers)
2598         completionHandler(succeeded);
2599 }
2600
2601 void WebPage::layerVolatilityTimerFired()
2602 {
2603     Seconds newInterval = m_layerVolatilityTimer.repeatInterval() * 2.;
2604     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2605     if (didSucceed || newInterval > maximumLayerVolatilityTimerInterval) {
2606         m_layerVolatilityTimer.stop();
2607         if (didSucceed)
2608             RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Succeeded in marking layers as volatile");
2609         else
2610             RELEASE_LOG_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark layers as volatile within %gms", maximumLayerVolatilityTimerInterval.milliseconds());
2611         callVolatilityCompletionHandlers(didSucceed);
2612         return;
2613     }
2614
2615     RELEASE_LOG_ERROR_IF_ALLOWED(Layers, "layerVolatilityTimerFired: Failed to mark all layers as volatile, will retry in %g ms", newInterval.milliseconds());
2616     m_layerVolatilityTimer.startRepeating(newInterval);
2617 }
2618
2619 bool WebPage::markLayersVolatileImmediatelyIfPossible()
2620 {
2621     return !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
2622 }
2623
2624 void WebPage::markLayersVolatile(WTF::Function<void (bool)>&& completionHandler)
2625 {
2626     RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile:");
2627
2628     if (m_layerVolatilityTimer.isActive())
2629         m_layerVolatilityTimer.stop();
2630
2631     if (completionHandler)
2632         m_markLayersAsVolatileCompletionHandlers.append(WTFMove(completionHandler));
2633
2634     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2635     if (didSucceed || m_isSuspendedUnderLock) {
2636         if (didSucceed)
2637             RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Successfully marked layers as volatile");
2638         else {
2639             // 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.
2640             RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Did what we could to mark IOSurfaces as purgeable after locking the screen");
2641         }
2642         callVolatilityCompletionHandlers(didSucceed);
2643         return;
2644     }
2645
2646     RELEASE_LOG_IF_ALLOWED(Layers, "markLayersVolatile: Failed to mark all layers as volatile, will retry in %g ms", initialLayerVolatilityTimerInterval.milliseconds());
2647     m_layerVolatilityTimer.startRepeating(initialLayerVolatilityTimerInterval);
2648 }
2649
2650 void WebPage::cancelMarkLayersVolatile()
2651 {
2652     RELEASE_LOG_IF_ALLOWED(Layers, "cancelMarkLayersVolatile:");
2653     m_layerVolatilityTimer.stop();
2654     m_markLayersAsVolatileCompletionHandlers.clear();
2655 }
2656
2657 class CurrentEvent {
2658 public:
2659     explicit CurrentEvent(const WebEvent& event)
2660         : m_previousCurrentEvent(g_currentEvent)
2661     {
2662         g_currentEvent = &event;
2663     }
2664
2665     ~CurrentEvent()
2666     {
2667         g_currentEvent = m_previousCurrentEvent;
2668     }
2669
2670 private:
2671     const WebEvent* m_previousCurrentEvent;
2672 };
2673
2674 #if ENABLE(CONTEXT_MENU_EVENT)
2675 static bool isContextClick(const PlatformMouseEvent& event)
2676 {
2677 #if USE(APPKIT)
2678     return WebEventFactory::shouldBeHandledAsContextClick(event);
2679 #else
2680     return event.button() == WebCore::RightButton;
2681 #endif
2682 }
2683
2684 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
2685 {
2686     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
2687     constexpr OptionSet<HitTestRequest::RequestType> hitType { HitTestRequest::ReadOnly, HitTestRequest::Active, HitTestRequest::DisallowUserAgentShadowContent,  HitTestRequest::AllowChildFrameContent };
2688     HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point, hitType);
2689
2690     Frame* frame = &page->corePage()->mainFrame();
2691     if (result.innerNonSharedNode())
2692         frame = result.innerNonSharedNode()->document().frame();
2693
2694     bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, *frame);
2695 #if ENABLE(CONTEXT_MENUS)
2696     if (handled)
2697         page->contextMenu()->show();
2698 #endif
2699     return handled;
2700 }
2701
2702 void WebPage::contextMenuForKeyEvent()
2703 {
2704 #if ENABLE(CONTEXT_MENUS)
2705     corePage()->contextMenuController().clearContextMenu();
2706 #endif
2707
2708     Frame& frame = m_page->focusController().focusedOrMainFrame();
2709     bool handled = frame.eventHandler().sendContextMenuEventForKey();
2710 #if ENABLE(CONTEXT_MENUS)
2711     if (handled)
2712         contextMenu()->show();
2713 #else
2714     UNUSED_PARAM(handled);
2715 #endif
2716 }
2717 #endif
2718
2719 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page)
2720 {
2721     Frame& frame = page->corePage()->mainFrame();
2722     if (!frame.view())
2723         return false;
2724
2725     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
2726
2727     switch (platformMouseEvent.type()) {
2728         case PlatformEvent::MousePressed: {
2729 #if ENABLE(CONTEXT_MENUS)
2730             if (isContextClick(platformMouseEvent))
2731                 page->corePage()->contextMenuController().clearContextMenu();
2732 #endif
2733
2734             bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
2735 #if ENABLE(CONTEXT_MENU_EVENT)
2736             if (isContextClick(platformMouseEvent))
2737                 handled = handleContextMenuEvent(platformMouseEvent, page);
2738 #endif
2739             return handled;
2740         }
2741         case PlatformEvent::MouseReleased:
2742             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
2743
2744         case PlatformEvent::MouseMoved:
2745 #if PLATFORM(COCOA)
2746             // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
2747             // button is currently pressed. It is possible that neither of those things will be true since on
2748             // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
2749             // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
2750             // efficient scrollbars-only version of the event.
2751             if (!(page->corePage()->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)))
2752                 return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
2753 #endif
2754             return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
2755
2756         case PlatformEvent::MouseForceChanged:
2757         case PlatformEvent::MouseForceDown:
2758         case PlatformEvent::MouseForceUp:
2759             return page->corePage()->userInputBridge().handleMouseForceEvent(platformMouseEvent);
2760
2761         default:
2762             ASSERT_NOT_REACHED();
2763             return false;
2764     }
2765 }
2766
2767 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
2768 {
2769     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2770
2771     m_userActivity.impulse();
2772
2773     bool shouldHandleEvent = true;
2774
2775 #if ENABLE(CONTEXT_MENUS)
2776     // Don't try to handle any pending mouse events if a context menu is showing.
2777     if (m_isShowingContextMenu)
2778         shouldHandleEvent = false;
2779 #endif
2780 #if ENABLE(DRAG_SUPPORT)
2781     if (m_isStartingDrag)
2782         shouldHandleEvent = false;
2783 #endif
2784
2785     if (!shouldHandleEvent) {
2786         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
2787         return;
2788     }
2789
2790     bool handled = false;
2791
2792 #if !PLATFORM(IOS_FAMILY)
2793     if (!handled && m_headerBanner)
2794         handled = m_headerBanner->mouseEvent(mouseEvent);
2795     if (!handled && m_footerBanner)
2796         handled = m_footerBanner->mouseEvent(mouseEvent);
2797 #endif // !PLATFORM(IOS_FAMILY)
2798
2799     if (!handled) {
2800         CurrentEvent currentEvent(mouseEvent);
2801         handled = handleMouseEvent(mouseEvent, this);
2802     }
2803
2804     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
2805 }
2806
2807 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
2808 {
2809     Frame& frame = page->mainFrame();
2810     if (!frame.view())
2811         return false;
2812
2813     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
2814     return page->userInputBridge().handleWheelEvent(platformWheelEvent);
2815 }
2816
2817 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
2818 {
2819     m_userActivity.impulse();
2820
2821     CurrentEvent currentEvent(wheelEvent);
2822
2823     bool handled = handleWheelEvent(wheelEvent, m_page.get());
2824
2825     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
2826 }
2827
2828 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
2829 {
2830     if (!page->mainFrame().view())
2831         return false;
2832
2833     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
2834         return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
2835     return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
2836 }
2837
2838 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
2839 {
2840     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2841
2842     m_userActivity.impulse();
2843
2844     PlatformKeyboardEvent::setCurrentModifierState(platform(keyboardEvent).modifiers());
2845
2846     CurrentEvent currentEvent(keyboardEvent);
2847
2848     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
2849     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
2850     if (!handled)
2851         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
2852
2853     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
2854 }
2855
2856 void WebPage::validateCommand(const String& commandName, CallbackID callbackID)
2857 {
2858     bool isEnabled = false;
2859     int32_t state = 0;
2860     Frame& frame = m_page->focusController().focusedOrMainFrame();
2861     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
2862         isEnabled = pluginView->isEditingCommandEnabled(commandName);
2863     else {
2864         Editor::Command command = frame.editor().command(commandName);
2865         state = command.state();
2866         isEnabled = command.isSupported() && command.isEnabled();
2867     }
2868
2869     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
2870 }
2871
2872 void WebPage::executeEditCommand(const String& commandName, const String& argument)
2873 {
2874     executeEditingCommand(commandName, argument);
2875 }
2876
2877 void WebPage::setNeedsFontAttributes(bool needsFontAttributes)
2878 {
2879     if (m_needsFontAttributes == needsFontAttributes)
2880         return;
2881
2882     m_needsFontAttributes = needsFontAttributes;
2883
2884     if (m_needsFontAttributes)
2885         scheduleFullEditorStateUpdate();
2886 }
2887
2888 void WebPage::restoreSessionInternal(const Vector<BackForwardListItemState>& itemStates, WasRestoredByAPIRequest restoredByAPIRequest, WebBackForwardListProxy::OverwriteExistingItem overwrite)
2889 {
2890     // Since we're merely restoring HistoryItems from the UIProcess, there is no need to send HistoryItem update notifications back to the UIProcess.
2891     // Also, with process-swap on navigation, these updates may actually overwrite important state in the UIProcess such as the scroll position.
2892     SetForScope<void (*)(WebCore::HistoryItem&)> bypassHistoryItemUpdateNotifications(WebCore::notifyHistoryItemChanged, [](WebCore::HistoryItem&){});
2893     for (const auto& itemState : itemStates) {
2894         auto historyItem = toHistoryItem(itemState);
2895         historyItem->setWasRestoredFromSession(restoredByAPIRequest == WasRestoredByAPIRequest::Yes);
2896         static_cast<WebBackForwardListProxy&>(corePage()->backForward().client()).addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_identifier, overwrite);
2897     }
2898 }
2899
2900 void WebPage::restoreSession(const Vector<BackForwardListItemState>& itemStates)
2901 {
2902     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::Yes, WebBackForwardListProxy::OverwriteExistingItem::No);
2903 }
2904
2905 void WebPage::updateBackForwardListForReattach(const Vector<WebKit::BackForwardListItemState>& itemStates)
2906 {
2907     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::No, WebBackForwardListProxy::OverwriteExistingItem::Yes);
2908 }
2909
2910 void WebPage::setCurrentHistoryItemForReattach(WebKit::BackForwardListItemState&& itemState)
2911 {
2912     auto historyItem = toHistoryItem(itemState);
2913     auto& historyItemRef = historyItem.get();
2914     static_cast<WebBackForwardListProxy&>(corePage()->backForward().client()).addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_identifier, WebBackForwardListProxy::OverwriteExistingItem::Yes);
2915     corePage()->mainFrame().loader().history().setCurrentItem(historyItemRef);
2916 }
2917
2918 void WebPage::requestFontAttributesAtSelectionStart(CallbackID callbackID)
2919 {
2920     auto attributes = m_page->focusController().focusedOrMainFrame().editor().fontAttributesAtSelectionStart();
2921     send(Messages::WebPageProxy::FontAttributesCallback(attributes, callbackID));
2922 }
2923
2924 void WebPage::cancelGesturesBlockedOnSynchronousReplies()
2925 {
2926 #if ENABLE(IOS_TOUCH_EVENTS)
2927     if (auto reply = WTFMove(m_pendingSynchronousTouchEventReply))
2928         reply(true);
2929 #endif
2930
2931 #if PLATFORM(IOS_FAMILY)
2932     if (auto reply = WTFMove(m_pendingSynchronousPositionInformationReply))
2933         reply(InteractionInformationAtPosition::invalidInformation());
2934 #endif
2935 }
2936
2937 #if ENABLE(TOUCH_EVENTS)
2938 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
2939 {
2940     if (!page->mainFrame().view())
2941         return false;
2942
2943     return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
2944 }
2945 #endif
2946
2947 #if ENABLE(IOS_TOUCH_EVENTS)
2948 void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
2949 {
2950     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2951     m_lastInteractionLocation = touchEvent.position();
2952     CurrentEvent currentEvent(touchEvent);
2953     handled = handleTouchEvent(touchEvent, m_page.get());
2954     updatePotentialTapSecurityOrigin(touchEvent, handled);
2955 }
2956
2957 void WebPage::touchEventSync(const WebTouchEvent& touchEvent, CompletionHandler<void(bool)>&& reply)
2958 {
2959     // Avoid UIProcess hangs when the WebContent process is stuck on a sync IPC.
2960     if (IPC::UnboundedSynchronousIPCScope::hasOngoingUnboundedSyncIPC()) {
2961         RELEASE_LOG_ERROR_IF_ALLOWED(Process, "touchEventSync: Not processing because the process is stuck on unbounded sync IPC");
2962         return reply(true);
2963     }
2964
2965     m_pendingSynchronousTouchEventReply = WTFMove(reply);
2966
2967     EventDispatcher::TouchEventQueue queuedEvents;
2968     WebProcess::singleton().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
2969     dispatchAsynchronousTouchEvents(queuedEvents);
2970
2971     bool handled = true;
2972     dispatchTouchEvent(touchEvent, handled);
2973
2974     if (auto reply = WTFMove(m_pendingSynchronousTouchEventReply))
2975         reply(handled);
2976 }
2977
2978 void WebPage::resetPotentialTapSecurityOrigin()
2979 {
2980     m_potentialTapSecurityOrigin = nullptr;
2981 }
2982
2983 void WebPage::updatePotentialTapSecurityOrigin(const WebTouchEvent& touchEvent, bool wasHandled)
2984 {
2985     if (wasHandled)
2986         return;
2987
2988     if (!touchEvent.isPotentialTap())
2989         return;
2990
2991     if (touchEvent.type() != WebEvent::TouchStart)
2992         return;
2993
2994     auto& mainFrame = m_page->mainFrame();
2995     auto document = mainFrame.document();
2996     if (!document)
2997         return;
2998
2999     if (!document->handlingTouchEvent())
3000         return;
3001
3002     Frame* touchEventTargetFrame = &mainFrame;
3003     while (auto subframe = touchEventTargetFrame->eventHandler().touchEventTargetSubframe())
3004         touchEventTargetFrame = subframe;
3005
3006     auto& touches = touchEventTargetFrame->eventHandler().touches();
3007     if (touches.isEmpty())
3008         return;
3009
3010     ASSERT(touches.size() == 1);
3011
3012     if (auto targetDocument = touchEventTargetFrame->document())
3013         m_potentialTapSecurityOrigin = &targetDocument->securityOrigin();
3014 }
3015 #elif ENABLE(TOUCH_EVENTS)
3016 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
3017 {
3018     CurrentEvent currentEvent(touchEvent);
3019
3020     bool handled = handleTouchEvent(touchEvent, m_page.get());
3021
3022     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
3023 }
3024 #endif
3025
3026 #if ENABLE(POINTER_EVENTS)
3027 void WebPage::cancelPointer(WebCore::PointerID pointerId, const WebCore::IntPoint& documentPoint)
3028 {
3029     m_page->pointerCaptureController().cancelPointer(pointerId, documentPoint);
3030 }
3031
3032 void WebPage::touchWithIdentifierWasRemoved(WebCore::PointerID pointerId)
3033 {
3034     m_page->pointerCaptureController().touchWithIdentifierWasRemoved(pointerId);
3035 }
3036 #endif
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     RELEASE_LOG_IF_ALLOWED(Layers, "didCompletePageTransition: Did complete page transition");
3339
3340     bool isInitialEmptyDocument = !m_mainFrame;
3341     if (!isInitialEmptyDocument)
3342         unfreezeLayerTree(LayerTreeFreezeReason::ProcessSwap);
3343 }
3344
3345 void WebPage::show()
3346 {
3347     send(Messages::WebPageProxy::ShowPage());
3348 }
3349
3350 String WebPage::userAgent(const URL& webCoreURL) const
3351 {
3352     String userAgent = platformUserAgent(webCoreURL);
3353     if (!userAgent.isEmpty())
3354         return userAgent;
3355     return m_userAgent;
3356 }
3357
3358 void WebPage::setUserAgent(const String& userAgent)
3359 {
3360     if (m_userAgent == userAgent)
3361         return;
3362
3363     m_userAgent = userAgent;
3364
3365     if (m_page)
3366         m_page->userAgentChanged();
3367 }
3368
3369 void WebPage::suspendActiveDOMObjectsAndAnimations()
3370 {
3371     m_page->suspendActiveDOMObjectsAndAnimations();
3372 }
3373
3374 void WebPage::resumeActiveDOMObjectsAndAnimations()
3375 {
3376     m_page->resumeActiveDOMObjectsAndAnimations();
3377 }
3378
3379 IntPoint WebPage::screenToRootView(const IntPoint& point)
3380 {
3381     IntPoint windowPoint;
3382     sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
3383     return windowPoint;
3384 }
3385     
3386 IntRect WebPage::rootViewToScreen(const IntRect& rect)
3387 {
3388     IntRect screenRect;
3389     sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
3390     return screenRect;
3391 }
3392     
3393 IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
3394 {
3395     IntPoint windowPoint;
3396     sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point), Messages::WebPageProxy::AccessibilityScreenToRootView::Reply(windowPoint));
3397     return windowPoint;
3398 }
3399
3400 IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
3401 {
3402     IntRect screenRect;
3403     sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
3404     return screenRect;
3405 }
3406
3407 KeyboardUIMode WebPage::keyboardUIMode()
3408 {
3409     bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled();
3410     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
3411 }
3412
3413 void WebPage::runJavaScript(WebFrame* frame, RunJavaScriptParameters&& parameters, ContentWorldIdentifier worldIdentifier, CallbackID callbackID)
3414 {
3415     // NOTE: We need to be careful when running scripts that the objects we depend on don't
3416     // disappear during script execution.
3417
3418     if (!frame || !frame->coreFrame()) {
3419         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript: Page is in invalid state"_s }, callbackID));
3420         return;
3421     }
3422
3423     auto* world = m_userContentController->worldForIdentifier(worldIdentifier);
3424     if (!world) {
3425         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript: Cannot find specified content world"_s }, callbackID));
3426         return;
3427     }
3428
3429     auto resolveFunction = [protectedThis = makeRef(*this), this, world = makeRef(*world), frame = makeRef(*frame), callbackID](ValueOrException result) {
3430         RefPtr<SerializedScriptValue> serializedResultValue;
3431         if (result) {
3432             serializedResultValue = SerializedScriptValue::create(frame->jsContextForWorld(world.ptr()),
3433                 toRef(frame->coreFrame()->script().globalObject(world->coreWorld()), result.value()), nullptr);
3434         }
3435
3436         IPC::DataReference dataReference;
3437         if (serializedResultValue)
3438             dataReference = serializedResultValue->data();
3439
3440         Optional<ExceptionDetails> details;
3441         if (!result)
3442             details = result.error();
3443
3444         send(Messages::WebPageProxy::ScriptValueCallback(dataReference, details, callbackID));
3445     };
3446     
3447     if (RuntimeEnabledFeatures::sharedFeatures().isInAppBrowserPrivacyEnabled() && frame->isMainFrame() && hasNavigatedAwayFromAppBoundDomain() == NavigatedAwayFromAppBoundDomain::Yes) {
3448         send(Messages::WebPageProxy::ScriptValueCallback({ }, ExceptionDetails { "Unable to execute JavaScript"_s }, callbackID));
3449         return;
3450     }
3451
3452     JSLockHolder lock(commonVM());
3453     frame->coreFrame()->script().executeAsynchronousUserAgentScriptInWorld(world->coreWorld(), WTFMove(parameters), WTFMove(resolveFunction));
3454 }
3455
3456 void WebPage::runJavaScriptInMainFrameScriptWorld(RunJavaScriptParameters&& parameters, const std::pair<ContentWorldIdentifier, String>& worldData, CallbackID callbackID)
3457 {
3458     m_userContentController->addContentWorld(worldData);
3459     runJavaScript(mainWebFrame(), WTFMove(parameters), worldData.first, callbackID);
3460 }
3461
3462 void WebPage::runJavaScriptInFrame(FrameIdentifier frameID, const String& script, bool forceUserGesture, CallbackID callbackID)
3463 {
3464     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
3465     ASSERT(mainWebFrame() != frame);
3466     runJavaScript(frame, { script, false, WTF::nullopt, forceUserGesture }, pageContentWorldIdentifier(), callbackID);
3467 }
3468
3469 void WebPage::getContentsAsString(ContentAsStringIncludesChildFrames includeChildFrames, CallbackID callbackID)
3470 {
3471     switch (includeChildFrames) {
3472     case ContentAsStringIncludesChildFrames::No: {
3473         String resultString = m_mainFrame->contentsAsString();
3474         send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3475         break;
3476     }
3477     case ContentAsStringIncludesChildFrames::Yes: {
3478         StringBuilder builder;
3479         for (RefPtr<Frame> frame = m_mainFrame->coreFrame(); frame; frame = frame->tree().traverseNextRendered()) {
3480             if (auto* webFrame = WebFrame::fromCoreFrame(*frame)) {
3481                 if (!builder.isEmpty())
3482                     builder.appendLiteral("\n\n");
3483
3484                 builder.append(webFrame->contentsAsString());
3485             }
3486         }
3487
3488         send(Messages::WebPageProxy::StringCallback(builder.toString(), callbackID));
3489         break;
3490     }
3491     }
3492 }
3493
3494 #if ENABLE(MHTML)
3495 void WebPage::getContentsAsMHTMLData(CallbackID callbackID)
3496 {
3497     send(Messages::WebPageProxy::DataCallback({ MHTMLArchive::generateMHTMLData(m_page.get()) }, callbackID));
3498 }
3499 #endif
3500
3501 void WebPage::getRenderTreeExternalRepresentation(CallbackID callbackID)
3502 {
3503     String resultString = renderTreeExternalRepresentation();
3504     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3505 }
3506
3507 static Frame* frameWithSelection(Page* page)
3508 {
3509     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3510         if (frame->selection().isRange())
3511             return frame;
3512     }
3513
3514     return 0;
3515 }
3516
3517 void WebPage::getSelectionAsWebArchiveData(CallbackID callbackID)
3518 {
3519 #if PLATFORM(COCOA)
3520     RetainPtr<CFDataRef> data;
3521     if (Frame* frame = frameWithSelection(m_page.get()))
3522         data = LegacyWebArchive::createFromSelection(frame)->rawDataRepresentation();
3523 #endif
3524
3525     IPC::SharedBufferDataReference dataReference;
3526 #if PLATFORM(COCOA)
3527     if (data)
3528         dataReference = SharedBuffer::create(data.get());
3529 #endif
3530     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
3531 }
3532
3533 void WebPage::getSelectionOrContentsAsString(CallbackID callbackID)
3534 {
3535     WebFrame* focusedOrMainFrame = WebFrame::fromCoreFrame(m_page->focusController().focusedOrMainFrame());
3536     String resultString = focusedOrMainFrame->selectionAsString();
3537     if (resultString.isEmpty())
3538         resultString = focusedOrMainFrame->contentsAsString();
3539     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
3540 }
3541