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