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