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