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