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