ea995eebfee8a255e008ef0a179434615bc2d93b
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2012, 2013 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 "Arguments.h"
32 #include "DataReference.h"
33 #include "DecoderAdapter.h"
34 #include "DragControllerAction.h"
35 #include "DrawingArea.h"
36 #include "DrawingAreaMessages.h"
37 #include "EditingRange.h"
38 #include "EditorState.h"
39 #include "EventDispatcher.h"
40 #include "InjectedBundle.h"
41 #include "InjectedBundleBackForwardList.h"
42 #include "InjectedBundleUserMessageCoders.h"
43 #include "LayerTreeHost.h"
44 #include "Logging.h"
45 #include "NetscapePlugin.h"
46 #include "NotificationPermissionRequestManager.h"
47 #include "PageBanner.h"
48 #include "PluginProcessAttributes.h"
49 #include "PluginProxy.h"
50 #include "PluginView.h"
51 #include "PrintInfo.h"
52 #include "SelectionOverlayController.h"
53 #include "SessionState.h"
54 #include "SessionTracker.h"
55 #include "ShareableBitmap.h"
56 #include "TelephoneNumberOverlayController.h"
57 #include "VisitedLinkTableController.h"
58 #include "WKSharedAPICast.h"
59 #include "WebAlternativeTextClient.h"
60 #include "WebBackForwardListItem.h"
61 #include "WebBackForwardListProxy.h"
62 #include "WebChromeClient.h"
63 #include "WebColorChooser.h"
64 #include "WebContextMenu.h"
65 #include "WebContextMenuClient.h"
66 #include "WebContextMessages.h"
67 #include "WebCoreArgumentCoders.h"
68 #include "WebDocumentLoader.h"
69 #include "WebDragClient.h"
70 #include "WebEditorClient.h"
71 #include "WebEvent.h"
72 #include "WebEventConversion.h"
73 #include "WebFrame.h"
74 #include "WebFrameLoaderClient.h"
75 #include "WebFullScreenManager.h"
76 #include "WebFullScreenManagerMessages.h"
77 #include "WebGeolocationClient.h"
78 #include "WebImage.h"
79 #include "WebInspector.h"
80 #include "WebInspectorClient.h"
81 #include "WebInspectorMessages.h"
82 #include "WebNotificationClient.h"
83 #include "WebOpenPanelResultListener.h"
84 #include "WebPageCreationParameters.h"
85 #include "WebPageGroupProxy.h"
86 #include "WebPageMessages.h"
87 #include "WebPageProxyMessages.h"
88 #include "WebPlugInClient.h"
89 #include "WebPopupMenu.h"
90 #include "WebPreferencesStore.h"
91 #include "WebProcess.h"
92 #include "WebProcessProxyMessages.h"
93 #include "WebProgressTrackerClient.h"
94 #include "WebUndoStep.h"
95 #include <JavaScriptCore/APICast.h>
96 #include <WebCore/ArchiveResource.h>
97 #include <WebCore/Chrome.h>
98 #include <WebCore/ContextMenuController.h>
99 #include <WebCore/DatabaseManager.h>
100 #include <WebCore/DocumentFragment.h>
101 #include <WebCore/DocumentLoader.h>
102 #include <WebCore/DocumentMarkerController.h>
103 #include <WebCore/DragController.h>
104 #include <WebCore/DragData.h>
105 #include <WebCore/ElementIterator.h>
106 #include <WebCore/EventHandler.h>
107 #include <WebCore/FocusController.h>
108 #include <WebCore/FormState.h>
109 #include <WebCore/FrameLoadRequest.h>
110 #include <WebCore/FrameLoaderTypes.h>
111 #include <WebCore/FrameView.h>
112 #include <WebCore/HTMLFormElement.h>
113 #include <WebCore/HTMLInputElement.h>
114 #include <WebCore/HTMLPlugInElement.h>
115 #include <WebCore/HTMLPlugInImageElement.h>
116 #include <WebCore/HistoryController.h>
117 #include <WebCore/HistoryItem.h>
118 #include <WebCore/HitTestResult.h>
119 #include <WebCore/JSDOMWindow.h>
120 #include <WebCore/KeyboardEvent.h>
121 #include <WebCore/MIMETypeRegistry.h>
122 #include <WebCore/MainFrame.h>
123 #include <WebCore/MouseEvent.h>
124 #include <WebCore/Page.h>
125 #include <WebCore/PageThrottler.h>
126 #include <WebCore/PlatformKeyboardEvent.h>
127 #include <WebCore/PluginDocument.h>
128 #include <WebCore/PrintContext.h>
129 #include <WebCore/Range.h>
130 #include <WebCore/RenderLayer.h>
131 #include <WebCore/RenderTreeAsText.h>
132 #include <WebCore/RenderView.h>
133 #include <WebCore/ResourceBuffer.h>
134 #include <WebCore/ResourceRequest.h>
135 #include <WebCore/ResourceResponse.h>
136 #include <WebCore/RuntimeEnabledFeatures.h>
137 #include <WebCore/SchemeRegistry.h>
138 #include <WebCore/ScriptController.h>
139 #include <WebCore/SerializedScriptValue.h>
140 #include <WebCore/SessionID.h>
141 #include <WebCore/Settings.h>
142 #include <WebCore/ShadowRoot.h>
143 #include <WebCore/SharedBuffer.h>
144 #include <WebCore/SubframeLoader.h>
145 #include <WebCore/SubstituteData.h>
146 #include <WebCore/TextIterator.h>
147 #include <WebCore/UserInputBridge.h>
148 #include <WebCore/VisiblePosition.h>
149 #include <WebCore/VisibleUnits.h>
150 #include <WebCore/markup.h>
151 #include <bindings/ScriptValue.h>
152 #include <profiler/ProfilerDatabase.h>
153 #include <runtime/JSCInlines.h>
154 #include <runtime/JSCJSValue.h>
155 #include <runtime/JSLock.h>
156 #include <wtf/RunLoop.h>
157
158 #if ENABLE(MHTML)
159 #include <WebCore/MHTMLArchive.h>
160 #endif
161
162 #if ENABLE(BATTERY_STATUS)
163 #include "WebBatteryClient.h"
164 #endif
165
166 #if ENABLE(VIBRATION)
167 #include "WebVibrationClient.h"
168 #endif
169
170 #if ENABLE(PROXIMITY_EVENTS)
171 #include "WebDeviceProximityClient.h"
172 #endif
173
174 #if PLATFORM(COCOA)
175 #include "PDFPlugin.h"
176 #include "RemoteLayerTreeTransaction.h"
177 #include <WebCore/LegacyWebArchive.h>
178 #endif
179
180 #if PLATFORM(GTK)
181 #include <gtk/gtk.h>
182 #include "DataObjectGtk.h"
183 #include "WebPrintOperationGtk.h"
184 #endif
185
186 #if PLATFORM(IOS)
187 #include "WebVideoFullscreenManager.h"
188 #include <CoreGraphics/CoreGraphics.h>
189 #include <WebCore/Icon.h>
190 #endif
191
192 #ifndef NDEBUG
193 #include <wtf/RefCountedLeakCounter.h>
194 #endif
195
196 #if USE(COORDINATED_GRAPHICS)
197 #include "CoordinatedLayerTreeHostMessages.h"
198 #endif
199
200 using namespace JSC;
201 using namespace WebCore;
202
203 namespace WebKit {
204
205 class SendStopResponsivenessTimer {
206 public:
207     SendStopResponsivenessTimer(WebPage* page)
208         : m_page(page)
209     {
210     }
211     
212     ~SendStopResponsivenessTimer()
213     {
214         m_page->send(Messages::WebPageProxy::StopResponsivenessTimer());
215     }
216
217 private:
218     WebPage* m_page;
219 };
220
221 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
222
223 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
224 {
225     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
226
227     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
228         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
229
230     return page.release();
231 }
232
233 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
234     : m_pageID(pageID)
235     , m_viewSize(parameters.viewSize)
236     , m_hasSeenPlugin(false)
237     , m_useFixedLayout(false)
238     , m_drawsBackground(true)
239     , m_drawsTransparentBackground(false)
240     , m_isInRedo(false)
241     , m_isClosed(false)
242     , m_tabToLinks(false)
243     , m_asynchronousPluginInitializationEnabled(false)
244     , m_asynchronousPluginInitializationEnabledForAllPlugins(false)
245     , m_artificialPluginInitializationDelayEnabled(false)
246     , m_scrollingPerformanceLoggingEnabled(false)
247     , m_mainFrameIsScrollable(true)
248 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
249     , m_readyToFindPrimarySnapshottedPlugin(false)
250     , m_didFindPrimarySnapshottedPlugin(false)
251     , m_numberOfPrimarySnapshotDetectionAttempts(0)
252     , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
253 #endif
254 #if ENABLE(SERVICE_CONTROLS)
255     , m_serviceControlsEnabled(false)
256 #endif
257     , m_layerHostingMode(parameters.layerHostingMode)
258 #if PLATFORM(COCOA)
259     , m_pdfPluginEnabled(false)
260     , m_hasCachedWindowFrame(false)
261     , m_viewGestureGeometryCollector(*this)
262 #elif PLATFORM(GTK) && HAVE(ACCESSIBILITY)
263     , m_accessibilityObject(0)
264 #endif
265     , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
266     , m_sendDidUpdateViewStateTimer(RunLoop::main(), this, &WebPage::didUpdateViewStateTimerFired)
267     , m_formClient(std::make_unique<API::InjectedBundle::FormClient>())
268     , m_uiClient(std::make_unique<API::InjectedBundle::PageUIClient>())
269     , m_findController(this)
270 #if ENABLE(INPUT_TYPE_COLOR)
271     , m_activeColorChooser(0)
272 #endif
273 #if ENABLE(GEOLOCATION)
274     , m_geolocationPermissionRequestManager(this)
275 #endif
276     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
277     , m_canRunModal(parameters.canRunModal)
278     , m_isRunningModal(false)
279     , m_cachedMainFrameIsPinnedToLeftSide(true)
280     , m_cachedMainFrameIsPinnedToRightSide(true)
281     , m_cachedMainFrameIsPinnedToTopSide(true)
282     , m_cachedMainFrameIsPinnedToBottomSide(true)
283     , m_canShortCircuitHorizontalWheelEvents(false)
284     , m_numWheelEventHandlers(0)
285     , m_cachedPageCount(0)
286     , m_autoSizingShouldExpandToViewHeight(false)
287 #if ENABLE(CONTEXT_MENUS)
288     , m_isShowingContextMenu(false)
289 #endif
290 #if PLATFORM(IOS)
291     , m_lastVisibleContentRectUpdateID(0)
292     , m_hasReceivedVisibleContentRectsAfterDidCommitLoad(false)
293     , m_scaleWasSetByUIProcess(false)
294     , m_userHasChangedPageScaleFactor(false)
295     , m_userIsInteracting(false)
296     , m_screenSize(parameters.screenSize)
297     , m_availableScreenSize(parameters.availableScreenSize)
298     , m_inDynamicSizeUpdate(false)
299 #endif
300     , m_inspectorClient(0)
301     , m_backgroundColor(Color::white)
302     , m_maximumRenderingSuppressionToken(0)
303     , m_scrollPinningBehavior(DoNotPin)
304     , m_useAsyncScrolling(false)
305     , m_viewState(parameters.viewState)
306     , m_processSuppressionDisabledByWebPreference("Process suppression is disabled.")
307     , m_pendingNavigationID(0)
308     , m_pageScaleWithoutThumbnailScale(1)
309     , m_thumbnailScale(1)
310 #if ENABLE(WEBGL)
311     , m_systemWebGLPolicy(WebGLAllowCreation)
312 #endif
313     , m_pageOverlayController(*this)
314 {
315     ASSERT(m_pageID);
316     // FIXME: This is a non-ideal location for this Setting and
317     // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
318     Settings::setDefaultMinDOMTimerInterval(0.004);
319
320 #if PLATFORM(IOS)
321     Settings::setShouldManageAudioSession(true);
322 #endif
323
324     Page::PageClients pageClients;
325     pageClients.chromeClient = new WebChromeClient(this);
326 #if ENABLE(CONTEXT_MENUS)
327     pageClients.contextMenuClient = new WebContextMenuClient(this);
328 #endif
329     pageClients.editorClient = new WebEditorClient(this);
330 #if ENABLE(DRAG_SUPPORT)
331     pageClients.dragClient = new WebDragClient(this);
332 #endif
333     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
334 #if ENABLE(INSPECTOR)
335     m_inspectorClient = new WebInspectorClient(this);
336     pageClients.inspectorClient = m_inspectorClient;
337 #endif
338 #if USE(AUTOCORRECTION_PANEL)
339     pageClients.alternativeTextClient = new WebAlternativeTextClient(this);
340 #endif
341     pageClients.plugInClient = new WebPlugInClient(this);
342     pageClients.loaderClientForMainFrame = new WebFrameLoaderClient;
343     pageClients.progressTrackerClient = new WebProgressTrackerClient(*this);
344
345     pageClients.visitedLinkStore = VisitedLinkTableController::getOrCreate(parameters.visitedLinkTableID);
346
347     m_page = std::make_unique<Page>(pageClients);
348
349     m_drawingArea = DrawingArea::create(this, parameters);
350     m_drawingArea->setPaintingEnabled(false);
351     m_pageOverlayController.initialize();
352
353 #if ENABLE(ASYNC_SCROLLING)
354     m_useAsyncScrolling = parameters.store.getBoolValueForKey(WebPreferencesKey::threadedScrollingEnabledKey());
355     if (!m_drawingArea->supportsAsyncScrolling())
356         m_useAsyncScrolling = false;
357     m_page->settings().setScrollingCoordinatorEnabled(m_useAsyncScrolling);
358 #endif
359
360     m_mainFrame = WebFrame::createWithCoreMainFrame(this, &m_page->mainFrame());
361
362 #if ENABLE(BATTERY_STATUS)
363     WebCore::provideBatteryTo(m_page.get(), new WebBatteryClient(this));
364 #endif
365 #if ENABLE(GEOLOCATION)
366     WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this));
367 #endif
368 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
369     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
370 #endif
371 #if ENABLE(VIBRATION)
372     WebCore::provideVibrationTo(m_page.get(), new WebVibrationClient(this));
373 #endif
374 #if ENABLE(PROXIMITY_EVENTS)
375     WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this));
376 #endif
377
378 #if ENABLE(REMOTE_INSPECTOR)
379     m_page->setRemoteInspectionAllowed(true);
380 #endif
381
382     m_page->setCanStartMedia(false);
383     m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
384
385     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
386     m_page->setGroupName(m_pageGroup->identifier());
387     m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
388 #if PLATFORM(IOS)
389     m_page->setTextAutosizingWidth(parameters.textAutosizingWidth);
390 #endif
391
392     updatePreferences(parameters.store);
393     platformInitialize();
394
395     setUseFixedLayout(parameters.useFixedLayout);
396
397     setDrawsBackground(parameters.drawsBackground);
398     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
399
400     setUnderlayColor(parameters.underlayColor);
401
402     setPaginationMode(parameters.paginationMode);
403     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
404     setPageLength(parameters.pageLength);
405     setGapBetweenPages(parameters.gapBetweenPages);
406
407     // If the page is created off-screen, its visibilityState should be prerender.
408     m_page->setViewState(m_viewState);
409     if (!isVisible())
410         m_page->setIsPrerender();
411     m_page->createPageThrottler();
412
413     updateIsInWindow(true);
414
415     setMinimumLayoutSize(parameters.minimumLayoutSize);
416     setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
417     
418     setScrollPinningBehavior(parameters.scrollPinningBehavior);
419     setBackgroundExtendsBeyondPage(parameters.backgroundExtendsBeyondPage);
420
421     setTopContentInset(parameters.topContentInset);
422
423     m_userAgent = parameters.userAgent;
424
425     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
426     
427     if (!parameters.sessionState.isEmpty())
428         restoreSession(parameters.sessionState);
429
430     if (parameters.sessionID.isValid())
431         setSessionID(parameters.sessionID);
432
433     m_drawingArea->setPaintingEnabled(true);
434     
435     setMediaVolume(parameters.mediaVolume);
436
437     // We use the DidFirstLayout milestone to determine when to unfreeze the layer tree.
438     m_page->addLayoutMilestones(DidFirstLayout);
439
440     WebProcess::shared().addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, *this);
441
442     // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
443     WebProcess::shared().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID, *this);
444 #if USE(COORDINATED_GRAPHICS)
445     WebProcess::shared().addMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID, *this);
446 #endif
447 #if ENABLE(INSPECTOR)
448     WebProcess::shared().addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, *this);
449 #endif
450 #if ENABLE(FULLSCREEN_API)
451     WebProcess::shared().addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, *this);
452 #endif
453
454 #ifndef NDEBUG
455     webPageCounter.increment();
456 #endif
457
458 #if ENABLE(ASYNC_SCROLLING)
459     if (m_useAsyncScrolling)
460         WebProcess::shared().eventDispatcher().addScrollingTreeForPage(this);
461 #endif
462 }
463
464 void WebPage::reinitializeWebPage(const WebPageCreationParameters& parameters)
465 {
466     if (m_viewState != parameters.viewState)
467         setViewState(parameters.viewState);
468     if (m_layerHostingMode != parameters.layerHostingMode)
469         setLayerHostingMode(static_cast<unsigned>(parameters.layerHostingMode));
470 }
471
472 WebPage::~WebPage()
473 {
474     if (m_backForwardList)
475         m_backForwardList->detach();
476
477     ASSERT(!m_page);
478
479 #if ENABLE(ASYNC_SCROLLING)
480     if (m_useAsyncScrolling)
481         WebProcess::shared().eventDispatcher().removeScrollingTreeForPage(this);
482 #endif
483
484     m_sandboxExtensionTracker.invalidate();
485
486     for (auto* pluginView : m_pluginViews)
487         pluginView->webPageDestroyed();
488
489 #if !PLATFORM(IOS)
490     if (m_headerBanner)
491         m_headerBanner->detachFromPage();
492     if (m_footerBanner)
493         m_footerBanner->detachFromPage();
494 #endif // !PLATFORM(IOS)
495
496     WebProcess::shared().removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID);
497
498     // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
499     WebProcess::shared().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID);
500 #if USE(COORDINATED_GRAPHICS)
501     WebProcess::shared().removeMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID);
502 #endif
503 #if ENABLE(INSPECTOR)
504     WebProcess::shared().removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID);
505 #endif
506 #if ENABLE(FULLSCREEN_API)
507     WebProcess::shared().removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID);
508 #endif
509
510 #ifndef NDEBUG
511     webPageCounter.decrement();
512 #endif
513 }
514
515 void WebPage::dummy(bool&)
516 {
517 }
518
519 IPC::Connection* WebPage::messageSenderConnection()
520 {
521     return WebProcess::shared().parentProcessConnection();
522 }
523
524 uint64_t WebPage::messageSenderDestinationID()
525 {
526     return pageID();
527 }
528
529 #if ENABLE(CONTEXT_MENUS)
530 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClientBase* client)
531 {
532     m_contextMenuClient.initialize(client);
533 }
534 #endif
535
536 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClientBase* client)
537 {
538     m_editorClient.initialize(client);
539 }
540
541 void WebPage::setInjectedBundleFormClient(std::unique_ptr<API::InjectedBundle::FormClient> formClient)
542 {
543     if (!formClient) {
544         m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
545         return;
546     }
547
548     m_formClient = std::move(formClient);
549 }
550
551 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClientBase* client)
552 {
553     m_loaderClient.initialize(client);
554
555     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
556     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
557     // for backwards compatibility.
558     LayoutMilestones milestones = 0;
559     if (client) {
560         if (m_loaderClient.client().didFirstLayoutForFrame)
561             milestones |= WebCore::DidFirstLayout;
562         if (m_loaderClient.client().didFirstVisuallyNonEmptyLayoutForFrame)
563             milestones |= WebCore::DidFirstVisuallyNonEmptyLayout;
564     }
565
566     if (milestones)
567         listenForLayoutMilestones(milestones);
568 }
569
570 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClientBase* client)
571 {
572     m_policyClient.initialize(client);
573 }
574
575 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClientBase* client)
576 {
577     m_resourceLoadClient.initialize(client);
578 }
579
580 void WebPage::setInjectedBundleUIClient(std::unique_ptr<API::InjectedBundle::PageUIClient> uiClient)
581 {
582     if (!uiClient) {
583         m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
584         return;
585     }
586
587     m_uiClient = std::move(uiClient);
588 }
589
590 #if ENABLE(FULLSCREEN_API)
591 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClientBase* client)
592 {
593     m_fullScreenClient.initialize(client);
594 }
595 #endif
596
597 void WebPage::initializeInjectedBundleDiagnosticLoggingClient(WKBundlePageDiagnosticLoggingClientBase* client)
598 {
599     m_logDiagnosticMessageClient.initialize(client);
600 }
601
602 #if ENABLE(NETSCAPE_PLUGIN_API)
603 PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, HTMLPlugInElement* pluginElement, const Plugin::Parameters& parameters, String& newMIMEType)
604 {
605     String frameURLString = frame->coreFrame()->loader().documentLoader()->responseURL().string();
606     String pageURLString = m_page->mainFrame().loader().documentLoader()->responseURL().string();
607     PluginProcessType processType = pluginElement->displayState() == HTMLPlugInElement::WaitingForSnapshot ? PluginProcessTypeSnapshot : PluginProcessTypeNormal;
608
609     bool allowOnlyApplicationPlugins = !frame->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
610
611     uint64_t pluginProcessToken;
612     uint32_t pluginLoadPolicy;
613     String unavailabilityDescription;
614     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)))
615         return nullptr;
616
617     bool isBlockedPlugin = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy) == PluginModuleBlocked;
618
619     if (isBlockedPlugin || !pluginProcessToken) {
620 #if ENABLE(PDFKIT_PLUGIN)
621         String path = parameters.url.path();
622         if (shouldUsePDFPlugin() && (MIMETypeRegistry::isPDFOrPostScriptMIMEType(parameters.mimeType) || (parameters.mimeType.isEmpty() && (path.endsWith(".pdf", false) || path.endsWith(".ps", false))))) {
623             RefPtr<PDFPlugin> pdfPlugin = PDFPlugin::create(frame);
624             return pdfPlugin.release();
625         }
626 #else
627         UNUSED_PARAM(frame);
628 #endif
629     }
630
631     if (isBlockedPlugin) {
632         bool replacementObscured = false;
633         if (pluginElement->renderer()->isEmbeddedObject()) {
634             RenderEmbeddedObject* renderObject = toRenderEmbeddedObject(pluginElement->renderer());
635             renderObject->setPluginUnavailabilityReasonWithDescription(RenderEmbeddedObject::InsecurePluginVersion, unavailabilityDescription);
636             replacementObscured = renderObject->isReplacementObscured();
637             renderObject->setUnavailablePluginIndicatorIsHidden(replacementObscured);
638         }
639
640         send(Messages::WebPageProxy::DidBlockInsecurePluginVersion(parameters.mimeType, parameters.url.string(), frameURLString, pageURLString, replacementObscured));
641         return nullptr;
642     }
643
644     if (!pluginProcessToken)
645         return nullptr;
646
647     bool isRestartedProcess = (pluginElement->displayState() == HTMLPlugInElement::Restarting || pluginElement->displayState() == HTMLPlugInElement::RestartingWithPendingMouseClick);
648     return PluginProxy::create(pluginProcessToken, isRestartedProcess);
649 }
650
651 #endif // ENABLE(NETSCAPE_PLUGIN_API)
652
653 #if ENABLE(WEBGL) && !PLATFORM(COCOA)
654 WebCore::WebGLLoadPolicy WebPage::webGLPolicyForURL(WebFrame*, const String& /* url */)
655 {
656     return WebGLAllowCreation;
657 }
658
659 WebCore::WebGLLoadPolicy WebPage::resolveWebGLPolicyForURL(WebFrame*, const String& /* url */)
660 {
661     return WebGLAllowCreation;
662 }
663 #endif
664
665 EditorState WebPage::editorState() const
666 {
667     Frame& frame = m_page->focusController().focusedOrMainFrame();
668
669     EditorState result;
670
671     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
672         if (!pluginView->getSelectionString().isNull()) {
673             result.selectionIsNone = false;
674             result.selectionIsRange = true;
675             result.isInPlugin = true;
676             return result;
677         }
678     }
679
680     const VisibleSelection& selection = frame.selection().selection();
681
682     result.selectionIsNone = selection.isNone();
683     result.selectionIsRange = selection.isRange();
684     result.isContentEditable = selection.isContentEditable();
685     result.isContentRichlyEditable = selection.isContentRichlyEditable();
686     result.isInPasswordField = selection.isInPasswordField();
687     result.hasComposition = frame.editor().hasComposition();
688     result.shouldIgnoreCompositionSelectionChange = frame.editor().ignoreCompositionSelectionChange();
689
690 #if PLATFORM(IOS)
691     if (frame.editor().hasComposition()) {
692         RefPtr<Range> compositionRange = frame.editor().compositionRange();
693         Vector<WebCore::SelectionRect> compositionRects;
694         compositionRange->collectSelectionRects(compositionRects);
695         if (compositionRects.size())
696             result.firstMarkedRect = compositionRects[0].rect();
697         if (compositionRects.size() > 1)
698             result.lastMarkedRect = compositionRects.last().rect();
699         else
700             result.lastMarkedRect = result.firstMarkedRect;
701         result.markedText = plainText(compositionRange.get());
702     }
703     FrameView* view = frame.view();
704     if (selection.isCaret()) {
705         result.caretRectAtStart = view->contentsToRootView(frame.selection().absoluteCaretBounds());
706         result.caretRectAtEnd = result.caretRectAtStart;
707         // FIXME: The following check should take into account writing direction.
708         result.isReplaceAllowed = result.isContentEditable && atBoundaryOfGranularity(selection.start(), WordGranularity, DirectionForward);
709         result.wordAtSelection = plainText(wordRangeFromPosition(selection.start()).get());
710         result.characterBeforeSelection = characterBeforePosition(selection.start());
711     } else if (selection.isRange()) {
712         result.caretRectAtStart = view->contentsToRootView(VisiblePosition(selection.start()).absoluteCaretBounds());
713         result.caretRectAtEnd = view->contentsToRootView(VisiblePosition(selection.end()).absoluteCaretBounds());
714         RefPtr<Range> selectedRange = selection.toNormalizedRange();
715         selectedRange->collectSelectionRects(result.selectionRects);
716         convertSelectionRectsToRootView(view, result.selectionRects);
717         String selectedText = plainText(selectedRange.get(), TextIteratorDefaultBehavior, true);
718         // FIXME: We should disallow replace when the string contains only CJ characters.
719         result.isReplaceAllowed = result.isContentEditable && !result.isInPasswordField && !selectedText.containsOnlyWhitespace();
720         result.selectedTextLength = selectedText.length();
721         const int maxSelectedTextLength = 200;
722         if (selectedText.length() <= maxSelectedTextLength)
723             result.wordAtSelection = selectedText;
724     }
725 #endif
726
727 #if PLATFORM(GTK)
728     result.cursorRect = frame.selection().absoluteCaretBounds();
729 #endif
730
731     return result;
732 }
733
734 String WebPage::renderTreeExternalRepresentation() const
735 {
736     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
737 }
738
739 String WebPage::renderTreeExternalRepresentationForPrinting() const
740 {
741     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextPrintingMode);
742 }
743
744 uint64_t WebPage::renderTreeSize() const
745 {
746     if (!m_page)
747         return 0;
748     return m_page->renderTreeSize();
749 }
750
751 void WebPage::setTracksRepaints(bool trackRepaints)
752 {
753     if (FrameView* view = mainFrameView())
754         view->setTracksRepaints(trackRepaints);
755 }
756
757 bool WebPage::isTrackingRepaints() const
758 {
759     if (FrameView* view = mainFrameView())
760         return view->isTrackingRepaints();
761
762     return false;
763 }
764
765 void WebPage::resetTrackedRepaints()
766 {
767     if (FrameView* view = mainFrameView())
768         view->resetTrackedRepaints();
769 }
770
771 PassRefPtr<API::Array> WebPage::trackedRepaintRects()
772 {
773     FrameView* view = mainFrameView();
774     if (!view)
775         return API::Array::create();
776
777     Vector<RefPtr<API::Object>> repaintRects;
778     repaintRects.reserveInitialCapacity(view->trackedRepaintRects().size());
779
780     for (const auto& repaintRect : view->trackedRepaintRects())
781         repaintRects.uncheckedAppend(API::Rect::create(toAPI(repaintRect)));
782
783     return API::Array::create(std::move(repaintRects));
784 }
785
786 PluginView* WebPage::focusedPluginViewForFrame(Frame& frame)
787 {
788     if (!frame.document()->isPluginDocument())
789         return 0;
790
791     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame.document());
792
793     if (pluginDocument->focusedElement() != pluginDocument->pluginElement())
794         return 0;
795
796     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
797     return pluginView;
798 }
799
800 PluginView* WebPage::pluginViewForFrame(Frame* frame)
801 {
802     if (!frame->document()->isPluginDocument())
803         return 0;
804
805     PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document());
806     PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
807     return pluginView;
808 }
809
810 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
811 {
812     Frame& frame = m_page->focusController().focusedOrMainFrame();
813
814     if (PluginView* pluginView = focusedPluginViewForFrame(frame)) {
815         pluginView->handleEditingCommand(commandName, argument);
816         return;
817     }
818     
819     frame.editor().command(commandName).execute(argument);
820 }
821
822 bool WebPage::isEditingCommandEnabled(const String& commandName)
823 {
824     Frame& frame = m_page->focusController().focusedOrMainFrame();
825
826     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
827         return pluginView->isEditingCommandEnabled(commandName);
828     
829     Editor::Command command = frame.editor().command(commandName);
830     return command.isSupported() && command.isEnabled();
831 }
832     
833 void WebPage::clearMainFrameName()
834 {
835     if (Frame* frame = mainFrame())
836         frame->tree().clearName();
837 }
838
839 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
840 {
841     m_drawingArea->setRootCompositingLayer(layer);
842 }
843
844 void WebPage::exitAcceleratedCompositingMode()
845 {
846     m_drawingArea->setRootCompositingLayer(0);
847 }
848
849 void WebPage::close()
850 {
851     if (m_isClosed)
852         return;
853
854     m_isClosed = true;
855
856     // If there is still no URL, then we never loaded anything in this page, so nothing to report.
857     if (!mainWebFrame()->url().isEmpty())
858         reportUsedFeatures();
859
860     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
861         WebProcess::shared().injectedBundle()->willDestroyPage(this);
862
863 #if ENABLE(INSPECTOR)
864     m_inspector = 0;
865 #endif
866 #if ENABLE(FULLSCREEN_API)
867     m_fullScreenManager = 0;
868 #endif
869
870     if (m_activePopupMenu) {
871         m_activePopupMenu->disconnectFromPage();
872         m_activePopupMenu = 0;
873     }
874
875     if (m_activeOpenPanelResultListener) {
876         m_activeOpenPanelResultListener->disconnectFromPage();
877         m_activeOpenPanelResultListener = 0;
878     }
879
880 #if ENABLE(INPUT_TYPE_COLOR)
881     if (m_activeColorChooser) {
882         m_activeColorChooser->disconnectFromPage();
883         m_activeColorChooser = 0;
884     }
885 #endif
886
887 #if PLATFORM(GTK)
888     if (m_printOperation) {
889         m_printOperation->disconnectFromPage();
890         m_printOperation = nullptr;
891     }
892 #endif
893
894     m_sandboxExtensionTracker.invalidate();
895
896 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
897     m_determinePrimarySnapshottedPlugInTimer.stop();
898 #endif
899
900 #if ENABLE(CONTEXT_MENUS)
901     m_contextMenuClient.initialize(0);
902 #endif
903     m_editorClient.initialize(0);
904     m_formClient = std::make_unique<API::InjectedBundle::FormClient>();
905     m_loaderClient.initialize(0);
906     m_policyClient.initialize(0);
907     m_resourceLoadClient.initialize(0);
908     m_uiClient = std::make_unique<API::InjectedBundle::PageUIClient>();
909 #if ENABLE(FULLSCREEN_API)
910     m_fullScreenClient.initialize(0);
911 #endif
912     m_logDiagnosticMessageClient.initialize(0);
913
914     m_printContext = nullptr;
915     m_mainFrame->coreFrame()->loader().detachFromParent();
916     m_page = nullptr;
917     m_drawingArea = nullptr;
918
919     bool isRunningModal = m_isRunningModal;
920     m_isRunningModal = false;
921
922     // The WebPage can be destroyed by this call.
923     WebProcess::shared().removeWebPage(m_pageID);
924
925     if (isRunningModal)
926         RunLoop::main().stop();
927 }
928
929 void WebPage::tryClose()
930 {
931     SendStopResponsivenessTimer stopper(this);
932
933     if (!corePage()->userInputBridge().tryClosePage()) {
934         send(Messages::WebPageProxy::StopResponsivenessTimer());
935         return;
936     }
937
938     send(Messages::WebPageProxy::ClosePage(true));
939 }
940
941 void WebPage::sendClose()
942 {
943     send(Messages::WebPageProxy::ClosePage(false));
944 }
945
946 void WebPage::loadURLInFrame(const String& url, uint64_t frameID)
947 {
948     WebFrame* frame = WebProcess::shared().webFrame(frameID);
949     if (!frame)
950         return;
951
952     frame->coreFrame()->loader().load(FrameLoadRequest(frame->coreFrame(), ResourceRequest(URL(URL(), url))));
953 }
954
955 void WebPage::loadRequest(uint64_t navigationID, const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle, IPC::MessageDecoder& decoder)
956 {
957     SendStopResponsivenessTimer stopper(this);
958
959     RefPtr<API::Object> userData;
960     InjectedBundleUserMessageDecoder userMessageDecoder(userData);
961     if (!decoder.decode(userMessageDecoder))
962         return;
963
964     ASSERT(!m_pendingNavigationID);
965     m_pendingNavigationID = navigationID;
966
967     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
968
969     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
970     // to all the client to set up any needed state.
971     m_loaderClient.willLoadURLRequest(this, request, userData.get());
972
973     // Initate the load in WebCore.
974     corePage()->userInputBridge().loadRequest(FrameLoadRequest(m_mainFrame->coreFrame(), request));
975
976     ASSERT(!m_pendingNavigationID);
977 }
978
979 void WebPage::loadDataImpl(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
980 {
981     SendStopResponsivenessTimer stopper(this);
982
983     RefPtr<API::Object> userData;
984     InjectedBundleUserMessageDecoder userMessageDecoder(userData);
985     if (!decoder.decode(userMessageDecoder))
986         return;
987
988     ResourceRequest request(baseURL);
989     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
990
991     // Let the InjectedBundle know we are about to start the load, passing the user data from the UIProcess
992     // to all the client to set up any needed state.
993     m_loaderClient.willLoadDataRequest(this, request, const_cast<SharedBuffer*>(substituteData.content()), substituteData.mimeType(), substituteData.textEncoding(), substituteData.failingURL(), userData.get());
994
995     // Initate the load in WebCore.
996     m_mainFrame->coreFrame()->loader().load(FrameLoadRequest(m_mainFrame->coreFrame(), request, substituteData));
997 }
998
999 void WebPage::loadString(const String& htmlString, const String& MIMEType, const URL& baseURL, const URL& unreachableURL, IPC::MessageDecoder& decoder)
1000 {
1001     if (!htmlString.isNull() && htmlString.is8Bit()) {
1002         RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters8()), htmlString.length() * sizeof(LChar));
1003         loadDataImpl(sharedBuffer, MIMEType, ASCIILiteral("latin1"), baseURL, unreachableURL, decoder);
1004     } else {
1005         RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters16()), htmlString.length() * sizeof(UChar));
1006         loadDataImpl(sharedBuffer, MIMEType, ASCIILiteral("utf-16"), baseURL, unreachableURL, decoder);
1007     }
1008 }
1009
1010 void WebPage::loadData(const IPC::DataReference& data, const String& MIMEType, const String& encodingName, const String& baseURLString, IPC::MessageDecoder& decoder)
1011 {
1012     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(data.data()), data.size());
1013     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1014     loadDataImpl(sharedBuffer, MIMEType, encodingName, baseURL, URL(), decoder);
1015 }
1016
1017 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString, IPC::MessageDecoder& decoder)
1018 {
1019     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1020     loadString(htmlString, ASCIILiteral("text/html"), baseURL, URL(), decoder);
1021 }
1022
1023 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString, IPC::MessageDecoder& decoder)
1024 {
1025     URL baseURL = baseURLString.isEmpty() ? blankURL() : URL(URL(), baseURLString);
1026     URL unreachableURL = unreachableURLString.isEmpty() ? URL() : URL(URL(), unreachableURLString);
1027     loadString(htmlString, ASCIILiteral("text/html"), baseURL, unreachableURL, decoder);
1028 }
1029
1030 void WebPage::loadPlainTextString(const String& string, IPC::MessageDecoder& decoder)
1031 {
1032     loadString(string, ASCIILiteral("text/plain"), blankURL(), URL(), decoder);
1033 }
1034
1035 void WebPage::loadWebArchiveData(const IPC::DataReference& webArchiveData, IPC::MessageDecoder& decoder)
1036 {
1037     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(webArchiveData.data()), webArchiveData.size() * sizeof(uint8_t));
1038     loadDataImpl(sharedBuffer, ASCIILiteral("application/x-webarchive"), ASCIILiteral("utf-16"), blankURL(), URL(), decoder);
1039 }
1040
1041 void WebPage::stopLoadingFrame(uint64_t frameID)
1042 {
1043     WebFrame* frame = WebProcess::shared().webFrame(frameID);
1044     if (!frame)
1045         return;
1046
1047     corePage()->userInputBridge().stopLoadingFrame(frame->coreFrame());
1048 }
1049
1050 void WebPage::stopLoading()
1051 {
1052     SendStopResponsivenessTimer stopper(this);
1053
1054     corePage()->userInputBridge().stopLoadingFrame(m_mainFrame->coreFrame());
1055 }
1056
1057 bool WebPage::defersLoading() const
1058 {
1059     return m_page->defersLoading();
1060 }
1061
1062 void WebPage::setDefersLoading(bool defersLoading)
1063 {
1064     m_page->setDefersLoading(defersLoading);
1065 }
1066
1067 void WebPage::reload(uint64_t navigationID, bool reloadFromOrigin, const SandboxExtension::Handle& sandboxExtensionHandle)
1068 {
1069     SendStopResponsivenessTimer stopper(this);
1070
1071     ASSERT(!m_pendingNavigationID);
1072     m_pendingNavigationID = navigationID;
1073
1074     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
1075     corePage()->userInputBridge().reloadFrame(m_mainFrame->coreFrame(), reloadFromOrigin);
1076 }
1077
1078 void WebPage::goForward(uint64_t backForwardItemID)
1079 {
1080     SendStopResponsivenessTimer stopper(this);
1081
1082     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1083     ASSERT(item);
1084     if (!item)
1085         return;
1086
1087     m_page->goToItem(item, FrameLoadTypeForward);
1088 }
1089
1090 void WebPage::goBack(uint64_t backForwardItemID)
1091 {
1092     SendStopResponsivenessTimer stopper(this);
1093
1094     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1095     ASSERT(item);
1096     if (!item)
1097         return;
1098
1099     m_page->goToItem(item, FrameLoadTypeBack);
1100 }
1101
1102 void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
1103 {
1104     SendStopResponsivenessTimer stopper(this);
1105
1106     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
1107     ASSERT(item);
1108     if (!item)
1109         return;
1110
1111     m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
1112 }
1113
1114 void WebPage::tryRestoreScrollPosition()
1115 {
1116     m_page->mainFrame().loader().history().restoreScrollPositionAndViewState();
1117 }
1118
1119 void WebPage::layoutIfNeeded()
1120 {
1121     if (m_mainFrame->coreFrame()->view())
1122         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
1123 }
1124
1125 WebPage* WebPage::fromCorePage(Page* page)
1126 {
1127     return static_cast<WebChromeClient&>(page->chrome().client()).page();
1128 }
1129
1130 void WebPage::setSize(const WebCore::IntSize& viewSize)
1131 {
1132     if (m_viewSize == viewSize)
1133         return;
1134
1135     FrameView* view = m_page->mainFrame().view();
1136     view->resize(viewSize);
1137     m_drawingArea->setNeedsDisplay();
1138     
1139     m_viewSize = viewSize;
1140
1141 #if USE(TILED_BACKING_STORE)
1142     if (view->useFixedLayout())
1143         sendViewportAttributesChanged();
1144 #endif
1145
1146     m_pageOverlayController.didChangeViewSize();
1147 }
1148
1149 #if USE(TILED_BACKING_STORE)
1150 void WebPage::setFixedVisibleContentRect(const IntRect& rect)
1151 {
1152     ASSERT(m_useFixedLayout);
1153
1154     m_page->mainFrame().view()->setFixedVisibleContentRect(rect);
1155 }
1156
1157 void WebPage::sendViewportAttributesChanged()
1158 {
1159     ASSERT(m_useFixedLayout);
1160
1161     // Viewport properties have no impact on zero sized fixed viewports.
1162     if (m_viewSize.isEmpty())
1163         return;
1164
1165     // Recalculate the recommended layout size, when the available size (device pixel) changes.
1166     Settings& settings = m_page->settings();
1167
1168     int minimumLayoutFallbackWidth = std::max(settings.layoutFallbackWidth(), m_viewSize.width());
1169
1170     // If unset  we use the viewport dimensions. This fits with the behavior of desktop browsers.
1171     int deviceWidth = (settings.deviceWidth() > 0) ? settings.deviceWidth() : m_viewSize.width();
1172     int deviceHeight = (settings.deviceHeight() > 0) ? settings.deviceHeight() : m_viewSize.height();
1173
1174     ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, 1, m_viewSize);
1175
1176     FrameView* view = m_page->mainFrame().view();
1177
1178     // If no layout was done yet set contentFixedOrigin to (0,0).
1179     IntPoint contentFixedOrigin = view->didFirstLayout() ? view->fixedVisibleContentRect().location() : IntPoint();
1180
1181     // Put the width and height to the viewport width and height. In css units however.
1182     // Use FloatSize to avoid truncated values during scale.
1183     FloatSize contentFixedSize = m_viewSize;
1184
1185 #if ENABLE(CSS_DEVICE_ADAPTATION)
1186     // CSS viewport descriptors might be applied to already affected viewport size
1187     // if the page enables/disables stylesheets, so need to keep initial viewport size.
1188     view->setInitialViewportSize(roundedIntSize(contentFixedSize));
1189 #endif
1190
1191     contentFixedSize.scale(1 / attr.initialScale);
1192     setFixedVisibleContentRect(IntRect(contentFixedOrigin, roundedIntSize(contentFixedSize)));
1193
1194     attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
1195
1196     // This also takes care of the relayout.
1197     setFixedLayoutSize(roundedIntSize(attr.layoutSize));
1198
1199     send(Messages::WebPageProxy::DidChangeViewportProperties(attr));
1200 }
1201 #endif
1202
1203 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
1204 {
1205     FrameView* frameView = m_page->mainFrame().view();
1206
1207     IntPoint scrollPosition = frameView->scrollPosition();
1208     IntPoint maximumScrollPosition = frameView->maximumScrollPosition();
1209
1210     // If the current scroll position in a direction is the max scroll position 
1211     // we don't want to scroll at all.
1212     IntSize newScrollOffset;
1213     if (scrollPosition.x() < maximumScrollPosition.x())
1214         newScrollOffset.setWidth(scrollOffset.width());
1215     if (scrollPosition.y() < maximumScrollPosition.y())
1216         newScrollOffset.setHeight(scrollOffset.height());
1217
1218     if (newScrollOffset.isZero())
1219         return;
1220
1221     frameView->setScrollPosition(frameView->scrollPosition() + newScrollOffset);
1222 }
1223
1224 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
1225 {
1226     GraphicsContextStateSaver stateSaver(graphicsContext);
1227     graphicsContext.clip(rect);
1228
1229     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
1230 }
1231
1232 double WebPage::textZoomFactor() const
1233 {
1234     Frame* frame = m_mainFrame->coreFrame();
1235     if (!frame)
1236         return 1;
1237     return frame->textZoomFactor();
1238 }
1239
1240 void WebPage::setTextZoomFactor(double zoomFactor)
1241 {
1242     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1243     if (pluginView && pluginView->handlesPageScaleFactor())
1244         return;
1245
1246     Frame* frame = m_mainFrame->coreFrame();
1247     if (!frame)
1248         return;
1249     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
1250 }
1251
1252 double WebPage::pageZoomFactor() const
1253 {
1254     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1255     if (pluginView && pluginView->handlesPageScaleFactor())
1256         return pluginView->pageScaleFactor();
1257
1258     Frame* frame = m_mainFrame->coreFrame();
1259     if (!frame)
1260         return 1;
1261     return frame->pageZoomFactor();
1262 }
1263
1264 void WebPage::setPageZoomFactor(double zoomFactor)
1265 {
1266     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1267     if (pluginView && pluginView->handlesPageScaleFactor()) {
1268         pluginView->setPageScaleFactor(zoomFactor, IntPoint());
1269         return;
1270     }
1271
1272     Frame* frame = m_mainFrame->coreFrame();
1273     if (!frame)
1274         return;
1275     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
1276 }
1277
1278 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1279 {
1280     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1281     if (pluginView && pluginView->handlesPageScaleFactor()) {
1282         pluginView->setPageScaleFactor(pageZoomFactor, IntPoint());
1283         return;
1284     }
1285
1286     Frame* frame = m_mainFrame->coreFrame();
1287     if (!frame)
1288         return;
1289     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
1290 }
1291
1292 void WebPage::windowScreenDidChange(uint64_t displayID)
1293 {
1294     m_page->chrome().windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
1295 }
1296
1297 void WebPage::scalePage(double scale, const IntPoint& origin)
1298 {
1299     bool willChangeScaleFactor = scale != pageScaleFactor();
1300
1301 #if PLATFORM(IOS)
1302     if (willChangeScaleFactor) {
1303         if (!m_inDynamicSizeUpdate)
1304             m_dynamicSizeUpdateHistory.clear();
1305         m_scaleWasSetByUIProcess = false;
1306     }
1307 #endif
1308     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1309     if (pluginView && pluginView->handlesPageScaleFactor()) {
1310         pluginView->setPageScaleFactor(scale, origin);
1311         return;
1312     }
1313
1314     m_page->setPageScaleFactor(scale, origin);
1315
1316     // We can't early return before setPageScaleFactor because the origin might be different.
1317     if (!willChangeScaleFactor)
1318         return;
1319
1320     for (auto* pluginView : m_pluginViews)
1321         pluginView->pageScaleFactorDidChange();
1322
1323     if (m_drawingArea->layerTreeHost())
1324         m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
1325
1326     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
1327 }
1328
1329 void WebPage::scalePageInViewCoordinates(double scale, IntPoint centerInViewCoordinates)
1330 {
1331     if (scale == pageScaleFactor())
1332         return;
1333
1334     IntPoint scrollPositionAtNewScale = mainFrameView()->rootViewToContents(-centerInViewCoordinates);
1335     double scaleRatio = scale / pageScaleFactor();
1336     scrollPositionAtNewScale.scale(scaleRatio, scaleRatio);
1337     scalePage(scale, scrollPositionAtNewScale);
1338 }
1339
1340 double WebPage::pageScaleFactor() const
1341 {
1342     PluginView* pluginView = pluginViewForFrame(&m_page->mainFrame());
1343     if (pluginView && pluginView->handlesPageScaleFactor())
1344         return pluginView->pageScaleFactor();
1345
1346     return m_page->pageScaleFactor();
1347 }
1348
1349 void WebPage::setDeviceScaleFactor(float scaleFactor)
1350 {
1351     if (scaleFactor == m_page->deviceScaleFactor())
1352         return;
1353
1354     m_page->setDeviceScaleFactor(scaleFactor);
1355
1356     // Tell all our plug-in views that the device scale factor changed.
1357 #if PLATFORM(MAC)
1358     for (auto* pluginView : m_pluginViews)
1359         pluginView->setDeviceScaleFactor(scaleFactor);
1360
1361     updateHeaderAndFooterLayersForDeviceScaleChange(scaleFactor);
1362 #endif
1363
1364     if (m_findController.isShowingOverlay()) {
1365         // We must have updated layout to get the selection rects right.
1366         layoutIfNeeded();
1367         m_findController.deviceScaleFactorDidChange();
1368     }
1369
1370     if (m_drawingArea->layerTreeHost())
1371         m_drawingArea->layerTreeHost()->deviceOrPageScaleFactorChanged();
1372
1373     m_pageOverlayController.didChangeDeviceScaleFactor();
1374 }
1375
1376 float WebPage::deviceScaleFactor() const
1377 {
1378     return m_page->deviceScaleFactor();
1379 }
1380
1381 void WebPage::setUseFixedLayout(bool fixed)
1382 {
1383     // Do not overwrite current settings if initially setting it to false.
1384     if (m_useFixedLayout == fixed)
1385         return;
1386     m_useFixedLayout = fixed;
1387
1388 #if !PLATFORM(IOS)
1389     m_page->settings().setFixedElementsLayoutRelativeToFrame(fixed);
1390 #endif
1391 #if USE(COORDINATED_GRAPHICS)
1392     m_page->settings().setAcceleratedCompositingForFixedPositionEnabled(fixed);
1393     m_page->settings().setFixedPositionCreatesStackingContext(fixed);
1394     m_page->settings().setDelegatesPageScaling(fixed);
1395     m_page->settings().setScrollingCoordinatorEnabled(fixed);
1396 #endif
1397
1398 #if USE(TILED_BACKING_STORE) && ENABLE(SMOOTH_SCROLLING)
1399     // Delegated scrolling will be enabled when the FrameView is created if fixed layout is enabled.
1400     // Ensure we don't do animated scrolling in the WebProcess in that case.
1401     m_page->settings().setScrollAnimatorEnabled(!fixed);
1402 #endif
1403
1404     FrameView* view = mainFrameView();
1405     if (!view)
1406         return;
1407
1408 #if USE(TILED_BACKING_STORE)
1409     view->setDelegatesScrolling(fixed);
1410     view->setPaintsEntireContents(fixed);
1411 #endif
1412     view->setUseFixedLayout(fixed);
1413     if (!fixed)
1414         setFixedLayoutSize(IntSize());
1415 }
1416
1417 void WebPage::setFixedLayoutSize(const IntSize& size)
1418 {
1419     FrameView* view = mainFrameView();
1420     if (!view || view->fixedLayoutSize() == size)
1421         return;
1422
1423     view->setFixedLayoutSize(size);
1424     // Do not force it until the first layout, this would then become our first layout prematurely.
1425     if (view->didFirstLayout())
1426         view->forceLayout();
1427 }
1428
1429 void WebPage::listenForLayoutMilestones(uint32_t milestones)
1430 {
1431     if (!m_page)
1432         return;
1433     m_page->addLayoutMilestones(static_cast<LayoutMilestones>(milestones));
1434 }
1435
1436 void WebPage::setSuppressScrollbarAnimations(bool suppressAnimations)
1437 {
1438     m_page->setShouldSuppressScrollbarAnimations(suppressAnimations);
1439 }
1440     
1441 void WebPage::setEnableVerticalRubberBanding(bool enableVerticalRubberBanding)
1442 {
1443     m_page->setVerticalScrollElasticity(enableVerticalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1444 }
1445     
1446 void WebPage::setEnableHorizontalRubberBanding(bool enableHorizontalRubberBanding)
1447 {
1448     m_page->setHorizontalScrollElasticity(enableHorizontalRubberBanding ? ScrollElasticityAllowed : ScrollElasticityNone);
1449 }
1450
1451 void WebPage::setBackgroundExtendsBeyondPage(bool backgroundExtendsBeyondPage)
1452 {
1453     if (m_page->settings().backgroundShouldExtendBeyondPage() != backgroundExtendsBeyondPage)
1454         m_page->settings().setBackgroundShouldExtendBeyondPage(backgroundExtendsBeyondPage);
1455 }
1456
1457 void WebPage::setPaginationMode(uint32_t mode)
1458 {
1459     Pagination pagination = m_page->pagination();
1460     pagination.mode = static_cast<Pagination::Mode>(mode);
1461     m_page->setPagination(pagination);
1462 }
1463
1464 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1465 {
1466     Pagination pagination = m_page->pagination();
1467     pagination.behavesLikeColumns = behavesLikeColumns;
1468     m_page->setPagination(pagination);
1469 }
1470
1471 void WebPage::setPageLength(double pageLength)
1472 {
1473     Pagination pagination = m_page->pagination();
1474     pagination.pageLength = pageLength;
1475     m_page->setPagination(pagination);
1476 }
1477
1478 void WebPage::setGapBetweenPages(double gap)
1479 {
1480     Pagination pagination = m_page->pagination();
1481     pagination.gap = gap;
1482     m_page->setPagination(pagination);
1483 }
1484
1485 void WebPage::postInjectedBundleMessage(const String& messageName, IPC::MessageDecoder& decoder)
1486 {
1487     InjectedBundle* injectedBundle = WebProcess::shared().injectedBundle();
1488     if (!injectedBundle)
1489         return;
1490
1491     RefPtr<API::Object> messageBody;
1492     InjectedBundleUserMessageDecoder messageBodyDecoder(messageBody);
1493     if (!decoder.decode(messageBodyDecoder))
1494         return;
1495
1496     injectedBundle->didReceiveMessageToPage(this, messageName, messageBody.get());
1497 }
1498
1499 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay, PageOverlay::FadeMode fadeMode)
1500 {
1501     m_pageOverlayController.installPageOverlay(pageOverlay, fadeMode);
1502 }
1503
1504 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, PageOverlay::FadeMode fadeMode)
1505 {
1506     m_pageOverlayController.uninstallPageOverlay(pageOverlay, fadeMode);
1507 }
1508
1509 #if !PLATFORM(IOS)
1510 void WebPage::setHeaderPageBanner(PassRefPtr<PageBanner> pageBanner)
1511 {
1512     if (m_headerBanner)
1513         m_headerBanner->detachFromPage();
1514
1515     m_headerBanner = pageBanner;
1516
1517     if (m_headerBanner)
1518         m_headerBanner->addToPage(PageBanner::Header, this);
1519 }
1520
1521 PageBanner* WebPage::headerPageBanner()
1522 {
1523     return m_headerBanner.get();
1524 }
1525
1526 void WebPage::setFooterPageBanner(PassRefPtr<PageBanner> pageBanner)
1527 {
1528     if (m_footerBanner)
1529         m_footerBanner->detachFromPage();
1530
1531     m_footerBanner = pageBanner;
1532
1533     if (m_footerBanner)
1534         m_footerBanner->addToPage(PageBanner::Footer, this);
1535 }
1536
1537 PageBanner* WebPage::footerPageBanner()
1538 {
1539     return m_footerBanner.get();
1540 }
1541
1542 void WebPage::hidePageBanners()
1543 {
1544     if (m_headerBanner)
1545         m_headerBanner->hide();
1546     if (m_footerBanner)
1547         m_footerBanner->hide();
1548 }
1549
1550 void WebPage::showPageBanners()
1551 {
1552     if (m_headerBanner)
1553         m_headerBanner->showIfHidden();
1554     if (m_footerBanner)
1555         m_footerBanner->showIfHidden();
1556 }
1557 #endif // !PLATFORM(IOS)
1558
1559 void WebPage::takeSnapshot(IntRect snapshotRect, IntSize bitmapSize, uint32_t options, uint64_t callbackID)
1560 {
1561     SnapshotOptions snapshotOptions = static_cast<SnapshotOptions>(options);
1562     snapshotOptions |= SnapshotOptionsShareable;
1563
1564     RefPtr<WebImage> image = snapshotAtSize(snapshotRect, bitmapSize, snapshotOptions);
1565
1566     ShareableBitmap::Handle handle;
1567     if (image)
1568         image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
1569
1570     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
1571 }
1572
1573 PassRefPtr<WebImage> WebPage::scaledSnapshotWithOptions(const IntRect& rect, double additionalScaleFactor, SnapshotOptions options)
1574 {
1575     IntRect snapshotRect = rect;
1576     if (options & SnapshotOptionsRespectDrawingAreaTransform)
1577         snapshotRect = m_drawingArea->rootLayerTransform().inverse().mapRect(snapshotRect);
1578
1579     IntSize bitmapSize = snapshotRect.size();
1580     double scaleFactor = additionalScaleFactor;
1581     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor))
1582         scaleFactor *= corePage()->deviceScaleFactor();
1583     bitmapSize.scale(scaleFactor);
1584
1585     return snapshotAtSize(rect, bitmapSize, options);
1586 }
1587
1588 PassRefPtr<WebImage> WebPage::snapshotAtSize(const IntRect& rect, const IntSize& bitmapSize, SnapshotOptions options)
1589 {
1590     Frame* coreFrame = m_mainFrame->coreFrame();
1591     if (!coreFrame)
1592         return nullptr;
1593
1594     FrameView* frameView = coreFrame->view();
1595     if (!frameView)
1596         return nullptr;
1597
1598     IntRect snapshotRect = rect;
1599     if (options & SnapshotOptionsRespectDrawingAreaTransform)
1600         snapshotRect = m_drawingArea->rootLayerTransform().inverse().mapRect(snapshotRect);
1601
1602     float horizontalScaleFactor = static_cast<float>(bitmapSize.width()) / rect.width();
1603     float verticalScaleFactor = static_cast<float>(bitmapSize.height()) / rect.height();
1604     float scaleFactor = std::max(horizontalScaleFactor, verticalScaleFactor);
1605
1606     RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options));
1607     if (!snapshot->bitmap())
1608         return nullptr;
1609
1610     auto graphicsContext = snapshot->bitmap()->createGraphicsContext();
1611
1612     graphicsContext->fillRect(IntRect(IntPoint(), bitmapSize), frameView->baseBackgroundColor(), ColorSpaceDeviceRGB);
1613
1614     if (!(options & SnapshotOptionsExcludeDeviceScaleFactor)) {
1615         double deviceScaleFactor = corePage()->deviceScaleFactor();
1616         graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
1617         scaleFactor /= deviceScaleFactor;
1618     }
1619
1620     graphicsContext->scale(FloatSize(scaleFactor, scaleFactor));
1621     graphicsContext->translate(-snapshotRect.x(), -snapshotRect.y());
1622
1623     FrameView::SelectionInSnapshot shouldPaintSelection = FrameView::IncludeSelection;
1624     if (options & SnapshotOptionsExcludeSelectionHighlighting)
1625         shouldPaintSelection = FrameView::ExcludeSelection;
1626
1627     FrameView::CoordinateSpaceForSnapshot coordinateSpace = FrameView::DocumentCoordinates;
1628     if (options & SnapshotOptionsInViewCoordinates)
1629         coordinateSpace = FrameView::ViewCoordinates;
1630
1631     frameView->paintContentsForSnapshot(graphicsContext.get(), snapshotRect, shouldPaintSelection, coordinateSpace);
1632
1633     if (options & SnapshotOptionsPaintSelectionRectangle) {
1634         FloatRect selectionRectangle = m_mainFrame->coreFrame()->selection().selectionBounds();
1635         graphicsContext->setStrokeColor(Color(0xFF, 0, 0), ColorSpaceDeviceRGB);
1636         graphicsContext->strokeRect(selectionRectangle, 1);
1637     }
1638     
1639     return snapshot.release();
1640 }
1641
1642 void WebPage::pageDidScroll()
1643 {
1644 #if PLATFORM(IOS)
1645     if (!m_inDynamicSizeUpdate)
1646         m_dynamicSizeUpdateHistory.clear();
1647 #endif
1648     m_uiClient->pageDidScroll(this);
1649
1650     send(Messages::WebPageProxy::PageDidScroll());
1651 }
1652
1653 #if USE(TILED_BACKING_STORE)
1654 void WebPage::pageDidRequestScroll(const IntPoint& point)
1655 {
1656     send(Messages::WebPageProxy::PageDidRequestScroll(point));
1657 }
1658 #endif
1659
1660 #if ENABLE(CONTEXT_MENUS)
1661 WebContextMenu* WebPage::contextMenu()
1662 {
1663     if (!m_contextMenu)
1664         m_contextMenu = WebContextMenu::create(this);
1665     return m_contextMenu.get();
1666 }
1667
1668 WebContextMenu* WebPage::contextMenuAtPointInWindow(const IntPoint& point)
1669 {
1670     corePage()->contextMenuController().clearContextMenu();
1671     
1672     // Simulate a mouse click to generate the correct menu.
1673     PlatformMouseEvent mouseEvent(point, point, RightButton, PlatformEvent::MousePressed, 1, false, false, false, false, currentTime());
1674     bool handled = corePage()->userInputBridge().handleContextMenuEvent(mouseEvent, &corePage()->mainFrame());
1675     if (!handled)
1676         return 0;
1677
1678     return contextMenu();
1679 }
1680 #endif
1681
1682 // Events 
1683
1684 static const WebEvent* g_currentEvent = 0;
1685
1686 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
1687 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
1688 // platform events passed to the event handler code.
1689 const WebEvent* WebPage::currentEvent()
1690 {
1691     return g_currentEvent;
1692 }
1693
1694 class CurrentEvent {
1695 public:
1696     explicit CurrentEvent(const WebEvent& event)
1697         : m_previousCurrentEvent(g_currentEvent)
1698     {
1699         g_currentEvent = &event;
1700     }
1701
1702     ~CurrentEvent()
1703     {
1704         g_currentEvent = m_previousCurrentEvent;
1705     }
1706
1707 private:
1708     const WebEvent* m_previousCurrentEvent;
1709 };
1710
1711 #if ENABLE(CONTEXT_MENUS)
1712 static bool isContextClick(const PlatformMouseEvent& event)
1713 {
1714     if (event.button() == WebCore::RightButton)
1715         return true;
1716
1717 #if PLATFORM(COCOA)
1718     // FIXME: this really should be about OSX-style UI, not about the Mac port
1719     if (event.button() == WebCore::LeftButton && event.ctrlKey())
1720         return true;
1721 #endif
1722
1723     return false;
1724 }
1725
1726 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, WebPage* page)
1727 {
1728     IntPoint point = page->corePage()->mainFrame().view()->windowToContents(platformMouseEvent.position());
1729     HitTestResult result = page->corePage()->mainFrame().eventHandler().hitTestResultAtPoint(point);
1730
1731     Frame* frame = &page->corePage()->mainFrame();
1732     if (result.innerNonSharedNode())
1733         frame = result.innerNonSharedNode()->document().frame();
1734
1735     bool handled = page->corePage()->userInputBridge().handleContextMenuEvent(platformMouseEvent, frame);
1736     if (handled)
1737         page->contextMenu()->show();
1738
1739     return handled;
1740 }
1741 #endif
1742
1743 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, WebPage* page, bool onlyUpdateScrollbars)
1744 {
1745     Frame& frame = page->corePage()->mainFrame();
1746     if (!frame.view())
1747         return false;
1748
1749     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
1750
1751     switch (platformMouseEvent.type()) {
1752         case PlatformEvent::MousePressed: {
1753 #if ENABLE(CONTEXT_MENUS)
1754             if (isContextClick(platformMouseEvent))
1755                 page->corePage()->contextMenuController().clearContextMenu();
1756 #endif
1757
1758             bool handled = page->corePage()->userInputBridge().handleMousePressEvent(platformMouseEvent);
1759 #if ENABLE(CONTEXT_MENUS)
1760             if (isContextClick(platformMouseEvent))
1761                 handled = handleContextMenuEvent(platformMouseEvent, page);
1762 #endif
1763             return handled;
1764         }
1765         case PlatformEvent::MouseReleased:
1766             return page->corePage()->userInputBridge().handleMouseReleaseEvent(platformMouseEvent);
1767
1768         case PlatformEvent::MouseMoved:
1769             if (onlyUpdateScrollbars)
1770                 return page->corePage()->userInputBridge().handleMouseMoveOnScrollbarEvent(platformMouseEvent);
1771             return page->corePage()->userInputBridge().handleMouseMoveEvent(platformMouseEvent);
1772         default:
1773             ASSERT_NOT_REACHED();
1774             return false;
1775     }
1776 }
1777
1778 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
1779 {
1780     ASSERT(m_page->pageThrottler());
1781     m_page->pageThrottler()->didReceiveUserInput();
1782
1783 #if ENABLE(CONTEXT_MENUS)
1784     // Don't try to handle any pending mouse events if a context menu is showing.
1785     if (m_isShowingContextMenu) {
1786         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
1787         return;
1788     }
1789 #endif
1790     bool handled = m_pageOverlayController.handleMouseEvent(mouseEvent);
1791
1792 #if !PLATFORM(IOS)
1793     if (!handled && m_headerBanner)
1794         handled = m_headerBanner->mouseEvent(mouseEvent);
1795     if (!handled && m_footerBanner)
1796         handled = m_footerBanner->mouseEvent(mouseEvent);
1797 #endif // !PLATFORM(IOS)
1798
1799     if (!handled && canHandleUserEvents()) {
1800         CurrentEvent currentEvent(mouseEvent);
1801
1802         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1803         // button is currently pressed. It is possible that neither of those things will be true since on
1804         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one
1805         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1806         // efficient scrollbars-only version of the event.
1807         bool onlyUpdateScrollbars = !(m_page->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1808         handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars);
1809     }
1810
1811     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
1812 }
1813
1814 void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled)
1815 {
1816     handled = m_pageOverlayController.handleMouseEvent(mouseEvent);
1817 #if !PLATFORM(IOS)
1818     if (!handled && m_headerBanner)
1819         handled = m_headerBanner->mouseEvent(mouseEvent);
1820     if (!handled && m_footerBanner)
1821         handled = m_footerBanner->mouseEvent(mouseEvent);
1822 #endif // !PLATFORM(IOS)
1823
1824     if (!handled) {
1825         CurrentEvent currentEvent(mouseEvent);
1826
1827         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1828         // button is currently pressed. It is possible that neither of those things will be true since on 
1829         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 
1830         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1831         // efficient scrollbars-only version of the event.
1832         bool onlyUpdateScrollbars = !(m_page->focusController().isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1833         handled = handleMouseEvent(mouseEvent, this, onlyUpdateScrollbars);
1834     }
1835 }
1836
1837 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
1838 {
1839     Frame& frame = page->mainFrame();
1840     if (!frame.view())
1841         return false;
1842
1843     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
1844     return page->userInputBridge().handleWheelEvent(platformWheelEvent);
1845 }
1846
1847 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
1848 {
1849     ASSERT(m_page->pageThrottler());
1850     m_page->pageThrottler()->didReceiveUserInput();
1851
1852     bool handled = false;
1853
1854     if (canHandleUserEvents()) {
1855         CurrentEvent currentEvent(wheelEvent);
1856
1857         handled = handleWheelEvent(wheelEvent, m_page.get());
1858     }
1859     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
1860 }
1861
1862 void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled)
1863 {
1864     CurrentEvent currentEvent(wheelEvent);
1865
1866     handled = handleWheelEvent(wheelEvent, m_page.get());
1867 }
1868
1869 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
1870 {
1871     if (!page->mainFrame().view())
1872         return false;
1873
1874     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
1875         return page->userInputBridge().handleAccessKeyEvent(platform(keyboardEvent));
1876     return page->userInputBridge().handleKeyEvent(platform(keyboardEvent));
1877 }
1878
1879 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
1880 {
1881     ASSERT(m_page->pageThrottler());
1882     m_page->pageThrottler()->didReceiveUserInput();
1883
1884     bool handled = false;
1885
1886     if (canHandleUserEvents()) {
1887         CurrentEvent currentEvent(keyboardEvent);
1888
1889         handled = handleKeyEvent(keyboardEvent, m_page.get());
1890         // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
1891         if (!handled)
1892             handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1893     }
1894     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
1895 }
1896
1897 void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled)
1898 {
1899     CurrentEvent currentEvent(keyboardEvent);
1900
1901     Frame& frame = m_page->focusController().focusedOrMainFrame();
1902     frame.document()->updateStyleIfNeeded();
1903
1904     handled = handleKeyEvent(keyboardEvent, m_page.get());
1905     if (!handled)
1906         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1907 }
1908
1909 void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
1910 {
1911     bool isEnabled = false;
1912     int32_t state = 0;
1913     Frame& frame = m_page->focusController().focusedOrMainFrame();
1914     if (PluginView* pluginView = focusedPluginViewForFrame(frame))
1915         isEnabled = pluginView->isEditingCommandEnabled(commandName);
1916     else {
1917         Editor::Command command = frame.editor().command(commandName);
1918         state = command.state();
1919         isEnabled = command.isSupported() && command.isEnabled();
1920     }
1921
1922     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
1923 }
1924
1925 void WebPage::executeEditCommand(const String& commandName)
1926 {
1927     executeEditingCommand(commandName, String());
1928 }
1929
1930 uint64_t WebPage::restoreSession(const SessionState& sessionState)
1931 {
1932     const BackForwardListItemVector& list = sessionState.list();
1933     size_t size = list.size();
1934     uint64_t currentItemID = 0;
1935     for (size_t i = 0; i < size; ++i) {
1936         WebBackForwardListItem* webItem = list[i].get();
1937         DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
1938         
1939         RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
1940         if (!item) {
1941             LOG_ERROR("Failed to decode a HistoryItem from session state data.");
1942             return 0;
1943         }
1944         
1945         if (i == sessionState.currentIndex())
1946             currentItemID = webItem->itemID();
1947         
1948         WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
1949     }    
1950     ASSERT(currentItemID);
1951     return currentItemID;
1952 }
1953
1954 void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState)
1955 {
1956     if (uint64_t currentItemID = restoreSession(sessionState))
1957         goToBackForwardItem(currentItemID);
1958 }
1959
1960 #if ENABLE(TOUCH_EVENTS)
1961 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
1962 {
1963     if (!page->mainFrame().view())
1964         return false;
1965
1966     return page->mainFrame().eventHandler().handleTouchEvent(platform(touchEvent));
1967 }
1968 #endif
1969
1970 #if ENABLE(IOS_TOUCH_EVENTS)
1971 void WebPage::dispatchTouchEvent(const WebTouchEvent& touchEvent, bool& handled)
1972 {
1973     RefPtr<Frame> oldFocusedFrame = m_page->focusController().focusedFrame();
1974     RefPtr<Element> oldFocusedElement = oldFocusedFrame ? oldFocusedFrame->document()->focusedElement() : nullptr;
1975     m_userIsInteracting = true;
1976
1977     m_lastInteractionLocation = touchEvent.position();
1978     CurrentEvent currentEvent(touchEvent);
1979     handled = handleTouchEvent(touchEvent, m_page.get());
1980
1981     RefPtr<Frame> newFocusedFrame = m_page->focusController().focusedFrame();
1982     RefPtr<Element> newFocusedElement = newFocusedFrame ? newFocusedFrame->document()->focusedElement() : nullptr;
1983
1984     // If the focus has not changed, we need to notify the client anyway, since it might be
1985     // necessary to start assisting the node.
1986     // If the node has been focused by JavaScript without user interaction, the
1987     // keyboard is not on screen.
1988     if (newFocusedElement && newFocusedElement == oldFocusedElement)
1989         elementDidFocus(newFocusedElement.get());
1990
1991     m_userIsInteracting = false;
1992 }
1993
1994 void WebPage::touchEventSync(const WebTouchEvent& touchEvent, bool& handled)
1995 {
1996     EventDispatcher::TouchEventQueue queuedEvents;
1997     WebProcess::shared().eventDispatcher().getQueuedTouchEventsForPage(*this, queuedEvents);
1998     dispatchAsynchronousTouchEvents(queuedEvents);
1999
2000     dispatchTouchEvent(touchEvent, handled);
2001 }
2002 #elif ENABLE(TOUCH_EVENTS)
2003 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
2004 {
2005
2006     bool handled = false;
2007     if (canHandleUserEvents()) {
2008         CurrentEvent currentEvent(touchEvent);
2009
2010         handled = handleTouchEvent(touchEvent, m_page.get());
2011     }
2012     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
2013 }
2014
2015 void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled)
2016 {
2017     CurrentEvent currentEvent(touchEvent);
2018     handled = handleTouchEvent(touchEvent, m_page.get());
2019 }
2020 #endif
2021
2022 bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
2023 {
2024     return page->userInputBridge().scrollRecursively(direction, granularity);
2025 }
2026
2027 bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
2028 {
2029     return page->userInputBridge().logicalScrollRecursively(direction, granularity);
2030 }
2031
2032 bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
2033 {
2034     return scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
2035 }
2036
2037 void WebPage::centerSelectionInVisibleArea()
2038 {
2039     Frame& frame = m_page->focusController().focusedOrMainFrame();
2040     frame.selection().revealSelection(ScrollAlignment::alignCenterAlways);
2041     m_findController.showFindIndicatorInSelection();
2042 }
2043
2044 #if ENABLE(REMOTE_INSPECTOR)
2045 void WebPage::setAllowsRemoteInspection(bool allow)
2046 {
2047     m_page->setRemoteInspectionAllowed(allow);
2048 }
2049 #endif
2050
2051 void WebPage::setDrawsBackground(bool drawsBackground)
2052 {
2053     if (m_drawsBackground == drawsBackground)
2054         return;
2055
2056     m_drawsBackground = drawsBackground;
2057
2058     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2059         if (FrameView* view = coreFrame->view())
2060             view->setTransparent(!drawsBackground);
2061     }
2062
2063     m_drawingArea->pageBackgroundTransparencyChanged();
2064     m_drawingArea->setNeedsDisplay();
2065 }
2066
2067 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
2068 {
2069     if (m_drawsTransparentBackground == drawsTransparentBackground)
2070         return;
2071
2072     m_drawsTransparentBackground = drawsTransparentBackground;
2073
2074     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
2075     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2076         if (FrameView* view = coreFrame->view())
2077             view->setBaseBackgroundColor(backgroundColor);
2078     }
2079
2080     m_drawingArea->pageBackgroundTransparencyChanged();
2081     m_drawingArea->setNeedsDisplay();
2082 }
2083
2084 void WebPage::setTopContentInset(float contentInset)
2085 {
2086     m_page->setTopContentInset(contentInset);
2087 }
2088
2089 void WebPage::viewWillStartLiveResize()
2090 {
2091     if (!m_page)
2092         return;
2093
2094     // FIXME: This should propagate to all ScrollableAreas.
2095     Frame& frame = m_page->focusController().focusedOrMainFrame();
2096     if (FrameView* view = frame.view())
2097         view->willStartLiveResize();
2098 }
2099
2100 void WebPage::viewWillEndLiveResize()
2101 {
2102     if (!m_page)
2103         return;
2104
2105     // FIXME: This should propagate to all ScrollableAreas.
2106     Frame& frame = m_page->focusController().focusedOrMainFrame();
2107     if (FrameView* view = frame.view())
2108         view->willEndLiveResize();
2109 }
2110
2111 void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
2112 {
2113     if (!m_page)
2114         return;
2115
2116     Frame& frame = m_page->focusController().focusedOrMainFrame();
2117     frame.document()->setFocusedElement(0);
2118
2119     if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
2120         PlatformKeyboardEvent platformEvent(platform(event));
2121         platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
2122         m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame.document()->defaultView()).get());
2123         return;
2124     }
2125
2126     m_page->focusController().setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
2127 }
2128
2129 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
2130 {
2131     if (m_windowResizerSize == windowResizerSize)
2132         return;
2133
2134     m_windowResizerSize = windowResizerSize;
2135
2136     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree().traverseNext()) {
2137         FrameView* view = coreFrame->view();
2138         if (view)
2139             view->windowResizerRectChanged();
2140     }
2141 }
2142
2143 void WebPage::setCanStartMediaTimerFired()
2144 {
2145     if (m_page)
2146         m_page->setCanStartMedia(true);
2147 }
2148
2149 #if !PLATFORM(MAC)
2150 void WebPage::didUpdateViewStateTimerFired()
2151 {
2152     send(Messages::WebPageProxy::DidUpdateViewState());
2153 }
2154 #endif
2155
2156 inline bool WebPage::canHandleUserEvents() const
2157 {
2158 #if USE(TILED_BACKING_STORE)
2159     // Should apply only if the area was frozen by didStartPageTransition().
2160     return !m_drawingArea->layerTreeStateIsFrozen();
2161 #endif
2162     return true;
2163 }
2164
2165 void WebPage::updateIsInWindow(bool isInitialState)
2166 {
2167     bool isInWindow = m_viewState & WebCore::ViewState::IsInWindow;
2168
2169     if (!isInWindow) {
2170         m_setCanStartMediaTimer.stop();
2171         m_page->setCanStartMedia(false);
2172         
2173         // The WebProcess does not yet know about this page; no need to tell it we're leaving the window.
2174         if (!isInitialState)
2175             WebProcess::shared().pageWillLeaveWindow(m_pageID);
2176     } else {
2177         // Defer the call to Page::setCanStartMedia() since it ends up sending a synchronous message to the UI process
2178         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
2179         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
2180         if (m_mayStartMediaWhenInWindow)
2181             m_setCanStartMediaTimer.startOneShot(0);
2182
2183         WebProcess::shared().pageDidEnterWindow(m_pageID);
2184     }
2185
2186     if (isInWindow)
2187         layoutIfNeeded();
2188 }
2189
2190 void WebPage::setViewState(ViewState::Flags viewState, bool wantsDidUpdateViewState)
2191 {
2192     ViewState::Flags changed = m_viewState ^ viewState;
2193     m_viewState = viewState;
2194
2195     m_drawingArea->viewStateDidChange(changed);
2196     m_page->setViewState(viewState);
2197     for (auto* pluginView : m_pluginViews)
2198         pluginView->viewStateDidChange(changed);
2199
2200     if (changed & ViewState::IsInWindow)
2201         updateIsInWindow();
2202
2203     if (wantsDidUpdateViewState)
2204         m_sendDidUpdateViewStateTimer.startOneShot(0);
2205 }
2206
2207 void WebPage::setLayerHostingMode(unsigned layerHostingMode)
2208 {
2209     m_layerHostingMode = static_cast<LayerHostingMode>(layerHostingMode);
2210
2211     m_drawingArea->setLayerHostingMode(m_layerHostingMode);
2212
2213     for (auto* pluginView : m_pluginViews)
2214         pluginView->setLayerHostingMode(m_layerHostingMode);
2215 }
2216
2217 void WebPage::setSessionID(SessionID sessionID)
2218 {
2219     if (sessionID.isEphemeral())
2220         WebProcess::shared().ensurePrivateBrowsingSession(sessionID);
2221     m_page->setSessionID(sessionID);
2222 }
2223
2224 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
2225 {
2226     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2227     if (!frame)
2228         return;
2229     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
2230 }
2231
2232 void WebPage::didStartPageTransition()
2233 {
2234     m_drawingArea->setLayerTreeStateIsFrozen(true);
2235 }
2236
2237 void WebPage::didCompletePageTransition()
2238 {
2239 #if USE(TILED_BACKING_STORE)
2240     if (m_mainFrame->coreFrame()->view()->delegatesScrolling())
2241         // Wait until the UI process sent us the visible rect it wants rendered.
2242         send(Messages::WebPageProxy::PageTransitionViewportReady());
2243     else
2244 #endif
2245         
2246     m_drawingArea->setLayerTreeStateIsFrozen(false);
2247 }
2248
2249 void WebPage::show()
2250 {
2251     send(Messages::WebPageProxy::ShowPage());
2252 }
2253
2254 void WebPage::setUserAgent(const String& userAgent)
2255 {
2256     m_userAgent = userAgent;
2257 }
2258
2259 void WebPage::suspendActiveDOMObjectsAndAnimations()
2260 {
2261     m_page->suspendActiveDOMObjectsAndAnimations();
2262 }
2263
2264 void WebPage::resumeActiveDOMObjectsAndAnimations()
2265 {
2266     m_page->resumeActiveDOMObjectsAndAnimations();
2267 }
2268
2269 IntPoint WebPage::screenToRootView(const IntPoint& point)
2270 {
2271     IntPoint windowPoint;
2272     sendSync(Messages::WebPageProxy::ScreenToRootView(point), Messages::WebPageProxy::ScreenToRootView::Reply(windowPoint));
2273     return windowPoint;
2274 }
2275     
2276 IntRect WebPage::rootViewToScreen(const IntRect& rect)
2277 {
2278     IntRect screenRect;
2279     sendSync(Messages::WebPageProxy::RootViewToScreen(rect), Messages::WebPageProxy::RootViewToScreen::Reply(screenRect));
2280     return screenRect;
2281 }
2282
2283 IntRect WebPage::windowResizerRect() const
2284 {
2285     if (m_windowResizerSize.isEmpty())
2286         return IntRect();
2287
2288     IntSize frameViewSize;
2289     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
2290         if (FrameView* view = coreFrame->view())
2291             frameViewSize = view->size();
2292     }
2293
2294     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 
2295                    m_windowResizerSize.width(), m_windowResizerSize.height());
2296 }
2297
2298 KeyboardUIMode WebPage::keyboardUIMode()
2299 {
2300     bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
2301     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
2302 }
2303
2304 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
2305 {
2306     // NOTE: We need to be careful when running scripts that the objects we depend on don't
2307     // disappear during script execution.
2308
2309     // Retain the SerializedScriptValue at this level so it (and the internal data) lives
2310     // long enough for the DataReference to be encoded by the sent message.
2311     RefPtr<SerializedScriptValue> serializedResultValue;
2312     IPC::DataReference dataReference;
2313
2314     JSLockHolder lock(JSDOMWindow::commonVM());
2315     if (JSValue resultValue = m_mainFrame->coreFrame()->script().executeScript(script, true).jsValue()) {
2316         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script().globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
2317             dataReference = serializedResultValue->data();
2318     }
2319
2320     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
2321 }
2322
2323 void WebPage::getContentsAsString(uint64_t callbackID)
2324 {
2325     String resultString = m_mainFrame->contentsAsString();
2326     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2327 }
2328
2329 #if ENABLE(MHTML)
2330 void WebPage::getContentsAsMHTMLData(uint64_t callbackID, bool useBinaryEncoding)
2331 {
2332     IPC::DataReference dataReference;
2333
2334     RefPtr<SharedBuffer> buffer = useBinaryEncoding
2335         ? MHTMLArchive::generateMHTMLDataUsingBinaryEncoding(m_page.get())
2336         : MHTMLArchive::generateMHTMLData(m_page.get());
2337
2338     if (buffer)
2339         dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2340
2341     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2342 }
2343 #endif
2344
2345 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
2346 {
2347     String resultString = renderTreeExternalRepresentation();
2348     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2349 }
2350
2351 static Frame* frameWithSelection(Page* page)
2352 {
2353     for (Frame* frame = &page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
2354         if (frame->selection().isRange())
2355             return frame;
2356     }
2357
2358     return 0;
2359 }
2360
2361 void WebPage::getSelectionAsWebArchiveData(uint64_t callbackID)
2362 {
2363     IPC::DataReference dataReference;
2364
2365 #if PLATFORM(COCOA)
2366     RefPtr<LegacyWebArchive> archive;
2367     RetainPtr<CFDataRef> data;
2368
2369     Frame* frame = frameWithSelection(m_page.get());
2370     if (frame) {
2371         archive = LegacyWebArchive::createFromSelection(frame);
2372         data = archive->rawDataRepresentation();
2373         dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2374     }
2375 #endif
2376
2377     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2378 }
2379
2380 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
2381 {
2382     String resultString = m_mainFrame->selectionAsString();
2383     if (resultString.isEmpty())
2384         resultString = m_mainFrame->contentsAsString();
2385     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2386 }
2387
2388 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
2389 {
2390     String resultString;
2391     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
2392        resultString = frame->source();
2393
2394     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
2395 }
2396
2397 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
2398 {
2399     IPC::DataReference dataReference;
2400
2401     RefPtr<ResourceBuffer> buffer;
2402     RefPtr<SharedBuffer> pdfResource;
2403     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2404         if (PluginView* pluginView = pluginViewForFrame(frame->coreFrame())) {
2405             if ((pdfResource = pluginView->liveResourceData()))
2406                 dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(pdfResource->data()), pdfResource->size());
2407         }
2408
2409         if (dataReference.isEmpty()) {
2410             if (DocumentLoader* loader = frame->coreFrame()->loader().documentLoader()) {
2411                 if ((buffer = loader->mainResourceData()))
2412                     dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2413             }
2414         }
2415     }
2416
2417     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2418 }
2419
2420 static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const URL& resourceURL)
2421 {
2422     DocumentLoader* loader = frame->loader().documentLoader();
2423     if (!loader)
2424         return 0;
2425
2426     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
2427     if (!subresource)
2428         return 0;
2429
2430     return subresource->data();
2431 }
2432
2433 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
2434 {
2435     IPC::DataReference dataReference;
2436     URL resourceURL(URL(), resourceURLString);
2437
2438     RefPtr<SharedBuffer> buffer;
2439     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2440         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
2441         if (!buffer) {
2442             // Try to get the resource data from the cache.
2443             buffer = cachedResponseDataForURL(resourceURL);
2444         }
2445
2446         if (buffer)
2447             dataReference = IPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
2448     }
2449
2450     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2451 }
2452
2453 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
2454 {
2455     IPC::DataReference dataReference;
2456
2457 #if PLATFORM(COCOA)
2458     RetainPtr<CFDataRef> data;
2459     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
2460         if ((data = frame->webArchiveData(0, 0)))
2461             dataReference = IPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
2462     }
2463 #else
2464     UNUSED_PARAM(frameID);
2465 #endif
2466
2467     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
2468 }
2469
2470 void WebPage::forceRepaintWithoutCallback()
2471 {
2472     m_drawingArea->forceRepaint();
2473 }
2474
2475 void WebPage::forceRepaint(uint64_t callbackID)
2476 {
2477     if (m_drawingArea->forceRepaintAsync(callbackID))
2478         return;
2479
2480     forceRepaintWithoutCallback();
2481     send(Messages::WebPageProxy::VoidCallback(callbackID));
2482 }
2483
2484 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
2485 {
2486     WebPreferencesStore::removeTestRunnerOverrides();
2487     updatePreferences(store);
2488 }
2489
2490 void WebPage::updatePreferences(const WebPreferencesStore& store)
2491 {
2492     Settings& settings = m_page->settings();
2493
2494     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
2495     m_asynchronousPluginInitializationEnabled = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledKey());
2496     m_asynchronousPluginInitializationEnabledForAllPlugins = store.getBoolValueForKey(WebPreferencesKey::asynchronousPluginInitializationEnabledForAllPluginsKey());
2497     m_artificialPluginInitializationDelayEnabled = store.getBoolValueForKey(WebPreferencesKey::artificialPluginInitializationDelayEnabledKey());
2498
2499     m_scrollingPerformanceLoggingEnabled = store.getBoolValueForKey(WebPreferencesKey::scrollingPerformanceLoggingEnabledKey());
2500
2501 #if PLATFORM(COCOA)
2502     m_pdfPluginEnabled = store.getBoolValueForKey(WebPreferencesKey::pdfPluginEnabledKey());
2503 #endif
2504
2505 #if ENABLE(SERVICE_CONTROLS)
2506     m_serviceControlsEnabled = store.getBoolValueForKey(WebPreferencesKey::serviceControlsEnabledKey());
2507 #endif
2508
2509     // FIXME: This should be generated from macro expansion for all preferences,
2510     // but we currently don't match the naming of WebCore exactly so we are
2511     // handrolling the boolean and integer preferences until that is fixed.
2512
2513 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings.set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
2514
2515     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
2516
2517 #undef INITIALIZE_SETTINGS
2518
2519     settings.setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
2520     settings.setScriptMarkupEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptMarkupEnabledKey()));
2521     settings.setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
2522     settings.setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
2523     settings.setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
2524     settings.setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
2525     settings.setJavaEnabledForLocalFiles(store.getBoolValueForKey(WebPreferencesKey::javaEnabledForLocalFilesKey()));    
2526     settings.setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
2527     settings.setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
2528     settings.setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
2529     settings.setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
2530     if (store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && !usesEphemeralSession())
2531         setSessionID(SessionID::legacyPrivateSessionID());
2532     else if (!store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()) && sessionID() == SessionID::legacyPrivateSessionID())
2533         setSessionID(SessionID::defaultSessionID());
2534     settings.setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
2535     settings.setJavaScriptExperimentsEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptExperimentsEnabledKey()));
2536     settings.setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
2537     settings.setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
2538     settings.setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
2539     settings.setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
2540     settings.setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
2541 #if ENABLE(WEB_ARCHIVE)
2542     settings.setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
2543 #endif
2544     settings.setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
2545     settings.setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
2546     settings.setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey()));
2547     settings.setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
2548     settings.setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
2549     settings.setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
2550     settings.setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
2551     settings.setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
2552     settings.setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
2553     settings.setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
2554     settings.setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
2555
2556     settings.setMinimumFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumFontSizeKey()));
2557     settings.setMinimumLogicalFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
2558     settings.setDefaultFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFontSizeKey()));
2559     settings.setDefaultFixedFontSize(store.getDoubleValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
2560     settings.setScreenFontSubstitutionEnabled(store.getBoolValueForKey(WebPreferencesKey::screenFontSubstitutionEnabledKey())
2561 #if PLATFORM(COCOA)
2562         || WebProcess::shared().shouldForceScreenFontSubstitution()
2563 #endif
2564     );
2565     settings.setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
2566     settings.setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
2567     settings.setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
2568     settings.setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
2569     settings.setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
2570
2571     settings.setAcceleratedCompositingForOverflowScrollEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingForOverflowScrollEnabledKey()));
2572     settings.setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()));
2573     settings.setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()));
2574     settings.setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()));
2575     settings.setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
2576     settings.setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
2577     settings.setShowTiledScrollingIndicator(store.getBoolValueForKey(WebPreferencesKey::tiledScrollingIndicatorVisibleKey()));
2578     settings.setAggressiveTileRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::aggressiveTileRetentionEnabledKey()));
2579     settings.setTemporaryTileCohortRetentionEnabled(store.getBoolValueForKey(WebPreferencesKey::temporaryTileCohortRetentionEnabledKey()));
2580     RuntimeEnabledFeatures::sharedFeatures().setCSSRegionsEnabled(store.getBoolValueForKey(WebPreferencesKey::cssRegionsEnabledKey()));
2581     RuntimeEnabledFeatures::sharedFeatures().setCSSCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCompositingEnabledKey()));
2582     settings.setRegionBasedColumnsEnabled(store.getBoolValueForKey(WebPreferencesKey::regionBasedColumnsEnabledKey()));
2583     settings.setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
2584     settings.setMultithreadedWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::multithreadedWebGLEnabledKey()));
2585     settings.setForceSoftwareWebGLRendering(store.getBoolValueForKey(WebPreferencesKey::forceSoftwareWebGLRenderingKey()));
2586     settings.setAccelerated2dCanvasEnabled(store.getBoolValueForKey(WebPreferencesKey::accelerated2dCanvasEnabledKey()));
2587     settings.setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey()));
2588     settings.setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey()));
2589     settings.setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
2590     settings.setHyperlinkAuditingEnabled(store.getBoolValueForKey(WebPreferencesKey::hyperlinkAuditingEnabledKey()));
2591     settings.setRequestAnimationFrameEnabled(store.getBoolValueForKey(WebPreferencesKey::requestAnimationFrameEnabledKey()));
2592 #if ENABLE(SMOOTH_SCROLLING)
2593     settings.setScrollAnimatorEnabled(store.getBoolValueForKey(WebPreferencesKey::scrollAnimatorEnabledKey()));
2594 #endif
2595     settings.setInteractiveFormValidationEnabled(store.getBoolValueForKey(WebPreferencesKey::interactiveFormValidationEnabledKey()));
2596     settings.setSpatialNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::spatialNavigationEnabledKey()));
2597
2598 #if ENABLE(SQL_DATABASE)
2599     DatabaseManager::manager().setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
2600 #endif
2601
2602 #if ENABLE(FULLSCREEN_API)
2603     settings.setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
2604 #endif
2605
2606 #if USE(AVFOUNDATION)
2607     settings.setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
2608 #endif
2609
2610 #if PLATFORM(COCOA)
2611     settings.setQTKitEnabled(store.getBoolValueForKey(WebPreferencesKey::isQTKitEnabledKey()));
2612 #endif
2613
2614 #if PLATFORM(IOS)
2615     settings.setAVKitEnabled(true);
2616 #endif
2617
2618 #if ENABLE(IOS_TEXT_AUTOSIZING)
2619     settings.setMinimumZoomFontSize(store.getDoubleValueForKey(WebPreferencesKey::minimumZoomFontSizeKey()));
2620 #endif
2621
2622 #if ENABLE(WEB_AUDIO)
2623     settings.setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey()));
2624 #endif
2625
2626 #if ENABLE(MEDIA_STREAM)
2627     settings.setMediaStreamEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaStreamEnabledKey()));
2628 #endif
2629
2630 #if ENABLE(SERVICE_CONTROLS)
2631     settings.setImageControlsEnabled(store.getBoolValueForKey(WebPreferencesKey::imageControlsEnabledKey()));
2632 #endif
2633
2634 #if ENABLE(IOS_AIRPLAY)
2635     settings.setMediaPlaybackAllowsAirPlay(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsAirPlayKey()));
2636 #endif
2637
2638     settings.setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey()));
2639     settings.setSuppressesIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressesIncrementalRenderingKey()));
2640     settings.setIncrementalRenderingSuppressionTimeoutInSeconds(store.getDoubleValueForKey(WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey()));
2641     settings.setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
2642     settings.setWantsBalancedSetDefersLoadingBehavior(store.getBoolValueForKey(WebPreferencesKey::wantsBalancedSetDefersLoadingBehaviorKey()));
2643     settings.setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey()));
2644
2645 #if ENABLE(VIDEO_TRACK)
2646     settings.setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey()));
2647     settings.setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey()));
2648     settings.setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
2649 #endif
2650
2651 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
2652     settings.setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
2653 #endif
2654
2655     settings.setShouldRespectImageOrientation(store.getBoolValueForKey(WebPreferencesKey::shouldRespectImageOrientationKey()));
2656     settings.setStorageBlockingPolicy(static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey())));
2657     settings.setCookieEnabled(store.getBoolValueForKey(WebPreferencesKey::cookieEnabledKey()));
2658
2659     settings.setDiagnosticLoggingEnabled(store.getBoolValueForKey(WebPreferencesKey::diagnosticLoggingEnabledKey()));
2660
2661     settings.setScrollingPerformanceLoggingEnabled(m_scrollingPerformanceLoggingEnabled);
2662
2663     settings.setPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::plugInSnapshottingEnabledKey()));
2664     settings.setSnapshotAllPlugIns(store.getBoolValueForKey(WebPreferencesKey::snapshotAllPlugInsKey()));
2665     settings.setAutostartOriginPlugInSnapshottingEnabled(store.getBoolValueForKey(WebPreferencesKey::autostartOriginPlugInSnapshottingEnabledKey()));
2666     settings.setPrimaryPlugInSnapshotDetectionEnabled(store.getBoolValueForKey(WebPreferencesKey::primaryPlugInSnapshotDetectionEnabledKey()));
2667     settings.setUsesEncodingDetector(store.getBoolValueForKey(WebPreferencesKey::usesEncodingDetectorKey()));
2668
2669 #if ENABLE(TEXT_AUTOSIZING)
2670     settings.setTextAutosizingEnabled(store.getBoolValueForKey(WebPreferencesKey::textAutosizingEnabledKey()));
2671 #endif
2672
2673     settings.setLogsPageMessagesToSystemConsoleEnabled(store.getBoolValueForKey(WebPreferencesKey::logsPageMessagesToSystemConsoleEnabledKey()));
2674     settings.setAsynchronousSpellCheckingEnabled(store.getBoolValueForKey(WebPreferencesKey::asynchronousSpellCheckingEnabledKey()));
2675
2676     settings.setSmartInsertDeleteEnabled(store.getBoolValueForKey(WebPreferencesKey::smartInsertDeleteEnabledKey()));
2677     settings.setSelectTrailingWhitespaceEnabled(store.getBoolValueForKey(WebPreferencesKey::selectTrailingWhitespaceEnabledKey()));
2678     settings.setShowsURLsInToolTips(store.getBoolValueForKey(WebPreferencesKey::showsURLsInToolTipsEnabledKey()));
2679
2680 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
2681     settings.setHiddenPageDOMTimerThrottlingEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageDOMTimerThrottlingEnabledKey()));
2682 #endif
2683 #if ENABLE(PAGE_VISIBILITY_API)
2684     settings.setHiddenPageCSSAnimationSuspensionEnabled(store.getBoolValueForKey(WebPreferencesKey::hiddenPageCSSAnimationSuspensionEnabledKey()));
2685 #endif
2686
2687     settings.setLowPowerVideoAudioBufferSizeEnabled(store.getBoolValueForKey(WebPreferencesKey::lowPowerVideoAudioBufferSizeEnabledKey()));
2688     settings.setSimpleLineLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutEnabledKey()));
2689     settings.setSimpleLineLayoutDebugBordersEnabled(store.getBoolValueForKey(WebPreferencesKey::simpleLineLayoutDebugBordersEnabledKey()));
2690
2691     settings.setUseLegacyTextAlignPositionedElementBehavior(store.getBoolValueForKey(WebPreferencesKey::useLegacyTextAlignPositionedElementBehaviorKey()));
2692
2693 #if ENABLE(MEDIA_SOURCE)
2694     settings.setMediaSourceEnabled(store.getBoolValueForKey(WebPreferencesKey::mediaSourceEnabledKey()));
2695 #endif
2696
2697     settings.setShouldConvertPositionStyleOnCopy(store.getBoolValueForKey(WebPreferencesKey::shouldConvertPositionStyleOnCopyKey()));
2698
2699     settings.setStandalone(store.getBoolValueForKey(WebPreferencesKey::standaloneKey()));
2700     settings.setTelephoneNumberParsingEnabled(store.getBoolValueForKey(WebPreferencesKey::telephoneNumberParsingEnabledKey()));
2701     settings.setAlwaysUseBaselineOfPrimaryFont(store.getBoolValueForKey(WebPreferencesKey::alwaysUseBaselineOfPrimaryFontKey()));
2702     settings.setAllowMultiElementImplicitSubmission(store.getBoolValueForKey(WebPreferencesKey::allowMultiElementImplicitSubmissionKey()));
2703     settings.setAlwaysUseAcceleratedOverflowScroll(store.getBoolValueForKey(WebPreferencesKey::alwaysUseAcceleratedOverflowScrollKey()));
2704
2705     settings.setPasswordEchoEnabled(store.getBoolValueForKey(WebPreferencesKey::passwordEchoEnabledKey()));
2706     settings.setPasswordEchoDurationInSeconds(store.getDoubleValueForKey(WebPreferencesKey::passwordEchoDurationKey()));
2707     
2708     settings.setLayoutInterval(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::duration<double>(store.getDoubleValueForKey(WebPreferencesKey::layoutIntervalKey()))));
2709     settings.setMaxParseDuration(store.getDoubleValueForKey(WebPreferencesKey::maxParseDurationKey()));
2710
2711     settings.setEnableInheritURIQueryComponent(store.getBoolValueForKey(WebPreferencesKey::enableInheritURIQueryComponentKey()));
2712
2713     if (store.getBoolValueForKey(WebPreferencesKey::pageVisibilityBasedProcessSuppressionEnabledKey()))
2714         m_processSuppressionDisabledByWebPreference.stop();
2715     else
2716         m_processSuppressionDisabledByWebPreference.start();
2717
2718     platformPreferencesDidChange(store);
2719
2720     if (m_drawingArea)
2721         m_drawingArea->updatePreferences(store);
2722
2723     m_pageOverlayController.didChangePreferences();
2724 }
2725
2726 #if PLATFORM(COCOA)
2727 void WebPage::willCommitLayerTree(RemoteLayerTreeTransaction& layerTransaction)
2728 {
2729     layerTransaction.setContentsSize(corePage()->mainFrame().view()->contentsSize());
2730     layerTransaction.setPageScaleFactor(corePage()->pageScaleFactor());
2731     layerTransaction.setRenderTreeSize(corePage()->renderTreeSize());
2732     layerTransaction.setPageExtendedBackgroundColor(corePage()->pageExtendedBackgroundColor());
2733 #if PLATFORM(IOS)
2734     layerTransaction.setLastVisibleContentRectUpdateID(m_lastVisibleContentRectUpdateID);
2735     layerTransaction.setScaleWasSetByUIProcess(scaleWasSetByUIProcess());
2736     layerTransaction.setMinimumScaleFactor(minimumPageScaleFactor());
2737     layerTransaction.setMaximumScaleFactor(maximumPageScaleFactor());
2738     layerTransaction.setAllowsUserScaling(allowsUserScaling());
2739 #endif
2740 }
2741 #endif
2742
2743     
2744 #if ENABLE(INSPECTOR)
2745 WebInspector* WebPage::inspector()
2746 {
2747     if (m_isClosed)
2748         return 0;
2749     if (!m_inspector)
2750         m_inspector = WebInspector::create(this, m_inspectorClient);
2751     return m_inspector.get();
2752 }
2753 #endif
2754     
2755 #if PLATFORM(IOS)
2756 WebVideoFullscreenManager* WebPage::videoFullscreenManager()
2757 {
2758     if (!m_videoFullscreenManager)
2759         m_videoFullscreenManager = WebVideoFullscreenManager::create(this);
2760     return m_videoFullscreenManager.get();
2761 }
2762 #endif
2763
2764 #if ENABLE(FULLSCREEN_API)
2765 WebFullScreenManager* WebPage::fullScreenManager()
2766 {
2767     if (!m_fullScreenManager)
2768         m_fullScreenManager = WebFullScreenManager::create(this);
2769     return m_fullScreenManager.get();
2770 }
2771 #endif
2772
2773 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
2774 {
2775     if (m_notificationPermissionRequestManager)
2776         return m_notificationPermissionRequestManager.get();
2777
2778     m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
2779     return m_notificationPermissionRequestManager.get();
2780 }
2781
2782 #if !PLATFORM(GTK) && !PLATFORM(COCOA)
2783 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
2784 {
2785     Node* node = evt->target()->toNode();
2786     ASSERT(node);
2787     Frame* frame = node->document().frame();
2788     ASSERT(frame);
2789
2790     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
2791     if (!keyEvent)
2792         return false;
2793
2794     Editor::Command command = frame->editor().command(interpretKeyEvent(evt));
2795
2796     if (keyEvent->type() == PlatformEvent::RawKeyDown) {
2797         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
2798         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
2799         // (e.g. Tab that inserts a Tab character, or Enter).
2800         return !command.isTextInsertion() && command.execute(evt);
2801     }
2802
2803     if (command.execute(evt))
2804         return true;
2805
2806     // Don't allow text insertion for nodes that cannot edit.
2807     if (!frame->editor().canEdit())
2808         return false;
2809
2810     // Don't insert null or control characters as they can result in unexpected behaviour
2811     if (evt->charCode() < ' ')
2812         return false;
2813
2814     return frame->editor().insertText(evt->keyEvent()->text(), evt);
2815 }
2816 #endif
2817
2818 #if ENABLE(DRAG_SUPPORT)
2819
2820 #if PLATFORM(GTK)
2821 void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
2822 {
2823     if (!m_page) {
2824         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
2825         DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2826         data->deref();
2827         return;
2828     }
2829
2830     switch (action) {
2831     case DragControllerActionEntered: {
2832         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2833         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2834         break;
2835     }
2836     case DragControllerActionUpdated: {
2837         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2838         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2839         break;
2840     }
2841     case DragControllerActionExited:
2842         m_page->dragController().dragExited(dragData);
2843         break;
2844
2845     case DragControllerActionPerformDragOperation: {
2846         m_page->dragController().performDragOperation(dragData);
2847         break;
2848     }
2849
2850     default:
2851         ASSERT_NOT_REACHED();
2852     }
2853     // DragData does not delete its platformData so we need to do that here.
2854     DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2855     data->deref();
2856 }
2857
2858 #else
2859 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsHandleArray)
2860 {
2861     if (!m_page) {
2862         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone, false, 0));
2863         return;
2864     }
2865
2866     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
2867     switch (action) {
2868     case DragControllerActionEntered: {
2869         DragOperation resolvedDragOperation = m_page->dragController().dragEntered(dragData);
2870         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2871         break;
2872
2873     }
2874     case DragControllerActionUpdated: {
2875         DragOperation resolvedDragOperation = m_page->dragController().dragUpdated(dragData);
2876         send(Messages::WebPageProxy::DidPerformDragControllerAction(resolvedDragOperation, m_page->dragController().mouseIsOverFileInput(), m_page->dragController().numberOfItemsToBeAccepted()));
2877         break;
2878     }
2879     case DragControllerActionExited:
2880         m_page->dragController().dragExited(dragData);
2881         break;
2882         
2883     case DragControllerActionPerformDragOperation: {
2884         ASSERT(!m_pendingDropSandboxExtension);
2885
2886         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
2887         for (size_t i = 0; i < sandboxExtensionsHandleArray.size(); i++) {
2888             if (RefPtr<SandboxExtension> extension = SandboxExtension::create(sandboxExtensionsHandleArray[i]))
2889                 m_pendingDropExtensionsForFileUpload.append(extension);
2890         }
2891
2892         m_page->dragController().performDragOperation(dragData);
2893
2894         // If we started loading a local file, the sandbox extension tracker would have adopted this
2895         // pending drop sandbox extension. If not, we'll play it safe and clear it.
2896         m_pendingDropSandboxExtension = nullptr;
2897
2898         m_pendingDropExtensionsForFileUpload.clear();
2899         break;
2900     }
2901
2902     default:
2903         ASSERT_NOT_REACHED();
2904     }
2905 }
2906 #endif
2907
2908 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
2909 {
2910     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController().dragOffset().x(), clientPosition.y() + m_page->dragController().dragOffset().y());
2911     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController().dragOffset().x(), globalPosition.y() + m_page->dragController().dragOffset().y());
2912
2913     m_page->dragController().dragEnded();
2914     FrameView* view = m_page->mainFrame().view();
2915     if (!view)
2916         return;
2917     // FIXME: These are fake modifier keys here, but they should be real ones instead.
2918     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime());
2919     m_page->mainFrame().eventHandler().dragSourceEndedAt(event, (DragOperation)operation);
2920 }
2921
2922 void WebPage::willPerformLoadDragDestinationAction()
2923 {
2924     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
2925 }
2926
2927 void WebPage::mayPerformUploadDragDestinationAction()
2928 {
2929     for (size_t i = 0; i < m_pendingDropExtensionsForFileUpload.size(); i++)
2930         m_pendingDropExtensionsForFileUpload[i]->consumePermanently();
2931     m_pendingDropExtensionsForFileUpload.clear();
2932 }
2933     
2934 #endif // ENABLE(DRAG_SUPPORT)
2935
2936 WebUndoStep* WebPage::webUndoStep(uint64_t stepID)
2937 {
2938     return m_undoStepMap.get(stepID);
2939 }
2940
2941 void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry)
2942 {
2943     m_undoStepMap.set(stepID, entry);
2944 }
2945
2946 void WebPage::removeWebEditCommand(uint64_t stepID)
2947 {
2948     m_undoStepMap.remove(stepID);
2949 }
2950
2951 void WebPage::unapplyEditCommand(uint64_t stepID)
2952 {
2953     WebUndoStep* step = webUndoStep(stepID);
2954     if (!step)
2955         return;
2956
2957     step->step()->unapply();
2958 }
2959
2960 void WebPage::reapplyEditCommand(uint64_t stepID)
2961 {
2962     WebUndoStep* step = webUndoStep(stepID);
2963     if (!step)
2964         return;
2965
2966     m_isInRedo = true;
2967     step->step()->reapply();
2968     m_isInRedo = false;
2969 }
2970
2971 void WebPage::didRemoveEditCommand(uint64_t commandID)
2972 {
2973     removeWebEditCommand(commandID);
2974 }
2975
2976 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
2977 {
2978     m_activePopupMenu = menu;
2979 }
2980
2981 #if ENABLE(INPUT_TYPE_COLOR)
2982 void WebPage::setActiveColorChooser(WebColorChooser* colorChooser)
2983 {
2984     m_activeColorChooser = colorChooser;
2985 }
2986
2987 void WebPage::didEndColorPicker()
2988 {
2989     m_activeColorChooser->didEndChooser();
2990 }
2991
2992 void WebPage::didChooseColor(const WebCore::Color& color)
2993 {
2994     m_activeColorChooser->didChooseColor(color);
2995 }
2996 #endif
2997
2998 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
2999 {
3000     m_activeOpenPanelResultListener = openPanelResultListener;
3001 }
3002
3003 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
3004 {
3005     return m_page->findString(target, options);
3006 }
3007
3008 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
3009 {
3010     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
3011 }
3012
3013 void WebPage::findStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3014 {
3015     m_findController.findStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3016 }
3017
3018 void WebPage::getImageForFindMatch(uint32_t matchIndex)
3019 {
3020     m_findController.getImageForFindMatch(matchIndex);
3021 }
3022
3023 void WebPage::selectFindMatch(uint32_t matchIndex)
3024 {
3025     m_findController.selectFindMatch(matchIndex);
3026 }
3027
3028 void WebPage::hideFindUI()
3029 {
3030     m_findController.hideFindUI();
3031 }
3032
3033 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
3034 {
3035     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
3036 }
3037
3038 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
3039 {
3040     changeSelectedIndex(newIndex);
3041     m_activePopupMenu = 0;
3042 }
3043
3044 void WebPage::changeSelectedIndex(int32_t index)
3045 {
3046     if (!m_activePopupMenu)
3047         return;
3048
3049     m_activePopupMenu->didChangeSelectedIndex(index);
3050 }
3051
3052 #if PLATFORM(IOS)
3053 void WebPage::didChooseFilesForOpenPanelWithDisplayStringAndIcon(const Vector<String>& files, const String& displayString, const IPC::DataReference& iconData)
3054 {
3055     if (!m_activeOpenPanelResultListener)
3056         return;
3057
3058     RefPtr<Icon> icon;
3059     if (!iconData.isEmpty()) {
3060         RetainPtr<CFDataRef> dataRef = adoptCF(CFDataCreate(nullptr, iconData.data(), iconData.size()));
3061         RetainPtr<CGDataProviderRef> imageProviderRef = adoptCF(CGDataProviderCreateWithCFData(dataRef.get()));
3062         RetainPtr<CGImageRef> imageRef = adoptCF(CGImageCreateWithJPEGDataProvider(imageProviderRef.get(), nullptr, true, kCGRenderingIntentDefault));
3063         icon = Icon::createIconForImage(imageRef.get());
3064     }
3065
3066     m_activeOpenPanelResultListener->didChooseFilesWithDisplayStringAndIcon(files, displayString, icon.get());
3067     m_activeOpenPanelResultListener = nullptr;
3068 }
3069 #endif
3070
3071 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
3072 {
3073     if (!m_activeOpenPanelResultListener)
3074         return;
3075
3076     m_activeOpenPanelResultListener->didChooseFiles(files);
3077     m_activeOpenPanelResultListener = 0;
3078 }
3079
3080 void WebPage::didCancelForOpenPanel()
3081 {
3082     m_activeOpenPanelResultListener = 0;
3083 }
3084
3085 #if ENABLE(WEB_PROCESS_SANDBOX)
3086 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
3087 {
3088     SandboxExtension::create(handle)->consumePermanently();
3089 }
3090 #endif
3091
3092 #if ENABLE(GEOLOCATION)
3093 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
3094 {
3095     m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
3096 }
3097 #endif
3098
3099 void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
3100 {
3101     notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
3102 }
3103
3104 #if !PLATFORM(IOS)
3105 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
3106 {
3107     Frame& frame = m_page->focusController().focusedOrMainFrame();
3108     frame.editor().advanceToNextMisspelling(startBeforeSelection);
3109 }
3110 #endif
3111
3112 void WebPage::changeSpellingToWord(const String& word)
3113 {
3114     replaceSelectionWithText(&m_page->focusController().focusedOrMainFrame(), word);
3115 }
3116
3117 void WebPage::unmarkAllMisspellings()
3118 {
3119     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3120         if (Document* document = frame->document())
3121             document->markers().removeMarkers(DocumentMarker::Spelling);
3122     }
3123 }
3124
3125 void WebPage::unmarkAllBadGrammar()
3126 {
3127     for (Frame* frame = &m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
3128         if (Document* document = frame->document())
3129             document->markers().removeMarkers(DocumentMarker::Grammar);
3130     }
3131 }
3132
3133 #if USE(APPKIT)
3134 void WebPage::uppercaseWord()
3135 {
3136     m_page->focusController().focusedOrMainFrame().editor().uppercaseWord();
3137 }
3138
3139 void WebPage::lowercaseWord()
3140 {
3141     m_page->focusController().focusedOrMainFrame().editor().lowercaseWord();
3142 }
3143
3144 void WebPage::capitalizeWord()
3145 {
3146     m_page->focusController().focusedOrMainFrame().editor().capitalizeWord();
3147 }
3148 #endif
3149     
3150 void WebPage::setTextForActivePopupMenu(int32_t index)
3151 {
3152     if (!m_activePopupMenu)
3153         return;
3154
3155     m_activePopupMenu->setTextForIndex(index);
3156 }
3157
3158 #if PLATFORM(GTK)
3159 void WebPage::failedToShowPopupMenu()
3160 {
3161     if (!m_activePopupMenu)
3162         return;
3163
3164     m_activePopupMenu->client()->popupDidHide();
3165 }
3166 #endif
3167
3168 #if ENABLE(CONTEXT_MENUS)
3169 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
3170 {
3171     if (!m_contextMenu)
3172         return;
3173
3174     m_contextMenu->itemSelected(item);
3175     m_contextMenu = 0;
3176 }
3177 #endif
3178
3179 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
3180 {
3181     bool selectReplacement = true;
3182     bool smartReplace = false;
3183     return frame->editor().replaceSelectionWithText(text, selectReplacement, smartReplace);
3184 }
3185
3186 #if !PLATFORM(IOS)
3187 void WebPage::clearSelection()
3188 {
3189     m_page->focusController().focusedOrMainFrame().selection().clear();
3190 }
3191 #endif
3192
3193 bool WebPage::mainFrameHasCustomContentProvider() const
3194 {
3195     if (Frame* frame = mainFrame()) {
3196         WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client());
3197         ASSERT(webFrameLoaderClient);
3198         return webFrameLoaderClient->frameHasCustomContentProvider();
3199     }
3200
3201     return false;
3202 }
3203
3204 void WebPage::addMIMETypeWithCustomContentProvider(const String& mimeType)
3205 {
3206     m_mimeTypesWithCustomContentProviders.add(mimeType);
3207 }
3208
3209 void WebPage::updateMainFrameScrollOffsetPinning()
3210 {
3211     Frame& frame = m_page->mainFrame();
3212     IntPoint scrollPosition = frame.view()->scrollPosition();
3213     IntPoint maximumScrollPosition = frame.view()->maximumScrollPosition();
3214     IntPoint minimumScrollPosition = frame.view()->minimumScrollPosition();
3215
3216     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
3217     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
3218     bool isPinnedToTopSide = (scrollPosition.y() <= minimumScrollPosition.y());
3219     bool isPinnedToBottomSide = (scrollPosition.y() >= maximumScrollPosition.y());
3220
3221     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide || isPinnedToTopSide != m_cachedMainFrameIsPinnedToTopSide || isPinnedToBottomSide != m_cachedMainFrameIsPinnedToBottomSide) {
3222         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide, isPinnedToTopSide, isPinnedToBottomSide));
3223         
3224         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
3225         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
3226         m_cachedMainFrameIsPinnedToTopSide = isPinnedToTopSide;
3227         m_cachedMainFrameIsPinnedToBottomSide = isPinnedToBottomSide;
3228     }
3229 }
3230
3231 void WebPage::mainFrameDidLayout()
3232 {
3233     unsigned pageCount = m_page->pageCount();
3234     if (pageCount != m_cachedPageCount) {
3235         send(Messages::WebPageProxy::DidChangePageCount(pageCount));
3236         m_cachedPageCount = pageCount;
3237     }
3238
3239 #if USE(TILED_BACKING_STORE)
3240     if (m_drawingArea && m_drawingArea->layerTreeHost()) {
3241         double red, green, blue, alpha;
3242         m_mainFrame->getDocumentBackgroundColor(&red, &green, &blue, &alpha);
3243         RGBA32 rgba = makeRGBA32FromFloats(red, green, blue, alpha);
3244         if (m_backgroundColor.rgb() != rgba) {
3245             m_backgroundColor.setRGB(rgba);
3246             m_drawingArea->layerTreeHost()->setBackgroundColor(m_backgroundColor);
3247         }
3248     }
3249 #endif
3250
3251 #if PLATFORM(MAC)
3252     m_viewGestureGeometryCollector.mainFrameDidLayout();
3253 #endif
3254 #if PLATFORM(IOS)
3255     if (FrameView* frameView = mainFrameView()) {
3256         m_viewportConfiguration.setContentsSize(frameView->contentsSize());
3257         viewportConfigurationChanged();
3258     }
3259 #endif
3260 }
3261
3262 void WebPage::addPluginView(PluginView* pluginView)
3263 {
3264     ASSERT(!m_pluginViews.contains(pluginView));
3265
3266     m_pluginViews.add(pluginView);
3267     m_hasSeenPlugin = true;
3268 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3269     LOG(Plugins, "Primary Plug-In Detection: triggering detection from addPluginView(%p)", pluginView);
3270     m_determinePrimarySnapshottedPlugInTimer.startOneShot(0);
3271 #endif
3272 }
3273
3274 void WebPage::removePluginView(PluginView* pluginView)
3275 {
3276     ASSERT(m_pluginViews.contains(pluginView));
3277
3278     m_pluginViews.remove(pluginView);
3279 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3280     LOG(Plugins, "Primary Plug-In Detection: removePluginView(%p)", pluginView);
3281 #endif
3282 }
3283
3284 void WebPage::sendSetWindowFrame(const FloatRect& windowFrame)
3285 {
3286 #if PLATFORM(COCOA)
3287     m_hasCachedWindowFrame = false;
3288 #endif
3289     send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
3290 }
3291
3292 #if PLATFORM(COCOA)
3293 void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates)
3294 {
3295     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
3296     m_windowFrameInUnflippedScreenCoordinates = windowFrameInUnflippedScreenCoordinates;
3297     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
3298     m_accessibilityPosition = accessibilityViewCoordinates;
3299     
3300     // Tell all our plug-in views that the window and view frames have changed.
3301     for (auto* pluginView : m_pluginViews)
3302         pluginView->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates));
3303
3304     m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty();
3305 }
3306 #endif
3307
3308 void WebPage::setMainFrameIsScrollable(bool isScrollable)
3309 {
3310     m_mainFrameIsScrollable = isScrollable;
3311     m_drawingArea->mainFrameScrollabilityChanged(isScrollable);
3312
3313     if (FrameView* frameView = m_mainFrame->coreFrame()->view()) {
3314         frameView->setCanHaveScrollbars(isScrollable);
3315         frameView->setProhibitsScrolling(!isScrollable);
3316     }
3317 }
3318
3319 bool WebPage::windowIsFocused() const
3320 {
3321     return m_page->focusController().isActive();
3322 }
3323
3324 bool WebPage::windowAndWebPageAreFocused() const
3325 {
3326     if (!isVisible())
3327         return false;
3328
3329     return m_page->focusController().isFocused() && m_page->focusController().isActive();
3330 }
3331
3332 void WebPage::didReceiveMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder)
3333 {
3334     if (decoder.messageReceiverName() == Messages::DrawingArea::messageReceiverName()) {
3335         if (m_drawingArea)
3336             m_drawingArea->didReceiveDrawingAreaMessage(connection, decoder);
3337         return;
3338     }
3339
3340 #if USE(TILED_BACKING_STORE)
3341     if (decoder.messageReceiverName() == Messages::CoordinatedLayerTreeHost::messageReceiverName()) {
3342         if (m_drawingArea)
3343             m_drawingArea->didReceiveCoordinatedLayerTreeHostMessage(connection, decoder);
3344         return;
3345     }
3346 #endif
3347     
3348 #if ENABLE(INSPECTOR)
3349     if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
3350         if (WebInspector* inspector = this->inspector())
3351             inspector->didReceiveWebInspectorMessage(connection, decoder);
3352         return;
3353     }
3354 #endif
3355
3356 #if ENABLE(FULLSCREEN_API)
3357     if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) {
3358         fullScreenManager()->didReceiveMessage(connection, decoder);
3359         return;
3360     }
3361 #endif
3362
3363     didReceiveWebPageMessage(connection, decoder);
3364 }
3365
3366 void WebPage::didReceiveSyncMessage(IPC::Connection* connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
3367 {   
3368     didReceiveSyncWebPageMessage(connection, decoder, replyEncoder);
3369 }
3370     
3371 InjectedBundleBackForwardList* WebPage::backForwardList()
3372 {
3373     if (!m_backForwardList)
3374         m_backForwardList = InjectedBundleBackForwardList::create(this);
3375     return m_backForwardList.get();
3376 }
3377
3378 #if ENABLE(ASYNC_SCROLLING)
3379 ScrollingCoordinator* WebPage::scrollingCoordinator() const
3380 {
3381     return m_page->scrollingCoordinator();
3382 }
3383 #endif
3384
3385 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
3386 {
3387     invalidate();
3388 }
3389
3390 void WebPage::SandboxExtensionTracker::invalidate()
3391 {
3392     m_pendingProvisionalSandboxExtension = nullptr;
3393
3394     if (m_provisionalSandboxExtension) {
3395         m_provisionalSandboxExtension->revoke();
3396         m_provisionalSandboxExtension = nullptr;
3397     }
3398
3399     if (m_committedSandboxExtension) {
3400         m_committedSandboxExtension->revoke();
3401         m_committedSandboxExtension = nullptr;
3402     }
3403 }
3404
3405 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
3406 {
3407     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
3408 }
3409
3410 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
3411 {
3412     ASSERT_UNUSED(frame, frame->isMainFrame());
3413
3414     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
3415 }
3416
3417 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
3418 {
3419     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;    
3420 }
3421
3422 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
3423 {
3424     ASSERT(frame->isMainFrame());
3425
3426     FrameLoader& frameLoader = frame->coreFrame()->loader();
3427     FrameLoadType frameLoadType = frameLoader.loadType();
3428
3429     // If the page is being reloaded, it should reuse whatever extension is committed.
3430     if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
3431         return true;
3432
3433     DocumentLoader* documentLoader = frameLoader.documentLoader();
3434     DocumentLoader* provisionalDocumentLoader = frameLoader.provisionalDocumentLoader();
3435     if (!documentLoader || !provisionalDocumentLoader)
3436         return false;
3437
3438     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
3439         return true;
3440
3441     return false;
3442 }
3443
3444 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
3445 {
3446     if (!frame->isMainFrame())
3447         return;
3448
3449     // We should only reuse the commited sandbox extension if it is not null. It can be
3450     // null if the last load was for an error page.
3451     if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame))
3452         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension;
3453
3454     ASSERT(!m_provisionalSandboxExtension);
3455
3456     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
3457     if (!m_provisionalSandboxExtension)
3458         return;
3459
3460     ASSERT(!m_provisionalSandboxExtension || frame->coreFrame()->loader().provisionalDocumentLoader()->url().isLocalFile());
3461
3462     m_provisionalSandboxExtension->consume();
3463 }
3464
3465 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
3466 {
3467     if (!frame->isMainFrame())
3468         return;
3469
3470     if (m_committedSandboxExtension)
3471         m_committedSandboxExtension->revoke();
3472
3473     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
3474
3475     // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started.
3476     // This extension is not cleared, because it does not pertain to the failed load, and will be needed.
3477 }
3478
3479 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
3480 {
3481     if (!frame->isMainFrame())
3482         return;
3483
3484     if (!m_provisionalSandboxExtension)
3485         return;
3486
3487     m_provisionalSandboxExtension->revoke();
3488     m_provisionalSandboxExtension = nullptr;
3489
3490     // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started
3491     // (notably, if the current one fails because the new one cancels it). This extension is not cleared,
3492     // because it does not pertain to the failed load, and will be needed.
3493 }
3494
3495 bool WebPage::hasLocalDataForURL(const URL& url)
3496 {
3497     if (url.isLocalFile())
3498         return true;
3499
3500     DocumentLoader* documentLoader = m_page->mainFrame().loader().documentLoader();
3501     if (documentLoader && documentLoader->subresource(url))
3502         return true;
3503
3504     return platformHasLocalDataForURL(url);
3505 }
3506
3507 void WebPage::setCustomTextEncodingName(const String& encoding)
3508 {
3509     m_page->mainFrame().loader().reloadWithOverrideEncoding(encoding);
3510 }
3511
3512 void WebPage::didRemoveBackForwardItem(uint64_t itemID)
3513 {
3514     WebBackForwardListProxy::removeItem(itemID);
3515 }
3516
3517 #if PLATFORM(COCOA)
3518
3519 bool WebPage::isSpeaking()
3520 {
3521     bool result;
3522     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
3523 }
3524
3525 void WebPage::speak(const String& string)
3526 {
3527     send(Messages::WebPageProxy::Speak(string));
3528 }
3529
3530 void WebPage::stopSpeaking()
3531 {
3532     send(Messages::WebPageProxy::StopSpeaking());
3533 }
3534
3535 #endif
3536
3537 #if PLATFORM(MAC)
3538 RetainPtr<PDFDocument> WebPage::pdfDocumentForPrintingFrame(Frame* coreFrame)
3539 {
3540     Document* document = coreFrame->document();
3541     if (!document)
3542         return 0;
3543
3544     if (!document->isPluginDocument())
3545         return 0;
3546
3547     PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget());
3548     if (!pluginView)
3549         return 0;
3550
3551     return pluginView->pdfDocumentForPrinting();
3552 }
3553 #endif // PLATFORM(MAC)
3554
3555 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
3556 {
3557     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3558     if (!frame)
3559         return;
3560
3561     Frame* coreFrame = frame->coreFrame();
3562     if (!coreFrame)
3563         return;
3564
3565 #if PLATFORM(MAC)
3566     if (pdfDocumentForPrintingFrame(coreFrame))
3567         return;
3568 #endif // PLATFORM(MAC)
3569
3570     if (!m_printContext)
3571         m_printContext = std::make_unique<PrintContext>(coreFrame);
3572
3573     drawingArea()->setLayerTreeStateIsFrozen(true);
3574     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
3575
3576     float fullPageHeight;
3577     m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
3578
3579 #if PLATFORM(GTK)
3580     if (!m_printOperation)
3581         m_printOperation = WebPrintOperationGtk::create(this, printInfo);
3582 #endif
3583 }
3584
3585 void WebPage::endPrinting()
3586 {
3587     drawingArea()->setLayerTreeStateIsFrozen(false);
3588     m_printContext = nullptr;
3589 }
3590
3591 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
3592 {
3593     Vector<IntRect> resultPageRects;
3594     double resultTotalScaleFactorForPrinting = 1;
3595
3596     beginPrinting(frameID, printInfo);
3597
3598     if (m_printContext) {
3599         resultPageRects = m_printContext->pageRects();
3600         resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
3601     }
3602 #if PLATFORM(COCOA)
3603     else
3604         computePagesForPrintingPDFDocument(frameID, printInfo, resultPageRects);
3605 #endif // PLATFORM(COCOA)
3606
3607     // If we're asked to print, we should actually print at least a blank page.
3608     if (resultPageRects.isEmpty())
3609         resultPageRects.append(IntRect(0, 0, 1, 1));
3610
3611     send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
3612 }
3613
3614 #if PLATFORM(COCOA)
3615 void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, uint64_t callbackID)
3616 {
3617     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3618     Frame* coreFrame = frame ? frame->coreFrame() : 0;
3619
3620     RefPtr<WebImage> image;
3621
3622 #if USE(CG)
3623     if (coreFrame) {
3624 #if PLATFORM(MAC)
3625         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
3626 #else
3627         ASSERT(coreFrame->document()->printing());
3628 #endif
3629
3630         RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha);
3631         auto graphicsContext = bitmap->createGraphicsContext();
3632
3633         float printingScale = static_cast<float>(imageSize.width()) / rect.width();
3634         graphicsContext->scale(FloatSize(printingScale, printingScale));
3635
3636 #if PLATFORM(MAC)
3637         if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
3638             ASSERT(!m_printContext);
3639             graphicsContext->scale(FloatSize(1, -1));
3640             graphicsContext->translate(0, -rect.height());
3641             drawPDFDocument(graphicsContext->platformContext(), pdfDocument.get(), printInfo, rect);
3642         } else
3643 #endif
3644         {
3645             m_printContext->spoolRect(*graphicsContext, rect);
3646         }
3647
3648         image = WebImage::create(bitmap.release());
3649     }
3650 #endif
3651
3652     ShareableBitmap::Handle handle;
3653
3654     if (image)
3655         image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
3656
3657     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
3658 }
3659
3660 void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
3661 {
3662     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3663     Frame* coreFrame = frame ? frame->coreFrame() : 0;
3664
3665     RetainPtr<CFMutableDataRef> pdfPageData = adoptCF(CFDataCreateMutable(0, 0));
3666
3667 #if USE(CG)
3668     if (coreFrame) {
3669
3670 #if PLATFORM(MAC)
3671         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
3672 #else
3673         ASSERT(coreFrame->document()->printing());
3674 #endif
3675
3676         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
3677         RetainPtr<CGDataConsumerRef> pdfDataConsumer = adoptCF(CGDataConsumerCreateWithCFData(pdfPageData.get()));
3678
3679         CGRect mediaBox = (m_printContext && m_printContext->pageCount()) ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight);
3680         RetainPtr<CGContextRef> context = adoptCF(CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
3681
3682 #if PLATFORM(MAC)
3683         if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
3684             ASSERT(!m_printContext);
3685             drawPagesToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, first, count);
3686         } else
3687 #endif
3688         {
3689             size_t pageCount = m_printContext->pageCount();
3690             for (uint32_t page = first; page < first + count; ++page) {
3691                 if (page >= pageCount)
3692                     break;
3693
3694                 RetainPtr<CFDictionaryRef> pageInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
3695                 CGPDFContextBeginPage(context.get(), pageInfo.get());
3696
3697                 GraphicsContext ctx(context.get());
3698                 ctx.scale(FloatSize(1, -1));
3699                 ctx.translate(0, -m_printContext->pageRect(page).height());
3700                 m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
3701
3702                 CGPDFContextEndPage(context.get());
3703             }
3704         }
3705         CGPDFContextClose(context.get());
3706     }
3707 #endif
3708
3709     send(Messages::WebPageProxy::DataCallback(IPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
3710 }
3711
3712 #elif PLATFORM(GTK)
3713 void WebPage::drawPagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
3714 {
3715     beginPrinting(frameID, printInfo);
3716     if (m_printContext && m_printOperation) {
3717         m_printOperation->startPrint(m_printContext.get(), callbackID);
3718         return;
3719     }
3720
3721     send(Messages::WebPageProxy::VoidCallback(callbackID));
3722 }
3723
3724 void WebPage::didFinishPrintOperation(const WebCore::ResourceError& error, uint64_t callbackID)
3725 {
3726     send(Messages::WebPageProxy::PrintFinishedCallback(error, callbackID));
3727     m_printOperation = nullptr;
3728 }
3729 #endif
3730
3731 void WebPage::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size)
3732 {
3733     send(Messages::WebPageProxy::SavePDFToFileInDownloadsFolder(suggestedFilename, originatingURLString, IPC::DataReference(data, size)));
3734 }
3735
3736 #if PLATFORM(COCOA)
3737 void WebPage::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID)
3738 {
3739     send(Messages::WebPageProxy::SavePDFToTemporaryFolderAndOpenWithNativeApplication(suggestedFilename, originatingURLString, IPC::DataReference(data, size), pdfUUID));
3740 }
3741 #endif
3742
3743 void WebPage::setMediaVolume(float volume)
3744 {
3745     m_page->setMediaVolume(volume);
3746 }
3747
3748 void WebPage::setMayStartMediaWhenInWindow(bool mayStartMedia)
3749 {
3750     if (mayStartMedia == m_mayStartMediaWhenInWindow)
3751         return;
3752
3753     m_mayStartMediaWhenInWindow = mayStartMedia;
3754     if (m_mayStartMediaWhenInWindow && m_page->isInWindow())
3755         m_setCanStartMediaTimer.startOneShot(0);
3756 }
3757
3758 void WebPage::runModal()
3759 {
3760     if (m_isClosed)
3761         return;
3762     if (m_isRunningModal)
3763         return;
3764
3765     m_isRunningModal = true;
3766     send(Messages::WebPageProxy::RunModal());
3767 #if !ASSERT_DISABLED
3768     Ref<WebPage> protector(*this);
3769 #endif
3770     RunLoop::run();
3771     ASSERT(!m_isRunningModal);
3772 }
3773
3774 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
3775 {
3776     if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
3777         return true;
3778
3779 #if ENABLE(BLOB)
3780     if (request.url().protocolIs("blob"))
3781         return true;
3782 #endif
3783
3784     return platformCanHandleRequest(request);
3785 }
3786
3787 #if USE(TILED_BACKING_STORE)
3788 void WebPage::commitPageTransitionViewport()
3789 {
3790     m_drawingArea->setLayerTreeStateIsFrozen(false);
3791 }
3792 #endif
3793
3794 #if PLATFORM(COCOA)
3795 void WebPage::handleAlternativeTextUIResult(const String& result)
3796 {
3797     Frame& frame = m_page->focusController().focusedOrMainFrame();
3798     frame.editor().handleAlternativeTextUIResult(result);
3799 }
3800 #endif
3801
3802 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
3803 {
3804     mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
3805 }
3806
3807 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
3808 {
3809     mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
3810 }
3811
3812 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
3813 {
3814     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
3815 }
3816
3817 void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length)
3818 {
3819     Frame& frame = m_page->focusController().focusedOrMainFrame();
3820     if (!frame.editor().canEdit())
3821         return;
3822
3823     Vector<CompositionUnderline> underlines;
3824     underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false));
3825     frame.editor().setComposition(compositionString, underlines, from, from + length);
3826 }
3827
3828 bool WebPage::hasCompositionForTesting()
3829 {
3830     Frame& frame = m_page->focusController().focusedOrMainFrame();
3831     return frame.editor().hasComposition();
3832 }
3833
3834 void WebPage::confirmCompositionForTesting(const String& compositionString)
3835 {
3836     Frame& frame = m_page->focusController().focusedOrMainFrame();
3837     if (!frame.editor().canEdit())
3838         return;
3839
3840     if (compositionString.isNull())
3841         frame.editor().confirmComposition();
3842     frame.editor().confirmComposition(compositionString);
3843 }
3844
3845 void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers)
3846 {
3847     if (m_numWheelEventHandlers == numWheelEventHandlers)
3848         return;
3849
3850     m_numWheelEventHandlers = numWheelEventHandlers;
3851     recomputeShortCircuitHorizontalWheelEventsState();
3852 }
3853
3854 static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea)
3855 {
3856     if (Scrollbar* scrollbar = scrollableArea->horizontalScrollbar())
3857         return scrollbar->enabled();
3858
3859     return false;
3860 }
3861
3862 static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame)
3863 {
3864     if (FrameView* frameView = mainFrame->view()) {
3865         if (hasEnabledHorizontalScrollbar(frameView))
3866             return true;
3867     }
3868
3869     for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
3870         FrameView* frameView = frame->view();
3871         if (!frameView)
3872             continue;
3873
3874         const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
3875         if (!scrollableAreas)
3876             continue;
3877
3878         for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
3879             ScrollableArea* scrollableArea = *it;
3880             if (!scrollableArea->scrollbarsCanBeActive())
3881                 continue;
3882
3883             if (hasEnabledHorizontalScrollbar(scrollableArea))
3884                 return true;
3885         }
3886     }
3887
3888     return false;
3889 }
3890
3891 void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
3892 {
3893     bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers;
3894
3895     if (canShortCircuitHorizontalWheelEvents) {
3896         // Check if we have any horizontal scroll bars on the page.
3897         if (pageContainsAnyHorizontalScrollbars(mainFrame()))
3898             canShortCircuitHorizontalWheelEvents = false;
3899     }
3900
3901     if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents)
3902         return;
3903
3904     m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents;
3905     send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents));
3906 }
3907
3908 Frame* WebPage::mainFrame() const
3909 {
3910     return m_page ? &m_page->mainFrame() : nullptr;
3911 }
3912
3913 FrameView* WebPage::mainFrameView() const
3914 {
3915     if (Frame* frame = mainFrame())
3916         return frame->view();
3917     
3918     return nullptr;
3919 }
3920
3921 void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled)
3922 {
3923     m_scrollingPerformanceLoggingEnabled = enabled;
3924
3925     FrameView* frameView = m_mainFrame->coreFrame()->view();
3926     if (!frameView)
3927         return;
3928
3929     frameView->setScrollingPerformanceLoggingEnabled(enabled);
3930 }
3931
3932 bool WebPage::canPluginHandleResponse(const ResourceResponse& response)
3933 {
3934 #if ENABLE(NETSCAPE_PLUGIN_API)
3935     uint32_t pluginLoadPolicy;
3936     bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
3937
3938     uint64_t pluginProcessToken;
3939     String newMIMEType;
3940     String unavailabilityDescription;
3941     if (!sendSync(Messages::WebPageProxy::FindPlugin(response.mimeType(), PluginProcessTypeNormal, response.url().string(), response.url().string(), response.url().string(), allowOnlyApplicationPlugins), Messages::WebPageProxy::FindPlugin::Reply(pluginProcessToken, newMIMEType, pluginLoadPolicy, unavailabilityDescription)))
3942         return false;
3943
3944     return pluginLoadPolicy != PluginModuleBlocked && pluginProcessToken;
3945 #else
3946     UNUSED_PARAM(response);
3947     return false;
3948 #endif
3949 }
3950
3951 bool WebPage::shouldUseCustomContentProviderForResponse(const ResourceResponse& response)
3952 {
3953     // If a plug-in exists that claims to support this response, it should take precedence over the custom content provider.
3954     return m_mimeTypesWithCustomContentProviders.contains(response.mimeType()) && !canPluginHandleResponse(response);
3955 }
3956
3957 #if PLATFORM(COCOA)
3958
3959 void WebPage::insertTextAsync(const String& text, const EditingRange& replacementEditingRange)
3960 {
3961     Frame& frame = m_page->focusController().focusedOrMainFrame();
3962
3963     if (replacementEditingRange.location != notFound) {
3964         RefPtr<Range> replacementRange = rangeFromEditingRange(frame, replacementEditingRange);
3965         if (replacementRange)
3966             frame.selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
3967     }
3968
3969     if (!frame.editor().hasComposition()) {
3970         // An insertText: might be handled by other responders in the chain if we don't handle it.
3971         // One example is space bar that results in scrolling down the page.
3972         frame.editor().insertText(text, nullptr);
3973     } else
3974         frame.editor().confirmComposition(text);
3975 }
3976
3977 void WebPage::getMarkedRangeAsync(uint64_t callbackID)
3978 {
3979     Frame& frame = m_page->focusController().focusedOrMainFrame();
3980
3981     RefPtr<Range> range = frame.editor().compositionRange();
3982     size_t location;
3983     size_t length;
3984     if (!range || !TextIterator::getLocationAndLengthFromRange(frame.selection().rootEditableElementOrDocumentElement(), range.get(), location, length)) {
3985         location = notFound;
3986         length = 0;
3987     }
3988
3989     send(Messages::WebPageProxy::EditingRangeCallback(EditingRange(location, length), callbackID));
3990 }
3991
3992 void WebPage::getSelectedRangeAsync(uint64_t callbackID)
3993 {
3994     Frame& frame = m_page->focusController().focusedOrMainFrame();
3995
3996     size_t location;
3997     size_t length;
3998     RefPtr<Range> range = frame.selection().toNormalizedRange();
3999     if (!range || !TextIterator::getLocationAndLengthFromRange(frame.selection().rootEditableElementOrDocumentElement(), range.get(), location, length)) {
4000         location = notFound;
4001         length = 0;
4002     }
4003
4004     send(Messages::WebPageProxy::EditingRangeCallback(EditingRange(location, length), callbackID));
4005 }
4006
4007 void WebPage::characterIndexForPointAsync(const WebCore::IntPoint& point, uint64_t callbackID)
4008 {
4009     uint64_t index = notFound;
4010
4011     HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(point);
4012     Frame* frame = result.innerNonSharedNode() ? result.innerNodeFrame() : &m_page->focusController().focusedOrMainFrame();
4013     
4014     RefPtr<Range> range = frame->rangeForPoint(result.roundedPointInInnerNodeFrame());
4015     if (range) {
4016         size_t location;
4017         size_t length;
4018         if (TextIterator::getLocationAndLengthFromRange(frame->selection().rootEditableElementOrDocumentElement(), range.get(), location, length))
4019             index = static_cast<uint64_t>(location);
4020     }
4021
4022     send(Messages::WebPageProxy::UnsignedCallback(index, callbackID));
4023 }
4024
4025 void WebPage::firstRectForCharacterRangeAsync(const EditingRange& editingRange, uint64_t callbackID)
4026 {
4027     Frame& frame = m_page->focusController().focusedOrMainFrame();
4028     IntRect result(IntPoint(0, 0), IntSize(0, 0));
4029     
4030     RefPtr<Range> range = rangeFromEditingRange(frame, editingRange);
4031     if (!range) {
4032         send(Messages::WebPageProxy::RectForCharacterRangeCallback(result, EditingRange(notFound, 0), callbackID));
4033         return;
4034     }
4035
4036     ASSERT(range->startContainer());
4037     ASSERT(range->endContainer());
4038
4039     result = frame.view()->contentsToWindow(frame.editor().firstRectForRange(range.get()));
4040
4041     // FIXME: Update actualRange to match the range of first rect.
4042     send(Messages::WebPageProxy::RectForCharacterRangeCallback(result, editingRange, callbackID));
4043 }
4044
4045 void WebPage::setCompositionAsync(const String& text, Vector<CompositionUnderline> underlines, const EditingRange& selection, const EditingRange& replacementEditingRange)
4046 {
4047     Frame& frame = m_page->focusController().focusedOrMainFrame();
4048
4049     if (frame.selection().selection().isContentEditable()) {
4050         RefPtr<Range> replacementRange;
4051         if (replacementEditingRange.location != notFound) {
4052             replacementRange = rangeFromEditingRange(frame, replacementEditingRange);
4053             frame.selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
4054         }
4055
4056         frame.editor().setComposition(text, underlines, selection.location, selection.location + selection.length);
4057     }
4058 }
4059
4060 void WebPage::confirmCompositionAsync()
4061 {
4062     Frame& frame = m_page->focusController().focusedOrMainFrame();
4063     frame.editor().confirmComposition();
4064 }
4065
4066 #endif // PLATFORM(COCOA)
4067
4068 #if PLATFORM(GTK)
4069 static Frame* targetFrameForEditing(WebPage* page)
4070 {
4071     Frame& targetFrame = page->corePage()->focusController().focusedOrMainFrame();
4072
4073     Editor& editor = targetFrame.editor();
4074     if (!editor.canEdit())
4075         return 0;
4076
4077     if (editor.hasComposition()) {
4078         // We should verify the parent node of this IME composition node are
4079         // editable because JavaScript may delete a parent node of the composition
4080         // node. In this case, WebKit crashes while deleting texts from the parent
4081         // node, which doesn't exist any longer.
4082         if (PassRefPtr<Range> range = editor.compositionRange()) {
4083             Node* node = range->startContainer();
4084             if (!node || !node->isContentEditable())
4085                 return 0;
4086         }
4087     }
4088     return &targetFrame;
4089 }
4090
4091 void WebPage::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength)
4092 {
4093     Frame* targetFrame = targetFrameForEditing(this);
4094     if (!targetFrame) {
4095         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4096         return;
4097     }
4098
4099     targetFrame->editor().confirmComposition(compositionString);
4100
4101     if (selectionStart == -1) {
4102         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4103         return;
4104     }
4105
4106     Element* scope = targetFrame->selection().selection().rootEditableElement();
4107     RefPtr<Range> selectionRange = TextIterator::rangeFromLocationAndLength(scope, selectionStart, selectionLength);
4108     ASSERT_WITH_MESSAGE(selectionRange, "Invalid selection: [%lld:%lld] in text of length %d", static_cast<long long>(selectionStart), static_cast<long long>(selectionLength), scope->innerText().length());
4109
4110     if (selectionRange) {
4111         VisibleSelection selection(selectionRange.get(), SEL_DEFAULT_AFFINITY);
4112         targetFrame->selection().setSelection(selection);
4113     }
4114     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4115 }
4116
4117 void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionLength, uint64_t replacementStart, uint64_t replacementLength)
4118 {
4119     Frame* targetFrame = targetFrameForEditing(this);
4120     if (!targetFrame || !targetFrame->selection().selection().isContentEditable()) {
4121         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4122         return;
4123     }
4124
4125     if (replacementLength > 0) {
4126         // The layout needs to be uptodate before setting a selection
4127         targetFrame->document()->updateLayout();
4128
4129         Element* scope = targetFrame->selection().selection().rootEditableElement();
4130         RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength);
4131         targetFrame->editor().setIgnoreCompositionSelectionChange(true);
4132         targetFrame->selection().setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
4133         targetFrame->editor().setIgnoreCompositionSelectionChange(false);
4134     }
4135
4136     targetFrame->editor().setComposition(text, underlines, selectionStart, selectionStart + selectionLength);
4137     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4138 }
4139
4140 void WebPage::cancelComposition()
4141 {
4142     if (Frame* targetFrame = targetFrameForEditing(this))
4143         targetFrame->editor().cancelComposition();
4144     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4145 }
4146 #endif
4147
4148 void WebPage::didChangeSelection()
4149 {
4150 #if (PLATFORM(MAC) && USE(ASYNC_NSTEXTINPUTCLIENT))
4151     Frame& frame = m_page->focusController().focusedOrMainFrame();
4152     // Abandon the current inline input session if selection changed for any other reason but an input method direct action.
4153     // FIXME: Many changes that affect composition node do not go through didChangeSelection(). We need to do something when DOM manipulation affects the composition, because otherwise input method's idea about it will be different from Editor's.
4154     // FIXME: We can't cancel composition when selection changes to NoSelection, but we probably should.
4155     if (frame.editor().hasComposition() && !frame.editor().ignoreCompositionSelectionChange() && !frame.selection().isNone()) {
4156         frame.editor().cancelComposition();
4157         send(Messages::WebPageProxy::CompositionWasCanceled(editorState()));
4158     } else
4159 #endif
4160         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
4161
4162 #if PLATFORM(IOS)
4163     m_drawingArea->scheduleCompositingLayerFlush();
4164 #endif