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