699e7b1195923f6d5bca3d9dd530f218efe7f7c2
[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     if (shouldIncludePostLayoutData == IncludePostLayoutDataHint::Yes && result.isContentEditable) {
860         auto& postLayoutData = result.postLayoutData();
861         if (!selection.isNone()) {
862             Node* nodeToRemove;
863             if (auto* style = Editor::styleForSelectionStart(&frame, nodeToRemove)) {
864                 if (isFontWeightBold(style->fontCascade().weight()))
865                     postLayoutData.typingAttributes |= AttributeBold;
866                 if (isItalic(style->fontCascade().italic()))
867                     postLayoutData.typingAttributes |= AttributeItalics;
868
869                 RefPtr<EditingStyle> typingStyle = frame.selection().typingStyle();
870                 if (typingStyle && typingStyle->style()) {
871                     String value = typingStyle->style()->getPropertyValue(CSSPropertyWebkitTextDecorationsInEffect);
872                 if (value.contains("underline"))
873                     postLayoutData.typingAttributes |= AttributeUnderline;
874                 } else {
875                     if (style->textDecorationsInEffect() & TextDecorationUnderline)
876                         postLayoutData.typingAttributes |= AttributeUnderline;
877                 }
878
879                 if (style->visitedDependentColor(CSSPropertyColor).isValid())
880                     postLayoutData.textColor = style->visitedDependentColor(CSSPropertyColor);
881
882                 switch (style->textAlign()) {
883                 case RIGHT:
884                 case WEBKIT_RIGHT:
885                     postLayoutData.textAlignment = RightAlignment;
886                     break;
887                 case LEFT:
888                 case WEBKIT_LEFT:
889                     postLayoutData.textAlignment = LeftAlignment;
890                     break;
891                 case CENTER:
892                 case WEBKIT_CENTER:
893                     postLayoutData.textAlignment = CenterAlignment;
894                     break;
895                 case JUSTIFY:
896                     postLayoutData.textAlignment = JustifiedAlignment;
897                     break;
898                 case TASTART:
899                     postLayoutData.textAlignment = style->isLeftToRightDirection() ? LeftAlignment : RightAlignment;
900                     break;
901                 case TAEND:
902                     postLayoutData.textAlignment = style->isLeftToRightDirection() ? RightAlignment : LeftAlignment;
903                     break;
904                 }
905                 
906                 HTMLElement* enclosingListElement = enclosingList(selection.start().deprecatedNode());
907                 if (enclosingListElement) {
908                     if (is<HTMLUListElement>(*enclosingListElement))
909                         postLayoutData.enclosingListType = UnorderedList;
910                     else if (is<HTMLOListElement>(*enclosingListElement))
911                         postLayoutData.enclosingListType = OrderedList;
912                     else
913                         ASSERT_NOT_REACHED();
914                 } else
915                     postLayoutData.enclosingListType = NoList;
916
917                 if (nodeToRemove)
918                     nodeToRemove->remove();
919             }
920         }
921     }
922 #endif
923
924     platformEditorState(frame, result, shouldIncludePostLayoutData);
925
926     m_lastEditorStateWasContentEditable = result.isContentEditable ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
927
928     return result;
929 }
930
931 void WebPage::updateEditorStateAfterLayoutIfEditabilityChanged()
932 {
933     // FIXME: We should update EditorStateIsContentEditable to track whether the state is richly
934     // editable or plainttext-only.
935     if (m_lastEditorStateWasContentEditable == EditorStateIsContentEditable::Unset)
936         return;
937
938     Frame& frame = m_page->focusController().focusedOrMainFrame();
939     EditorStateIsContentEditable editorStateIsContentEditable = frame.selection().selection().isContentEditable() ? EditorStateIsContentEditable::Yes : EditorStateIsContentEditable::No;
940     if (m_lastEditorStateWasContentEditable != editorStateIsContentEditable)
941         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
942 }
943
944 String WebPage::renderTreeExternalRepresentation() const
945 {
946     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
947 }
948
949 String WebPage::renderTreeExternalRepresentationForPrinting() const
950 {
951     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextPrintingMode);
952 }
953
954 uint64_t WebPage::renderTreeSize() const
955 {
956     if (!m_page)
957         return 0;
958     return m_page->renderTreeSize();
959 }
960
961 void WebPage::setTracksRepaints(bool trackRepaints)
962 {
963     if (FrameView* view = mainFrameView())
964         view->setTracksRepaints(trackRepaints);
965 }
966
967 bool WebPage::isTrackingRepaints() const
968 {
969     if (FrameView* view = mainFrameView())
970         return view->isTrackingRepaints();
971
972     return false;
973 }
974
975 void WebPage::resetTrackedRepaints()
976 {
977     if (FrameView* view = mainFrameView())
978         view->resetTrackedRepaints();
979 }
980
981 Ref<API::Array> WebPage::trackedRepaintRects()
982 {
983     FrameView* view = mainFrameView();
984     if (!view)
985         return API::Array::create();
986
987     Vector<RefPtr<API::Object>> repaintRects;
988     repaintRects.reserveInitialCapacity(view->trackedRepaintRects().size());
989
990     for (const auto& repaintRect : view->trackedRepaintRects())
991         repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
992
993     return API::Array::create(WTFMove(repaintRects));
994 }
995
996 PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
997 {
998     if (!frame.document()->isPluginDocument())
999         return 0;
1000
1001     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame.document());
1002
1003     if (pluginDocument->focusedElement() != pluginDocument->pluginElement())
1004         return 0;
1005
1006     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1007     return pluginView;
1008 }
1009
1010 PluginView* WebPage::pluginViewForFrame(Frame* frame)
1011 {
1012     if (!frame->document()->isPluginDocument())
1013         return 0;
1014
1015     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document());
1016     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1017     return pluginView;
1018 }
1019
1020 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
1021 {
1022     Frame& frame = m_page->focusController().focusedOrMainFrame();
1023
1024     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
1025         pluginView->handleEditingCommand(commandName, argument);
1026         return;
1027     }
1028     
1029     frame.editor().command(commandName).execute(argument);
1030 }
1031
1032 void WebPage::setEditable(bool editable)
1033 {
1034     m_page->setEditable(editable);
1035     m_page->setTabKeyCyclesThroughElements(!editable);
1036     Frame& frame = m_page->focusController().focusedOrMainFrame();
1037     if (editable) {
1038         frame.editor().applyEditingStyleToBodyElement();
1039         // If the page is made editable and the selection is empty, set it to something.
1040         if (frame.selection().isNone())
1041             frame.selection().setSelectionFromNone();
1042     }
1043 }
1044
1045 bool WebPage::isEditingCommandEnabled(const String& commandName)
1046 {
1047     Frame& frame = m_page->focusController().focusedOrMainFrame();
1048
1049     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
1050         return pluginView->isEditingCommandEnabled(commandName);
1051     
1052     Editor::Command command = frame.editor().command(commandName);
1053     return command.isSupported() && command.isEnabled();
1054 }
1055     
1056 void WebPage::clearMainFrameName()
1057 {
1058     if (Frame* frame = mainFrame())
1059         frame->tree().clearName();
1060 }
1061
1062 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
1063 {
1064     m_drawingArea->setRootCompositingLayer(layer);
1065 }
1066
1067 void WebPage::exitAcceleratedCompositingMode()
1068 {
1069     m_drawingArea->setRootCompositingLayer(0);
1070 }
1071
1072 void WebPage::close()
1073 {
1074     if (m_isClosed)
1075         return;
1076
1077     m_isClosed = true;
1078
1079     // If there is still no URL, then we never loaded anything in this page, so nothing to report.
1080     if (!mainWebFrame()->url().isEmpty())
1081         reportUsedFeatures();
1082
1083     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::singleton().injectedBundle())
1084         WebProcess::singleton().injectedBundle()->willDestroyPage(this);
1085
1086     if (m_inspector) {
1087         m_inspector->disconnectFromPage();
1088         m_inspector = nullptr;
1089     }
1090
1091     m_page->inspectorController().disconnectAllFrontends();
1092
1093 #if ENABLE(FULLSCREEN_API)
1094     m_fullScreenManager = nullptr;
1095 #endif
1096
1097     if (m_activePopupMenu) {
1098         m_activePopupMenu->disconnectFromPage();
1099         m_activePopupMenu = nullptr;
1100     }
1101
1102     if (m_activeOpenPanelResultListener) {
1103         m_activeOpenPanelResultListener->disconnectFromPage();
1104         m_activeOpenPanelResultListener = nullptr;
1105     }
1106
1107 #if ENABLE(INPUT_TYPE_COLOR)
1108     if (m_activeColorChooser) {
1109         m_activeColorChooser->disconnectFromPage();
1110         m_activeColorChooser = nullptr;
1111     }
1112 #endif
1113
1114 #if PLATFORM(GTK)
1115     if (m_printOperation) {
1116         m_printOperation->disconnectFromPage();
1117         m_printOperation = nullptr;
1118     }
1119 #endif
1120
1121 #if ENABLE(VIDEO) && USE(GSTREAMER)
1122     if (m_installMediaPluginsCallback) {
1123         m_installMediaPluginsCallback->invalidate();
1124         m_installMediaPluginsCallback = nullptr;
1125     }
1126 #endif
1127
1128     m_sandboxExtensionTracker.invalidate();
1129
1130 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
1131     m_determinePrimarySnapshottedPlugInTimer.stop();
1132 #endif
1133
1134 #if ENABLE(CONTEXT_MENUS)
1135     m_contextMenuClient = std::make_unique<API::InjectedBundle::PageContextMenuClient>();
1136 #endif
1137     m_editorClient = std::make_unique<API::InjectedBundle::EditorClient>();
1138     m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
1139     m_loaderClient = std::make_unique<API::InjectedBundle::PageLoaderClient>();
1140     m_policyClient.initialize(0);
1141     m_resourceLoadClient = std::make_unique<API::InjectedBundle::ResourceLoadClient>();
1142     m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
1143 #if ENABLE(FULLSCREEN_API)
1144     m_fullScreenClient.initialize(0);
1145 #endif
1146
1147     m_printContext = nullptr;
1148     m_mainFrame->coreFrame()->loader().detachFromParent();
1149     m_drawingArea = nullptr;
1150
1151     DeferredPageDestructor::createDeferredPageDestructor(WTFMove(m_page), this);
1152
1153     bool isRunningModal = m_isRunningModal;
1154     m_isRunningModal = false;
1155
1156     // The WebPage can be destroyed by this call.
1157     WebProcess::singleton().removeWebPage(m_pageID);
1158
1159     WebProcess::singleton().updateActivePages();
1160
1161     if (isRunningModal)
1162         RunLoop::main().stop();
1163 }
1164
1165 void WebPage::tryClose()
1166 {
1167     SendStopResponsivenessTimer stopper;
1168
1169     if (!corePage()->userInputBridge().tryClosePage())
1170         return;
1171
1172     send(Messages::WebPageProxy::ClosePage(true));
1173 }
1174
1175 void WebPage::sendClose()
1176 {
1177     send(Messages::WebPageProxy::ClosePage(false));
1178 }
1179
1180 void WebPage::loadURLInFrame(const String& url, uint64_t frameID)
1181 {
1182     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1183     if (!frame)
1184         return;
1185
1186     frame->coreFrame()->loader().load(FrameLoadRequest(*frame->coreFrame(), ResourceRequest(URL(URL(), url)), ShouldOpenExternalURLsPolicy::ShouldNotAllow));
1187 }
1188
1189 #if !PLATFORM(COCOA)
1190 void WebPage::platformDidReceiveLoadParameters(const LoadParameters& loadParameters)
1191 {
1192 }
1193 #endif
1194
1195 void WebPage::loadRequest(const LoadParameters& loadParameters)
1196 {
1197     SendStopResponsivenessTimer stopper;
1198
1199     m_pendingNavigationID = loadParameters.navigationID;
1200
1201     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), loadParameters.sandboxExtensionHandle);
1202
1203     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1204     // to all the client to set up any needed state.
1205     m_loaderClient->willLoadURLRequest(*this, loadParameters.request, WebProcess::singleton().transformHandlesToObjects(loadParameters.userData.object()).get());
1206
1207     platformDidReceiveLoadParameters(loadParameters);
1208
1209     // Initate the load in WebCore.
1210     FrameLoadRequest frameLoadRequest { *m_mainFrame->coreFrame(), loadParameters.request, ShouldOpenExternalURLsPolicy::ShouldNotAllow };
1211     ShouldOpenExternalURLsPolicy externalURLsPolicy = static_cast<ShouldOpenExternalURLsPolicy>(loadParameters.shouldOpenExternalURLsPolicy);
1212     frameLoadRequest.setShouldOpenExternalURLsPolicy(externalURLsPolicy);
1213
1214     corePage()->userInputBridge().loadRequest(WTFMove(frameLoadRequest));
1215
1216     ASSERT(!m_pendingNavigationID);
1217 }
1218
1219 void WebPage::loadDataImpl(uint64_t navigationID, Ref<SharedBuffer>&& sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
1220 {
1221     SendStopResponsivenessTimer stopper;
1222
1223     m_pendingNavigationID = navigationID;
1224
1225     ResourceRequest request(baseURL);
1226     ResourceResponse response(URL(), MIMEType, sharedBuffer->size(), encodingName);
1227     SubstituteData substituteData(WTFMove(sharedBuffer), unreachableURL, response, SubstituteData::SessionHistoryVisibility::Hidden);
1228
1229     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
1230     // to all the client to set up any needed state.
1231     m_loaderClient->willLoadDataRequest(*this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), WebProcess::singleton().transformHandlesToObjects(userData.object()).get());
1232
1233     // Initate the load in WebCore.
1234     m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(*m_mainFrame->coreFrame(), request, ShouldOpenExternalURLsPolicy::ShouldNotAllow, substituteData));
1235 }
1236
1237 void WebPage::loadStringImpl(uint64_t navigationID, const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, const UserData& userData)
1238 {
1239     if (!htmlString.isNull() && htmlString.is8Bit()) {
1240         auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters8()), htmlString.length() * sizeof(LChar));
1241         loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, userData);
1242     } else {
1243         auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters16()), htmlString.length() * sizeof(UChar));
1244         loadDataImpl(navigationID, WTFMove(sharedBuffer), MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, userData);
1245     }
1246 }
1247
1248 void WebPage::loadData(const LoadParameters& loadParameters)
1249 {
1250     platformDidReceiveLoadParameters(loadParameters);
1251
1252     auto sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(loadParameters.data.data()), loadParameters.data.size());
1253     URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
1254     loadDataImpl(loadParameters.navigationID, WTFMove(sharedBuffer), loadParameters.MIMEType, loadParameters.encodingName, baseURL, URL(), loadParameters.userData);
1255 }
1256
1257 void WebPage::loadString(const LoadParameters& loadParameters)
1258 {
1259     platformDidReceiveLoadParameters(loadParameters);
1260
1261     URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
1262     loadStringImpl(loadParameters.navigationID, loadParameters.string, loadParameters.MIMEType, baseURL, URL(), loadParameters.userData);
1263 }
1264
1265 void WebPage::loadAlternateHTMLString(const LoadParameters& loadParameters)
1266 {
1267     platformDidReceiveLoadParameters(loadParameters);
1268
1269     URL baseURL = loadParameters.baseURLString.isEmpty() ? blankURL() : URL(URL(), loadParameters.baseURLString);
1270     URL unreachableURL = loadParameters.unreachableURLString.isEmpty() ? URL() : URL(URL(), loadParameters.unreachableURLString);
1271     URL provisionalLoadErrorURL = loadParameters.provisionalLoadErrorURLString.isEmpty() ? URL() : URL(URL(), loadParameters.provisionalLoadErrorURLString);
1272     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL(provisionalLoadErrorURL);
1273     loadStringImpl(0, loadParameters.string, ASCIILiteral("text/html"), baseURL, unreachableURL, loadParameters.userData);
1274     m_mainFrame->coreFrame()->loader().setProvisionalLoadErrorBeingHandledURL({ });
1275 }
1276
1277 void WebPage::navigateToPDFLinkWithSimulatedClick(const String& url, IntPoint documentPoint, IntPoint screenPoint)
1278 {
1279     Frame* mainFrame = m_mainFrame->coreFrame();
1280     Document* mainFrameDocument = mainFrame->document();
1281     if (!mainFrameDocument)
1282         return;
1283
1284     const int singleClick = 1;
1285     RefPtr<MouseEvent> mouseEvent = MouseEvent::create(eventNames().clickEvent, true, true, currentTime(), nullptr, singleClick, screenPoint.x(), screenPoint.y(), documentPoint.x(), documentPoint.y(),
1286 #if ENABLE(POINTER_LOCK)
1287         0, 0,
1288 #endif
1289         false, false, false, false, 0, nullptr, 0, WebCore::NoTap, nullptr);
1290
1291     mainFrame->loader().urlSelected(mainFrameDocument->completeURL(url), emptyString(), mouseEvent.get(), LockHistory::No, LockBackForwardList::No, ShouldSendReferrer::MaybeSendReferrer, ShouldOpenExternalURLsPolicy::ShouldNotAllow);
1292 }
1293
1294 void WebPage::stopLoadingFrame(uint64_t frameID)
1295 {
1296     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
1297     if (!frame)
1298         return;
1299
1300     corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
1301 }
1302
1303 void WebPage::stopLoading()
1304 {
1305     SendStopResponsivenessTimer stopper;
1306
1307     corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
1308 }
1309
1310 bool WebPage::defersLoading() const
1311 {
1312     return m_page->defersLoading();
1313 }
1314
1315 void WebPage::setDefersLoading(bool defersLoading)
1316 {
1317     m_page->setDefersLoading(defersLoading);
1318 }
1319
1320 void WebPage::reload(uint64_t navigationID, uint32_t reloadOptions, const SandboxExtension::Handle& sandboxExtensionHandle)
1321 {
1322     SendStopResponsivenessTimer stopper;
1323
1324     ASSERT(!m_mainFrame->coreFrame()->loader().frameHasLoaded() || !m_pendingNavigationID);
1325     m_pendingNavigationID = navigationID;
1326
1327     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
1328     corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), OptionSet<ReloadOption>::fromRaw(reloadOptions));
1329 }
1330
1331 void WebPage::goForward(uint64_t navigationID, uint64_t backForwardItemID)
1332 {
1333     SendStopResponsivenessTimer stopper;
1334
1335     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1336     ASSERT(item);
1337     if (!item)
1338         return;
1339
1340     ASSERT(!m_pendingNavigationID);
1341     m_pendingNavigationID = navigationID;
1342
1343     m_page->goToItem(*item, FrameLoadType::Forward);
1344 }
1345
1346 void WebPage::goBack(uint64_t navigationID, uint64_t backForwardItemID)
1347 {
1348     SendStopResponsivenessTimer stopper;
1349
1350     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1351     ASSERT(item);
1352     if (!item)
1353         return;
1354
1355     ASSERT(!m_pendingNavigationID);
1356     m_pendingNavigationID = navigationID;
1357
1358     m_page->goToItem(*item, FrameLoadType::Back);
1359 }
1360
1361 void WebPage::goToBackForwardItem(uint64_t navigationID, uint64_t backForwardItemID)
1362 {
1363     SendStopResponsivenessTimer stopper;
1364
1365     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1366     ASSERT(item);
1367     if (!item)
1368         return;
1369
1370     ASSERT(!m_pendingNavigationID);
1371     m_pendingNavigationID = navigationID;
1372
1373     m_page->goToItem(*item, FrameLoadType::IndexedBackForward);
1374 }
1375
1376 void WebPage::tryRestoreScrollPosition()
1377 {
1378     m_page->mainFrame().loader().history().restoreScrollPositionAndViewState();
1379 }
1380
1381 void WebPage::layoutIfNeeded()
1382 {
1383     if (m_mainFrame->coreFrame()->view())
1384         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
1385 }
1386
1387 WebPage* WebPage::fromCorePage(Page* page)
1388 {
1389     return &static_cast<WebChromeClient&>(page->chrome().client()).page();
1390 }
1391
1392 void WebPage::setSize(const WebCore::IntSize& viewSize)
1393 {
1394     if (m_viewSize == viewSize)
1395         return;
1396
1397     m_viewSize = viewSize;
1398     FrameView* view = m_page->mainFrame().view();
1399     view->resize(viewSize);
1400     m_drawingArea->setNeedsDisplay();
1401
1402 #if USE(COORDINATED_GRAPHICS)
1403     if (view->useFixedLayout())
1404         sendViewportAttributesChanged(m_page->viewportArguments());
1405 #endif
1406 }
1407
1408 #if USE(COORDINATED_GRAPHICS)
1409 void WebPage::sendViewportAttributesChanged(const ViewportArguments& viewportArguments)
1410 {
1411     FrameView* view = m_page->mainFrame().view();
1412     ASSERT(view && view->useFixedLayout());
1413
1414     // Viewport properties have no impact on zero sized fixed viewports.
1415     if (m_viewSize.isEmpty())
1416         return;
1417
1418     // Recalculate the recommended layout size, when the available size (device pixel) changes.
1419     Settings& settings = m_page->settings();
1420
1421     int minimumLayoutFallbackWidth = std::max(settings.layoutFallbackWidth(), m_viewSize.width());
1422
1423     // If unset  we use the viewport dimensions. This fits with the behavior of desktop browsers.
1424     int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
1425     int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
1426
1427     ViewportAttributes attr = computeViewportAttributes(viewportArguments, minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
1428
1429     // If no layout was done yet set contentFixedOrigin to (0,0).
1430     IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
1431
1432     // Put the width and height to the viewport width and height. In css units however.
1433     // Use FloatSize to avoid truncated values during scale.
1434     FloatSize contentFixedSize = m_viewSize;
1435
1436 #if ENABLE(CSS_DEVICE_ADAPTATION)
1437     // CSS viewport descriptors might be applied to already affected viewport size
1438     // if the page enables/disables stylesheets, so need to keep initial viewport size.
1439     view->setInitialViewportSize(roundedIntSize(contentFixedSize));
1440 #endif
1441
1442     contentFixedSize.scale(1 / attr.initialScale);
1443     view->setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
1444
1445     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
1446
1447     // This also takes care of the relayout.
1448     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
1449
1450 #if USE(COORDINATED_GRAPHICS_THREADED)
1451     m_drawingArea->didChangeViewportAttributes(WTFMove(attr));
1452 #else
1453     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
1454 #endif
1455 }
1456 #endif
1457
1458 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
1459 {
1460     FrameView* frameView = m_page->mainFrame().view();
1461
1462     ScrollPosition scrollPosition = frameView->scrollPosition();
1463     ScrollPosition maximumScrollPosition = frameView->maximumScrollPosition();
1464
1465     // If the current scroll position in a direction is the max scroll position 
1466     // we don't want to scroll at all.
1467     IntSize newScrollOffset;
1468     if (scrollPosition.x() < maximumScrollPosition.x())
1469         newScrollOffset.setWidth(scrollOffset.width());
1470     if (scrollPosition.y() < maximumScrollPosition.y())
1471         newScrollOffset.setHeight(scrollOffset.height());
1472
1473     if (newScrollOffset.isZero())
1474         return;
1475
1476     frameView->setScrollPosition(frameView->scrollPosition() + newScrollOffset);
1477 }
1478
1479 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
1480 {
1481     GraphicsContextStateSaver stateSaver(graphicsContext);
1482     graphicsContext.clip(rect);
1483
1484     m_mainFrame->coreFrame()->view()->paint(graphicsContext, rect);
1485 }
1486
1487 double WebPage::textZoomFactor() const
1488 {
1489     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1490     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1491         if (pluginView->handlesPageScaleFactor())
1492             return pluginView->pageScaleFactor();
1493         return pageScaleFactor();
1494     }
1495
1496     Frame* frame = m_mainFrame->coreFrame();
1497     if (!frame)
1498         return 1;
1499     return frame->textZoomFactor();
1500 }
1501
1502 void WebPage::setTextZoomFactor(double zoomFactor)
1503 {
1504     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1505     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1506         if (pluginView->handlesPageScaleFactor())
1507             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1508         else
1509             scalePage(zoomFactor, IntPoint());
1510         return;
1511     }
1512
1513     Frame* frame = m_mainFrame->coreFrame();
1514     if (!frame)
1515         return;
1516     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
1517 }
1518
1519 double WebPage::pageZoomFactor() const
1520 {
1521     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1522     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1523         if (pluginView->handlesPageScaleFactor())
1524             return pluginView->pageScaleFactor();
1525         return pageScaleFactor();
1526     }
1527
1528     Frame* frame = m_mainFrame->coreFrame();
1529     if (!frame)
1530         return 1;
1531     return frame->pageZoomFactor();
1532 }
1533
1534 void WebPage::setPageZoomFactor(double zoomFactor)
1535 {
1536     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1537     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1538         if (pluginView->handlesPageScaleFactor())
1539             pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1540         else
1541             scalePage(zoomFactor, IntPoint());
1542         return;
1543     }
1544
1545     Frame* frame = m_mainFrame->coreFrame();
1546     if (!frame)
1547         return;
1548     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
1549 }
1550
1551 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1552 {
1553     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1554     if (pluginView && pluginView->requiresUnifiedScaleFactor()) {
1555         if (pluginView->handlesPageScaleFactor())
1556             pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
1557         else
1558             scalePage(pageZoomFactor, IntPoint());
1559         return;
1560     }
1561
1562     Frame* frame = m_mainFrame->coreFrame();
1563     if (!frame)
1564         return;
1565     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
1566 }
1567
1568 void WebPage::windowScreenDidChange(uint32_t displayID)
1569 {
1570     m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
1571 }
1572
1573 void WebPage::scalePage(double scale, const IntPoint& origin)
1574 {
1575     double totalScale = scale * viewScaleFactor();
1576     bool willChangeScaleFactor = totalScale != totalScaleFactor();
1577
1578 #if PLATFORM(IOS)
1579     if (willChangeScaleFactor) {
1580         if (!m_inDynamicSizeUpdate)
1581             m_dynamicSizeUpdateHistory.clear();
1582         m_scaleWasSetByUIProcess = false;
1583     }
1584 #endif
1585     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1586     if (pluginView && pluginView->handlesPageScaleFactor()) {
1587         // If the main-frame plugin wants to handle the page scale factor, make sure to reset WebCore's page scale.
1588         // Otherwise, we can end up with an immutable but non-1 page scale applied by WebCore on top of whatever the plugin does.
1589         if (m_page->pageScaleFactor() != 1) {
1590             m_page->setPageScaleFactor(1, origin);
1591             for (auto* pluginView : m_pluginViews)
1592                 pluginView->pageScaleFactorDidChange();
1593         }
1594
1595         pluginView->setPageScaleFactor(totalScale, origin);
1596         return;
1597     }
1598
1599     m_page->setPageScaleFactor(totalScale, origin);
1600
1601     // We can't early return before setPageScaleFactor because the origin might be different.
1602     if (!willChangeScaleFactor)
1603         return;
1604
1605     for (auto* pluginView : m_pluginViews)
1606         pluginView->pageScaleFactorDidChange();
1607
1608 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
1609     m_drawingArea->deviceOrPageScaleFactorChanged();
1610 #endif
1611
1612     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
1613 }
1614
1615 void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
1616 {
1617     double totalScale = scale * viewScaleFactor();
1618     if (totalScale == totalScaleFactor())
1619         return;
1620
1621     IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
1622     double scaleRatio = scale / pageScaleFactor();
1623     scrollPositionAtNewScale.scale(scaleRatio);
1624     scalePage(scale, scrollPositionAtNewScale);
1625 }
1626
1627 double WebPage::totalScaleFactor() const
1628 {
1629     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1630     if (pluginView && pluginView->handlesPageScaleFactor())
1631         return pluginView->pageScaleFactor();
1632
1633     return m_page->pageScaleFactor();
1634 }
1635
1636 double WebPage::pageScaleFactor() const
1637 {
1638     return totalScaleFactor() / viewScaleFactor();
1639 }
1640
1641 double WebPage::viewScaleFactor() const
1642 {
1643     return m_page->viewScaleFactor();
1644 }
1645
1646 void WebPage::scaleView(double scale)
1647 {
1648     if (viewScaleFactor() == scale)
1649         return;
1650
1651     float pageScale = pageScaleFactor();
1652
1653     IntPoint scrollPositionAtNewScale;
1654     if (FrameView* mainFrameView = m_page->mainFrame().view()) {
1655         double scaleRatio = scale / viewScaleFactor();
1656         scrollPositionAtNewScale = mainFrameView->scrollPosition();
1657         scrollPositionAtNewScale.scale(scaleRatio);
1658     }
1659
1660     m_page->setViewScaleFactor(scale);
1661     scalePage(pageScale, scrollPositionAtNewScale);
1662 }
1663
1664 void WebPage::setDeviceScaleFactor(float scaleFactor)
1665 {
1666     if (scaleFactor == m_page->deviceScaleFactor())
1667         return;
1668
1669     m_page->setDeviceScaleFactor(scaleFactor);
1670
1671     // Tell all our plug-in views that the device scale factor changed.
1672 #if PLATFORM(MAC)
1673     for (auto* pluginView : m_pluginViews)
1674         pluginView->setDeviceScaleFactor(scaleFactor);
1675
1676     updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor);
1677 #endif
1678
1679     if (findController().isShowingOverlay()) {
1680         // We must have updated layout to get the selection rects right.
1681         layoutIfNeeded();
1682         findController().deviceScaleFactorDidChange();
1683     }
1684
1685 #if USE(COORDINATED_GRAPHICS) || USE(TEXTURE_MAPPER)
1686     m_drawingArea->deviceOrPageScaleFactorChanged();
1687 #endif
1688 }
1689
1690 float WebPage::deviceScaleFactor() const
1691 {
1692     return m_page->deviceScaleFactor();
1693 }
1694
1695 void WebPage::accessibilitySettingsDidChange()
1696 {
1697     m_page->accessibilitySettingsDidChange();
1698 }
1699
1700 void WebPage::setUseFixedLayout(bool fixed)
1701 {
1702     // Do not overwrite current settings if initially setting it to false.
1703     if (m_useFixedLayout == fixed)
1704         return;
1705     m_useFixedLayout = fixed;
1706
1707 #if !PLATFORM(IOS)
1708     m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
1709 #endif
1710 #if USE(COORDINATED_GRAPHICS)
1711     m_page->settings().setAcceleratedCompositingForFixedPositionEnabled(fixed);
1712     m_page->settings().setDelegatesPageScaling(fixed);
1713     m_page->settings().setScrollingCoordinatorEnabled(fixed);
1714 #endif
1715
1716 #if USE(COORDINATED_GRAPHICS) && ENABLE(SMOOTH_SCROLLING)
1717     // Delegated scrolling will be enabled when the FrameView is created if fixed layout is enabled.
1718     // Ensure we don't do animated scrolling in the WebProcess in that case.
1719     m_page->settings().setScrollAnimatorEnabled(!fixed);
1720 #endif
1721
1722     FrameView* view = mainFrameView();
1723     if (!view)
1724         return;
1725
1726 #if USE(COORDINATED_GRAPHICS)
1727     view->setDelegatesScrolling(fixed);
1728     view->setPaintsEntireContents(fixed);
1729 #endif
1730     view->setUseFixedLayout(fixed);
1731     if (!fixed)
1732         setFixedLayoutSize(IntSize());
1733
1734     send(Messages::WebPageProxy::UseFixedLayoutDidChange(fixed));
1735 }
1736
1737 bool WebPage::setFixedLayoutSize(const IntSize& size)
1738 {
1739     FrameView* view = mainFrameView();
1740     if (!view || view->fixedLayoutSize() == size)
1741         return false;
1742
1743     view->setFixedLayoutSize(size);
1744
1745     send(Messages::WebPageProxy::FixedLayoutSizeDidChange(size));
1746     return true;
1747 }
1748
1749 IntSize WebPage::fixedLayoutSize() const
1750 {
1751     FrameView* view = mainFrameView();
1752     if (!view)
1753         return IntSize();
1754     return view->fixedLayoutSize();
1755 }
1756
1757 void WebPage::viewportPropertiesDidChange(const ViewportArguments& viewportArguments)
1758 {
1759 #if PLATFORM(IOS)
1760     if (m_viewportConfiguration.setViewportArguments(viewportArguments))
1761         viewportConfigurationChanged();
1762 #endif
1763
1764 #if USE(COORDINATED_GRAPHICS)
1765     FrameView* view = m_page->mainFrame().view();
1766     if (view && view->useFixedLayout())
1767         sendViewportAttributesChanged(viewportArguments);
1768 #if USE(COORDINATED_GRAPHICS_THREADED)
1769     else
1770         m_drawingArea->didChangeViewportAttributes(ViewportAttributes());
1771 #endif
1772 #endif
1773
1774 #if !PLATFORM(IOS) && !USE(COORDINATED_GRAPHICS)
1775     UNUSED_PARAM(viewportArguments);
1776 #endif
1777 }
1778
1779 void WebPage::listenForLayoutMilestones(uint32_t milestones)
1780 {
1781     if (!m_page)
1782         return;
1783     m_page->addLayoutMilestones(static_cast<LayoutMilestones>(milestones));
1784 }
1785
1786 void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
1787 {
1788     m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
1789 }
1790     
1791 void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
1792 {
1793     m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1794 }
1795     
1796 void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
1797 {
1798     m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1799 }
1800
1801 void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
1802 {
1803     if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
1804         m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
1805 }
1806
1807 void WebPage::setPaginationMode(uint32_t mode)
1808 {
1809     Pagination pagination = m_page->pagination();
1810     pagination.mode = static_cast<Pagination::Mode>(mode);
1811     m_page->setPagination(pagination);
1812 }
1813
1814 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1815 {
1816     Pagination pagination = m_page->pagination();
1817     pagination.behavesLikeColumns = behavesLikeColumns;
1818     m_page->setPagination(pagination);
1819 }
1820
1821 void WebPage::setPageLength(double pageLength)
1822 {
1823     Pagination pagination = m_page->pagination();
1824     pagination.pageLength = pageLength;
1825     m_page->setPagination(pagination);
1826 }
1827
1828 void WebPage::setGapBetweenPages(double gap)
1829 {
1830     Pagination pagination = m_page->pagination();
1831     pagination.gap = gap;
1832     m_page->setPagination(pagination);
1833 }
1834
1835 void WebPage::setPaginationLineGridEnabled(bool lineGridEnabled)
1836 {
1837     m_page->setPaginationLineGridEnabled(lineGridEnabled);
1838 }
1839
1840 void WebPage::postInjectedBundleMessage(const String& messageName, const UserData& userData)
1841 {
1842     auto& webProcess = WebProcess::singleton();
1843     InjectedBundle* injectedBundle = webProcess.injectedBundle();
1844     if (!injectedBundle)
1845         return;
1846
1847     injectedBundle->didReceiveMessageToPage(this, messageName, webProcess.transformHandlesToObjects(userData.object()).get());
1848 }
1849
1850 #if !PLATFORM(IOS)
1851
1852 void WebPage::setHeaderPageBanner(PageBanner* pageBanner)
1853 {
1854     if (m_headerBanner)
1855         m_headerBanner->detachFromPage();
1856
1857     m_headerBanner = pageBanner;
1858
1859     if (m_headerBanner)
1860         m_headerBanner->addToPage(PageBanner::Header, this);
1861 }
1862
1863 PageBanner* WebPage::headerPageBanner()
1864 {
1865     return m_headerBanner.get();
1866 }
1867
1868 void WebPage::setFooterPageBanner(PageBanner* pageBanner)
1869 {
1870     if (m_footerBanner)
1871         m_footerBanner->detachFromPage();
1872
1873     m_footerBanner = pageBanner;
1874
1875     if (m_footerBanner)
1876         m_footerBanner->addToPage(PageBanner::Footer, this);
1877 }
1878
1879 PageBanner* WebPage::footerPageBanner()
1880 {
1881     return m_footerBanner.get();
1882 }
1883
1884 void WebPage::hidePageBanners()
1885 {
1886     if (m_headerBanner)
1887         m_headerBanner->hide();
1888     if (m_footerBanner)
1889         m_footerBanner->hide();
1890 }
1891
1892 void WebPage::showPageBanners()
1893 {
1894     if (m_headerBanner)
1895         m_headerBanner->showIfHidden();
1896     if (m_footerBanner)
1897         m_footerBanner->showIfHidden();
1898 }
1899
1900 void WebPage::setHeaderBannerHeightForTesting(int height)
1901 {
1902 #if ENABLE(RUBBER_BANDING)
1903     corePage()->addHeaderWithHeight(height);
1904 #endif
1905 }
1906
1907 void WebPage::setFooterBannerHeightForTesting(int height)
1908 {
1909 #if ENABLE(RUBBER_BANDING)
1910     corePage()->addFooterWithHeight(height);
1911 #endif
1912 }
1913
1914 #endif // !PLATFORM(IOS)
1915
1916 void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, CallbackID callbackID)
1917 {
1918     SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
1919     snapshotOptions |= SnapshotOptionsShareable;
1920
1921     RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
1922
1923     ShareableBitmap::Handle handle;
1924     if (image)
1925         image->bitmap().createHandle(handle, SharedMemory::Protection::ReadOnly);
1926
1927     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
1928 }
1929
1930 RefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
1931 {
1932     IntRect snapshotRect = rect;
1933     IntSize bitmapSize = snapshotRect.size();
1934     if (options & SnapshotOptionsPrinting) {
1935         ASSERT(additionalScaleFactor == 1);
1936         Frame* coreFrame = m_mainFrame->coreFrame();
1937         if (!coreFrame)
1938             return nullptr;
1939         bitmapSize.setHeight(PrintContext::numberOfPages(*coreFrame, bitmapSize) * (bitmapSize.height() + 1) - 1);
1940     } else {
1941         double scaleFactor = additionalScaleFactor;
1942         if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
1943             scaleFactor *= corePage()->deviceScaleFactor();
1944         bitmapSize.scale(scaleFactor);
1945     }
1946
1947     return snapshotAtSize(rect, bitmapSize, options);
1948 }
1949
1950 static void paintSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options, Frame& frame, FrameView& frameView, GraphicsContext& graphicsContext)
1951 {
1952     IntRect snapshotRect = rect;
1953     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
1954     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
1955     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
1956
1957     if (options & SnapshotOptionsPrinting) {
1958         PrintContext::spoolAllPagesWithBoundaries(frame, graphicsContext, snapshotRect.size());
1959         return;
1960     }
1961
1962     Color documentBackgroundColor = frameView.documentBackgroundColor();
1963     Color backgroundColor = (frame.settings().backgroundShouldExtendBeyondPage() && documentBackgroundColor.isValid()) ? documentBackgroundColor : frameView.baseBackgroundColor();
1964     graphicsContext.fillRect(IntRect(IntPoint(), bitmapSize), backgroundColor);
1965
1966     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
1967         double deviceScaleFactor = frame.page()->deviceScaleFactor();
1968         graphicsContext.applyDeviceScaleFactor(deviceScaleFactor);
1969         scaleFactor /= deviceScaleFactor;
1970     }
1971
1972     graphicsContext.scale(scaleFactor);
1973     graphicsContext.translate(-snapshotRect.x(), -snapshotRect.y());
1974
1975     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
1976     if (options & SnapshotOptionsExcludeSelectionHighlighting)
1977         shouldPaintSelection = FrameView::ExcludeSelection;
1978
1979     FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates;
1980     if (options & SnapshotOptionsInViewCoordinates)
1981         coordinateSpace = FrameView::ViewCoordinates;
1982
1983     frameView.paintContentsForSnapshot(graphicsContext, snapshotRect, shouldPaintSelection, coordinateSpace);
1984
1985     if (options & SnapshotOptionsPaintSelectionRectangle) {
1986         FloatRect selectionRectangle = frame.selection().selectionBounds();
1987         graphicsContext.setStrokeColor(Color(0xFF, 0, 0));
1988         graphicsContext.strokeRect(selectionRectangle, 1);
1989     }
1990 }
1991
1992 RefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
1993 {
1994     Frame* coreFrame = m_mainFrame->coreFrame();
1995     if (!coreFrame)
1996         return nullptr;
1997
1998     FrameView* frameView = coreFrame->view();
1999     if (!frameView)
2000         return nullptr;
2001
2002     auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
2003     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2004
2005     paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, *graphicsContext);
2006
2007     return snapshot;
2008 }
2009
2010 #if USE(CF)
2011 RetainPtr<CFDataRef> WebPage::pdfSnapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
2012 {
2013     Frame* coreFrame = m_mainFrame->coreFrame();
2014     if (!coreFrame)
2015         return nullptr;
2016
2017     FrameView* frameView = coreFrame->view();
2018     if (!frameView)
2019         return nullptr;
2020
2021     auto data = adoptCF(CFDataCreateMutable(kCFAllocatorDefault, 0));
2022
2023 #if USE(CG)
2024     auto dataConsumer = adoptCF(CGDataConsumerCreateWithCFData(data.get()));
2025     auto mediaBox = CGRectMake(0, 0, bitmapSize.width(), bitmapSize.height());
2026     auto pdfContext = adoptCF(CGPDFContextCreate(dataConsumer.get(), &mediaBox, nullptr));
2027
2028     CGPDFContextBeginPage(pdfContext.get(), nullptr);
2029
2030     GraphicsContext graphicsContext { pdfContext.get() };
2031     graphicsContext.scale({ 1, -1 });
2032     graphicsContext.translate(0, -bitmapSize.height());
2033     paintSnapshotAtSize(rect, bitmapSize, options, *coreFrame, *frameView, graphicsContext);
2034
2035     CGPDFContextEndPage(pdfContext.get());
2036     CGPDFContextClose(pdfContext.get());
2037 #endif
2038
2039     return WTFMove(data);
2040 }
2041 #endif
2042
2043 RefPtr<WebImage> WebPage::snapshotNode(WebCore::Node& node, SnapshotOptions options, unsigned maximumPixelCount)
2044 {
2045     Frame* coreFrame = m_mainFrame->coreFrame();
2046     if (!coreFrame)
2047         return nullptr;
2048
2049     FrameView* frameView = coreFrame->view();
2050     if (!frameView)
2051         return nullptr;
2052
2053     if (!node.renderer())
2054         return nullptr;
2055
2056     LayoutRect topLevelRect;
2057     IntRect snapshotRect = snappedIntRect(node.renderer()->paintingRootRect(topLevelRect));
2058     if (snapshotRect.isEmpty())
2059         return nullptr;
2060
2061     double scaleFactor = 1;
2062     IntSize snapshotSize = snapshotRect.size();
2063     unsigned maximumHeight = maximumPixelCount / snapshotSize.width();
2064     if (maximumHeight < static_cast<unsigned>(snapshotSize.height())) {
2065         scaleFactor = static_cast<double>(maximumHeight) / snapshotSize.height();
2066         snapshotSize = IntSize(snapshotSize.width() * scaleFactor, maximumHeight);
2067     }
2068
2069     auto snapshot = WebImage::create(snapshotSize, snapshotOptionsToImageOptions(options));
2070
2071     auto graphicsContext = snapshot->bitmap().createGraphicsContext();
2072
2073     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
2074         double deviceScaleFactor = corePage()->deviceScaleFactor();
2075         graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
2076         scaleFactor /= deviceScaleFactor;
2077     }
2078
2079     graphicsContext->scale(scaleFactor);
2080     graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
2081
2082     Color savedBackgroundColor = frameView->baseBackgroundColor();
2083     frameView->setBaseBackgroundColor(Color::transparent);
2084     frameView->setNodeToDraw(&node);
2085
2086     frameView->paintContentsForSnapshot(*graphicsContext, snapshotRect, FrameView::ExcludeSelection, FrameView::DocumentCoordinates);
2087
2088     frameView->setBaseBackgroundColor(savedBackgroundColor);
2089     frameView->setNodeToDraw(nullptr);
2090
2091     return snapshot;
2092 }
2093
2094 void WebPage::pageDidScroll()
2095 {
2096 #if PLATFORM(IOS)
2097     if (!m_inDynamicSizeUpdate)
2098         m_dynamicSizeUpdateHistory.clear();
2099 #endif
2100     m_uiClient->pageDidScroll(this);
2101
2102     m_pageScrolledHysteresis.impulse();
2103
2104     send(Messages::WebPageProxy::PageDidScroll());
2105 }
2106
2107 void WebPage::pageStoppedScrolling()
2108 {
2109     // Maintain the current history item's scroll position up-to-date.
2110     if (Frame* frame = m_mainFrame->coreFrame())
2111         frame->loader().history().saveScrollPositionAndViewStateToItem(frame->loader().history().currentItem());
2112 }
2113
2114 #if USE(COORDINATED_GRAPHICS)
2115 void WebPage::pageDidRequestScroll(const IntPoint& point)
2116 {
2117 #if USE(COORDINATED_GRAPHICS_THREADED)
2118     drawingArea()->scroll(IntRect(point, IntSize()), IntSize());
2119 #endif
2120 }
2121 #endif
2122
2123 #if ENABLE(CONTEXT_MENUS)
2124 WebContextMenu* WebPage::contextMenu()
2125 {
2126     if (!m_contextMenu)
2127         m_contextMenu = WebContextMenu::create(this);
2128     return m_contextMenu.get();
2129 }
2130
2131 WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
2132 {
2133     corePage()->contextMenuController().clearContextMenu();
2134
2135     // Simulate a mouse click to generate the correct menu.
2136     PlatformMouseEvent mousePressEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, WebCore::NoTap);
2137     corePage()->userInputBridge().handleMousePressEvent(mousePressEvent);
2138     bool handled = corePage()->userInputBridge().handleContextMenuEvent(mousePressEvent, corePage()->mainFrame());
2139     auto* menu = handled ? contextMenu() : nullptr;
2140     PlatformMouseEvent mouseReleaseEvent(point, point, RightButton, PlatformEvent::MouseReleased, 1, false, false, false, false, currentTime(), WebCore::ForceAtClick, WebCore::NoTap);
2141     corePage()->userInputBridge().handleMouseReleaseEvent(mouseReleaseEvent);
2142
2143     return menu;
2144 }
2145 #endif
2146
2147 // Events 
2148
2149 static const WebEvent* g_currentEvent = 0;
2150
2151 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
2152 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
2153 // platform events passed to the event handler code.
2154 const WebEvent* WebPage::currentEvent()
2155 {
2156     return g_currentEvent;
2157 }
2158
2159 void WebPage::setLayerTreeStateIsFrozen(bool frozen)
2160 {
2161     auto* drawingArea = this->drawingArea();
2162     if (!drawingArea)
2163         return;
2164
2165     drawingArea->setLayerTreeStateIsFrozen(frozen);
2166 }
2167
2168 void WebPage::callVolatilityCompletionHandlers()
2169 {
2170     auto completionHandlers = WTFMove(m_markLayersAsVolatileCompletionHandlers);
2171     for (auto& completionHandler : completionHandlers)
2172         completionHandler();
2173 }
2174
2175 void WebPage::layerVolatilityTimerFired()
2176 {
2177     Seconds newInterval = m_layerVolatilityTimer.repeatInterval() * 2.;
2178     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2179     if (didSucceed || newInterval > maximumLayerVolatilityTimerInterval) {
2180         m_layerVolatilityTimer.stop();
2181         RELEASE_LOG_IF_ALLOWED("%p - WebPage - Attempted to mark layers as volatile, success? %d", this, didSucceed);
2182         callVolatilityCompletionHandlers();
2183         return;
2184     }
2185
2186     RELEASE_LOG_ERROR_IF_ALLOWED("%p - WebPage - Failed to mark all layers as volatile, will retry in %g ms", this, newInterval.value() * 1000);
2187     m_layerVolatilityTimer.startRepeating(newInterval);
2188 }
2189
2190 bool WebPage::markLayersVolatileImmediatelyIfPossible()
2191 {
2192     return !drawingArea() || drawingArea()->markLayersVolatileImmediatelyIfPossible();
2193 }
2194
2195 void WebPage::markLayersVolatile(WTF::Function<void ()>&& completionHandler)
2196 {
2197     RELEASE_LOG_IF_ALLOWED("%p - WebPage::markLayersVolatile()", this);
2198
2199     if (m_layerVolatilityTimer.isActive())
2200         m_layerVolatilityTimer.stop();
2201
2202     if (completionHandler)
2203         m_markLayersAsVolatileCompletionHandlers.append(WTFMove(completionHandler));
2204
2205     bool didSucceed = markLayersVolatileImmediatelyIfPossible();
2206     if (didSucceed || m_isSuspendedUnderLock) {
2207         if (didSucceed)
2208             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Successfully marked layers as volatile", this);
2209         else {
2210             // 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.
2211             RELEASE_LOG_IF_ALLOWED("%p - WebPage - Did what we could to mark IOSurfaces as purgeable after locking the screen", this);
2212         }
2213         callVolatilityCompletionHandlers();
2214         return;
2215     }
2216
2217     RELEASE_LOG_IF_ALLOWED("%p - Failed to mark all layers as volatile, will retry in %g ms", this, initialLayerVolatilityTimerInterval.value() * 1000);
2218     m_layerVolatilityTimer.startRepeating(initialLayerVolatilityTimerInterval);
2219 }
2220
2221 void WebPage::cancelMarkLayersVolatile()
2222 {
2223     RELEASE_LOG_IF_ALLOWED("%p - WebPage::cancelMarkLayersVolatile()", this);
2224     m_layerVolatilityTimer.stop();
2225     m_markLayersAsVolatileCompletionHandlers.clear();
2226 }
2227
2228 class CurrentEvent {
2229 public:
2230     explicit CurrentEvent(const WebEvent& event)
2231         : m_previousCurrentEvent(g_currentEvent)
2232     {
2233         g_currentEvent = &event;
2234     }
2235
2236     ~CurrentEvent()
2237     {
2238         g_currentEvent = m_previousCurrentEvent;
2239     }
2240
2241 private:
2242     const WebEvent* m_previousCurrentEvent;
2243 };
2244
2245 #if ENABLE(CONTEXT_MENUS)
2246 static bool isContextClick(const PlatformMouseEvent& event)
2247 {
2248 #if PLATFORM(COCOA)
2249     return WebEventFactory::shouldBeHandledAsContextClick(event);
2250 #else
2251     return event.button() == WebCore::RightButton;
2252 #endif
2253 }
2254
2255 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
2256 {
2257     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
2258     HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point);
2259
2260     Frame* frame = &page->corePage()->mainFrame();
2261     if (result.innerNonSharedNode())
2262         frame = result.innerNonSharedNode()->document().frame();
2263
2264     bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, *frame);
2265     if (handled)
2266         page->contextMenu()->show();
2267
2268     return handled;
2269 }
2270
2271 void WebPage::contextMenuForKeyEvent()
2272 {
2273     corePage()->contextMenuController().clearContextMenu();
2274
2275     Frame& frame = m_page->focusController().focusedOrMainFrame();
2276     bool handled = frame.eventHandler().sendContextMenuEventForKey();
2277     if (handled)
2278         contextMenu()->show();
2279 }
2280 #endif
2281
2282 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page)
2283 {
2284     Frame& frame = page->corePage()->mainFrame();
2285     if (!frame.view())
2286         return false;
2287
2288     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
2289
2290     switch (platformMouseEvent.type()) {
2291         case PlatformEvent::MousePressed: {
2292 #if ENABLE(CONTEXT_MENUS)
2293             if (isContextClick(platformMouseEvent))
2294                 page->corePage()->contextMenuController().clearContextMenu();
2295 #endif
2296
2297             bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
2298 #if ENABLE(CONTEXT_MENUS)
2299             if (isContextClick(platformMouseEvent))
2300                 handled = handleContextMenuEvent(platformMouseEvent, page);
2301 #endif
2302             return handled;
2303         }
2304         case PlatformEvent::MouseReleased:
2305             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
2306
2307         case PlatformEvent::MouseMoved:
2308 #if PLATFORM(COCOA)
2309             // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
2310             // button is currently pressed. It is possible that neither of those things will be true since on
2311             // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
2312             // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
2313             // efficient scrollbars-only version of the event.
2314             if (!(page->corePage()->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton)))
2315                 return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
2316 #endif
2317             return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
2318
2319         case PlatformEvent::MouseForceChanged:
2320         case PlatformEvent::MouseForceDown:
2321         case PlatformEvent::MouseForceUp:
2322             return page->corePage()->userInputBridge().handleMouseForceEvent(platformMouseEvent);
2323
2324         default:
2325             ASSERT_NOT_REACHED();
2326             return false;
2327     }
2328 }
2329
2330 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
2331 {
2332     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2333
2334     m_userActivityHysteresis.impulse();
2335
2336     bool shouldHandleEvent = true;
2337
2338 #if ENABLE(CONTEXT_MENUS)
2339     // Don't try to handle any pending mouse events if a context menu is showing.
2340     if (m_isShowingContextMenu)
2341         shouldHandleEvent = false;
2342 #endif
2343 #if ENABLE(DRAG_SUPPORT)
2344     if (m_isStartingDrag)
2345         shouldHandleEvent = false;
2346 #endif
2347
2348     if (!shouldHandleEvent) {
2349         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
2350         return;
2351     }
2352
2353     bool handled = false;
2354
2355 #if !PLATFORM(IOS)
2356     if (!handled && m_headerBanner)
2357         handled = m_headerBanner->mouseEvent(mouseEvent);
2358     if (!handled && m_footerBanner)
2359         handled = m_footerBanner->mouseEvent(mouseEvent);
2360 #endif // !PLATFORM(IOS)
2361
2362     if (!handled) {
2363         CurrentEvent currentEvent(mouseEvent);
2364         handled = handleMouseEvent(mouseEvent, this);
2365     }
2366
2367     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
2368 }
2369
2370 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
2371 {
2372     Frame& frame = page->mainFrame();
2373     if (!frame.view())
2374         return false;
2375
2376     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
2377     return page->userInputBridge().handleWheelEvent(platformWheelEvent);
2378 }
2379
2380 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
2381 {
2382     m_userActivityHysteresis.impulse();
2383
2384     CurrentEvent currentEvent(wheelEvent);
2385
2386     bool handled = handleWheelEvent(wheelEvent, m_page.get());
2387
2388     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
2389 }
2390
2391 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
2392 {
2393     if (!page->mainFrame().view())
2394         return false;
2395
2396     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
2397         return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
2398     return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
2399 }
2400
2401 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
2402 {
2403     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2404
2405     m_userActivityHysteresis.impulse();
2406
2407     CurrentEvent currentEvent(keyboardEvent);
2408
2409     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
2410     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
2411     if (!handled)
2412         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
2413
2414     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
2415 }
2416
2417 void WebPage::validateCommand(const String& commandName, CallbackID callbackID)
2418 {
2419     bool isEnabled = false;
2420     int32_t state = 0;
2421     Frame& frame = m_page->focusController().focusedOrMainFrame();
2422     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
2423         isEnabled = pluginView->isEditingCommandEnabled(commandName);
2424     else {
2425         Editor::Command command = frame.editor().command(commandName);
2426         state = command.state();
2427         isEnabled = command.isSupported() && command.isEnabled();
2428     }
2429
2430     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
2431 }
2432
2433 void WebPage::executeEditCommand(const String& commandName, const String& argument)
2434 {
2435     executeEditingCommand(commandName, argument);
2436 }
2437
2438 void WebPage::restoreSessionInternal(const Vector<BackForwardListItemState>& itemStates, WasRestoredByAPIRequest restoredByAPIRequest)
2439 {
2440     for (const auto& itemState : itemStates) {
2441         auto historyItem = toHistoryItem(itemState.pageState);
2442         historyItem->setWasRestoredFromSession(restoredByAPIRequest == WasRestoredByAPIRequest::Yes);
2443         static_cast<WebBackForwardListProxy*>(corePage()->backForward().client())->addItemFromUIProcess(itemState.identifier, WTFMove(historyItem), m_pageID);
2444     }
2445 }
2446
2447 void WebPage::restoreSession(const Vector<BackForwardListItemState>& itemStates)
2448 {
2449     restoreSessionInternal(itemStates, WasRestoredByAPIRequest::Yes);
2450 }
2451
2452 #if ENABLE(TOUCH_EVENTS)
2453 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
2454 {
2455     if (!page->mainFrame().view())
2456         return false;
2457
2458     return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
2459 }
2460 #endif
2461
2462 #if ENABLE(IOS_TOUCH_EVENTS)
2463 void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
2464 {
2465     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2466
2467     m_lastInteractionLocation = touchEvent.position();
2468     CurrentEvent currentEvent(touchEvent);
2469     handled = handleTouchEvent(touchEvent, m_page.get());
2470 }
2471
2472 void WebPage::touchEventSync(const WebTouchEvent& touchEvent, bool& handled)
2473 {
2474     EventDispatcher::TouchEventQueue queuedEvents;
2475     WebProcess::singleton().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
2476     dispatchAsynchronousTouchEvents(queuedEvents);
2477
2478     dispatchTouchEvent(touchEvent, handled);
2479 }
2480 #elif ENABLE(TOUCH_EVENTS)
2481 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
2482 {
2483     CurrentEvent currentEvent(touchEvent);
2484
2485     bool handled = handleTouchEvent(touchEvent, m_page.get());
2486
2487     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
2488 }
2489 #endif
2490
2491 #if ENABLE(MAC_GESTURE_EVENTS)
2492 static bool handleGestureEvent(const WebGestureEvent& event, Page* page)
2493 {
2494     if (!page->mainFrame().view())
2495         return false;
2496
2497     return page->mainFrame().eventHandler().handleGestureEvent(platform(event));
2498 }
2499
2500 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
2501 {
2502     CurrentEvent currentEvent(gestureEvent);
2503     bool handled = handleGestureEvent(gestureEvent, m_page.get());
2504     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
2505 }
2506 #endif
2507
2508 bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
2509 {
2510     return page->userInputBridge().scrollRecursively(direction, granularity);
2511 }
2512
2513 bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
2514 {
2515     return page->userInputBridge().logicalScrollRecursively(direction, granularity);
2516 }
2517
2518 bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
2519 {
2520     return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
2521 }
2522
2523 void WebPage::centerSelectionInVisibleArea()
2524 {
2525     Frame& frame = m_page->focusController().focusedOrMainFrame();
2526     frame.selection().revealSelection(SelectionRevealMode::Reveal, ScrollAlignment::alignCenterAlways);
2527     findController().showFindIndicatorInSelection();
2528 }
2529
2530 bool WebPage::isControlledByAutomation() const
2531 {
2532     return m_page->isControlledByAutomation();
2533 }
2534
2535 void WebPage::setControlledByAutomation(bool controlled)
2536 {
2537     m_page->setControlledByAutomation(controlled);
2538 }
2539
2540 void WebPage::insertNewlineInQuotedContent()
2541 {
2542     Frame& frame = m_page->focusController().focusedOrMainFrame();
2543     if (frame.selection().isNone())
2544         return;
2545     frame.editor().insertParagraphSeparatorInQuotedContent();
2546 }
2547
2548 #if ENABLE(REMOTE_INSPECTOR)
2549 void WebPage::setAllowsRemoteInspection(bool allow)
2550 {
2551     m_page->setRemoteInspectionAllowed(allow);
2552 }
2553
2554 void WebPage::setRemoteInspectionNameOverride(const String& name)
2555 {
2556     m_page->setRemoteInspectionNameOverride(name);
2557 }
2558 #endif
2559
2560 void WebPage::setDrawsBackground(bool drawsBackground)
2561 {
2562     if (m_drawsBackground == drawsBackground)
2563         return;
2564
2565     m_drawsBackground = drawsBackground;
2566
2567     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2568         if (FrameView* view = coreFrame->view())
2569             view->setTransparent(!drawsBackground);
2570     }
2571
2572     m_drawingArea->pageBackgroundTransparencyChanged();
2573     m_drawingArea->setNeedsDisplay();
2574 }
2575
2576 #if PLATFORM(COCOA)
2577 void WebPage::setTopContentInsetFenced(float contentInset, IPC::Attachment fencePort)
2578 {
2579     m_drawingArea->addFence(MachSendRight::create(fencePort.port()));
2580
2581     setTopContentInset(contentInset);
2582
2583     mach_port_deallocate(mach_task_self(), fencePort.port());
2584 }
2585 #endif
2586
2587 void WebPage::setTopContentInset(float contentInset)
2588 {
2589     if (contentInset == m_page->topContentInset())
2590         return;
2591
2592     m_page->setTopContentInset(contentInset);
2593
2594     for (auto* pluginView : m_pluginViews)
2595         pluginView->topContentInsetDidChange();
2596 }
2597
2598 void WebPage::viewWillStartLiveResize()
2599 {
2600     if (!m_page)
2601         return;
2602
2603     // FIXME: This should propagate to all ScrollableAreas.
2604     Frame& frame = m_page->focusController().focusedOrMainFrame();
2605     if (FrameView* view = frame.view())
2606         view->willStartLiveResize();
2607 }
2608
2609 void WebPage::viewWillEndLiveResize()
2610 {
2611     if (!m_page)
2612         return;
2613
2614     // FIXME: This should propagate to all ScrollableAreas.
2615     Frame& frame = m_page->focusController().focusedOrMainFrame();
2616     if (FrameView* view = frame.view())
2617         view->willEndLiveResize();
2618 }
2619
2620 void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event, CallbackID callbackID)
2621 {
2622     if (!m_page)
2623         return;
2624
2625     SetForScope<bool> userIsInteractingChange { m_userIsInteracting, true };
2626
2627     Frame& frame = m_page->focusController().focusedOrMainFrame();
2628     frame.document()->setFocusedElement(0);
2629
2630     if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
2631         PlatformKeyboardEvent platformEvent(platform(event));
2632         platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
2633         m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, &KeyboardEvent::create(platformEvent, frame.document()->defaultView()).get());
2634
2635         send(Messages::WebPageProxy::VoidCallback(callbackID));
2636         return;
2637     }
2638
2639     m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, nullptr);
2640     send(Messages::WebPageProxy::VoidCallback(callbackID));
2641 }
2642
2643 void WebPage::setCanStartMediaTimerFired()
2644 {
2645     if (m_page)
2646         m_page->setCanStartMedia(true);
2647 }
2648
2649 void WebPage::updateIsInWindow(bool isInitialState)
2650 {
2651     bool isInWindow = m_activityState & WebCore::ActivityState::IsInWindow;
2652
2653     if (!isInWindow) {
2654         m_setCanStartMediaTimer.stop();
2655         m_page->setCanStartMedia(false);
2656         
2657         // The WebProcess does not yet know about this page; no need to tell it we're leaving the window.
2658         if (!isInitialState)
2659             WebProcess::singleton().pageWillLeaveWindow(m_pageID);
2660     } else {
2661         // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process
2662         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
2663         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
2664         if (m_mayStartMediaWhenInWindow)
2665             m_setCanStartMediaTimer.startOneShot(0_s);
2666
2667         WebProcess::singleton().pageDidEnterWindow(m_pageID);
2668     }
2669
2670     if (isInWindow)
2671         layoutIfNeeded();
2672 }
2673
2674 void WebPage::visibilityDidChange()
2675 {
2676     bool isVisible = m_activityState & ActivityState::IsVisible;
2677     if (!isVisible) {
2678         // We save the document / scroll state when backgrounding a tab so that we are able to restore it
2679         // if it gets terminated while in the background.
2680         if (auto* frame = m_mainFrame->coreFrame())
2681             frame->loader().history().saveDocumentAndScrollState();
2682     }
2683 }
2684
2685 void WebPage::setActivityState(ActivityState::Flags activityState, bool wantsDidUpdateActivityState, const Vector<CallbackID>& callbackIDs)
2686 {
2687     ActivityState::Flags changed = m_activityState ^ activityState;
2688     m_activityState = activityState;
2689
2690     if (changed)
2691         updateThrottleState();
2692
2693     m_page->setActivityState(activityState);
2694     for (auto* pluginView : m_pluginViews)
2695         pluginView->activityStateDidChange(changed);
2696
2697     m_drawingArea->activityStateDidChange(changed, wantsDidUpdateActivityState, callbackIDs);
2698     WebProcess::singleton().pageActivityStateDidChange(m_pageID, changed);
2699
2700     if (changed & ActivityState::IsInWindow)
2701         updateIsInWindow();
2702
2703     if (changed & ActivityState::IsVisible)
2704         visibilityDidChange();
2705 }
2706
2707 void WebPage::setLayerHostingMode(LayerHostingMode layerHostingMode)
2708 {
2709     m_layerHostingMode = layerHostingMode;
2710
2711     m_drawingArea->setLayerHostingMode(m_layerHostingMode);
2712
2713     for (auto* pluginView : m_pluginViews)
2714         pluginView->setLayerHostingMode(m_layerHostingMode);
2715 }
2716
2717 void WebPage::setSessionID(PAL::SessionID sessionID)
2718 {
2719     if (sessionID.isEphemeral())
2720         WebProcess::singleton().ensurePrivateBrowsingSession(sessionID);
2721     m_page->setSessionID(sessionID);
2722 }
2723
2724 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t navigationID, const DownloadID& downloadID)
2725 {
2726     WebFrame* frame = WebProcess::singleton().webFrame(frameID);
2727     if (!frame)
2728         return;
2729     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), navigationID, downloadID);
2730 }
2731
2732 void WebPage::didStartPageTransition()
2733 {
2734     m_drawingArea->setLayerTreeStateIsFrozen(true);
2735
2736 #if PLATFORM(MAC)
2737     bool hasPreviouslyFocusedDueToUserInteraction = m_hasEverFocusedElementDueToUserInteractionSincePageTransition;
2738 #endif
2739     m_hasEverFocusedElementDueToUserInteractionSincePageTransition = false;
2740     m_isAssistingNodeDueToUserInteraction = false;
2741     m_lastEditorStateWasContentEditable = EditorStateIsContentEditable::Unset;
2742 #if PLATFORM(MAC)
2743     if (hasPreviouslyFocusedDueToUserInteraction)
2744         send(Messages::WebPageProxy::SetHasHadSelectionChangesFromUserInteraction(m_hasEverFocusedElementDueToUserInteractionSincePageTransition));
2745     if (m_needsHiddenContentEditableQuirk) {
2746         m_needsHiddenContentEditableQuirk = false;
2747         send(Messages::WebPageProxy::SetNeedsHiddenContentEditableQuirk(m_needsHiddenContentEditableQuirk));
2748     }
2749     if (m_needsPlainTextQuirk) {
2750         m_needsPlainTextQuirk = false;
2751         send(Messages::WebPageProxy::SetNeedsPlainTextQuirk(m_needsPlainTextQuirk));
2752     }
2753 #endif
2754 }
2755
2756 void WebPage::didCompletePageTransition()
2757 {
2758     m_drawingArea->setLayerTreeStateIsFrozen(false);
2759 }
2760
2761 void WebPage::show()
2762 {
2763     send(Messages::WebPageProxy::ShowPage());
2764 }
2765
2766 String WebPage::userAgent(const URL& webCoreURL) const
2767 {
2768     return userAgent(nullptr, webCoreURL);
2769 }
2770
2771 String WebPage::userAgent(WebFrame* frame, const URL& webcoreURL) const
2772 {
2773     if (frame) {
2774         String userAgent = m_loaderClient->userAgentForURL(*frame, webcoreURL);
2775         if (!userAgent.isEmpty())
2776             return userAgent;
2777     }
2778
2779     String userAgent = platformUserAgent(webcoreURL);
2780     if (!userAgent.isEmpty())
2781         return userAgent;
2782     return m_userAgent;
2783 }
2784     
2785 void WebPage::setUserAgent(const String& userAgent)
2786 {
2787     m_userAgent = userAgent;
2788 }
2789
2790 void WebPage::suspendActiveDOMObjectsAndAnimations()
2791 {
2792     m_page->suspendActiveDOMObjectsAndAnimations();
2793 }
2794
2795 void WebPage::resumeActiveDOMObjectsAndAnimations()
2796 {
2797     m_page->resumeActiveDOMObjectsAndAnimations();
2798 }
2799
2800 IntPoint WebPage::screenToRootView(const IntPoint& point)
2801 {
2802     IntPoint windowPoint;
2803     sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
2804     return windowPoint;
2805 }
2806     
2807 IntRect WebPage::rootViewToScreen(const IntRect& rect)
2808 {
2809     IntRect screenRect;
2810     sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
2811     return screenRect;
2812 }
2813     
2814 #if PLATFORM(IOS)
2815 IntPoint WebPage::accessibilityScreenToRootView(const IntPoint& point)
2816 {
2817     IntPoint windowPoint;
2818     sendSync(Messages::WebPageProxy::AccessibilityScreenToRootView(point), Messages::WebPageProxy::AccessibilityScreenToRootView::Reply(windowPoint));
2819     return windowPoint;
2820 }
2821
2822 IntRect WebPage::rootViewToAccessibilityScreen(const IntRect& rect)
2823 {
2824     IntRect screenRect;
2825     sendSync(Messages::WebPageProxy::RootViewToAccessibilityScreen(rect), Messages::WebPageProxy::RootViewToAccessibilityScreen::Reply(screenRect));
2826     return screenRect;
2827 }
2828 #endif
2829
2830 KeyboardUIMode WebPage::keyboardUIMode()
2831 {
2832     bool fullKeyboardAccessEnabled = WebProcess::singleton().fullKeyboardAccessEnabled();
2833     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
2834 }
2835
2836 void WebPage::runJavaScriptInMainFrame(const String& script, bool forceUserGesture, CallbackID callbackID)
2837 {
2838     // NOTE: We need to be careful when running scripts that the objects we depend on don't
2839     // disappear during script execution.
2840
2841     RefPtr<SerializedScriptValue> serializedResultValue;
2842     JSLockHolder lock(commonVM());
2843     bool hadException = true;
2844     ExceptionDetails details;
2845     if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScript(script, forceUserGesture, &details)) {
2846         hadException = false;
2847         serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(),
2848             toRef(m_mainFrame->coreFrame()->script().globalObject(mainThreadNormalWorld())->globalExec(), resultValue), nullptr);
2849     }
2850
2851     IPC::DataReference dataReference;
2852     if (serializedResultValue)
2853         dataReference = serializedResultValue->data();
2854     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, hadException, details, callbackID));
2855 }
2856
2857 void WebPage::getContentsAsString(CallbackID callbackID)
2858 {
2859     String resultString = m_mainFrame->contentsAsString();
2860     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2861 }
2862
2863 #if ENABLE(MHTML)
2864 void WebPage::getContentsAsMHTMLData(CallbackID callbackID)
2865 {
2866     auto buffer = MHTMLArchive::generateMHTMLData(m_page.get());
2867
2868     // FIXME: Use SharedBufferDataReference.
2869     IPC::DataReference dataReference;
2870     dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2871     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2872 }
2873 #endif
2874
2875 void WebPage::getRenderTreeExternalRepresentation(CallbackID callbackID)
2876 {
2877     String resultString = renderTreeExternalRepresentation();
2878     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2879 }
2880
2881 static Frame* frameWithSelection(Page* page)
2882 {
2883     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
2884         if (frame->selection().isRange())
2885             return frame;
2886     }
2887
2888     return 0;
2889 }
2890
2891 void WebPage::getSelectionAsWebArchiveData(CallbackID callbackID)
2892 {
2893 #if PLATFORM(COCOA)
2894     RetainPtr<CFDataRef> data;
2895     if (Frame* frame = frameWithSelection(m_page.get()))
2896         data = LegacyWebArchive::createFromSelection(frame)->rawDataRepresentation();
2897 #endif
2898
2899     IPC::DataReference dataReference;
2900 #if PLATFORM(COCOA)
2901     if (data)
2902         dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2903 #endif
2904     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2905 }
2906
2907 void WebPage::getSelectionOrContentsAsString(CallbackID callbackID)
2908 {
2909     WebFrame* focusedOrMainFrame = WebFrame::fromCoreFrame(m_page->focusController().focusedOrMainFrame());
2910     String resultString = focusedOrMainFrame->selectionAsString();
2911     if (resultString.isEmpty())
2912         resultString = focusedOrMainFrame->contentsAsString();
2913     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2914 }
2915
2916 void WebPage::getSourceForFrame(uint64_t frameID, CallbackID callbackID)
2917 {
2918     String resultString;
2919     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
2920        resultString = frame->source();
2921
2922     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2923 }
2924
2925 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, CallbackID callbackID)
2926 {
2927     RefPtr<SharedBuffer> buffer;
2928     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID)) {
2929         if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame()))
2930             buffer = pluginView->liveResourceData();
2931         if (!buffer) {
2932             if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader())
2933                 buffer = loader->mainResourceData();
2934         }
2935     }
2936
2937     // FIXME: Use SharedBufferDataReference.
2938     IPC::DataReference dataReference;
2939     if (buffer)
2940         dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2941     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2942 }
2943
2944 static RefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
2945 {
2946     DocumentLoader* loader = frame->loader().documentLoader();
2947     if (!loader)
2948         return nullptr;
2949
2950     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
2951     if (!subresource)
2952         return nullptr;
2953
2954     return &subresource->data();
2955 }
2956
2957 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, CallbackID callbackID)
2958 {
2959     RefPtr<SharedBuffer> buffer;
2960     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID)) {
2961         URL resourceURL(URL(), resourceURLString);
2962         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
2963         if (!buffer) {
2964             // Try to get the resource data from the cache.
2965             buffer = cachedResponseDataForURL(resourceURL);
2966         }
2967     }
2968
2969     // FIXME: Use SharedBufferDataReference.
2970     IPC::DataReference dataReference;
2971     if (buffer)
2972         dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2973     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2974 }
2975
2976 void WebPage::getWebArchiveOfFrame(uint64_t frameID, CallbackID callbackID)
2977 {
2978 #if PLATFORM(COCOA)
2979     RetainPtr<CFDataRef> data;
2980     if (WebFrame* frame = WebProcess::singleton().webFrame(frameID))
2981         data = frame->webArchiveData(nullptr, nullptr);
2982 #else
2983     UNUSED_PARAM(frameID);
2984 #endif
2985
2986     IPC::DataReference dataReference;
2987 #if PLATFORM(COCOA)
2988     if (data)
2989         dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2990 #endif
2991     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2992 }
2993
2994 void WebPage::forceRepaintWithoutCallback()
2995 {
2996     m_drawingArea->forceRepaint();
2997 }
2998
2999 void WebPage::forceRepaint(CallbackID callbackID)
3000 {
3001     if (m_drawingArea->forceRepaintAsync(callbackID))
3002         return;
3003
3004     forceRepaintWithoutCallback();
3005     send(Messages::WebPageProxy::VoidCallback(callbackID));
3006 }
3007
3008 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
3009 {
3010     WebPreferencesStore::removeTestRunnerOverrides();
3011     updatePreferences(store);
3012 }
3013
3014 void WebPage::updatePreferences(const WebPreferencesStore& store)
3015 {
3016     Settings& settings = m_page->settings();
3017
3018     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
3019     m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey());
3020     m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey());
3021     m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey());
3022
3023     m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey());
3024
3025 #if PLATFORM(COCOA)
3026     m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey());
3027 #endif
3028
3029     // FIXME: This should be generated from macro expansion for all preferences,
3030     // but we currently don't match the naming of WebCore exactly so we are
3031     // handrolling the boolean and integer preferences until that is fixed.
3032
3033 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue, HumanReadableName, HumanReadableDescription) settings.set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
3034
3035     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
3036
3037 #undef INITIALIZE_SETTINGS
3038
3039     settings.setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
3040     settings.setScriptMarkupEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptMarkupEnabledKey()));
3041     settings.setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
3042     settings.setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
3043     settings.setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
3044     settings.setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
3045     settings.setJavaEnabledForLocalFiles(store.getBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey()));    
3046     settings.setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
3047     settings.setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
3048     settings.setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
3049     settings.setFrameFlattening(static_cast<WebCore::FrameFlattening>(store.getUInt32ValueForKey(WebPreferencesKey::frameFlatteningKey())));
3050     settings.setAsyncFrameScrollingEnabled(store.getBoolValueForKey(WebPreferencesKey::asyncFrameScrollingEnabledKey()));
3051     if (store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && !usesEphemeralSession())
3052         setSessionID(PAL::SessionID::legacyPrivateSessionID());
3053     else if (!store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && sessionID() == PAL::SessionID::legacyPrivateSessionID())
3054         setSessionID(PAL::SessionID::defaultSessionID());
3055     settings.setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
3056     settings.setJavaScriptRuntimeFlags(RuntimeFlags(store.getUInt32ValueForKey(WebPreferencesKey::javaScriptRuntimeFlagsKey())));
3057     settings.setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
3058     settings.setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
3059     settings.setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
3060     settings.setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
3061     settings.setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
3062     settings.setDOMTimersThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::domTimersThrottlingEnabledKey()));
3063 #if ENABLE(WEB_ARCHIVE)
3064     settings.setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
3065 #endif
3066     settings.setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
3067     settings.setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
3068     settings.setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey()));
3069     settings.setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
3070     settings.setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
3071     settings.setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
3072     settings.setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
3073     settings.setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
3074     settings.setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
3075     settings.setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
3076     settings.setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
3077     settings.setNeedsStorageAccessFromFileURLsQuirk(store.getBoolValueForKey(WebPreferencesKey::needsStorageAccessFromFileURLsQuirkKey()));
3078
3079     settings.setMinimumFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumFontSizeKey()));
3080     settings.setMinimumLogicalFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
3081     settings.setDefaultFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFontSizeKey()));
3082     settings.setDefaultFixedFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
3083     settings.setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
3084     settings.setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
3085     settings.setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
3086     settings.setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
3087     settings.setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
3088
3089     settings.setAcceleratedCompositingForOverflowScrollEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingForOverflowScrollEnabledKey()));
3090     settings.setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()));
3091     settings.setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()));
3092     settings.setDisplayListDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::displayListDrawingEnabledKey()));
3093     settings.setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()));
3094     settings.setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
3095     settings.setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
3096     settings.setShowTiledScrollingIndicator(store.getBoolValueForKey(WebPreferencesKey::tiledScrollingIndicatorVisibleKey()));
3097     settings.setVisibleDebugOverlayRegions(store.getUInt32ValueForKey(WebPreferencesKey::visibleDebugOverlayRegionsKey()));
3098     settings.setUseGiantTiles(store.getBoolValueForKey(WebPreferencesKey::useGiantTilesKey()));
3099     settings.setSubpixelAntialiasedLayerTextEnabled(store.getBoolValueForKey(WebPreferencesKey::subpixelAntialiasedLayerTextEnabledKey()));
3100
3101     settings.setAggressiveTileRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::aggressiveTileRetentionEnabledKey()));
3102     settings.setTemporaryTileCohortRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::temporaryTileCohortRetentionEnabledKey()));
3103 #if ENABLE(CSS_ANIMATIONS_LEVEL_2)
3104     RuntimeEnabledFeatures::sharedFeatures().setAnimationTriggersEnabled(store.getBoolValueForKey(WebPreferencesKey::cssAnimationTriggersEnabledKey()));
3105 #endif
3106 #if ENABLE(WEB_ANIMATIONS)
3107     RuntimeEnabledFeatures::sharedFeatures().setWebAnimationsEnabled(store.getBoolValueForKey(WebPreferencesKey::webAnimationsEnabledKey()));
3108 #endif
3109     settings.setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
3110     settings.setForceSoftwareWebGLRendering(store.getBoolValueForKey(WebPreferencesKey::forceSoftwareWebGLRenderingKey()));
3111     settings.setAccelerated2dCanvasEnabled(store.getBoolValueForKey(WebPreferencesKey::accelerated2dCanvasEnabledKey()));
3112     bool requiresUserGestureForMedia = store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForMediaPlaybackKey());
3113     settings.setVideoPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForVideoPlaybackKey()));
3114     settings.setAudioPlaybackRequiresUserGesture(requiresUserGestureForMedia || store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureForAudioPlaybackKey()));
3115     settings.setRequiresUserGestureToLoadVideo(store.getBoolValueForKey(WebPreferencesKey::requiresUserGestureToLoadVideoKey()));
3116     settings.setMainContentUserGestureOverrideEnabled(store.getBoolValueForKey(WebPreferencesKey::mainContentUserGestureOverrideEnabledKey()));
3117     settings.setMediaUserGestureInheritsFromDocument(store.getBoolValueForKey(WebPreferencesKey::mediaUserGestureInheritsFromDocumentKey()));
3118     settings.setAllowsInlineMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackKey()));
3119     settings.setAllowsInlineMediaPlaybackAfterFullscreen(store.getBoolValueForKey(WebPreferencesKey::allowsInlineMediaPlaybackAfterFullscreenKey()));
3120     settings.setInlineMediaPlaybackRequiresPlaysInlineAttribute(store.getBoolValueForKey(WebPreferencesKey::inlineMediaPlaybackRequiresPlaysInlineAttributeKey()));
3121     settings.setInvisibleAutoplayNotPermitted(store.getBoolValueForKey(WebPreferencesKey::invisibleAutoplayNotPermittedKey()));
3122     settings.setMediaDataLoadsAutomatically(store.getBoolValueForKey(WebPreferencesKey::mediaDataLoadsAutomaticallyKey()));
3123 #if ENABLE(ATTACHMENT_ELEMENT)
3124     settings.setAttachmentElementEnabled(store.getBoolValueForKey(WebPreferencesKey::attachmentElementEnabledKey()));
3125 #endif
3126     settings.setAllowsPictureInPictureMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsPictureInPictureMediaPlaybackKey()));
3127     settings.setMediaControlsScaleWithPageZoom(store.getBoolValueForKey(WebPreferencesKey::mediaControlsScaleWithPageZoomKey()));
3128     settings.setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
3129     settings.setHyperlinkAuditingEnabled(store.getBoolValueForKey(WebPreferencesKey::hyperlinkAuditingEnabledKey()));
3130     settings.setRequestAnimationFrameEnabled(store.getBoolValueForKey(WebPreferencesKey::requestAnimationFrameEnabledKey()));
3131 #if ENABLE(SMOOTH_SCROLLING)
3132     settings.setScrollAnimatorEnabled(store.getBoolValueForKey(WebPreferencesKey::scrollAnimatorEnabledKey()));
3133 #endif
3134     settings.setForceUpdateScrollbarsOnMainThreadForPerformanceTesting(store.getBoolValueForKey(WebPreferencesKey::forceUpdateScrollbarsOnMainThreadForPerformanceTestingKey()));
3135     settings.setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
3136     settings.setSpatialNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::spatialNavigationEnabledKey()));
3137
3138     settings.setHttpEquivEnabled(store.getBoolValueForKey(WebPreferencesKey::httpEquivEnabledKey()));
3139
3140     settings.setSelectionPaintingWithoutSelectionGapsEnabled(store.getBoolValueForKey(WebPreferencesKey::selectionPaintingWithoutSelectionGapsEnabledKey()));
3141
3142     DatabaseManager::singleton().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
3143
3144 #if ENABLE(FULLSCREEN_API)
3145     settings.setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
3146 #endif
3147
3148 #if USE(AVFOUNDATION)
3149     settings.setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
3150     settings.setAVFoundationNSURLSessionEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationNSURLSessionEnabledKey()));
3151 #endif
3152
3153 #if USE(GSTREAMER)
3154     settings.setGStreamerEnabled(store.getBoolValueForKey(WebPreferencesKey::isGStreamerEnabledKey()));
3155 #endif
3156
3157 #if PLATFORM(COCOA)
3158     settings.setQTKitEnabled(store.getBoolValueForKey(WebPreferencesKey::isQTKitEnabledKey()));
3159 #endif
3160
3161 #if PLATFORM(IOS) && HAVE(AVKIT)
3162     settings.setAVKitEnabled(true);
3163 #endif
3164
3165 #if ENABLE(WEB_AUDIO)
3166     settings.setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey()));
3167 #endif
3168
3169 #if ENABLE(MEDIA_STREAM)
3170     RuntimeEnabledFeatures::sharedFeatures().setMediaDevicesEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaDevicesEnabledKey()));
3171     RuntimeEnabledFeatures::sharedFeatures().setMediaStreamEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaStreamEnabledKey()));
3172 #endif
3173
3174 #if ENABLE(WEB_RTC)
3175     RuntimeEnabledFeatures::sharedFeatures().setPeerConnectionEnabled(store.getBoolValueForKey(WebPreferencesKey::peerConnectionEnabledKey()));
3176     RuntimeEnabledFeatures::sharedFeatures().setWebRTCLegacyAPIEnabled(!store.getBoolValueForKey(WebPreferencesKey::webRTCLegacyAPIDisabledKey()));
3177 #endif
3178
3179 #if ENABLE(SERVICE_CONTROLS)
3180     settings.setImageControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey()));
3181 #endif
3182
3183 #if ENABLE(SERVICE_WORKER)
3184     RuntimeEnabledFeatures::sharedFeatures().setServiceWorkerEnabled(store.getBoolValueForKey(WebPreferencesKey::serviceWorkersEnabledKey()));
3185 #endif
3186
3187 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
3188     settings.setAllowsAirPlayForMediaPlayback(store.getBoolValueForKey(WebPreferencesKey::allowsAirPlayForMediaPlaybackKey()));
3189 #endif
3190
3191 #if ENABLE(RESOURCE_USAGE)
3192     settings.setResourceUsageOverlayVisible(store.getBoolValueForKey(WebPreferencesKey::resourceUsageOverlayVisibleKey()));
3193 #endif
3194
3195     settings.setSuppressesIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressesIncrementalRenderingKey()));
3196     settings.setIncrementalRenderingSuppressionTimeoutInSeconds(store.getDoubleValueForKey(WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey()));
3197     settings.setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
3198     settings.setWantsBalancedSetDefersLoadingBehavior(store.getBoolValueForKey(WebPreferencesKey::wantsBalancedSetDefersLoadingBehaviorKey()));
3199     settings.setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey()));
3200
3201 #if ENABLE(VIDEO_TRACK)
3202     settings.setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey()));
3203     settings.setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey()));
3204     settings.setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
3205 #endif
3206
3207 #if ENABLE(NOTIFICATIONS)
3208     settings.setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
3209 #endif
3210
3211     settings.setShouldRespectImageOrientation(store.getBoolValueForKey(WebPreferencesKey::shouldRespectImageOrientationKey()));
3212     settings.setStorageBlockingPolicy(static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey())));
3213     settings.setCookieEnabled(store.getBoolValueForKey(WebPreferencesKey::cookieEnabledKey()));
3214
3215     settings.setDiagnosticLoggingEnabled(store.getBoolValueForKey(WebPreferencesKey::diagnosticLoggingEnabledKey()));
3216
3217     settings.setScrollingPerformanceLoggingEnabled(m_scrollingPerformanceLoggingEnabled);
3218
3219     settings.setPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::plugInSnapshottingEnabledKey()));
3220     settings.setSnapshotAllPlugIns(store.getBoolValueForKey(WebPreferencesKey::snapshotAllPlugInsKey()));
3221     settings.setAutostartOriginPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::autostartOriginPlugInSnapshottingEnabledKey()));
3222     settings.setPrimaryPlugInSnapshotDetectionEnabled(store.getBoolValueForKey(WebPreferencesKey::primaryPlugInSnapshotDetectionEnabledKey()));
3223     settings.setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
3224
3225 #if ENABLE(TEXT_AUTOSIZING)
3226     settings.setTextAutosizingEnabled(store.getBoolValueForKey(WebPreferencesKey::textAutosizingEnabledKey()));
3227     settings.setMinimumZoomFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumZoomFontSizeKey()));
3228 #endif
3229
3230     settings.setLogsPageMessagesToSystemConsoleEnabled(store.getBoolValueForKey(WebPreferencesKey::logsPageMessagesToSystemConsoleEnabledKey()));
3231     settings.setAsynchronousSpellCheckingEnabled(store.getBoolValueForKey(WebPreferencesKey::asynchronousSpellCheckingEnabledKey()));
3232
3233     settings.setSmartInsertDeleteEnabled(store.getBoolValueForKey(WebPreferencesKey::smartInsertDeleteEnabledKey()));
3234     settings.setSelectTrailingWhitespaceEnabled(store.getBoolValueForKey(WebPreferencesKey::selectTrailingWhitespaceEnabledKey()));
3235     settings.setShowsURLsInToolTips(store.getBoolValueForKey(WebPreferencesKey::showsURLsInToolTipsEnabledKey()));
3236
3237     settings.setHiddenPageDOMTimerThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingEnabledKey()));
3238     settings.setHiddenPageDOMTimerThrottlingAutoIncreases(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingAutoIncreasesKey()));
3239
3240     settings.setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey()));
3241     settings.setLowPowerVideoAudioBufferSizeEnabled(store.getBoolValueForKey(WebPreferencesKey::lowPowerVideoAudioBufferSizeEnabledKey()));
3242     settings.setSimpleLineLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutEnabledKey()));
3243     settings.setSimpleLineLayoutDebugBordersEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutDebugBordersEnabledKey()));
3244     
3245     settings.setNewBlockInsideInlineModelEnabled(store.getBoolValueForKey(WebPreferencesKey::newBlockInsideInlineModelEnabledKey()));
3246     settings.setDeferredCSSParserEnabled(store.getBoolValueForKey(WebPreferencesKey::deferredCSSParserEnabledKey()));
3247
3248     settings.setSubpixelCSSOMElementMetricsEnabled(store.getBoolValueForKey(WebPreferencesKey::subpixelCSSOMElementMetricsEnabledKey()));
3249
3250     settings.setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey()));
3251
3252 #if ENABLE(MEDIA_SOURCE)
3253     settings.setMediaSourceEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaSourceEnabledKey()));
3254 #endif
3255
3256 #if ENABLE(MEDIA_STREAM)
3257     settings.setMockCaptureDevicesEnabled(store.getBoolValueForKey(WebPreferencesKey::mockCaptureDevicesEnabledKey()));
3258     settings.setMediaCaptureRequiresSecureConnection(store.getBoolValueForKey(WebPreferencesKey::mediaCaptureRequiresSecureConnectionKey()));
3259 #endif
3260
3261     settings.setShouldConvertPositionStyleOnCopy(store.getBoolValueForKey(WebPreferencesKey::shouldConvertPositionStyleOnCopyKey()));
3262
3263     settings.setStandalone(store.getBoolValueForKey(WebPreferencesKey::standaloneKey()));
3264     settings.setTelephoneNumberParsingEnabled(store.getBoolValueForKey(WebPreferencesKey::telephoneNumberParsingEnabledKey()));
3265     settings.setAllowMultiElementImplicitSubmission(store.getBoolValueForKey(WebPreferencesKey::allowMultiElementImplicitSubmissionKey()));
3266     settings.setAlwaysUseAcceleratedOverflowScroll(store.getBoolValueForKey(WebPreferencesKey::alwaysUseAcceleratedOverflowScrollKey()));
3267
3268     settings.setPasswordEchoEnabled(store.getBoolValueForKey(WebPreferencesKey::passwordEchoEnabledKey()));
3269     settings.setPasswordEchoDurationInSeconds(store.getDoubleValueForKey(WebPreferencesKey::passwordEchoDurationKey()));
3270     
3271     settings.setLayoutInterval(Seconds(store.getDoubleValueForKey(WebPreferencesKey::layoutIntervalKey())));
3272     settings.setMaxParseDuration(store.getDoubleValueForKey(WebPreferencesKey::maxParseDurationKey()));
3273
3274     settings.setEnableInheritURIQueryComponent(store.getBoolValueForKey(WebPreferencesKey::enableInheritURIQueryComponentKey()));
3275
3276     auto userInterfaceDirectionPolicyCandidate = static_cast<WebCore::UserInterfaceDirectionPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionPolicyKey()));
3277     if (userInterfaceDirectionPolicyCandidate == WebCore::UserInterfaceDirectionPolicy::Content || userInterfaceDirectionPolicyCandidate == WebCore::UserInterfaceDirectionPolicy::System)
3278         settings.setUserInterfaceDirectionPolicy(userInterfaceDirectionPolicyCandidate);
3279     TextDirection systemLayoutDirectionCandidate = static_cast<TextDirection>(store.getUInt32ValueForKey(WebPreferencesKey::systemLayoutDirectionKey()));
3280     if (systemLayoutDirectionCandidate == WebCore::LTR || systemLayoutDirectionCandidate == WebCore::RTL)
3281         settings.setSystemLayoutDirection(systemLayoutDirectionCandidate);
3282
3283 #if ENABLE(APPLE_PAY)
3284     settings.setApplePayEnabled(store.getBoolValueForKey(WebPreferencesKey::applePayEnabledKey()));
3285     settings.setApplePayCapabilityDisclosureAllowed(store.getBoolValueForKey(WebPreferencesKey::applePayCapabilityDisclosureAllowedKey()));
3286 #endif
3287
3288 #if PLATFORM(IOS)
3289     settings.setUseImageDocumentForSubframePDF(true);
3290 #endif
3291
3292 #if ENABLE(DATA_DETECTION)
3293     settings.setDataDetectorTypes(static_cast<DataDetectorTypes>(store.getUInt32ValueForKey(WebPreferencesKey::dataDetectorTypesKey())));
3294 #endif
3295 #if ENABLE(GAMEPAD)
3296     RuntimeEnabledFeatures::sharedFeatures().setGamepadsEnabled(store.getBoolValueForKey(WebPreferencesKey::gamepadsEnabledKey()));
3297 #endif
3298
3299 #if ENABLE(SERVICE_CONTROLS)
3300     settings.setServiceControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::serviceControlsEnabledKey()));
3301 #endif
3302
3303     RuntimeEnabledFeatures::sharedFeatures().setCacheAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::cacheAPIEnabledKey()));
3304     RuntimeEnabledFeatures::sharedFeatures().setFetchAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::fetchAPIEnabledKey()));
3305
3306 #if ENABLE(DOWNLOAD_ATTRIBUTE)
3307     RuntimeEnabledFeatures::sharedFeatures().setDownloadAttributeEnabled(store.getBoolValueForKey(WebPreferencesKey::downloadAttributeEnabledKey()));
3308 #endif
3309
3310     RuntimeEnabledFeatures::sharedFeatures().setShadowDOMEnabled(store.getBoolValueForKey(WebPreferencesKey::shadowDOMEnabledKey()));
3311
3312     RuntimeEnabledFeatures::sharedFeatures().setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
3313
3314     // Experimental Features.
3315
3316     RuntimeEnabledFeatures::sharedFeatures().setCSSGridLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::cssGridLayoutEnabledKey()));
3317     
3318     RuntimeEnabledFeatures::sharedFeatures().setCustomElementsEnabled(store.getBoolValueForKey(WebPreferencesKey::customElementsEnabledKey()));
3319
3320     RuntimeEnabledFeatures::sharedFeatures().setDataTransferItemsEnabled(store.getBoolValueForKey(WebPreferencesKey::dataTransferItemsEnabledKey()));
3321
3322 #if ENABLE(WEBGL2)
3323     RuntimeEnabledFeatures::sharedFeatures().setWebGL2Enabled(store.getBoolValueForKey(WebPreferencesKey::webGL2EnabledKey()));
3324 #endif
3325
3326 #if ENABLE(WEBGPU)
3327     RuntimeEnabledFeatures::sharedFeatures().setWebGPUEnabled(store.getBoolValueForKey(WebPreferencesKey::webGPUEnabledKey()));
3328 #endif
3329
3330     settings.setSpringTimingFunctionEnabled(store.getBoolValueForKey(WebPreferencesKey::springTimingFunctionEnabledKey()));
3331
3332     settings.setConstantPropertiesEnabled(store.getBoolValueForKey(WebPreferencesKey::constantPropertiesEnabledKey()));
3333
3334     settings.setViewportFitEnabled(store.getBoolValueForKey(WebPreferencesKey::viewportFitEnabledKey()));
3335
3336     settings.setVisualViewportEnabled(store.getBoolValueForKey(WebPreferencesKey::visualViewportEnabledKey()));
3337
3338     settings.setInputEventsEnabled(store.getBoolValueForKey(WebPreferencesKey::inputEventsEnabledKey()));
3339     RuntimeEnabledFeatures::sharedFeatures().setInputEventsEnabled(store.getBoolValueForKey(WebPreferencesKey::inputEventsEnabledKey()));
3340
3341     RuntimeEnabledFeatures::sharedFeatures().setModernMediaControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::modernMediaControlsEnabledKey()));
3342
3343 #if ENABLE(ENCRYPTED_MEDIA)
3344     RuntimeEnabledFeatures::sharedFeatures().setEncryptedMediaAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::encryptedMediaAPIEnabledKey()));
3345 #endif
3346
3347 #if ENABLE(INTERSECTION_OBSERVER)
3348     RuntimeEnabledFeatures::sharedFeatures().setIntersectionObserverEnabled(store.getBoolValueForKey(WebPreferencesKey::intersectionObserverEnabledKey()));
3349 #endif
3350
3351     RuntimeEnabledFeatures::sharedFeatures().setDisplayContentsEnabled(store.getBoolValueForKey(WebPreferencesKey::displayContentsEnabledKey()));
3352     RuntimeEnabledFeatures::sharedFeatures().setUserTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::userTimingEnabledKey()));
3353     RuntimeEnabledFeatures::sharedFeatures().setResourceTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::resourceTimingEnabledKey()));
3354     RuntimeEnabledFeatures::sharedFeatures().setLinkPreloadEnabled(store.getBoolValueForKey(WebPreferencesKey::linkPreloadEnabledKey()));
3355     RuntimeEnabledFeatures::sharedFeatures().setMediaPreloadingEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaPreloadingEnabledKey()));
3356     RuntimeEnabledFeatures::sharedFeatures().setCredentialManagementEnabled(store.getBoolValueForKey(WebPreferencesKey::credentialManagementEnabledKey()));
3357     RuntimeEnabledFeatures::sharedFeatures().setIsSecureContextAttributeEnabled(store.getBoolValueForKey(WebPreferencesKey::isSecureContextAttributeEnabledKey()));
3358
3359     bool processSuppressionEnabled = store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey());
3360     if (m_processSuppressionEnabled != processSuppressionEnabled) {
3361         m_processSuppressionEnabled = processSuppressionEnabled;
3362         updateThrottleState();
3363     }
3364
3365     settings.setSubresourceIntegrityEnabled(store.getBoolValueForKey(WebPreferencesKey::subresourceIntegrityEnabledKey()));
3366
3367 #if ENABLE(BEACON_API)
3368     settings.setBeaconAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::beaconAPIEnabledKey()));
3369 #endif
3370
3371 #if ENABLE(PAYMENT_REQUEST)
3372     settings.setPaymentRequestEnabled(store.getBoolValueForKey(WebPreferencesKey::paymentRequestEnabledKey()));
3373 #endif
3374
3375     platformPreferencesDidChange(store);
3376
3377     if (m_drawingArea)
3378         m_drawingArea->updatePreferences(store);
3379
3380 #if PLATFORM(IOS)
3381     m_ignoreViewportScalingConstraints = store.getBoolValueForKey(WebPreferencesKey::ignoreViewportScalingConstraintsKey());
3382     m_viewportConfiguration.setCanIgnoreScalingConstraints(m_ignoreViewportScalingConstraints);
3383     setForceAlwaysUserScalable(m_forceAlwaysUserScalable || store.getBoolValueForKey(WebPreferencesKey::forceAlwaysUserScalableKey()));
3384 #endif
3385     settings.setLargeImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::largeImageAsyncDecodingEnabledKey()));
3386     settings.setAnimatedImageAsyncDecodingEnabled(store.getBoolValueForKey(WebPreferencesKey::animatedImageAsyncDecodingEnabledKey()));
3387     settings.setShouldSuppressKeyboardInputDuringProvisionalNavigation(store.getBoolValueForKey(WebPreferencesKey::shouldSuppressKeyboardInputDuringProvisionalNavigationKey()));
3388     settings.setMediaContentTypesRequiringHardwareSupport(store.getStringValueForKey(WebPreferencesKey::mediaContentTypesRequiringHardwareSupportKey()));
3389     settings.setAllowMediaContentTypesRequiringHardwareSupportAsFallback(store.getBoolValueForKey(WebPreferencesKey::allowMediaContentTypesRequiringHardwareSupportAsFallbackKey()));
3390
3391 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
3392     RuntimeEnabledFeatures::sharedFeatures().setLegacyEncryptedMediaAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::legacyEncryptedMediaAPIEnabledKey()));
3393 #endif
3394
3395     RuntimeEnabledFeatures::sharedFeatures().setInspectorAdditionsEnabled(store.getBoolValueForKey(WebPreferencesKey::inspectorAdditionsEnabledKey()));
3396 }
3397
3398 #if ENABLE(DATA_DETECTION)
3399 void WebPage::setDataDetectionResults(NSArray *detectionResults)
3400 {
3401     DataDetectionResult dataDetectionResult;
3402     dataDetectionResult.results = detectionResults;
3403     send(Messages::WebPageProxy::SetDataDetectionResult(dataDetectionResult));
3404 }
3405 #endif
3406
3407 #if PLATFORM(COCOA)
3408 void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
3409 {
3410     FrameView* frameView = corePage()->mainFrame().view();
3411     if (!frameView)
3412         return;
3413
3414     layerTransaction.setContentsSize(frameView->contentsSize());
3415     layerTransaction.setScrollOrigin(frameView->scrollOrigin());
3416     layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
3417     layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
3418     layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
3419
3420     layerTransaction.setBaseLayoutViewportSize(frameView->baseLayoutViewportSize());
3421     layerTransaction.setMinStableLayoutViewportOrigin(frameView->minStableLayoutViewportOrigin());
3422     layerTransaction.setMaxStableLayoutViewportOrigin(frameView->maxStableLayoutViewportOrigin());
3423
3424 #if PLATFORM(IOS)
3425     layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
3426     layerTransaction.setMinimumScaleFactor(m_viewportConfiguration.minimumScale());
3427     layerTransaction.setMaximumScaleFactor(m_viewportConfiguration.maximumScale());
3428     layerTransaction.setInitialScaleFactor(m_viewportConfiguration.initialScale());
3429     layerTransaction.setViewportMetaTagWidth(m_viewportConfiguration.viewportArguments().width);
3430     layerTransaction.setViewportMetaTagWidthWasExplicit(m_viewportConfiguration.viewportArguments().widthWasExplicit);
3431     layerTransaction.setViewportMetaTagCameFromImageDocument(m_viewportConfiguration.viewportArguments().type == ViewportArguments::ImageDocument);
3432     layerTransaction.setAvoidsUnsafeArea(m_viewportConfiguration.avoidsUnsafeArea());
3433     layerTransaction.setIsInStableState(m_isInStableState);
3434     layerTransaction.setAllowsUserScaling(allowsUserScaling());
3435 #endif
3436
3437 #if PLATFORM(MAC)
3438     layerTransaction.setScrollPosition(frameView->scrollPosition());
3439 #endif
3440 }
3441
3442 void WebPage::didFlushLayerTreeAtTime(MonotonicTime timestamp)
3443 {
3444 #if PLATFORM(IOS)
3445     if (m_oldestNonStableUpdateVisibleContentRectsTimestamp != MonotonicTime()) {
3446         Seconds elapsed = timestamp - m_oldestNonStableUpdateVisibleContentRectsTimestamp;
3447         m_oldestNonStableUpdateVisibleContentRectsTimestamp = MonotonicTime();
3448
3449         m_estimatedLatency = m_estimatedLatency * 0.80 + elapsed * 0.20;
3450     }
3451 #else
3452     UNUSED_PARAM(timestamp);
3453 #endif
3454 }
3455 #endif
3456
3457 WebInspector* WebPage::inspector(LazyCreationPolicy behavior)
3458 {
3459     if (m_isClosed)
3460         return nullptr;
3461     if (!m_inspector && behavior == LazyCreationPolicy::CreateIfNeeded)
3462         m_inspector = WebInspector::create(this);
3463     return m_inspector.get();
3464 }
3465
3466 WebInspectorUI* WebPage::inspectorUI()
3467 {
3468     if (m_isClosed)
3469         return nullptr;
3470     if (!m_inspectorUI)
3471         m_inspectorUI = WebInspectorUI::create(*this);
3472     return m_inspectorUI.get();
3473 }
3474
3475 RemoteWebInspectorUI* WebPage::remoteInspectorUI()
3476 {
3477     if (m_isClosed)
3478         return nullptr;
3479     if (!m_remoteInspectorUI)
3480         m_remoteInspectorUI = RemoteWebInspectorUI::create(*this);
3481     return m_remoteInspectorUI.get();
3482 }
3483
3484 #if (PLATFORM(IOS) && HAVE(AVKIT)) || (PLATFORM(MAC) && ENABLE(VIDEO_PRESENTATION_MODE))
3485 PlaybackSessionManager& WebPage::playbackSessionManager()
3486 {
3487     if (!m_playbackSessionManager)
3488         m_playbackSessionManager = PlaybackSessionManager::create(*this);
3489     return *m_playbackSessionManager;
3490 }
3491
3492 VideoFullscreenManager& WebPage::videoFullscreenManager()
3493 {
3494     if (!m_videoFullscreenManager)
3495         m_videoFullscreenManager = VideoFullscreenManager::create(*this, playbackSessionManager());
3496     return *m_videoFullscreenManager;
3497 }
3498 #endif
3499
3500 #if PLATFORM(IOS)
3501 void WebPage::setAllowsMediaDocumentInlinePlayback(bool allows)
3502 {
3503     m_page->setAllowsMediaDocumentInlinePlayback(allows);
3504 }
3505 #endif
3506
3507 #if ENABLE(FULLSCREEN_API)
3508 WebFullScreenManager* WebPage::fullScreenManager()
3509 {
3510     if (!m_fullScreenManager)
3511         m_fullScreenManager = WebFullScreenManager::create(this);
3512     return m_fullScreenManager.get();
3513 }
3514 #endif
3515
3516 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
3517 {
3518     if (m_notificationPermissionRequestManager)
3519         return m_notificationPermissionRequestManager.get();
3520
3521     m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
3522     return m_notificationPermissionRequestManager.get();
3523 }
3524
3525 #if !PLATFORM(GTK) && !PLATFORM(COCOA) && !PLATFORM(WPE)
3526 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
3527 {
3528     Node* node = evt->target()->toNode();
3529     ASSERT(node);
3530     Frame* frame = node->document().frame();
3531     ASSERT(frame);
3532
3533     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
3534     if (!keyEvent)
3535         return false;
3536
3537     Editor::Command command = frame->editor().command(interpretKeyEvent(evt));
3538
3539     if (keyEvent->type() == PlatformEvent::RawKeyDown) {
3540         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
3541         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
3542         // (e.g. Tab that inserts a Tab character, or Enter).
3543         return !command.isTextInsertion() && command.execute(evt);
3544     }
3545
3546     if (command.execute(evt))
3547         return true;
3548
3549     // Don't allow text insertion for nodes that cannot edit.
3550     if (!frame->editor().canEdit())
3551         return false;
3552
3553     // Don't insert null or control characters as they can result in unexpected behaviour
3554     if (evt->charCode() < ' ')
3555         return false;
3556
3557     return frame->editor().insertText(evt->keyEvent()->text(), evt);
3558 }
3559 #endif
3560
3561 #if ENABLE(DRAG_SUPPORT)
3562
3563 #if PLATFORM(GTK)
3564 void WebPage::performDragControllerAction(uint64_t action, const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t draggingSourceOperationMask, WebSelectionData&& selection, uint32_t flags)
3565 {
3566     if (!m_page) {
3567         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0, { }));
3568         return;
3569     }
3570
3571     DragData dragData(selection.selectionData.ptr(), clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
3572     switch (action) {
3573     case DragControllerActionEntered: {
3574         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3575         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }));
3576         break;
3577     }
3578     case DragControllerActionUpdated: {
3579         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3580         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), { }));
3581         break;
3582     }
3583     case DragControllerActionExited:
3584         m_page->dragController().dragExited(dragData);
3585         break;
3586
3587     case DragControllerActionPerformDragOperation: {
3588         m_page->dragController().performDragOperation(dragData);
3589         break;
3590     }
3591
3592     default:
3593         ASSERT_NOT_REACHED();
3594     }
3595 }
3596 #else
3597 void WebPage::performDragControllerAction(uint64_t action, const WebCore::DragData& dragData, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray)
3598 {
3599     if (!m_page) {
3600         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0, { }));
3601         return;
3602     }
3603
3604     switch (action) {
3605     case DragControllerActionEntered: {
3606         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
3607         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), m_page->dragCaretController().caretRectInRootViewCoordinates()));
3608         break;
3609
3610     }
3611     case DragControllerActionUpdated: {
3612         DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
3613         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted(), m_page->dragCaretController().caretRectInRootViewCoordinates()));
3614         break;
3615     }
3616     case DragControllerActionExited:
3617         m_page->dragController().dragExited(dragData);
3618         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0, { }));
3619         break;
3620         
3621     case DragControllerActionPerformDragOperation: {
3622         ASSERT(!m_pendingDropSandboxExtension);
3623
3624         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
3625         for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
3626             if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionsHandleArray[i]))
3627                 m_pendingDropExtensionsForFileUpload.append(extension);
3628         }
3629
3630         bool handled = m_page->dragController().performDragOperation(dragData);
3631
3632         // If we started loading a local file, the sandbox extension tracker would have adopted this
3633         // pending drop sandbox extension. If not, we'll play it safe and clear it.
3634         m_pendingDropSandboxExtension = nullptr;
3635
3636         m_pendingDropExtensionsForFileUpload.clear();
3637 #if ENABLE(DATA_INTERACTION)
3638         send(Messages::WebPageProxy::DidPerformDataInteractionControllerOperation(handled));
3639 #else
3640         UNUSED_PARAM(handled);
3641 #endif
3642         break;
3643     }
3644
3645     default:
3646         ASSERT_NOT_REACHED();
3647     }
3648 }
3649 #endif
3650
3651 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
3652 {
3653     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController().dragOffset().x(), clientPosition.y() + m_page->dragController().dragOffset().y());
3654     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController().dragOffset().x(), globalPosition.y() + m_page->dragController().dragOffset().y());
3655
3656     m_page->dragController().dragEnded();
3657     FrameView* view = m_page->mainFrame().view();
3658     if (!view)
3659         return;
3660     // FIXME: These are fake modifier keys here, but they should be real ones instead.
3661     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime(), 0, WebCore::NoTap);
3662     m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
3663
3664     send(Messages::WebPageProxy::DidEndDragging());
3665 }
3666
3667 void WebPage::willPerformLoadDragDestinationAction()
3668 {
3669     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(WTFMove(m_pendingDropSandboxExtension));
3670 }
3671
3672 void WebPage::mayPerformUploadDragDestinationAction()
3673 {
3674     for (size_t i = 0; i < m_pendingDropExtensionsForFileUpload.size(); i++)
3675         m_pendingDropExtensionsForFileUpload[i]->consumePermanently();
3676     m_pendingDropExtensionsForFileUpload.clear();
3677 }
3678
3679 void WebPage::didStartDrag()
3680 {
3681     m_isStartingDrag = false;
3682     m_page->mainFrame().eventHandler().didStartDrag();
3683 }
3684
3685 void WebPage::dragCancelled()
3686 {
3687     m_isStartingDrag = false;
3688     m_page->mainFrame().eventHandler().dragCancelled();
3689 }
3690     
3691 #endif // ENABLE(DRAG_SUPPORT)
3692
3693 WebUndoStep* WebPage::webUndoStep(uint64_t stepID)
3694 {
3695     return m_undoStepMap.get(stepID);
3696 }
3697
3698 void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry)
3699 {
3700     m_undoStepMap.set(stepID, entry);
3701 }
3702
3703 void WebPage::removeWebEditCommand(uint64_t stepID)
3704 {
3705     m_undoStepMap.remove(stepID);
3706 }
3707
3708 bool WebPage::isAlwaysOnLoggingAllowed() const
3709 {
3710     return corePage() && corePage()->isAlwaysOnLoggingAllowed();
3711 }
3712
3713 void WebPage::unapplyEditCommand(uint64_t stepID)
3714 {
3715     WebUndoStep* step = webUndoStep(stepID);
3716     if (!step)
3717         return;
3718
3719     step->step().unapply();
3720 }
3721
3722 void WebPage::reapplyEditCommand(uint64_t stepID)
3723 {
3724     WebUndoStep* step = webUndoStep(stepID);
3725     if (!step)
3726         return;
3727
3728     m_isInRedo = true;
3729     step->step().reapply();
3730     m_isInRedo = false;
3731 }
3732
3733 void WebPage::didRemoveEditCommand(uint64_t commandID)
3734 {
3735     removeWebEditCommand(commandID);
3736 }
3737
3738 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
3739 {
3740     m_activePopupMenu = menu;
3741 }
3742
3743 #if ENABLE(INPUT_TYPE_COLOR)
3744
3745 void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
3746 {
3747     m_activeColorChooser = colorChooser;
3748 }
3749
3750 void WebPage::didEndColorPicker()
3751 {
3752     m_activeColorChooser->didEndChooser();
3753 }
3754
3755 void WebPage::didChooseColor(const WebCore::Color& color)
3756 {
3757     m_activeColorChooser->didChooseColor(color);
3758 }
3759
3760 #endif
3761
3762 void WebPage::setActiveOpenPanelResultListener(Ref<WebOpenPanelResultListener>&& openPanelResultListener)
3763 {
3764     m_activeOpenPanelResultListener = WTFMove(openPanelResultListener);
3765 }
3766
3767 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
3768 {
3769     return m_page->findString(target, options);
3770 }
3771
3772 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
3773 {
3774     findController().findString(string, static_cast<FindOptions>(options), maxMatchCount);
3775 }
3776
3777 void WebPage::findStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3778 {
3779     findController().findStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3780 }
3781
3782 void WebPage::getImageForFindMatch(uint32_t matchIndex)
3783 {
3784     findController().getImageForFindMatch(matchIndex);
3785 }
3786
3787 void WebPage::selectFindMatch(uint32_t matchIndex)
3788 {
3789     findController().selectFindMatch(matchIndex);
3790 }
3791
3792 void WebPage::hideFindUI()
3793 {
3794     findController().hideFindUI();
3795 }
3796
3797 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3798 {
3799     findController().countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3800 }
3801
3802 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
3803 {
3804     changeSelectedIndex(newIndex);
3805     m_activePopupMenu = nullptr;
3806 }
3807
3808 void WebPage::changeSelectedIndex(int32_t index)
3809 {
3810     if (!m_activePopupMenu)
3811         return;
3812
3813     m_activePopupMenu->didChangeSelectedIndex(index);
3814 }
3815
3816 #if PLATFORM(IOS)
3817 void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, const IPC::DataReference& iconData)
3818 {
3819     if (!m_activeOpenPanelResultListener)
3820         return;
3821
3822     RefPtr<Icon> icon;
3823     if (!iconData.isEmpty()) {
3824         RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
3825         RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
3826         RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
3827         icon = Icon::createIconForImage(imageRef.get());
3828     }
3829
3830     m_activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
3831     m_activeOpenPanelResultListener = nullptr;
3832 }
3833 #endif
3834
3835 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
3836 {
3837     if (!m_activeOpenPanelResultListener)
3838         return;
3839
3840     m_activeOpenPanelResultListener->didChooseFiles(files);
3841     m_activeOpenPanelResultListener = nullptr;
3842 }
3843
3844 void WebPage::didCancelForOpenPanel()
3845 {
3846     m_activeOpenPanelResultListener = nullptr;
3847 }
3848
3849 #if ENABLE(SANDBOX_EXTENSIONS)
3850 void WebPage::extendSandboxForFilesFromOpenPanel(SandboxExtension::HandleArray&& handles)
3851 {
3852     for (size_t i = 0; i < handles.size(); ++i) {
3853         bool result = SandboxExtension::consumePermanently(handles[i]);
3854         if (!result) {
3855             // We have reports of cases where this fails for some unknown reason, <rdar://problem/10156710>.
3856             WTFLogAlways("WebPage::extendSandboxForFileFromOpenPanel(): Could not consume a sandbox extension");
3857         }
3858     }
3859 }
3860 #endif
3861
3862 #if ENABLE(GEOLOCATION)
3863 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
3864 {
3865     geolocationPermissionRequestManager().didReceiveGeolocationPermissionDecision(geolocationID, allowed);
3866 }
3867 #endif
3868
3869 void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
3870 {
3871     notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
3872 }
3873
3874 #if ENABLE(MEDIA_STREAM)
3875 void WebPage::userMediaAccessWasGranted(uint64_t userMediaID, String&& audioDeviceUID, String&& videoDeviceUID, String&& mediaDeviceIdentifierHashSalt)
3876 {
3877     m_userMediaPermissionRequestManager->userMediaAccessWasGranted(userMediaID, WTFMove(audioDeviceUID), WTFMove(videoDeviceUID), WTFMove(mediaDeviceIdentifierHashSalt));
3878 }
3879
3880 void WebPage::userMediaAccessWasDenied(uint64_t userMediaID, uint64_t reason, String&& invalidConstraint)
3881 {
3882     m_userMediaPermissionRequestManager->userMediaAccessWasDenied(userMediaID, static_cast<UserMediaRequest::MediaAccessDenialReason>(reason), WTFMove(invalidConstraint));
3883 }
3884
3885 void WebPage::didCompleteMediaDeviceEnumeration(uint64_t userMediaID, const Vector<CaptureDevice>& devices, String&& deviceIdentifierHashSalt, bool originHasPersistentAccess)
3886 {
3887     m_userMediaPermissionRequestManager->didCompleteMediaDeviceEnumeration(userMediaID, devices, WTFMove(deviceIdentifierHashSalt), originHasPersistentAccess);
3888 }
3889 #if ENABLE(SANDBOX_EXTENSIONS)
3890 void WebPage::grantUserMediaDeviceSandboxExtensions(const MediaDeviceSandboxExtensions& extensions)
3891 {
3892     m_userMediaPermissionRequestManager->grantUserMediaDeviceSandboxExtensions(extensions);
3893 }
3894
3895 void WebPage::revokeUserMediaDeviceSandboxExtensions(const Vector<String>& extensionIDs)
3896 {
3897     m_userMediaPermissionRequestManager->revokeUserMediaDeviceSandboxExtensions(extensionIDs);
3898 }
3899 #endif
3900 #endif
3901
3902 #if !PLATFORM(IOS)
3903 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
3904 {
3905     Frame& frame = m_page->focusController().focusedOrMainFrame();
3906     frame.editor().advanceToNextMisspelling(startBeforeSelection);
3907 }
3908 #endif
3909
3910 bool WebPage::hasRichlyEditableSelection() const
3911 {
3912     auto& frame = m_page->focusController().focusedOrMainFrame();
3913     if (m_page->dragCaretController().isContentRichlyEditable())
3914         return true;
3915
3916     return frame.selection().selection().isContentRichlyEditable();
3917 }
3918
3919 void WebPage::changeSpellingToWord(const String& word)
3920 {
3921     replaceSelectionWithText(&m_page->focusController().focusedOrMainFrame(), word);
3922 }
3923
3924 void WebPage::unmarkAllMisspellings()
3925 {
3926     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3927         if (Document* document = frame->document())
3928             document->markers().removeMarkers(DocumentMarker::Spelling);
3929     }
3930 }
3931
3932 void WebPage::unmarkAllBadGrammar()
3933 {
3934     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3935         if (Document* document = frame->document())
3936             document->markers().removeMarkers(DocumentMarker::Grammar);
3937     }
3938 }
3939
3940 #if USE(APPKIT)
3941 void WebPage::uppercaseWord()
3942 {
3943     m_page->focusController().focusedOrMainFrame().editor().uppercaseWord();
3944 }
3945
3946 void WebPage::lowercaseWord()
3947 {
3948     m_page->focusController().focusedOrMainFrame().editor().lowercaseWord();
3949 }
3950
3951 void WebPage::capitalizeWord()
3952 {
3953     m_page->focusController().focusedOrMainFrame().editor().capitalizeWord();
3954 }
3955 #endif
3956     
3957 void WebPage::setTextForActivePopupMenu(int32_t index)
3958 {
3959     if (!m_activePopupMenu)
3960         return;
3961
3962     m_activePopupMenu->setTextForIndex(index);
3963 }
3964
3965 #if PLATFORM(GTK)
3966 void WebPage::failedToShowPopupMenu()
3967 {
3968     if (!m_activePopupMenu)
3969         return;
3970
3971     m_activePopupMenu->client()->popupDidHide();
3972 }
3973 #endif
3974
3975 #if ENABLE(CONTEXT_MENUS)
3976 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
3977 {
3978     if (!m_contextMenu)
3979         return;
3980
3981     m_contextMenu->itemSelected(item);
3982     m_contextMenu = nullptr;
3983 }
3984 #endif
3985
3986 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
3987 {
3988     bool selectReplacement = true;
3989     bool smartReplace = false;
3990     return frame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
3991 }
3992
3993 #if !PLATFORM(IOS)
3994 void WebPage::clearSelection()
3995 {
3996     m_page->focusController().focusedOrMainFrame().selection().clear();
3997 }
3998 #endif
3999
4000 void WebPage::restoreSelectionInFocusedEditableElement()
4001 {
4002     Frame& frame = m_page->focusController().focusedOrMainFrame();
4003     if (!frame.selection().isNone())
4004         return;
4005
4006     if (auto document = frame.document()) {
4007         if (auto element = document->focusedElement())
4008             element->updateFocusAppearance(SelectionRestorationMode::Restore, SelectionRevealMode::DoNotReveal);
4009     }
4010 }
4011
4012 bool WebPage::mainFrameHasCustomContentProvider() const
4013 {
4014     if (Frame* frame = mainFrame()) {
4015         WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
4016         ASSERT(webFrameLoaderClient);
4017         return webFrameLoaderClient->frameHasCustomContentProvider();
4018     }
4019
4020     return false;
4021 }
4022
4023 void WebPage::addMIMETypeWithCustomContentProvider(const String& mimeType)
4024 {
4025     m_mimeTypesWithCustomContentProviders.add(mimeType);
4026 }
4027
4028 void WebPage::updateMainFrameScrollOffsetPinning()
4029 {
4030     Frame& frame = m_page->mainFrame();
4031     ScrollPosition scrollPosition = frame.view()->scrollPosition();
4032     ScrollPosition maximumScrollPosition = frame.view()->maximumScrollPosition();
4033     ScrollPosition minimumScrollPosition = frame.view()->minimumScrollPosition();
4034
4035     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
4036     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
4037     bool isPinnedToTopSide = (scrollPosition.y() <= minimumScrollPosition.y());
4038     bool isPinnedToBottomSide = (scrollPosition.y() >= maximumScrollPosition.y());
4039
4040     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide || isPinnedToTopSide != m_cachedMainFrameIsPinnedToTopSide || isPinnedToBottomSide != m_cachedMainFrameIsPinnedToBottomSide) {
4041         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide, isPinnedToTopSide, isPinnedToBottomSide));
4042         
4043         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
4044         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
4045         m_cachedMainFrameIsPinnedToTopSide = isPinnedToTopSide;
4046         m_cachedMainFrameIsPinnedToBottomSide = isPinnedToBottomSide;
4047     }
4048 }
4049
4050 void WebPage::mainFrameDidLayout()
4051 {
4052     unsigned pageCount = m_page->pageCount();
4053     if (pageCount != m_cachedPageCount) {
4054         send(Messages::WebPageProxy::DidChangePageCount(pageCount));
4055         m_cachedPageCount = pageCount;
4056     }
4057
4058 #if PLATFORM(MAC)
4059     m_viewGestureGeometryCollector->mainFrameDidLayout();
4060 #endif
4061 #if PLATFORM(IOS)
4062     if (FrameView* frameView = mainFrameView()) {
4063         IntSize newContentSize = frameView->contentsSize();
4064         if (m_viewportConfiguration.setContentsSize(newContentSize))
4065             viewportConfigurationChanged();
4066     }
4067     findController().redraw();
4068 #endif
4069 }
4070
4071 void WebPage::addPluginView(PluginView* pluginView)
4072 {
4073     ASSERT(!m_pluginViews.contains(pluginView));
4074
4075     m_pluginViews.add(pluginView);
4076     m_hasSeenPlugin = true;
4077 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4078     LOG(Plugins, "Primary Plug-In Detection: triggering detection from addPluginView(%p)", pluginView);
4079     m_determinePrimarySnapshottedPlugInTimer.startOneShot(0_s);
4080 #endif
4081 }
4082
4083 void WebPage::removePluginView(PluginView* pluginView)
4084 {
4085     ASSERT(m_pluginViews.contains(pluginView));
4086
4087     m_pluginViews.remove(pluginView);
4088 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4089     LOG(Plugins, "Primary Plug-In Detection: removePluginView(%p)", pluginView);
4090 #endif
4091 }
4092
4093 void WebPage::sendSetWindowFrame(const FloatRect& windowFrame)
4094 {
4095 #if PLATFORM(COCOA)
4096     m_hasCachedWindowFrame = false;
4097 #endif
4098     send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
4099 }
4100
4101 #if PLATFORM(COCOA)
4102 void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates)
4103 {
4104     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
4105     m_windowFrameInUnflippedScreenCoordinates = windowFrameInUnflippedScreenCoordinates;
4106     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
4107     m_accessibilityPosition = accessibilityViewCoordinates;
4108     
4109     // Tell all our plug-in views that the window and view frames have changed.
4110     for (auto* pluginView : m_pluginViews)
4111         pluginView->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates));
4112
4113     m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty();
4114 }
4115 #endif
4116
4117 void WebPage::setMainFrameIsScrollable(bool isScrollable)
4118 {
4119     m_mainFrameIsScrollable = isScrollable;
4120     m_drawingArea->mainFrameScrollabilityChanged(isScrollable);
4121
4122     if (FrameView* frameView = m_mainFrame->coreFrame()->view()) {
4123         frameView->setCanHaveScrollbars(isScrollable);
4124         frameView->setProhibitsScrolling(!isScrollable);
4125     }
4126 }
4127
4128 bool WebPage::windowIsFocused() const
4129 {
4130     return m_page->focusController().isActive();
4131 }
4132
4133 bool WebPage::windowAndWebPageAreFocused() const
4134 {
4135     if (!isVisible())
4136         return false;
4137
4138     return m_page->focusController().isFocused() && m_page->focusController().isActive();
4139 }
4140
4141 void WebPage::didReceiveMessage(IPC::Connection& connection, IPC::Decoder& decoder)
4142 {
4143     if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
4144         if (WebInspector* inspector = this->inspector())
4145             inspector->didReceiveMessage(connection, decoder);
4146         return;
4147     }
4148
4149     if (decoder.messageReceiverName() == Messages::WebInspectorUI::messageReceiverName()) {
4150         if (WebInspectorUI* inspectorUI = this->inspectorUI())
4151             inspectorUI->didReceiveMessage(connection, decoder);
4152         return;