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