9a1d26e4be0ceb3ea85f39e626d65d28a6f09028
[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_hasSeenPlugin(false)
230     , m_useFixedLayout(false)
231     , m_drawsBackground(true)
232     , m_drawsTransparentBackground(false)
233     , m_isInRedo(false)
234     , m_isClosed(false)
235     , m_tabToLinks(false)
236     , m_asynchronousPluginInitializationEnabled(false)
237     , m_asynchronousPluginInitializationEnabledForAllPlugins(false)
238     , m_artificialPluginInitializationDelayEnabled(false)
239     , m_scrollingPerformanceLoggingEnabled(false)
240     , m_mainFrameIsScrollable(true)
241 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
242     , m_readyToFindPrimarySnapshottedPlugin(false)
243     , m_didFindPrimarySnapshottedPlugin(false)
244     , m_numberOfPrimarySnapshotDetectionAttempts(0)
245     , m_determinePrimarySnapshottedPlugInTimer(RunLoop::main(), this, &WebPage::determinePrimarySnapshottedPlugInTimerFired)
246 #endif
247 #if PLATFORM(MAC)
248     , m_pdfPluginEnabled(false)
249     , m_hasCachedWindowFrame(false)
250     , m_windowIsVisible(false)
251     , m_layerHostingMode(parameters.layerHostingMode)
252     , m_keyboardEventBeingInterpreted(0)
253 #elif PLATFORM(GTK)
254     , m_accessibilityObject(0)
255 #endif
256     , m_setCanStartMediaTimer(RunLoop::main(), this, &WebPage::setCanStartMediaTimerFired)
257     , m_sendDidUpdateInWindowStateTimer(RunLoop::main(), this, &WebPage::didUpdateInWindowStateTimerFired)
258     , m_findController(this)
259 #if ENABLE(TOUCH_EVENTS)
260 #if PLATFORM(QT)
261     , m_tapHighlightController(this)
262 #endif
263 #endif
264 #if ENABLE(INPUT_TYPE_COLOR)
265     , m_activeColorChooser(0)
266 #endif
267 #if ENABLE(GEOLOCATION)
268     , m_geolocationPermissionRequestManager(this)
269 #endif
270     , m_pageID(pageID)
271     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
272     , m_canRunModal(parameters.canRunModal)
273     , m_isRunningModal(false)
274     , m_cachedMainFrameIsPinnedToLeftSide(false)
275     , m_cachedMainFrameIsPinnedToRightSide(false)
276     , m_cachedMainFrameIsPinnedToTopSide(false)
277     , m_cachedMainFrameIsPinnedToBottomSide(false)
278     , m_canShortCircuitHorizontalWheelEvents(false)
279     , m_numWheelEventHandlers(0)
280     , m_cachedPageCount(0)
281     , m_autoSizingShouldExpandToViewHeight(false)
282 #if ENABLE(CONTEXT_MENUS)
283     , m_isShowingContextMenu(false)
284 #endif
285     , m_willGoToBackForwardItemCallbackEnabled(true)
286 #if ENABLE(PAGE_VISIBILITY_API)
287     , m_visibilityState(WebCore::PageVisibilityStateVisible)
288 #endif
289     , m_inspectorClient(0)
290     , m_backgroundColor(Color::white)
291     , m_maximumRenderingSuppressionToken(0)
292     , m_scrollPinningBehavior(DoNotPin)
293 {
294     ASSERT(m_pageID);
295     // FIXME: This is a non-ideal location for this Setting and
296     // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
297     Settings::setDefaultMinDOMTimerInterval(0.004);
298
299     Page::PageClients pageClients;
300     pageClients.chromeClient = new WebChromeClient(this);
301 #if ENABLE(CONTEXT_MENUS)
302     pageClients.contextMenuClient = new WebContextMenuClient(this);
303 #endif
304     pageClients.editorClient = new WebEditorClient(this);
305 #if ENABLE(DRAG_SUPPORT)
306     pageClients.dragClient = new WebDragClient(this);
307 #endif
308     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
309 #if ENABLE(INSPECTOR)
310     m_inspectorClient = new WebInspectorClient(this);
311     pageClients.inspectorClient = m_inspectorClient;
312 #endif
313 #if USE(AUTOCORRECTION_PANEL)
314     pageClients.alternativeTextClient = new WebAlternativeTextClient(this);
315 #endif
316     pageClients.plugInClient = new WebPlugInClient(this);
317
318     m_page = adoptPtr(new Page(pageClients));
319
320 #if ENABLE(BATTERY_STATUS)
321     WebCore::provideBatteryTo(m_page.get(), new WebBatteryClient(this));
322 #endif
323 #if ENABLE(GEOLOCATION)
324     WebCore::provideGeolocationTo(m_page.get(), new WebGeolocationClient(this));
325 #endif
326 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(QT) && HAVE(QTSENSORS)
327     WebCore::provideDeviceMotionTo(m_page.get(), new DeviceMotionClientQt);
328     WebCore::provideDeviceOrientationTo(m_page.get(), new DeviceOrientationClientQt);
329 #endif
330 #if ENABLE(NETWORK_INFO)
331     WebCore::provideNetworkInfoTo(m_page.get(), new WebNetworkInfoClient(this));
332 #endif
333 #if ENABLE(NOTIFICATIONS) || ENABLE(LEGACY_NOTIFICATIONS)
334     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
335 #endif
336 #if ENABLE(VIBRATION)
337     WebCore::provideVibrationTo(m_page.get(), new WebVibrationClient(this));
338 #endif
339 #if ENABLE(PROXIMITY_EVENTS)
340     WebCore::provideDeviceProximityTo(m_page.get(), new WebDeviceProximityClient(this));
341 #endif
342
343     m_page->setCanStartMedia(false);
344     m_mayStartMediaWhenInWindow = parameters.mayStartMediaWhenInWindow;
345
346     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
347     m_page->setGroupName(m_pageGroup->identifier());
348     m_page->setDeviceScaleFactor(parameters.deviceScaleFactor);
349
350     m_drawingArea = DrawingArea::create(this, parameters);
351     m_drawingArea->setPaintingEnabled(false);
352
353     updatePreferences(parameters.store);
354     platformInitialize();
355
356     m_mainFrame = WebFrame::createMainFrame(this);
357
358     setUseFixedLayout(parameters.useFixedLayout);
359
360     setDrawsBackground(parameters.drawsBackground);
361     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
362
363     setUnderlayColor(parameters.underlayColor);
364
365     setPaginationMode(parameters.paginationMode);
366     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
367     setPageLength(parameters.pageLength);
368     setGapBetweenPages(parameters.gapBetweenPages);
369
370     setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
371
372     setActive(parameters.isActive);
373     setFocused(parameters.isFocused);
374
375     // Page defaults to in-window, but setIsInWindow depends on it being a valid indicator of actually having been put into a window.
376     if (!parameters.isInWindow)
377         m_page->setIsInWindow(false);
378     else
379         WebProcess::shared().pageDidEnterWindow(m_pageID);
380
381     setIsInWindow(parameters.isInWindow);
382
383     setMinimumLayoutSize(parameters.minimumLayoutSize);
384     setAutoSizingShouldExpandToViewHeight(parameters.autoSizingShouldExpandToViewHeight);
385     
386     setScrollPinningBehavior(parameters.scrollPinningBehavior);
387
388     m_userAgent = parameters.userAgent;
389
390     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
391     
392     if (!parameters.sessionState.isEmpty())
393         restoreSession(parameters.sessionState);
394
395     m_drawingArea->setPaintingEnabled(true);
396     
397     setMediaVolume(parameters.mediaVolume);
398
399     // We use the DidFirstLayout milestone to determine when to unfreeze the layer tree.
400     m_page->addLayoutMilestones(DidFirstLayout);
401
402     WebProcess::shared().addMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID, this);
403
404     // FIXME: This should be done in the object constructors, and the objects themselves should be message receivers.
405     WebProcess::shared().addMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID, this);
406 #if USE(COORDINATED_GRAPHICS)
407     WebProcess::shared().addMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID, this);
408 #endif
409 #if ENABLE(INSPECTOR)
410     WebProcess::shared().addMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID, this);
411 #endif
412 #if ENABLE(FULLSCREEN_API)
413     WebProcess::shared().addMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID, this);
414 #endif
415
416 #ifndef NDEBUG
417     webPageCounter.increment();
418 #endif
419 }
420
421 WebPage::~WebPage()
422 {
423     if (m_backForwardList)
424         m_backForwardList->detach();
425
426     ASSERT(!m_page);
427
428     m_sandboxExtensionTracker.invalidate();
429
430     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
431         (*it)->webPageDestroyed();
432
433     if (m_headerBanner)
434         m_headerBanner->detachFromPage();
435     if (m_footerBanner)
436         m_footerBanner->detachFromPage();
437
438     WebProcess::shared().removeMessageReceiver(Messages::WebPage::messageReceiverName(), m_pageID);
439
440     // FIXME: This should be done in the object destructors, and the objects themselves should be message receivers.
441     WebProcess::shared().removeMessageReceiver(Messages::DrawingArea::messageReceiverName(), m_pageID);
442 #if USE(COORDINATED_GRAPHICS)
443     WebProcess::shared().removeMessageReceiver(Messages::CoordinatedLayerTreeHost::messageReceiverName(), m_pageID);
444 #endif
445 #if ENABLE(INSPECTOR)
446     WebProcess::shared().removeMessageReceiver(Messages::WebInspector::messageReceiverName(), m_pageID);
447 #endif
448 #if ENABLE(FULLSCREEN_API)
449     WebProcess::shared().removeMessageReceiver(Messages::WebFullScreenManager::messageReceiverName(), m_pageID);
450 #endif
451
452 #ifndef NDEBUG
453     webPageCounter.decrement();
454 #endif
455 }
456
457 void WebPage::dummy(bool&)
458 {
459 }
460
461 CoreIPC::Connection* WebPage::messageSenderConnection()
462 {
463     return WebProcess::shared().parentProcessConnection();
464 }
465
466 uint64_t WebPage::messageSenderDestinationID()
467 {
468     return pageID();
469 }
470
471 #if ENABLE(CONTEXT_MENUS)
472 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
473 {
474     m_contextMenuClient.initialize(client);
475 }
476 #endif
477
478 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
479 {
480     m_editorClient.initialize(client);
481 }
482
483 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
484 {
485     m_formClient.initialize(client);
486 }
487
488 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
489 {
490     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
491     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
492     // for backwards compatibility.
493     LayoutMilestones milestones = 0;
494     if (client) {
495         if (client->didFirstLayoutForFrame)
496             milestones |= WebCore::DidFirstLayout;
497         if (client->didFirstVisuallyNonEmptyLayoutForFrame)
498             milestones |= WebCore::DidFirstVisuallyNonEmptyLayout;
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 bool WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
1978 {
1979     return page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
1980 }
1981
1982 bool WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
1983 {
1984     return page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
1985 }
1986
1987 bool WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
1988 {
1989     return 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     m_hasSeenPlugin = true;
3072 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3073     LOG(Plugins, "Primary Plug-In Detection: triggering detection from addPluginView(%p)", pluginView);
3074     m_determinePrimarySnapshottedPlugInTimer.startOneShot(0);
3075 #endif
3076 }
3077
3078 void WebPage::removePluginView(PluginView* pluginView)
3079 {
3080     ASSERT(m_pluginViews.contains(pluginView));
3081
3082     m_pluginViews.remove(pluginView);
3083 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
3084     LOG(Plugins, "Primary Plug-In Detection: removePluginView(%p)", pluginView);
3085 #endif
3086 }
3087
3088 void WebPage::sendSetWindowFrame(const FloatRect& windowFrame)
3089 {
3090 #if PLATFORM(MAC)
3091     m_hasCachedWindowFrame = false;
3092 #endif
3093     send(Messages::WebPageProxy::SetWindowFrame(windowFrame));
3094 }
3095
3096 #if PLATFORM(MAC)
3097 void WebPage::setWindowIsVisible(bool windowIsVisible)
3098 {
3099     m_windowIsVisible = windowIsVisible;
3100
3101     corePage()->focusController()->setContainingWindowIsVisible(windowIsVisible);
3102
3103     // Tell all our plug-in views that the window visibility changed.
3104     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
3105         (*it)->setWindowIsVisible(windowIsVisible);
3106 }
3107
3108 void WebPage::windowAndViewFramesChanged(const FloatRect& windowFrameInScreenCoordinates, const FloatRect& windowFrameInUnflippedScreenCoordinates, const FloatRect& viewFrameInWindowCoordinates, const FloatPoint& accessibilityViewCoordinates)
3109 {
3110     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
3111     m_windowFrameInUnflippedScreenCoordinates = windowFrameInUnflippedScreenCoordinates;
3112     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
3113     m_accessibilityPosition = accessibilityViewCoordinates;
3114     
3115     // Tell all our plug-in views that the window and view frames have changed.
3116     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
3117         (*it)->windowAndViewFramesChanged(enclosingIntRect(windowFrameInScreenCoordinates), enclosingIntRect(viewFrameInWindowCoordinates));
3118
3119     m_hasCachedWindowFrame = !m_windowFrameInUnflippedScreenCoordinates.isEmpty();
3120 }
3121 #endif
3122
3123 void WebPage::viewExposedRectChanged(const FloatRect& exposedRect, bool clipsToExposedRect)
3124 {
3125     m_drawingArea->setExposedRect(exposedRect);
3126     m_drawingArea->setClipsToExposedRect(clipsToExposedRect);
3127 }
3128
3129 void WebPage::setMainFrameIsScrollable(bool isScrollable)
3130 {
3131     m_mainFrameIsScrollable = isScrollable;
3132     m_drawingArea->mainFrameScrollabilityChanged(isScrollable);
3133
3134     if (FrameView* frameView = m_mainFrame->coreFrame()->view()) {
3135         frameView->setCanHaveScrollbars(isScrollable);
3136         frameView->setProhibitsScrolling(!isScrollable);
3137     }
3138 }
3139
3140 bool WebPage::windowIsFocused() const
3141 {
3142     return m_page->focusController()->isActive();
3143 }
3144
3145 bool WebPage::windowAndWebPageAreFocused() const
3146 {
3147 #if PLATFORM(MAC)
3148     if (!m_windowIsVisible)
3149         return false;
3150 #endif
3151     return m_page->focusController()->isFocused() && m_page->focusController()->isActive();
3152 }
3153
3154 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder)
3155 {
3156     if (decoder.messageReceiverName() == Messages::DrawingArea::messageReceiverName()) {
3157         if (m_drawingArea)
3158             m_drawingArea->didReceiveDrawingAreaMessage(connection, decoder);
3159         return;
3160     }
3161
3162 #if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING)
3163     if (decoder.messageReceiverName() == Messages::CoordinatedLayerTreeHost::messageReceiverName()) {
3164         if (m_drawingArea)
3165             m_drawingArea->didReceiveCoordinatedLayerTreeHostMessage(connection, decoder);
3166         return;
3167     }
3168 #endif
3169     
3170 #if ENABLE(INSPECTOR)
3171     if (decoder.messageReceiverName() == Messages::WebInspector::messageReceiverName()) {
3172         if (WebInspector* inspector = this->inspector())
3173             inspector->didReceiveWebInspectorMessage(connection, decoder);
3174         return;
3175     }
3176 #endif
3177
3178 #if ENABLE(FULLSCREEN_API)
3179     if (decoder.messageReceiverName() == Messages::WebFullScreenManager::messageReceiverName()) {
3180         fullScreenManager()->didReceiveMessage(connection, decoder);
3181         return;
3182     }
3183 #endif
3184
3185     didReceiveWebPageMessage(connection, decoder);
3186 }
3187
3188 void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder)
3189 {   
3190     didReceiveSyncWebPageMessage(connection, decoder, replyEncoder);
3191 }
3192     
3193 InjectedBundleBackForwardList* WebPage::backForwardList()
3194 {
3195     if (!m_backForwardList)
3196         m_backForwardList = InjectedBundleBackForwardList::create(this);
3197     return m_backForwardList.get();
3198 }
3199
3200 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
3201 {
3202     invalidate();
3203 }
3204
3205 void WebPage::SandboxExtensionTracker::invalidate()
3206 {
3207     m_pendingProvisionalSandboxExtension = nullptr;
3208
3209     if (m_provisionalSandboxExtension) {
3210         m_provisionalSandboxExtension->revoke();
3211         m_provisionalSandboxExtension = nullptr;
3212     }
3213
3214     if (m_committedSandboxExtension) {
3215         m_committedSandboxExtension->revoke();
3216         m_committedSandboxExtension = nullptr;
3217     }
3218 }
3219
3220 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
3221 {
3222     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
3223 }
3224
3225 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
3226 {
3227     ASSERT_UNUSED(frame, frame->isMainFrame());
3228
3229     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
3230 }
3231
3232 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
3233 {
3234     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;    
3235 }
3236
3237 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
3238 {
3239     ASSERT(frame->isMainFrame());
3240
3241     FrameLoader* frameLoader = frame->coreFrame()->loader();
3242     FrameLoadType frameLoadType = frameLoader->loadType();
3243
3244     // If the page is being reloaded, it should reuse whatever extension is committed.
3245     if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
3246         return true;
3247
3248     DocumentLoader* documentLoader = frameLoader->documentLoader();
3249     DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
3250     if (!documentLoader || !provisionalDocumentLoader)
3251         return false;
3252
3253     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
3254         return true;
3255
3256     return false;
3257 }
3258
3259 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
3260 {
3261     if (!frame->isMainFrame())
3262         return;
3263
3264     // We should only reuse the commited sandbox extension if it is not null. It can be
3265     // null if the last load was for an error page.
3266     if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame))
3267         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension;
3268
3269     ASSERT(!m_provisionalSandboxExtension);
3270
3271     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
3272     if (!m_provisionalSandboxExtension)
3273         return;
3274
3275     ASSERT(!m_provisionalSandboxExtension || frame->coreFrame()->loader()->provisionalDocumentLoader()->url().isLocalFile());
3276
3277     m_provisionalSandboxExtension->consume();
3278 }
3279
3280 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
3281 {
3282     if (!frame->isMainFrame())
3283         return;
3284
3285     if (m_committedSandboxExtension)
3286         m_committedSandboxExtension->revoke();
3287
3288     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
3289
3290     // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started.
3291     // This extension is not cleared, because it does not pertain to the failed load, and will be needed.
3292 }
3293
3294 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
3295 {
3296     if (!frame->isMainFrame())
3297         return;
3298
3299     if (!m_provisionalSandboxExtension)
3300         return;
3301
3302     m_provisionalSandboxExtension->revoke();
3303     m_provisionalSandboxExtension = nullptr;
3304
3305     // We can also have a non-null m_pendingProvisionalSandboxExtension if a new load is being started
3306     // (notably, if the current one fails because the new one cancels it). This extension is not cleared,
3307     // because it does not pertain to the failed load, and will be needed.
3308 }
3309
3310 bool WebPage::hasLocalDataForURL(const KURL& url)
3311 {
3312     if (url.isLocalFile())
3313         return true;
3314
3315     FrameLoader* frameLoader = m_page->mainFrame()->loader();
3316     DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
3317     if (documentLoader && documentLoader->subresource(url))
3318         return true;
3319
3320     return platformHasLocalDataForURL(url);
3321 }
3322
3323 void WebPage::setCustomTextEncodingName(const String& encoding)
3324 {
3325     m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
3326 }
3327
3328 void WebPage::didRemoveBackForwardItem(uint64_t itemID)
3329 {
3330     WebBackForwardListProxy::removeItem(itemID);
3331 }
3332
3333 #if PLATFORM(MAC)
3334
3335 bool WebPage::isSpeaking()
3336 {
3337     bool result;
3338     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
3339 }
3340
3341 void WebPage::speak(const String& string)
3342 {
3343     send(Messages::WebPageProxy::Speak(string));
3344 }
3345
3346 void WebPage::stopSpeaking()
3347 {
3348     send(Messages::WebPageProxy::StopSpeaking());
3349 }
3350
3351 #endif
3352
3353 #if PLATFORM(MAC)
3354 RetainPtr<PDFDocument> WebPage::pdfDocumentForPrintingFrame(Frame* coreFrame)
3355 {
3356     Document* document = coreFrame->document();
3357     if (!document)
3358         return 0;
3359
3360     if (!document->isPluginDocument())
3361         return 0;
3362
3363     PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget());
3364     if (!pluginView)
3365         return 0;
3366
3367     return pluginView->pdfDocumentForPrinting();
3368 }
3369 #endif // PLATFORM(MAC)
3370
3371 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
3372 {
3373     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3374     if (!frame)
3375         return;
3376
3377     Frame* coreFrame = frame->coreFrame();
3378     if (!coreFrame)
3379         return;
3380
3381 #if PLATFORM(MAC)
3382     if (pdfDocumentForPrintingFrame(coreFrame))
3383         return;
3384 #endif // PLATFORM(MAC)
3385
3386     if (!m_printContext)
3387         m_printContext = adoptPtr(new PrintContext(coreFrame));
3388
3389     drawingArea()->setLayerTreeStateIsFrozen(true);
3390     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
3391
3392     float fullPageHeight;
3393     m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
3394
3395 #if PLATFORM(GTK)
3396     if (!m_printOperation)
3397         m_printOperation = WebPrintOperationGtk::create(this, printInfo);
3398 #endif
3399 }
3400
3401 void WebPage::endPrinting()
3402 {
3403     drawingArea()->setLayerTreeStateIsFrozen(false);
3404 #if PLATFORM(GTK)
3405     m_printOperation = 0;
3406 #endif
3407     m_printContext = nullptr;
3408 }
3409
3410 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
3411 {
3412     Vector<IntRect> resultPageRects;
3413     double resultTotalScaleFactorForPrinting = 1;
3414
3415     beginPrinting(frameID, printInfo);
3416
3417     if (m_printContext) {
3418         resultPageRects = m_printContext->pageRects();
3419         resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
3420     }
3421 #if PLATFORM(MAC)
3422     else
3423         computePagesForPrintingPDFDocument(frameID, printInfo, resultPageRects);
3424 #endif // PLATFORM(MAC)
3425
3426     // If we're asked to print, we should actually print at least a blank page.
3427     if (resultPageRects.isEmpty())
3428         resultPageRects.append(IntRect(0, 0, 1, 1));
3429
3430     send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
3431 }
3432
3433 #if PLATFORM(MAC)
3434 void WebPage::drawRectToImage(uint64_t frameID, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, uint64_t callbackID)
3435 {
3436     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3437     Frame* coreFrame = frame ? frame->coreFrame() : 0;
3438
3439     RefPtr<WebImage> image;
3440
3441 #if USE(CG)
3442     if (coreFrame) {
3443 #if PLATFORM(MAC)
3444         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
3445 #else
3446         ASSERT(coreFrame->document()->printing());
3447 #endif
3448
3449         RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(imageSize, ShareableBitmap::SupportsAlpha);
3450         OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
3451
3452         float printingScale = static_cast<float>(imageSize.width()) / rect.width();
3453         graphicsContext->scale(FloatSize(printingScale, printingScale));
3454
3455 #if PLATFORM(MAC)
3456         if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
3457             ASSERT(!m_printContext);
3458             graphicsContext->scale(FloatSize(1, -1));
3459             graphicsContext->translate(0, -rect.height());
3460             drawPDFDocument(graphicsContext->platformContext(), pdfDocument.get(), printInfo, rect);
3461         } else
3462 #endif
3463         {
3464             m_printContext->spoolRect(*graphicsContext, rect);
3465         }
3466
3467         image = WebImage::create(bitmap.release());
3468     }
3469 #endif
3470
3471     ShareableBitmap::Handle handle;
3472
3473     if (image)
3474         image->bitmap()->createHandle(handle, SharedMemory::ReadOnly);
3475
3476     send(Messages::WebPageProxy::ImageCallback(handle, callbackID));
3477 }
3478
3479 void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
3480 {
3481     WebFrame* frame = WebProcess::shared().webFrame(frameID);
3482     Frame* coreFrame = frame ? frame->coreFrame() : 0;
3483
3484     RetainPtr<CFMutableDataRef> pdfPageData = adoptCF(CFDataCreateMutable(0, 0));
3485
3486 #if USE(CG)
3487     if (coreFrame) {
3488
3489 #if PLATFORM(MAC)
3490         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
3491 #else
3492         ASSERT(coreFrame->document()->printing());
3493 #endif
3494
3495         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
3496         RetainPtr<CGDataConsumerRef> pdfDataConsumer = adoptCF(CGDataConsumerCreateWithCFData(pdfPageData.get()));
3497
3498         CGRect mediaBox = (m_printContext && m_printContext->pageCount()) ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight);
3499         RetainPtr<CGContextRef> context = adoptCF(CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
3500
3501 #if PLATFORM(MAC)
3502         if (RetainPtr<PDFDocument> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
3503             ASSERT(!m_printContext);
3504             drawPagesToPDFFromPDFDocument(context.get(), pdfDocument.get(), printInfo, first, count);
3505         } else
3506 #endif
3507         {
3508             size_t pageCount = m_printContext->pageCount();
3509             for (uint32_t page = first; page < first + count; ++page) {
3510                 if (page >= pageCount)
3511                     break;
3512
3513                 RetainPtr<CFDictionaryRef> pageInfo = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
3514                 CGPDFContextBeginPage(context.get(), pageInfo.get());
3515
3516                 GraphicsContext ctx(context.get());
3517                 ctx.scale(FloatSize(1, -1));
3518                 ctx.translate(0, -m_printContext->pageRect(page).height());
3519                 m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
3520
3521                 CGPDFContextEndPage(context.get());
3522             }
3523         }
3524         CGPDFContextClose(context.get());
3525     }
3526 #endif
3527
3528     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
3529 }
3530
3531 #elif PLATFORM(GTK)
3532
3533 void WebPage::drawPagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
3534 {
3535     beginPrinting(frameID, printInfo);
3536     if (m_printContext && m_printOperation) {
3537         m_printOperation->startPrint(m_printContext.get(), callbackID);
3538         return;
3539     }
3540
3541     send(Messages::WebPageProxy::VoidCallback(callbackID));
3542 }
3543 #endif
3544
3545 void WebPage::savePDFToFileInDownloadsFolder(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size)
3546 {
3547     send(Messages::WebPageProxy::SavePDFToFileInDownloadsFolder(suggestedFilename, originatingURLString, CoreIPC::DataReference(data, size)));
3548 }
3549
3550 #if PLATFORM(MAC)
3551 void WebPage::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String& suggestedFilename, const String& originatingURLString, const uint8_t* data, unsigned long size, const String& pdfUUID)
3552 {
3553     send(Messages::WebPageProxy::SavePDFToTemporaryFolderAndOpenWithNativeApplication(suggestedFilename, originatingURLString, CoreIPC::DataReference(data, size), pdfUUID));
3554 }
3555 #endif
3556
3557 void WebPage::setMediaVolume(float volume)
3558 {
3559     m_page->setMediaVolume(volume);
3560 }
3561
3562 void WebPage::setMayStartMediaWhenInWindow(bool mayStartMedia)
3563 {
3564     if (mayStartMedia == m_mayStartMediaWhenInWindow)
3565         return;
3566
3567     m_mayStartMediaWhenInWindow = mayStartMedia;
3568     if (m_mayStartMediaWhenInWindow && m_page->isOnscreen())
3569         m_setCanStartMediaTimer.startOneShot(0);
3570 }
3571
3572 void WebPage::runModal()
3573 {
3574     if (m_isClosed)
3575         return;
3576     if (m_isRunningModal)
3577         return;
3578
3579     m_isRunningModal = true;
3580     send(Messages::WebPageProxy::RunModal());
3581     RunLoop::run();
3582     ASSERT(!m_isRunningModal);
3583 }
3584
3585 void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
3586 {
3587     m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled);
3588 }
3589
3590 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
3591 {
3592     if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
3593         return true;
3594
3595 #if ENABLE(BLOB)
3596     if (request.url().protocolIs("blob"))
3597         return true;
3598 #endif
3599
3600     return platformCanHandleRequest(request);
3601 }
3602
3603 #if USE(TILED_BACKING_STORE)
3604 void WebPage::commitPageTransitionViewport()
3605 {
3606     m_drawingArea->setLayerTreeStateIsFrozen(false);
3607 }
3608 #endif
3609
3610 #if PLATFORM(MAC)
3611 void WebPage::handleAlternativeTextUIResult(const String& result)
3612 {
3613     Frame* frame = m_page->focusController()->focusedOrMainFrame();
3614     if (!frame)
3615         return;
3616     frame->editor().handleAlternativeTextUIResult(result);
3617 }
3618 #endif
3619
3620 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
3621 {
3622     mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
3623 }
3624
3625 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
3626 {
3627     mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
3628 }
3629
3630 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
3631 {
3632     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
3633 }
3634
3635 void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length)
3636 {
3637     Frame* frame = m_page->focusController()->focusedOrMainFrame();
3638     if (!frame || !frame->editor().canEdit())
3639         return;
3640
3641     Vector<CompositionUnderline> underlines;
3642     underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false));
3643     frame->editor().setComposition(compositionString, underlines, from, from + length);
3644 }
3645
3646 bool WebPage::hasCompositionForTesting()
3647 {
3648     Frame* frame = m_page->focusController()->focusedOrMainFrame();
3649     return frame && frame->editor().hasComposition();
3650 }
3651
3652 void WebPage::confirmCompositionForTesting(const String& compositionString)
3653 {
3654     Frame* frame = m_page->focusController()->focusedOrMainFrame();
3655     if (!frame || !frame->editor().canEdit())
3656         return;
3657
3658     if (compositionString.isNull())
3659         frame->editor().confirmComposition();
3660     frame->editor().confirmComposition(compositionString);
3661 }
3662
3663 void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers)
3664 {
3665     if (m_numWheelEventHandlers == numWheelEventHandlers)
3666         return;
3667
3668     m_numWheelEventHandlers = numWheelEventHandlers;
3669     recomputeShortCircuitHorizontalWheelEventsState();
3670 }
3671
3672 static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea)
3673 {
3674     if (Scrollbar* scrollbar = scrollableArea->horizontalScrollbar())
3675         return scrollbar->enabled();
3676
3677     return false;
3678 }
3679
3680 static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame)
3681 {
3682     if (FrameView* frameView = mainFrame->view()) {
3683         if (hasEnabledHorizontalScrollbar(frameView))
3684             return true;
3685     }
3686
3687     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
3688         FrameView* frameView = frame->view();
3689         if (!frameView)
3690             continue;
3691
3692         const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
3693         if (!scrollableAreas)
3694             continue;
3695
3696         for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
3697             ScrollableArea* scrollableArea = *it;
3698             if (!scrollableArea->scrollbarsCanBeActive())
3699                 continue;
3700
3701             if (hasEnabledHorizontalScrollbar(scrollableArea))
3702                 return true;
3703         }
3704     }
3705
3706     return false;
3707 }
3708
3709 void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
3710 {
3711     bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers;
3712
3713     if (canShortCircuitHorizontalWheelEvents) {
3714         // Check if we have any horizontal scroll bars on the page.
3715         if (pageContainsAnyHorizontalScrollbars(mainFrame()))
3716             canShortCircuitHorizontalWheelEvents = false;
3717     }
3718
3719     if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents)
3720         return;
3721
3722     m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents;
3723     send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents));
3724 }
3725
3726 Frame* WebPage::mainFrame() const
3727 {
3728     return m_page ? m_page->mainFrame() : 0;
3729 }
3730
3731 FrameView* WebPage::mainFrameView() const
3732 {
3733     if (Frame* frame = mainFrame())
3734         return frame->view();
3735     
3736     return 0;
3737 }
3738
3739 #if ENABLE(PAGE_VISIBILITY_API) || ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
3740 void WebPage::setVisibilityState(uint32_t visibilityState, bool isInitialState)
3741 {
3742     if (!m_page)
3743         return;
3744
3745     WebCore::PageVisibilityState state = static_cast<WebCore::PageVisibilityState>(visibilityState);
3746
3747 #if ENABLE(PAGE_VISIBILITY_API)
3748     if (m_visibilityState == state)
3749         return;
3750
3751     FrameView* view = m_page->mainFrame() ? m_page->mainFrame()->view() : 0;
3752
3753     if (state == WebCore::PageVisibilityStateVisible) {
3754         m_page->didMoveOnscreen();
3755         if (view)
3756             view->show();
3757     }
3758
3759     m_page->setVisibilityState(state, isInitialState);
3760     m_visibilityState = state;
3761
3762     if (state == WebCore::PageVisibilityStateHidden) {
3763         m_page->willMoveOffscreen();
3764         if (view)
3765             view->hide();
3766     }
3767 #endif
3768
3769 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) && !ENABLE(PAGE_VISIBILITY_API)
3770     m_page->setVisibilityState(state, isInitialState);
3771 #endif
3772 }
3773 #endif
3774
3775 void WebPage::setThrottled(bool isThrottled)
3776 {
3777     if (m_page)
3778         m_page->setThrottled(isThrottled);
3779 }
3780
3781 void WebPage::setScrollingPerformanceLoggingEnabled(bool enabled)
3782 {
3783     m_scrollingPerformanceLoggingEnabled = enabled;
3784
3785     FrameView* frameView = m_mainFrame->coreFrame()->view();
3786     if (!frameView)
3787         return;
3788
3789     frameView->setScrollingPerformanceLoggingEnabled(enabled);
3790 }
3791
3792 bool WebPage::canPluginHandleResponse(const ResourceResponse& response)
3793 {
3794 #if ENABLE(NETSCAPE_PLUGIN_API)
3795     uint32_t pluginLoadPolicy;
3796     bool allowOnlyApplicationPlugins = !m_mainFrame->coreFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin);
3797
3798     uint64_t pluginProcessToken;
3799     String newMIMEType;
3800     String unavailabilityDescription;
3801     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)))
3802         return false;
3803
3804     return pluginLoadPolicy != PluginModuleBlocked && pluginProcessToken;
3805 #else
3806     return false;
3807 #endif
3808 }
3809
3810 #if PLATFORM(QT) || PLATFORM(GTK)
3811 static Frame* targetFrameForEditing(WebPage* page)
3812 {
3813     Frame* targetFrame = page->corePage()->focusController()->focusedOrMainFrame();
3814
3815     if (!targetFrame)
3816         return 0;
3817
3818     Editor& editor = targetFrame->editor();
3819     if (!editor.canEdit())
3820         return 0;
3821
3822     if (editor.hasComposition()) {
3823         // We should verify the parent node of this IME composition node are
3824         // editable because JavaScript may delete a parent node of the composition
3825         // node. In this case, WebKit crashes while deleting texts from the parent
3826         // node, which doesn't exist any longer.
3827         if (PassRefPtr<Range> range = editor.compositionRange()) {
3828             Node* node = range->startContainer();
3829             if (!node || !node->isContentEditable())
3830                 return 0;
3831         }
3832     }
3833     return targetFrame;
3834 }
3835
3836 void WebPage::confirmComposition(const String& compositionString, int64_t selectionStart, int64_t selectionLength)
3837 {
3838     Frame* targetFrame = targetFrameForEditing(this);
3839     if (!targetFrame) {
3840         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3841         return;
3842     }
3843
3844     targetFrame->editor().confirmComposition(compositionString);
3845
3846     if (selectionStart == -1) {
3847         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3848         return;
3849     }
3850
3851     Element* scope = targetFrame->selection()->rootEditableElement();
3852     RefPtr<Range> selectionRange = TextIterator::rangeFromLocationAndLength(scope, selectionStart, selectionLength);
3853     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());
3854
3855     if (selectionRange) {
3856         VisibleSelection selection(selectionRange.get(), SEL_DEFAULT_AFFINITY);
3857         targetFrame->selection()->setSelection(selection);
3858     }
3859     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3860 }
3861
3862 void WebPage::setComposition(const String& text, Vector<CompositionUnderline> underlines, uint64_t selectionStart, uint64_t selectionEnd, uint64_t replacementStart, uint64_t replacementLength)
3863 {
3864     Frame* targetFrame = targetFrameForEditing(this);
3865     if (!targetFrame || !targetFrame->selection()->isContentEditable()) {
3866         send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3867         return;
3868     }
3869
3870     if (replacementLength > 0) {
3871         // The layout needs to be uptodate before setting a selection
3872         targetFrame->document()->updateLayout();
3873
3874         Element* scope = targetFrame->selection()->rootEditableElement();
3875         RefPtr<Range> replacementRange = TextIterator::rangeFromLocationAndLength(scope, replacementStart, replacementLength);
3876         targetFrame->editor().setIgnoreCompositionSelectionChange(true);
3877         targetFrame->selection()->setSelection(VisibleSelection(replacementRange.get(), SEL_DEFAULT_AFFINITY));
3878         targetFrame->editor().setIgnoreCompositionSelectionChange(false);
3879     }
3880
3881     targetFrame->editor().setComposition(text, underlines, selectionStart, selectionEnd);
3882     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3883 }
3884
3885 void WebPage::cancelComposition()
3886 {
3887     if (Frame* targetFrame = targetFrameForEditing(this))
3888         targetFrame->editor().cancelComposition();
3889     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3890 }
3891 #endif
3892
3893 void WebPage::didChangeSelection()
3894 {
3895     send(Messages::WebPageProxy::EditorStateChanged(editorState()));
3896 }
3897
3898 void WebPage::setMainFrameInViewSourceMode(bool inViewSourceMode)
3899 {
3900     m_mainFrame->coreFrame()->setInViewSourceMode(inViewSourceMode);
3901 }
3902
3903 void WebPage::setMinimumLayoutSize(const IntSize& minimumLayoutSize)
3904 {
3905     if (m_minimumLayoutSize == minimumLayoutSize)
3906         return;
3907
3908     m_minimumLayoutSize = minimumLayoutSize;
3909     if (minimumLayoutSize.width() <= 0) {
3910         corePage()->mainFrame()->view()->enableAutoSizeMode(false, IntSize(), IntSize());
3911         return;
3912     }
3913
3914     int minimumLayoutWidth = minimumLayoutSize.width();
3915     int minimumLayoutHeight = std::max(minimumLayoutSize.height(), 1);
3916
3917     int maximumSize = std::numeric_limits<int>::max();
3918
3919     corePage()->mainFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize));
3920 }
3921
3922 void WebPage::setAutoSizingShouldExpandToViewHeight(bool shouldExpand)
3923 {
3924     if (m_autoSizingShouldExpandToViewHeight == shouldExpand)
3925         return;
3926
3927     m_autoSizingShouldExpandToViewHeight = shouldExpand;
3928
3929     corePage()->mainFrame()->view()->setAutoSizeFixedMinimumHeight(shouldExpand ? m_viewSize.height() : 0);
3930 }
3931
3932 bool WebPage::isSmartInsertDeleteEnabled()
3933 {
3934     return m_page->settings().smartInsertDeleteEnabled();
3935 }
3936
3937 void WebPage::setSmartInsertDeleteEnabled(bool enabled)
3938 {
3939     if (m_page->settings().smartInsertDeleteEnabled() != enabled) {
3940         m_page->settings().setSmartInsertDeleteEnabled(enabled);
3941         setSelectTrailingWhitespaceEnabled(!enabled);
3942     }
3943 }
3944
3945 bool WebPage::isSelectTrailingWhitespaceEnabled()
3946 {
3947     return m_page->settings().selectTrailingWhitespaceEnabled();
3948 }
3949
3950 void WebPage::setSelectTrailingWhitespaceEnabled(bool enabled)
3951 {
3952     if (m_page->settings().selectTrailingWhitespaceEnabled() != enabled) {
3953         m_page->settings().setSelectTrailingWhitespaceEnabled(enabled);
3954         setSmartInsertDeleteEnabled(!enabled);
3955     }
3956 }
3957
3958 bool WebPage::canShowMIMEType(const String& MIMEType) const
3959 {
3960     if (MIMETypeRegistry::canShowMIMEType(MIMEType))
3961         return true;
3962
3963     if (PluginData* pluginData = m_page->pluginData()) {
3964         if (pluginData->supportsMimeType(MIMEType, PluginData::AllPlugins) && corePage()->mainFrame()->loader()->subframeLoader()->allowPlugins(NotAboutToInstantiatePlugin))
3965             return true;
3966
3967         // We can use application plugins even if plugins aren't enabled.
3968         if (pluginData->supportsMimeType(MIMEType, PluginData::OnlyApplicationPlugins))
3969             return true;
3970     }
3971
3972     return false;
3973 }
3974
3975 void WebPage::addTextCheckingRequest(uint64_t requestID, PassRefPtr<TextCheckingRequest> request)
3976 {
3977     m_pendingTextCheckingRequestMap.add(requestID, request);
3978 }
3979
3980 void WebPage::didFinishCheckingText(uint64_t requestID, const Vector<TextCheckingResult>& result)
3981 {
3982     TextCheckingRequest* request = m_pendingTextCheckingRequestMap.get(requestID);
3983     if (!request)
3984         return;
3985
3986     request->didSucceed(result);
3987     m_pendingTextCheckingRequestMap.remove(requestID);
3988 }
3989
3990 void WebPage::didCancelCheckingText(uint64_t requestID)
3991 {
3992     TextCheckingRequest* request = m_pendingTextCheckingRequestMap.get(requestID);
3993     if (!request)
3994         return;
3995
3996     request->didCancel();
3997     m_pendingTextCheckingRequestMap.remove(requestID);
3998 }
3999
4000 void WebPage::didCommitLoad(WebFrame* frame)
4001 {
4002     if (!frame->isMainFrame())
4003         return;
4004
4005     // If previous URL is invalid, then it's not a real page that's being navigated away from.
4006     // Most likely, this is actually the first load to be committed in this page.
4007     if (frame->coreFrame()->loader()->previousURL().isValid())
4008         reportUsedFeatures();
4009
4010     // Only restore the scale factor for standard frame loads (of the main frame).
4011     if (frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
4012         Page* page = frame->coreFrame()->page();
4013         if (page && page->pageScaleFactor() != 1)
4014             scalePage(1, IntPoint());
4015     }
4016
4017 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4018     resetPrimarySnapshottedPlugIn();
4019 #endif
4020
4021     WebProcess::shared().updateActivePages();
4022 }
4023
4024 void WebPage::didFinishLoad(WebFrame* frame)
4025 {
4026 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4027     if (!frame->isMainFrame())
4028         return;
4029
4030     m_readyToFindPrimarySnapshottedPlugin = true;
4031     LOG(Plugins, "Primary Plug-In Detection: triggering detection from didFinishLoad (marking as ready to detect).");
4032     m_determinePrimarySnapshottedPlugInTimer.startOneShot(0);
4033 #else
4034     UNUSED_PARAM(frame);
4035 #endif
4036 }
4037
4038 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4039 static int primarySnapshottedPlugInSearchLimit = 3000;
4040 static int primarySnapshottedPlugInSearchGap = 200;
4041 static float primarySnapshottedPlugInSearchBucketSize = 1.1;
4042 static int primarySnapshottedPlugInMinimumWidth = 400;
4043 static int primarySnapshottedPlugInMinimumHeight = 300;
4044 static unsigned maxPrimarySnapshottedPlugInDetectionAttempts = 2;
4045 static int deferredPrimarySnapshottedPlugInDetectionDelay = 3;
4046
4047 #if ENABLE(PRIMARY_SNAPSHOTTED_PLUGIN_HEURISTIC)
4048 void WebPage::determinePrimarySnapshottedPlugInTimerFired()
4049 {
4050     if (!m_page)
4051         return;
4052     
4053     Settings& settings = m_page->settings();
4054     if (!settings.snapshotAllPlugIns() && settings.primaryPlugInSnapshotDetectionEnabled())
4055         determinePrimarySnapshottedPlugIn();
4056 }
4057 #endif
4058
4059 void WebPage::determinePrimarySnapshottedPlugIn()
4060 {
4061     if (!m_page->settings().plugInSnapshottingEnabled())
4062         return;
4063
4064     LOG(Plugins, "Primary Plug-In Detection: began.");
4065
4066     if (!m_readyToFindPrimarySnapshottedPlugin) {
4067         LOG(Plugins, "Primary Plug-In Detection: exiting - not ready to find plugins.");
4068         return;
4069     }
4070
4071     if (!m_hasSeenPlugin) {
4072         LOG(Plugins, "Primary Plug-In Detection: exiting - we never saw a plug-in get added to the page.");
4073         return;
4074     }
4075
4076     if (m_didFindPrimarySnapshottedPlugin) {
4077         LOG(Plugins, "Primary Plug-In Detection: exiting - we've already found a primary plug-in.");
4078         return;
4079     }
4080
4081     ++m_numberOfPrimarySnapshotDetectionAttempts;
4082
4083     RenderView* renderView = corePage()->mainFrame()->view()->renderView();
4084
4085     IntRect searchRect = IntRect(IntPoint(), corePage()->mainFrame()->view()->contentsSize());
4086     searchRect.intersect(IntRect(IntPoint(), IntSize(primarySnapshottedPlugInSearchLimit, primarySnapshottedPlugInSearchLimit)));
4087
4088     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::AllowChildFrameContent | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent);
4089
4090     HashSet<RenderObject*> seenRenderers;
4091     HTMLPlugInImageElement* candidatePlugIn = 0;
4092     unsigned candidatePlugInArea = 0;
4093
4094     for (int x = searchRect.x(); x <= searchRect.width(); x += primarySnapshottedPlugInSearchGap) {
4095         for (int y = searchRect.y(); y <= searchRect.height(); y += primarySnapshottedPlugInSearchGap) {
4096             HitTestResult hitTestResult = HitTestResult(LayoutPoint(x, y));
4097             renderView->hitTest(request, hitTestResult);
4098
4099             Element* element = hitTestResult.innerElement();
4100             if (!element)
4101                 continue;
4102
4103             RenderObject* renderer = element->renderer();
4104             if (!renderer || !renderer->isBox())
4105                 continue;
4106
4107             RenderBox* renderBox = toRenderBox(renderer);
4108
4109             if (!seenRenderers.add(renderer).isNewEntry)
4110                 continue;
4111
4112             if (!element->isPluginElement())
4113                 continue;
4114
4115             HTMLPlugInElement* plugInElement = toHTMLPlugInElement(element);
4116             if (!plugInElement->isPlugInImageElement())
4117                 continue;
4118
4119             HTMLPlugInImageElement* plugInImageElement = toHTMLPlugInImageElement(plugInElement);
4120
4121             if (plugInElement->displayState() == HTMLPlugInElement::Playing)
4122                 continue;
4123
4124             if (renderBox->contentWidth() < primarySnapshottedPlugInMinimumWidth || renderBox->contentHeight() < primarySnapshottedPlugInMinimumHeight)
4125                 continue;
4126
4127             LayoutUnit contentArea = renderBox->contentWidth() * renderBox->contentHeight();
4128
4129             if (contentArea > candidatePlugInArea * primarySnapshottedPlugInSearchBucketSize) {
4130                 candidatePlugIn = plugInImageElement;
4131                 candidatePlugInArea = contentArea;
4132             }
4133         }
4134     }
4135
4136     if (!candidatePlugIn) {
4137         LOG(Plugins, "Primary Plug-In Detection: fail - did not find a candidate plug-in.");
4138         if (m_numberOfPrimarySnapshotDetectionAttempts < maxPrimarySnapshottedPlugInDetectionAttempts) {
4139             LOG(Plugins, "Primary Plug-In Detection: will attempt again in %ds.", deferredPrimarySnapshottedPlugInDetectionDelay);
4140             m_determinePrimarySnapshottedPlugInTimer.startOneShot(deferredPrimarySnapshottedPlugInDetectionDelay);
4141         }
4142         return;
4143     }
4144
4145     LOG(Plugins, "Primary Plug-In Detection: success - found a candidate plug-in - inform it.");
4146     m_didFindPrimarySnapshottedPlugin = true;
4147     m_primaryPlugInPageOrigin = m_page->mainFrame()->document()->baseURL().host();
4148     m_primaryPlugInOrigin = candidatePlugIn->loadedUrl().host();
4149     m_primaryPlugInMimeType = candidatePlugIn->loadedMimeType();
4150
4151     candidatePlugIn->setIsPrimarySnapshottedPlugIn(true);
4152 }
4153
4154 void WebPage::resetPrimarySnapshottedPlugIn()
4155 {
4156     m_readyToFindPrimarySnapshottedPlugin = false;
4157     m_didFindPrimarySnapshottedPlugin = false;
4158     m_numberOfPrimarySnapshotDetectionAttempts = 0;
4159     m_hasSeenPlugin = false;