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