[WK2] Trivial build fix after r108615.
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebPage / WebPage.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebPage.h"
28
29 #include "Arguments.h"
30 #include "DataReference.h"
31 #include "DecoderAdapter.h"
32 #include "DrawingArea.h"
33 #include "InjectedBundle.h"
34 #include "InjectedBundleBackForwardList.h"
35 #include "LayerTreeHost.h"
36 #include "MessageID.h"
37 #include "NetscapePlugin.h"
38 #include "NotificationPermissionRequestManager.h"
39 #include "PageOverlay.h"
40 #include "PluginProxy.h"
41 #include "PluginView.h"
42 #include "PrintInfo.h"
43 #include "SessionState.h"
44 #include "ShareableBitmap.h"
45 #include "WebBackForwardList.h"
46 #include "WebBackForwardListItem.h"
47 #include "WebBackForwardListProxy.h"
48 #include "WebChromeClient.h"
49 #include "WebContextMenu.h"
50 #include "WebContextMenuClient.h"
51 #include "WebContextMessages.h"
52 #include "WebCoreArgumentCoders.h"
53 #include "WebDragClient.h"
54 #include "WebEditorClient.h"
55 #include "WebEvent.h"
56 #include "WebEventConversion.h"
57 #include "WebFrame.h"
58 #include "WebFullScreenManager.h"
59 #include "WebGeolocationClient.h"
60 #include "WebGeometry.h"
61 #include "WebImage.h"
62 #include "WebInspector.h"
63 #include "WebInspectorClient.h"
64 #include "WebNotificationClient.h"
65 #include "WebOpenPanelResultListener.h"
66 #include "WebPageCreationParameters.h"
67 #include "WebPageGroupProxy.h"
68 #include "WebPageProxyMessages.h"
69 #include "WebPopupMenu.h"
70 #include "WebPreferencesStore.h"
71 #include "WebProcess.h"
72 #include "WebProcessProxyMessages.h"
73 #include <JavaScriptCore/APICast.h>
74 #include <WebCore/AbstractDatabase.h>
75 #include <WebCore/ArchiveResource.h>
76 #include <WebCore/Chrome.h>
77 #include <WebCore/ContextMenuController.h>
78 #include <WebCore/DocumentFragment.h>
79 #include <WebCore/DocumentLoader.h>
80 #include <WebCore/DocumentMarkerController.h>
81 #include <WebCore/DragController.h>
82 #include <WebCore/DragData.h>
83 #include <WebCore/DragSession.h>
84 #include <WebCore/EventHandler.h>
85 #include <WebCore/FocusController.h>
86 #include <WebCore/FormState.h>
87 #include <WebCore/Frame.h>
88 #include <WebCore/FrameLoadRequest.h>
89 #include <WebCore/FrameLoaderTypes.h>
90 #include <WebCore/FrameView.h>
91 #include <WebCore/HTMLFormElement.h>
92 #include <WebCore/HTMLInputElement.h>
93 #include <WebCore/HistoryItem.h>
94 #include <WebCore/KeyboardEvent.h>
95 #include <WebCore/MouseEvent.h>
96 #include <WebCore/Page.h>
97 #include <WebCore/PlatformKeyboardEvent.h>
98 #include <WebCore/PluginDocument.h>
99 #include <WebCore/PrintContext.h>
100 #include <WebCore/RenderArena.h>
101 #include <WebCore/RenderLayer.h>
102 #include <WebCore/RenderTreeAsText.h>
103 #include <WebCore/RenderView.h>
104 #include <WebCore/ReplaceSelectionCommand.h>
105 #include <WebCore/ResourceRequest.h>
106 #include <WebCore/RunLoop.h>
107 #include <WebCore/SchemeRegistry.h>
108 #include <WebCore/ScriptValue.h>
109 #include <WebCore/SerializedScriptValue.h>
110 #include <WebCore/Settings.h>
111 #include <WebCore/SharedBuffer.h>
112 #include <WebCore/SubstituteData.h>
113 #include <WebCore/TextIterator.h>
114 #include <WebCore/markup.h>
115 #include <runtime/JSLock.h>
116 #include <runtime/JSValue.h>
117
118 #include <WebCore/Range.h>
119 #include <WebCore/VisiblePosition.h>
120
121 #if ENABLE(PLUGIN_PROCESS)
122 #if PLATFORM(MAC)
123 #include "MachPort.h"
124 #endif
125 #endif
126
127 #if PLATFORM(MAC)
128 #include "BuiltInPDFView.h"
129 #endif
130
131 #if PLATFORM(QT)
132 #include "HitTestResult.h"
133 #include <QMimeData>
134 #endif
135
136 #if PLATFORM(GTK)
137 #include <gtk/gtk.h>
138 #include "DataObjectGtk.h"
139 #include "WebPrintOperationGtk.h"
140 #endif
141
142 #ifndef NDEBUG
143 #include <wtf/RefCountedLeakCounter.h>
144 #endif
145
146 using namespace JSC;
147 using namespace WebCore;
148 using namespace std;
149
150 namespace WebKit {
151
152 class SendStopResponsivenessTimer {
153 public:
154     SendStopResponsivenessTimer(WebPage* page)
155         : m_page(page)
156     {
157     }
158     
159     ~SendStopResponsivenessTimer()
160     {
161         m_page->send(Messages::WebPageProxy::StopResponsivenessTimer());
162     }
163
164 private:
165     WebPage* m_page;
166 };
167
168 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageCounter, ("WebPage"));
169
170 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
171 {
172     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
173
174     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
175         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
176
177     return page.release();
178 }
179
180 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
181     : m_viewSize(parameters.viewSize)
182     , m_useFixedLayout(false)
183     , m_drawsBackground(true)
184     , m_drawsTransparentBackground(false)
185     , m_isInRedo(false)
186     , m_isClosed(false)
187     , m_tabToLinks(false)
188 #if PLATFORM(MAC)
189     , m_windowIsVisible(false)
190     , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled)
191     , m_keyboardEventBeingInterpreted(0)
192 #elif PLATFORM(WIN)
193     , m_nativeWindow(parameters.nativeWindow)
194 #elif PLATFORM(GTK)
195     , m_accessibilityObject(0)
196 #endif
197     , m_setCanStartMediaTimer(WebProcess::shared().runLoop(), this, &WebPage::setCanStartMediaTimerFired)
198     , m_findController(this)
199 #if PLATFORM(QT)
200     , m_tapHighlightController(this)
201 #endif
202     , m_geolocationPermissionRequestManager(this)
203     , m_pageID(pageID)
204     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
205     , m_canRunModal(parameters.canRunModal)
206     , m_isRunningModal(false)
207     , m_cachedMainFrameIsPinnedToLeftSide(false)
208     , m_cachedMainFrameIsPinnedToRightSide(false)
209     , m_canShortCircuitHorizontalWheelEvents(false)
210     , m_numWheelEventHandlers(0)
211     , m_cachedPageCount(0)
212     , m_isShowingContextMenu(false)
213     , m_willGoToBackForwardItemCallbackEnabled(true)
214 #if PLATFORM(WIN)
215     , m_gestureReachedScrollingLimit(false)
216 #endif
217 {
218     ASSERT(m_pageID);
219     // FIXME: This is a non-ideal location for this Setting and
220     // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
221     Settings::setDefaultMinDOMTimerInterval(0.004);
222
223     Page::PageClients pageClients;
224     pageClients.chromeClient = new WebChromeClient(this);
225     pageClients.contextMenuClient = new WebContextMenuClient(this);
226     pageClients.editorClient = new WebEditorClient(this);
227     pageClients.dragClient = new WebDragClient(this);
228     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
229 #if ENABLE(CLIENT_BASED_GEOLOCATION)
230     pageClients.geolocationClient = new WebGeolocationClient(this);
231 #endif
232 #if ENABLE(INSPECTOR)
233     pageClients.inspectorClient = new WebInspectorClient(this);
234 #endif
235     
236     m_page = adoptPtr(new Page(pageClients));
237
238 #if ENABLE(NOTIFICATIONS)
239     WebCore::provideNotification(m_page.get(), new WebNotificationClient(this));
240 #endif
241
242     // Qt does not yet call setIsInWindow. Until it does, just leave
243     // this line out so plug-ins and video will work. Eventually all platforms
244     // should call setIsInWindow and this comment and #if should be removed,
245     // leaving behind the setCanStartMedia call.
246 #if !PLATFORM(QT)
247     m_page->setCanStartMedia(false);
248 #endif
249
250     updatePreferences(parameters.store);
251
252     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
253     m_page->setGroupName(m_pageGroup->identifier());
254
255     platformInitialize();
256
257     m_drawingArea = DrawingArea::create(this, parameters);
258     m_drawingArea->setPaintingEnabled(false);
259
260     m_mainFrame = WebFrame::createMainFrame(this);
261
262     setUseFixedLayout(parameters.useFixedLayout);
263
264     setDrawsBackground(parameters.drawsBackground);
265     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
266
267     setPaginationMode(parameters.paginationMode);
268     setPaginationBehavesLikeColumns(parameters.paginationBehavesLikeColumns);
269     setPageLength(parameters.pageLength);
270     setGapBetweenPages(parameters.gapBetweenPages);
271
272     setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
273
274     setActive(parameters.isActive);
275     setFocused(parameters.isFocused);
276     setIsInWindow(parameters.isInWindow);
277
278     m_userAgent = parameters.userAgent;
279
280     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
281     
282     if (!parameters.sessionState.isEmpty())
283         restoreSession(parameters.sessionState);
284
285     m_drawingArea->setPaintingEnabled(true);
286     
287     setMediaVolume(parameters.mediaVolume);
288
289 #ifndef NDEBUG
290     webPageCounter.increment();
291 #endif
292 }
293
294 WebPage::~WebPage()
295 {
296     if (m_backForwardList)
297         m_backForwardList->detach();
298
299     ASSERT(!m_page);
300
301     m_sandboxExtensionTracker.invalidate();
302
303 #if PLATFORM(MAC)
304     ASSERT(m_pluginViews.isEmpty());
305 #endif
306
307 #ifndef NDEBUG
308     webPageCounter.decrement();
309 #endif
310 }
311
312 void WebPage::dummy(bool&)
313 {
314 }
315
316 CoreIPC::Connection* WebPage::connection() const
317 {
318     return WebProcess::shared().connection();
319 }
320
321 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
322 {
323     m_contextMenuClient.initialize(client);
324 }
325
326 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
327 {
328     m_editorClient.initialize(client);
329 }
330
331 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
332 {
333     m_formClient.initialize(client);
334 }
335
336 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
337 {
338     m_loaderClient.initialize(client);
339 }
340
341 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client)
342 {
343     m_policyClient.initialize(client);
344 }
345
346 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client)
347 {
348     m_resourceLoadClient.initialize(client);
349 }
350
351 void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
352 {
353     m_uiClient.initialize(client);
354 }
355
356 #if ENABLE(FULLSCREEN_API)
357 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client)
358 {
359     m_fullScreenClient.initialize(client);
360 }
361 #endif
362
363 PassRefPtr<Plugin> WebPage::createPlugin(WebFrame* frame, const Plugin::Parameters& parameters)
364 {
365     String pluginPath;
366
367     if (!WebProcess::shared().connection()->sendSync(
368             Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()), 
369             Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) {
370         return 0;
371     }
372
373     if (pluginPath.isNull()) {
374 #if PLATFORM(MAC)
375         if (parameters.mimeType == "application/pdf"
376             || (parameters.mimeType.isEmpty() && parameters.url.path().lower().endsWith(".pdf")))
377             return BuiltInPDFView::create(frame);
378 #else
379         UNUSED_PARAM(frame);
380 #endif
381         return 0;
382     }
383
384 #if ENABLE(PLUGIN_PROCESS)
385     return PluginProxy::create(pluginPath);
386 #else
387     NetscapePlugin::setSetExceptionFunction(NPRuntimeObjectMap::setGlobalException);
388     return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath));
389 #endif
390 }
391
392 EditorState WebPage::editorState() const
393 {
394     Frame* frame = m_page->focusController()->focusedOrMainFrame();
395     ASSERT(frame);
396
397     EditorState result;
398     result.selectionIsNone = frame->selection()->isNone();
399     result.selectionIsRange = frame->selection()->isRange();
400     result.isContentEditable = frame->selection()->isContentEditable();
401     result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable();
402     result.isInPasswordField = frame->selection()->isInPasswordField();
403     result.hasComposition = frame->editor()->hasComposition();
404     result.shouldIgnoreCompositionSelectionChange = frame->editor()->ignoreCompositionSelectionChange();
405
406 #if PLATFORM(QT)
407     size_t location = 0;
408     size_t length = 0;
409
410     Element* selectionRoot = frame->selection()->rootEditableElement();
411     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
412
413     if (!scope)
414         return result;
415
416     if (scope->hasTagName(HTMLNames::inputTag)) {
417         HTMLInputElement* input = static_cast<HTMLInputElement*>(scope);
418         if (input->isTelephoneField())
419             result.inputMethodHints |= Qt::ImhDialableCharactersOnly;
420         else if (input->isNumberField())
421             result.inputMethodHints |= Qt::ImhDigitsOnly;
422         else if (input->isEmailField()) {
423             result.inputMethodHints |= Qt::ImhEmailCharactersOnly;
424             result.inputMethodHints |= Qt::ImhNoAutoUppercase;
425         } else if (input->isURLField()) {
426             result.inputMethodHints |= Qt::ImhUrlCharactersOnly;
427             result.inputMethodHints |= Qt::ImhNoAutoUppercase;
428         } else if (input->isPasswordField()) {
429             // Set ImhHiddenText flag for password fields. The Qt platform
430             // is responsible for determining which widget will receive input
431             // method events for password fields.
432             result.inputMethodHints |= Qt::ImhHiddenText;
433             result.inputMethodHints |= Qt::ImhNoAutoUppercase;
434             result.inputMethodHints |= Qt::ImhNoPredictiveText;
435             result.inputMethodHints |= Qt::ImhSensitiveData;
436         }
437     }
438
439     if (selectionRoot)
440         result.editorRect = frame->view()->contentsToWindow(selectionRoot->getRect());
441
442     RefPtr<Range> range;
443     if (result.hasComposition && (range = frame->editor()->compositionRange())) {
444         frame->editor()->getCompositionSelection(result.anchorPosition, result.cursorPosition);
445
446         result.compositionRect = frame->view()->contentsToWindow(range->boundingBox());
447     }
448
449     if (!result.hasComposition && !result.selectionIsNone && (range = frame->selection()->selection().firstRange())) {
450         TextIterator::getLocationAndLengthFromRange(scope, range.get(), location, length);
451         bool baseIsFirst = frame->selection()->selection().isBaseFirst();
452
453         result.cursorPosition = (baseIsFirst) ? location + length : location;
454         result.anchorPosition = (baseIsFirst) ? location : location + length;
455         result.selectedText = range->text();
456     }
457
458     if (range)
459         result.cursorRect = frame->view()->contentsToWindow(frame->editor()->firstRectForRange(range.get()));
460
461     // FIXME: We should only transfer innerText when it changes and do this on the UI side.
462     if (result.isContentEditable && !result.isInPasswordField) {
463         result.surroundingText = scope->innerText();
464         if (result.hasComposition) {
465             // The anchor is always the left position when they represent a composition.
466             result.surroundingText.remove(result.anchorPosition, result.cursorPosition - result.anchorPosition);
467         }
468     }
469 #endif
470
471     return result;
472 }
473
474 String WebPage::renderTreeExternalRepresentation() const
475 {
476     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
477 }
478
479 uint64_t WebPage::renderTreeSize() const
480 {
481     if (!m_page)
482         return 0;
483
484     Frame* mainFrame = m_page->mainFrame();
485     if (!mainFrame)
486         return 0;
487
488     uint64_t size = 0;
489     for (Frame* coreFrame = mainFrame; coreFrame; coreFrame = coreFrame->tree()->traverseNext())
490         size += coreFrame->document()->renderArena()->totalRenderArenaSize();
491
492     return size;
493 }
494
495 void WebPage::setPaintedObjectsCounterThreshold(uint64_t threshold)
496 {
497     if (!m_page)
498         return;
499     m_page->setRelevantRepaintedObjectsCounterThreshold(threshold);
500 }
501
502 void WebPage::setTracksRepaints(bool trackRepaints)
503 {
504     if (FrameView* view = mainFrameView())
505         view->setTracksRepaints(trackRepaints);
506 }
507
508 bool WebPage::isTrackingRepaints() const
509 {
510     if (FrameView* view = mainFrameView())
511         return view->isTrackingRepaints();
512
513     return false;
514 }
515
516 void WebPage::resetTrackedRepaints()
517 {
518     if (FrameView* view = mainFrameView())
519         view->resetTrackedRepaints();
520 }
521
522 PassRefPtr<ImmutableArray> WebPage::trackedRepaintRects()
523 {
524     FrameView* view = mainFrameView();
525     if (!view)
526         return ImmutableArray::create();
527
528     const Vector<IntRect>& rects = view->trackedRepaintRects();
529     size_t size = rects.size();
530     if (!size)
531         return ImmutableArray::create();
532
533     Vector<RefPtr<APIObject> > vector;
534     vector.reserveInitialCapacity(size);
535
536     for (size_t i = 0; i < size; ++i)
537         vector.uncheckedAppend(WebRect::create(toAPI(rects[i])));
538
539     return ImmutableArray::adopt(vector);
540 }
541
542 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
543 {
544     Frame* frame = m_page->focusController()->focusedOrMainFrame();
545     if (!frame)
546         return;
547     frame->editor()->command(commandName).execute(argument);
548 }
549
550 bool WebPage::isEditingCommandEnabled(const String& commandName)
551 {
552     Frame* frame = m_page->focusController()->focusedOrMainFrame();
553     if (!frame)
554         return false;
555     
556     Editor::Command command = frame->editor()->command(commandName);
557     return command.isSupported() && command.isEnabled();
558 }
559     
560 void WebPage::clearMainFrameName()
561 {
562     if (Frame* frame = mainFrame())
563         frame->tree()->clearName();
564 }
565
566 #if USE(ACCELERATED_COMPOSITING)
567 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
568 {
569     m_drawingArea->setRootCompositingLayer(layer);
570 }
571
572 void WebPage::exitAcceleratedCompositingMode()
573 {
574     m_drawingArea->setRootCompositingLayer(0);
575 }
576 #endif
577
578 void WebPage::close()
579 {
580     if (m_isClosed)
581         return;
582
583     m_isClosed = true;
584
585     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
586         WebProcess::shared().injectedBundle()->willDestroyPage(this);
587
588 #if ENABLE(INSPECTOR)
589     m_inspector = 0;
590 #endif
591 #if ENABLE(FULLSCREEN_API)
592     m_fullScreenManager = 0;
593 #endif
594
595     if (m_activePopupMenu) {
596         m_activePopupMenu->disconnectFromPage();
597         m_activePopupMenu = 0;
598     }
599
600     if (m_activeOpenPanelResultListener) {
601         m_activeOpenPanelResultListener->disconnectFromPage();
602         m_activeOpenPanelResultListener = 0;
603     }
604
605     m_sandboxExtensionTracker.invalidate();
606
607     m_underlayPage = nullptr;
608     m_printContext = nullptr;
609     m_mainFrame->coreFrame()->loader()->detachFromParent();
610     m_page = nullptr;
611     m_drawingArea = nullptr;
612
613     bool isRunningModal = m_isRunningModal;
614     m_isRunningModal = false;
615
616     // The WebPage can be destroyed by this call.
617     WebProcess::shared().removeWebPage(m_pageID);
618
619     if (isRunningModal)
620         WebProcess::shared().runLoop()->stop();
621 }
622
623 void WebPage::tryClose()
624 {
625     SendStopResponsivenessTimer stopper(this);
626
627     if (!m_mainFrame->coreFrame()->loader()->shouldClose()) {
628         send(Messages::WebPageProxy::StopResponsivenessTimer());
629         return;
630     }
631
632     send(Messages::WebPageProxy::ClosePage(true));
633 }
634
635 void WebPage::sendClose()
636 {
637     send(Messages::WebPageProxy::ClosePage(false));
638 }
639
640 void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle)
641 {
642     loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle);
643 }
644
645 void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle)
646 {
647     SendStopResponsivenessTimer stopper(this);
648
649     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
650     m_mainFrame->coreFrame()->loader()->load(request, false);
651 }
652
653 void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL)
654 {
655     SendStopResponsivenessTimer stopper(this);
656
657     ResourceRequest request(baseURL);
658     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
659     m_mainFrame->coreFrame()->loader()->load(request, substituteData, false);
660 }
661
662 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString)
663 {
664     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
665     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
666     loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL());
667 }
668
669 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString)
670 {
671     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
672     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
673     KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString);
674     loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL);
675 }
676
677 void WebPage::loadPlainTextString(const String& string)
678 {
679     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar));
680     loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL());
681 }
682
683 void WebPage::linkClicked(const String& url, const WebMouseEvent& event)
684 {
685     Frame* frame = m_page->mainFrame();
686     if (!frame)
687         return;
688
689     RefPtr<Event> coreEvent;
690     if (event.type() != WebEvent::NoType)
691         coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0);
692
693     frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)), 
694         false, false, coreEvent.get(), 0, MaybeSendReferrer);
695 }
696
697 void WebPage::stopLoadingFrame(uint64_t frameID)
698 {
699     WebFrame* frame = WebProcess::shared().webFrame(frameID);
700     if (!frame)
701         return;
702
703     frame->coreFrame()->loader()->stopForUserCancel();
704 }
705
706 void WebPage::stopLoading()
707 {
708     SendStopResponsivenessTimer stopper(this);
709
710     m_mainFrame->coreFrame()->loader()->stopForUserCancel();
711 }
712
713 void WebPage::setDefersLoading(bool defersLoading)
714 {
715     m_page->setDefersLoading(defersLoading);
716 }
717
718 void WebPage::reload(bool reloadFromOrigin, const SandboxExtension::Handle& sandboxExtensionHandle)
719 {
720     SendStopResponsivenessTimer stopper(this);
721
722     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
723     m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
724 }
725
726 void WebPage::goForward(uint64_t backForwardItemID)
727 {
728     SendStopResponsivenessTimer stopper(this);
729
730     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
731     ASSERT(item);
732     if (!item)
733         return;
734
735     m_page->goToItem(item, FrameLoadTypeForward);
736 }
737
738 void WebPage::goBack(uint64_t backForwardItemID)
739 {
740     SendStopResponsivenessTimer stopper(this);
741
742     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
743     ASSERT(item);
744     if (!item)
745         return;
746
747     m_page->goToItem(item, FrameLoadTypeBack);
748 }
749
750 void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
751 {
752     SendStopResponsivenessTimer stopper(this);
753
754     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
755     ASSERT(item);
756     if (!item)
757         return;
758
759     m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
760 }
761
762 void WebPage::tryRestoreScrollPosition()
763 {
764     m_page->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
765 }
766
767 void WebPage::layoutIfNeeded()
768 {
769     if (m_mainFrame->coreFrame()->view())
770         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
771
772     if (m_underlayPage) {
773         if (FrameView *frameView = m_underlayPage->mainFrameView())
774             frameView->updateLayoutAndStyleIfNeededRecursive();
775     }
776 }
777
778 void WebPage::setSize(const WebCore::IntSize& viewSize)
779 {
780     FrameView* view = m_page->mainFrame()->view();
781
782 #if USE(TILED_BACKING_STORE)
783     // If we are resizing to content ignore external attempts.
784     if (view->useFixedLayout())
785         return;
786 #endif
787
788     if (m_viewSize == viewSize)
789         return;
790
791     view->resize(viewSize);
792     view->setNeedsLayout();
793     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize));
794     
795     m_viewSize = viewSize;
796 }
797
798 #if USE(TILED_BACKING_STORE)
799 void WebPage::setFixedVisibleContentRect(const IntRect& rect)
800 {
801     ASSERT(m_useFixedLayout);
802
803     Frame* frame = m_page->mainFrame();
804
805     frame->view()->setFixedVisibleContentRect(rect);
806 }
807
808 void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize)
809 {
810     ASSERT(m_useFixedLayout);
811     ASSERT(!targetLayoutSize.isEmpty());
812
813     FrameView* view = m_page->mainFrame()->view();
814
815     view->setDelegatesScrolling(true);
816     view->setUseFixedLayout(true);
817     view->setPaintsEntireContents(true);
818
819     if (view->fixedLayoutSize() == targetLayoutSize)
820         return;
821
822     // Always reset even when empty.
823     view->setFixedLayoutSize(targetLayoutSize);
824
825     // Schedule a layout to use the new target size.
826     if (!view->layoutPending()) {
827         view->setNeedsLayout();
828         view->scheduleRelayout();
829     }
830 }
831
832 void WebPage::resizeToContentsIfNeeded()
833 {
834     ASSERT(m_useFixedLayout);
835
836     FrameView* view = m_page->mainFrame()->view();
837
838     if (!view->useFixedLayout())
839         return;
840
841     IntSize contentSize = view->contentsSize();
842     if (contentSize == m_viewSize)
843         return;
844
845     m_viewSize = contentSize;
846     view->resize(m_viewSize);
847     view->setNeedsLayout();
848 }
849
850 void WebPage::setViewportSize(const IntSize& size)
851 {
852     ASSERT(m_useFixedLayout);
853
854     if (m_viewportSize == size)
855         return;
856
857      m_viewportSize = size;
858
859     // Recalculate the recommended layout size, when the available size (device pixel) changes.
860     Settings* settings = m_page->settings();
861
862     int minimumLayoutFallbackWidth = std::max(settings->layoutFallbackWidth(), size.width());
863
864     IntSize targetLayoutSize = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, settings->deviceWidth(), settings->deviceHeight(), settings->deviceDPI(), size).layoutSize;
865     setResizesToContentsUsingLayoutSize(targetLayoutSize);
866 }
867
868 #endif
869
870 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
871 {
872     Frame* frame = m_page->mainFrame();
873
874     IntPoint scrollPosition = frame->view()->scrollPosition();
875     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
876
877     // If the current scroll position in a direction is the max scroll position 
878     // we don't want to scroll at all.
879     IntSize newScrollOffset;
880     if (scrollPosition.x() < maximumScrollPosition.x())
881         newScrollOffset.setWidth(scrollOffset.width());
882     if (scrollPosition.y() < maximumScrollPosition.y())
883         newScrollOffset.setHeight(scrollOffset.height());
884
885     if (newScrollOffset.isZero())
886         return;
887
888     frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset);
889 }
890
891 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
892 {
893     GraphicsContextStateSaver stateSaver(graphicsContext);
894     graphicsContext.clip(rect);
895
896     if (m_underlayPage) {
897         m_underlayPage->drawRect(graphicsContext, rect);
898
899         graphicsContext.beginTransparencyLayer(1);
900         m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
901         graphicsContext.endTransparencyLayer();
902         return;
903     }
904
905     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
906 }
907
908 void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect)
909 {
910     ASSERT(m_pageOverlay);
911
912     GraphicsContextStateSaver stateSaver(graphicsContext);
913     graphicsContext.clip(rect);
914     m_pageOverlay->drawRect(graphicsContext, rect);
915 }
916
917 double WebPage::textZoomFactor() const
918 {
919     Frame* frame = m_mainFrame->coreFrame();
920     if (!frame)
921         return 1;
922     return frame->textZoomFactor();
923 }
924
925 void WebPage::setTextZoomFactor(double zoomFactor)
926 {
927     Frame* frame = m_mainFrame->coreFrame();
928     if (!frame)
929         return;
930     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
931 }
932
933 double WebPage::pageZoomFactor() const
934 {
935     Frame* frame = m_mainFrame->coreFrame();
936     if (!frame)
937         return 1;
938     return frame->pageZoomFactor();
939 }
940
941 void WebPage::setPageZoomFactor(double zoomFactor)
942 {
943     Frame* frame = m_mainFrame->coreFrame();
944     if (!frame)
945         return;
946     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
947 }
948
949 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
950 {
951     Frame* frame = m_mainFrame->coreFrame();
952     if (!frame)
953         return;
954     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
955 }
956
957 void WebPage::windowScreenDidChange(uint64_t displayID)
958 {
959     m_page->windowScreenDidChange(static_cast<PlatformDisplayID>(displayID));
960 }
961
962 void WebPage::scalePage(double scale, const IntPoint& origin)
963 {
964     m_page->setPageScaleFactor(scale, origin);
965
966     send(Messages::WebPageProxy::PageScaleFactorDidChange(scale));
967 }
968
969 double WebPage::pageScaleFactor() const
970 {
971     return m_page->pageScaleFactor();
972 }
973
974 void WebPage::setDeviceScaleFactor(float scaleFactor)
975 {
976     if (scaleFactor == m_page->deviceScaleFactor())
977         return;
978
979     m_page->setDeviceScaleFactor(scaleFactor);
980
981     // Tell all our plug-in views that the device scale factor changed.
982 #if PLATFORM(MAC)
983     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
984         (*it)->setDeviceScaleFactor(scaleFactor);
985 #endif
986
987     if (m_findController.isShowingOverlay()) {
988         // We must have updated layout to get the selection rects right.
989         layoutIfNeeded();
990         m_findController.deviceScaleFactorDidChange();
991     }
992 }
993
994 float WebPage::deviceScaleFactor() const
995 {
996     return m_page->deviceScaleFactor();
997 }
998
999 void WebPage::setUseFixedLayout(bool fixed)
1000 {
1001     m_useFixedLayout = fixed;
1002
1003     FrameView* view = mainFrameView();
1004     if (!view)
1005         return;
1006
1007     view->setUseFixedLayout(fixed);
1008     if (!fixed)
1009         view->setFixedLayoutSize(IntSize());
1010 }
1011
1012 void WebPage::setFixedLayoutSize(const IntSize& size)
1013 {
1014     FrameView* view = mainFrameView();
1015     if (!view)
1016         return;
1017
1018     view->setFixedLayoutSize(size);
1019     view->forceLayout();
1020 }
1021
1022 void WebPage::setPaginationMode(uint32_t mode)
1023 {
1024     Page::Pagination pagination = m_page->pagination();
1025     pagination.mode = static_cast<Page::Pagination::Mode>(mode);
1026     m_page->setPagination(pagination);
1027 }
1028
1029 void WebPage::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1030 {
1031     Page::Pagination pagination = m_page->pagination();
1032     pagination.behavesLikeColumns = behavesLikeColumns;
1033     m_page->setPagination(pagination);
1034 }
1035
1036 void WebPage::setPageLength(double pageLength)
1037 {
1038     Page::Pagination pagination = m_page->pagination();
1039     pagination.pageLength = pageLength;
1040     m_page->setPagination(pagination);
1041 }
1042
1043 void WebPage::setGapBetweenPages(double gap)
1044 {
1045     Page::Pagination pagination = m_page->pagination();
1046     pagination.gap = gap;
1047     m_page->setPagination(pagination);
1048 }
1049
1050 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
1051 {
1052     bool shouldFadeIn = true;
1053     
1054     if (m_pageOverlay) {
1055         m_pageOverlay->setPage(0);
1056
1057         if (pageOverlay) {
1058             // We're installing a page overlay when a page overlay is already active.
1059             // In this case we don't want to fade in the new overlay.
1060             shouldFadeIn = false;
1061         }
1062     }
1063
1064     m_pageOverlay = pageOverlay;
1065     m_pageOverlay->setPage(this);
1066
1067     if (shouldFadeIn)
1068         m_pageOverlay->startFadeInAnimation();
1069
1070     m_drawingArea->didInstallPageOverlay();
1071 #if PLATFORM(WIN)
1072     send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(true));
1073 #endif
1074
1075     m_pageOverlay->setNeedsDisplay();
1076 }
1077
1078 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut)
1079 {
1080     if (pageOverlay != m_pageOverlay)
1081         return;
1082
1083     if (fadeOut) {
1084         m_pageOverlay->startFadeOutAnimation();
1085         return;
1086     }
1087
1088     m_pageOverlay->setPage(0);
1089     m_pageOverlay = nullptr;
1090
1091     m_drawingArea->didUninstallPageOverlay();
1092 #if PLATFORM(WIN)
1093     send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(false));
1094 #endif
1095 }
1096
1097 PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
1098 {
1099     FrameView* frameView = m_mainFrame->coreFrame()->view();
1100     if (!frameView)
1101         return 0;
1102
1103     IntSize bitmapSize = rect.size();
1104     float deviceScaleFactor = corePage()->deviceScaleFactor();
1105     bitmapSize.scale(deviceScaleFactor);
1106
1107     RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, options);
1108     if (!snapshot->bitmap())
1109         return 0;
1110     
1111     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
1112     graphicsContext->applyDeviceScaleFactor(deviceScaleFactor);
1113     graphicsContext->translate(-rect.x(), -rect.y());
1114
1115     frameView->updateLayoutAndStyleIfNeededRecursive();
1116
1117     PaintBehavior oldBehavior = frameView->paintBehavior();
1118     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
1119     frameView->paint(graphicsContext.get(), rect);
1120     frameView->setPaintBehavior(oldBehavior);
1121
1122     return snapshot.release();
1123 }
1124
1125 PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
1126 {
1127     FrameView* frameView = m_mainFrame->coreFrame()->view();
1128     if (!frameView)
1129         return 0;
1130
1131     float combinedScaleFactor = scaleFactor * corePage()->deviceScaleFactor();
1132     IntSize size(ceil(rect.width() * combinedScaleFactor), ceil(rect.height() * combinedScaleFactor));
1133     RefPtr<WebImage> snapshot = WebImage::create(size, options);
1134     if (!snapshot->bitmap())
1135         return 0;
1136
1137     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
1138     graphicsContext->applyDeviceScaleFactor(combinedScaleFactor);
1139     graphicsContext->translate(-rect.x(), -rect.y());
1140
1141     frameView->updateLayoutAndStyleIfNeededRecursive();
1142
1143     PaintBehavior oldBehavior = frameView->paintBehavior();
1144     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
1145     frameView->paintContents(graphicsContext.get(), rect);
1146     frameView->setPaintBehavior(oldBehavior);
1147
1148     return snapshot.release();
1149 }
1150
1151 PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
1152 {
1153     return scaledSnapshotInDocumentCoordinates(rect, 1, options);
1154 }
1155
1156 void WebPage::pageDidScroll()
1157 {
1158     // Hide the find indicator.
1159     m_findController.hideFindIndicator();
1160
1161     m_uiClient.pageDidScroll(this);
1162
1163     send(Messages::WebPageProxy::PageDidScroll());
1164 }
1165
1166 #if USE(TILED_BACKING_STORE)
1167 void WebPage::pageDidRequestScroll(const IntPoint& point)
1168 {
1169     send(Messages::WebPageProxy::PageDidRequestScroll(point));
1170 }
1171 #endif
1172
1173 WebContextMenu* WebPage::contextMenu()
1174 {
1175     if (!m_contextMenu)
1176         m_contextMenu = WebContextMenu::create(this);
1177     return m_contextMenu.get();
1178 }
1179
1180 // Events 
1181
1182 static const WebEvent* g_currentEvent = 0;
1183
1184 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
1185 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
1186 // platform events passed to the event handler code.
1187 const WebEvent* WebPage::currentEvent()
1188 {
1189     return g_currentEvent;
1190 }
1191
1192 class CurrentEvent {
1193 public:
1194     explicit CurrentEvent(const WebEvent& event)
1195         : m_previousCurrentEvent(g_currentEvent)
1196     {
1197         g_currentEvent = &event;
1198     }
1199
1200     ~CurrentEvent()
1201     {
1202         g_currentEvent = m_previousCurrentEvent;
1203     }
1204
1205 private:
1206     const WebEvent* m_previousCurrentEvent;
1207 };
1208
1209 static bool isContextClick(const PlatformMouseEvent& event)
1210 {
1211     if (event.button() == WebCore::RightButton)
1212         return true;
1213
1214 #if PLATFORM(MAC)
1215     // FIXME: this really should be about OSX-style UI, not about the Mac port
1216     if (event.button() == WebCore::LeftButton && event.ctrlKey())
1217         return true;
1218 #endif
1219
1220     return false;
1221 }
1222
1223 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, Page* page)
1224 {
1225     IntPoint point = page->mainFrame()->view()->windowToContents(platformMouseEvent.position());
1226     HitTestResult result = page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false);
1227
1228     Frame* frame = page->mainFrame();
1229     if (result.innerNonSharedNode())
1230         frame = result.innerNonSharedNode()->document()->frame();
1231     
1232     bool handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent);
1233     if (handled)
1234         page->chrome()->showContextMenu();
1235
1236     return handled;
1237 }
1238
1239 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page, bool onlyUpdateScrollbars)
1240 {
1241     Frame* frame = page->mainFrame();
1242     if (!frame->view())
1243         return false;
1244
1245     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
1246
1247     switch (platformMouseEvent.type()) {
1248         case PlatformEvent::MousePressed: {
1249             if (isContextClick(platformMouseEvent))
1250                 page->contextMenuController()->clearContextMenu();
1251             
1252             bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent);
1253             if (isContextClick(platformMouseEvent))
1254                 handled = handleContextMenuEvent(platformMouseEvent, page);
1255
1256             return handled;
1257         }
1258         case PlatformEvent::MouseReleased:
1259             return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent);
1260         case PlatformEvent::MouseMoved:
1261             if (onlyUpdateScrollbars)
1262                 return frame->eventHandler()->passMouseMovedEventToScrollbars(platformMouseEvent);
1263             return frame->eventHandler()->mouseMoved(platformMouseEvent);
1264         default:
1265             ASSERT_NOT_REACHED();
1266             return false;
1267     }
1268 }
1269
1270 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
1271 {
1272     // Don't try to handle any pending mouse events if a context menu is showing.
1273     if (m_isShowingContextMenu) {
1274         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
1275         return;
1276     }
1277     
1278     bool handled = false;
1279     
1280     if (m_pageOverlay) {
1281         // Let the page overlay handle the event.
1282         handled = m_pageOverlay->mouseEvent(mouseEvent);
1283     }
1284
1285     if (!handled) {
1286         CurrentEvent currentEvent(mouseEvent);
1287
1288         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1289         // button is currently pressed. It is possible that neither of those things will be true since on 
1290         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 
1291         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1292         // efficient scrollbars-only version of the event.
1293         bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1294         handled = handleMouseEvent(mouseEvent, m_page.get(), onlyUpdateScrollbars);
1295     }
1296
1297     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
1298 }
1299
1300 void WebPage::mouseEventSyncForTesting(const WebMouseEvent& mouseEvent, bool& handled)
1301 {
1302     // Don't try to handle any pending mouse events if a context menu is showing.
1303     if (m_isShowingContextMenu) {
1304         handled = true;
1305         return;
1306     }
1307
1308     handled = m_pageOverlay && m_pageOverlay->mouseEvent(mouseEvent);
1309
1310     if (!handled) {
1311         CurrentEvent currentEvent(mouseEvent);
1312
1313         // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
1314         // button is currently pressed. It is possible that neither of those things will be true since on 
1315         // Lion when legacy scrollbars are enabled, WebKit receives mouse events all the time. If it is one 
1316         // of those cases where the page is not active and the mouse is not pressed, then we can fire a more
1317         // efficient scrollbars-only version of the event.
1318         bool onlyUpdateScrollbars = !(m_page->focusController()->isActive() || (mouseEvent.button() != WebMouseEvent::NoButton));
1319         handled = handleMouseEvent(mouseEvent, m_page.get(), onlyUpdateScrollbars);
1320     }
1321 }
1322
1323 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
1324 {
1325     Frame* frame = page->mainFrame();
1326     if (!frame->view())
1327         return false;
1328
1329     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
1330     return frame->eventHandler()->handleWheelEvent(platformWheelEvent);
1331 }
1332
1333 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
1334 {
1335     CurrentEvent currentEvent(wheelEvent);
1336
1337     bool handled = handleWheelEvent(wheelEvent, m_page.get());
1338     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
1339 }
1340
1341 void WebPage::wheelEventSyncForTesting(const WebWheelEvent& wheelEvent, bool& handled)
1342 {
1343     CurrentEvent currentEvent(wheelEvent);
1344
1345     handled = handleWheelEvent(wheelEvent, m_page.get());
1346 }
1347
1348 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
1349 {
1350     if (!page->mainFrame()->view())
1351         return false;
1352
1353     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
1354         return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent));
1355     return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent));
1356 }
1357
1358 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
1359 {
1360     CurrentEvent currentEvent(keyboardEvent);
1361
1362     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
1363     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
1364     if (!handled)
1365         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1366
1367     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
1368 }
1369
1370 void WebPage::keyEventSyncForTesting(const WebKeyboardEvent& keyboardEvent, bool& handled)
1371 {
1372     CurrentEvent currentEvent(keyboardEvent);
1373
1374     handled = handleKeyEvent(keyboardEvent, m_page.get());
1375     if (!handled)
1376         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1377 }
1378
1379 #if ENABLE(GESTURE_EVENTS)
1380 static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page)
1381 {
1382     Frame* frame = page->mainFrame();
1383     if (!frame->view())
1384         return false;
1385
1386     PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
1387     return frame->eventHandler()->handleGestureEvent(platformGestureEvent);
1388 }
1389
1390 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
1391 {
1392     CurrentEvent currentEvent(gestureEvent);
1393
1394     bool handled = handleGestureEvent(gestureEvent, m_page.get());
1395     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
1396 }
1397 #endif
1398
1399 void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
1400 {
1401     bool isEnabled = false;
1402     int32_t state = 0;
1403     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1404     if (frame) {
1405         Editor::Command command = frame->editor()->command(commandName);
1406         state = command.state();
1407         isEnabled = command.isSupported() && command.isEnabled();
1408     }
1409
1410     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
1411 }
1412
1413 void WebPage::executeEditCommand(const String& commandName)
1414 {
1415     executeEditingCommand(commandName, String());
1416 }
1417
1418 uint64_t WebPage::restoreSession(const SessionState& sessionState)
1419 {
1420     const BackForwardListItemVector& list = sessionState.list();
1421     size_t size = list.size();
1422     uint64_t currentItemID = 0;
1423     for (size_t i = 0; i < size; ++i) {
1424         WebBackForwardListItem* webItem = list[i].get();
1425         DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
1426         
1427         RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
1428         if (!item) {
1429             LOG_ERROR("Failed to decode a HistoryItem from session state data.");
1430             return 0;
1431         }
1432         
1433         if (i == sessionState.currentIndex())
1434             currentItemID = webItem->itemID();
1435         
1436         WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
1437     }    
1438     ASSERT(currentItemID);
1439     return currentItemID;
1440 }
1441
1442 void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState)
1443 {
1444     if (uint64_t currentItemID = restoreSession(sessionState))
1445         goToBackForwardItem(currentItemID);
1446 }
1447
1448 #if ENABLE(TOUCH_EVENTS)
1449 #if PLATFORM(QT)
1450 void WebPage::highlightPotentialActivation(const IntPoint& point)
1451 {
1452     Node* activationNode = 0;
1453     Frame* mainframe = m_page->mainFrame();
1454
1455     if (point != IntPoint::zero()) {
1456         HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
1457         activationNode = result.innerNode();
1458
1459         if (!activationNode->isFocusable())
1460             activationNode = activationNode->enclosingLinkEventParentOrSelf();
1461     }
1462
1463     if (activationNode)
1464         tapHighlightController().highlight(activationNode);
1465     else
1466         tapHighlightController().hideHighlight();
1467 }
1468 #endif
1469
1470 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
1471 {
1472     Frame* frame = page->mainFrame();
1473     if (!frame->view())
1474         return false;
1475
1476     return frame->eventHandler()->handleTouchEvent(platform(touchEvent));
1477 }
1478
1479 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
1480 {
1481     CurrentEvent currentEvent(touchEvent);
1482
1483     bool handled = handleTouchEvent(touchEvent, m_page.get());
1484
1485     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
1486 }
1487
1488 void WebPage::touchEventSyncForTesting(const WebTouchEvent& touchEvent, bool& handled)
1489 {
1490     CurrentEvent currentEvent(touchEvent);
1491     handled = handleTouchEvent(touchEvent, m_page.get());
1492 }
1493 #endif
1494
1495 void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
1496 {
1497     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
1498 }
1499
1500 void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
1501 {
1502     page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
1503 }
1504
1505 void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
1506 {
1507     scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
1508 }
1509
1510 void WebPage::centerSelectionInVisibleArea()
1511 {
1512     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1513     if (!frame)
1514         return;
1515     
1516     frame->selection()->revealSelection(ScrollAlignment::alignCenterAlways);
1517     m_findController.showFindIndicatorInSelection();
1518 }
1519
1520 void WebPage::setActive(bool isActive)
1521 {
1522     m_page->focusController()->setActive(isActive);
1523
1524 #if PLATFORM(MAC)    
1525     // Tell all our plug-in views that the window focus changed.
1526     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1527         (*it)->setWindowIsFocused(isActive);
1528 #endif
1529 }
1530
1531 void WebPage::setDrawsBackground(bool drawsBackground)
1532 {
1533     if (m_drawsBackground == drawsBackground)
1534         return;
1535
1536     m_drawsBackground = drawsBackground;
1537
1538     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1539         if (FrameView* view = coreFrame->view())
1540             view->setTransparent(!drawsBackground);
1541     }
1542
1543     m_drawingArea->pageBackgroundTransparencyChanged();
1544     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1545 }
1546
1547 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
1548 {
1549     if (m_drawsTransparentBackground == drawsTransparentBackground)
1550         return;
1551
1552     m_drawsTransparentBackground = drawsTransparentBackground;
1553
1554     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
1555     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1556         if (FrameView* view = coreFrame->view())
1557             view->setBaseBackgroundColor(backgroundColor);
1558     }
1559
1560     m_drawingArea->pageBackgroundTransparencyChanged();
1561     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1562 }
1563
1564 void WebPage::viewWillStartLiveResize()
1565 {
1566     if (!m_page)
1567         return;
1568
1569     // FIXME: This should propagate to all ScrollableAreas.
1570     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1571         if (FrameView* view = frame->view())
1572             view->willStartLiveResize();
1573     }
1574 }
1575
1576 void WebPage::viewWillEndLiveResize()
1577 {
1578     if (!m_page)
1579         return;
1580
1581     // FIXME: This should propagate to all ScrollableAreas.
1582     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1583         if (FrameView* view = frame->view())
1584             view->willEndLiveResize();
1585     }
1586 }
1587
1588 void WebPage::setFocused(bool isFocused)
1589 {
1590     m_page->focusController()->setFocused(isFocused);
1591 }
1592
1593 void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
1594 {
1595     if (!m_page || !m_page->focusController())
1596         return;
1597
1598     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1599     frame->document()->setFocusedNode(0);
1600
1601     if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
1602         PlatformKeyboardEvent platformEvent(platform(event));
1603         platformEvent.disambiguateKeyDownEvent(PlatformEvent::RawKeyDown);
1604         m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame->document()->defaultView()).get());
1605         return;
1606     }
1607
1608     m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
1609 }
1610
1611 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
1612 {
1613     if (m_windowResizerSize == windowResizerSize)
1614         return;
1615
1616     m_windowResizerSize = windowResizerSize;
1617
1618     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1619         FrameView* view = coreFrame->view();
1620         if (view)
1621             view->windowResizerRectChanged();
1622     }
1623 }
1624
1625 void WebPage::setCanStartMediaTimerFired()
1626 {
1627     if (m_page)
1628         m_page->setCanStartMedia(true);
1629 }
1630
1631 void WebPage::setIsInWindow(bool isInWindow)
1632 {
1633     if (!isInWindow) {
1634         m_setCanStartMediaTimer.stop();
1635         m_page->setCanStartMedia(false);
1636         m_page->willMoveOffscreen();
1637     } else {
1638         // Defer the call to Page::setCanStartMedia() since it ends up sending a syncrhonous messages to the UI process
1639         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
1640         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
1641         m_setCanStartMediaTimer.startOneShot(0);
1642         m_page->didMoveOnscreen();
1643     }
1644 }
1645
1646 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
1647 {
1648     WebFrame* frame = WebProcess::shared().webFrame(frameID);
1649     if (!frame)
1650         return;
1651     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
1652 }
1653
1654 void WebPage::show()
1655 {
1656     send(Messages::WebPageProxy::ShowPage());
1657 }
1658
1659 void WebPage::setUserAgent(const String& userAgent)
1660 {
1661     m_userAgent = userAgent;
1662 }
1663   
1664 IntPoint WebPage::screenToWindow(const IntPoint& point)
1665 {
1666     IntPoint windowPoint;
1667     sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint));
1668     return windowPoint;
1669 }
1670     
1671 IntRect WebPage::windowToScreen(const IntRect& rect)
1672 {
1673     IntRect screenRect;
1674     sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect));
1675     return screenRect;
1676 }
1677
1678 IntRect WebPage::windowResizerRect() const
1679 {
1680     if (m_windowResizerSize.isEmpty())
1681         return IntRect();
1682
1683     IntSize frameViewSize;
1684     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
1685         if (FrameView* view = coreFrame->view())
1686             frameViewSize = view->size();
1687     }
1688
1689     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 
1690                    m_windowResizerSize.width(), m_windowResizerSize.height());
1691 }
1692
1693 KeyboardUIMode WebPage::keyboardUIMode()
1694 {
1695     bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
1696     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
1697 }
1698
1699 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
1700 {
1701     // NOTE: We need to be careful when running scripts that the objects we depend on don't
1702     // disappear during script execution.
1703
1704     // Retain the SerializedScriptValue at this level so it (and the internal data) lives
1705     // long enough for the DataReference to be encoded by the sent message.
1706     RefPtr<SerializedScriptValue> serializedResultValue;
1707     CoreIPC::DataReference dataReference;
1708
1709     JSLock lock(SilenceAssertionsOnly);
1710     if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) {
1711         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
1712             dataReference = serializedResultValue->data();
1713     }
1714
1715     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
1716 }
1717
1718 void WebPage::getContentsAsString(uint64_t callbackID)
1719 {
1720     String resultString = m_mainFrame->contentsAsString();
1721     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1722 }
1723
1724 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
1725 {
1726     String resultString = renderTreeExternalRepresentation();
1727     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1728 }
1729
1730 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
1731 {
1732     String resultString = m_mainFrame->selectionAsString();
1733     if (resultString.isEmpty())
1734         resultString = m_mainFrame->contentsAsString();
1735     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1736 }
1737
1738 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
1739 {
1740     String resultString;
1741     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
1742        resultString = frame->source();
1743
1744     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1745 }
1746
1747 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
1748 {
1749     CoreIPC::DataReference dataReference;
1750
1751     RefPtr<SharedBuffer> buffer;
1752     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1753         if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
1754             if ((buffer = loader->mainResourceData()))
1755                 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1756         }
1757     }
1758
1759     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1760 }
1761
1762 static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const KURL& resourceURL)
1763 {
1764     DocumentLoader* loader = frame->loader()->documentLoader();
1765     if (!loader)
1766         return 0;
1767
1768     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
1769     if (!subresource)
1770         return 0;
1771
1772     return subresource->data();
1773 }
1774
1775 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
1776 {
1777     CoreIPC::DataReference dataReference;
1778     KURL resourceURL(KURL(), resourceURLString);
1779
1780     RefPtr<SharedBuffer> buffer;
1781     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1782         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
1783         if (!buffer) {
1784             // Try to get the resource data from the cache.
1785             buffer = cachedResponseDataForURL(resourceURL);
1786         }
1787
1788         if (buffer)
1789             dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1790     }
1791
1792     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1793 }
1794
1795 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
1796 {
1797     CoreIPC::DataReference dataReference;
1798
1799 #if PLATFORM(MAC) || PLATFORM(WIN)
1800     RetainPtr<CFDataRef> data;
1801     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1802         if ((data = frame->webArchiveData(0, 0)))
1803             dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
1804     }
1805 #endif
1806
1807     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1808 }
1809
1810 void WebPage::forceRepaintWithoutCallback()
1811 {
1812     m_drawingArea->forceRepaint();
1813 }
1814
1815 void WebPage::forceRepaint(uint64_t callbackID)
1816 {
1817     forceRepaintWithoutCallback();
1818     send(Messages::WebPageProxy::VoidCallback(callbackID));
1819 }
1820
1821 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
1822 {
1823     WebPreferencesStore::removeTestRunnerOverrides();
1824     updatePreferences(store);
1825 }
1826
1827 void WebPage::updatePreferences(const WebPreferencesStore& store)
1828 {
1829     Settings* settings = m_page->settings();
1830
1831     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
1832
1833     // FIXME: This should be generated from macro expansion for all preferences,
1834     // but we currently don't match the naming of WebCore exactly so we are
1835     // handrolling the boolean and integer preferences until that is fixed.
1836
1837 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
1838
1839     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
1840
1841 #undef INITIALIZE_SETTINGS
1842
1843     settings->setScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
1844     settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
1845     settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
1846     settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
1847     settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
1848     settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
1849     settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
1850     settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
1851     settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
1852     settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
1853     settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
1854     settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
1855     settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
1856     settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
1857     settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
1858     settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
1859 #if ENABLE(WEB_ARCHIVE)
1860     settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
1861 #endif
1862     settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
1863     settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
1864     settings->setPageCacheSupportsPlugins(store.getBoolValueForKey(WebPreferencesKey::pageCacheSupportsPluginsKey()));
1865     settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
1866     settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
1867     settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
1868     settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
1869     settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
1870     settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
1871     settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
1872     settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
1873
1874     settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
1875     settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
1876     settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey()));
1877     settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
1878     settings->setLayoutFallbackWidth(store.getUInt32ValueForKey(WebPreferencesKey::layoutFallbackWidthKey()));
1879     settings->setDeviceDPI(store.getUInt32ValueForKey(WebPreferencesKey::deviceDPIKey()));
1880     settings->setDeviceWidth(store.getUInt32ValueForKey(WebPreferencesKey::deviceWidthKey()));
1881     settings->setDeviceHeight(store.getUInt32ValueForKey(WebPreferencesKey::deviceHeightKey()));
1882     settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
1883     settings->setShowsToolTipOverTruncatedText(store.getBoolValueForKey(WebPreferencesKey::showsToolTipOverTruncatedTextKey()));
1884
1885     settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1886     settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1887     settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1888     settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
1889     settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
1890     settings->setCSSCustomFilterEnabled(store.getBoolValueForKey(WebPreferencesKey::cssCustomFilterEnabledKey()));
1891     settings->setCSSRegionsEnabled(store.getBoolValueForKey(WebPreferencesKey::cssRegionsEnabledKey()));
1892     settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
1893     settings->setMediaPlaybackRequiresUserGesture(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackRequiresUserGestureKey()));
1894     settings->setMediaPlaybackAllowsInline(store.getBoolValueForKey(WebPreferencesKey::mediaPlaybackAllowsInlineKey()));
1895     settings->setMockScrollbarsEnabled(store.getBoolValueForKey(WebPreferencesKey::mockScrollbarsEnabledKey()));
1896
1897     // <rdar://problem/10697417>: It is necessary to force compositing when accelerate drawing
1898     // is enabled on Mac so that scrollbars are always in their own layers.
1899 #if PLATFORM(MAC)
1900     if (settings->acceleratedDrawingEnabled())
1901         settings->setForceCompositingMode(LayerTreeHost::supportsAcceleratedCompositing());
1902     else
1903 #endif
1904         settings->setForceCompositingMode(store.getBoolValueForKey(WebPreferencesKey::forceCompositingModeKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1905
1906 #if ENABLE(SQL_DATABASE)
1907     AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
1908 #endif
1909
1910 #if ENABLE(FULLSCREEN_API)
1911     settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
1912 #endif
1913
1914     settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory());
1915
1916 #if USE(AVFOUNDATION)
1917     settings->setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
1918 #endif
1919
1920 #if ENABLE(WEB_SOCKETS)
1921     settings->setUseHixie76WebSocketProtocol(store.getBoolValueForKey(WebPreferencesKey::hixie76WebSocketProtocolEnabledKey()));
1922 #endif
1923
1924 #if ENABLE(WEB_AUDIO)
1925     settings->setWebAudioEnabled(store.getBoolValueForKey(WebPreferencesKey::webAudioEnabledKey()));
1926 #endif
1927
1928     settings->setApplicationChromeMode(store.getBoolValueForKey(WebPreferencesKey::applicationChromeModeKey()));    
1929     settings->setSuppressIncrementalRendering(store.getBoolValueForKey(WebPreferencesKey::suppressIncrementalRenderingKey()));
1930     settings->setBackspaceKeyNavigationEnabled(store.getBoolValueForKey(WebPreferencesKey::backspaceKeyNavigationEnabledKey()));
1931     settings->setCaretBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::caretBrowsingEnabledKey()));
1932
1933 #if ENABLE(VIDEO_TRACK)
1934     settings->setShouldDisplaySubtitles(store.getBoolValueForKey(WebPreferencesKey::shouldDisplaySubtitlesKey()));
1935     settings->setShouldDisplayCaptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayCaptionsKey()));
1936     settings->setShouldDisplayTextDescriptions(store.getBoolValueForKey(WebPreferencesKey::shouldDisplayTextDescriptionsKey()));
1937 #endif
1938
1939 #if ENABLE(NOTIFICATIONS)
1940     settings->setNotificationsEnabled(store.getBoolValueForKey(WebPreferencesKey::notificationsEnabledKey()));
1941 #endif
1942
1943     platformPreferencesDidChange(store);
1944 }
1945
1946 #if ENABLE(INSPECTOR)
1947 WebInspector* WebPage::inspector()
1948 {
1949     if (m_isClosed)
1950         return 0;
1951     if (!m_inspector)
1952         m_inspector = WebInspector::create(this);
1953     return m_inspector.get();
1954 }
1955 #endif
1956
1957 #if ENABLE(FULLSCREEN_API)
1958 WebFullScreenManager* WebPage::fullScreenManager()
1959 {
1960     if (!m_fullScreenManager)
1961         m_fullScreenManager = WebFullScreenManager::create(this);
1962     return m_fullScreenManager.get();
1963 }
1964 #endif
1965
1966 NotificationPermissionRequestManager* WebPage::notificationPermissionRequestManager()
1967 {
1968     if (m_notificationPermissionRequestManager)
1969         return m_notificationPermissionRequestManager.get();
1970
1971     m_notificationPermissionRequestManager = NotificationPermissionRequestManager::create(this);
1972     return m_notificationPermissionRequestManager.get();
1973 }
1974
1975 #if !PLATFORM(GTK) && !PLATFORM(MAC)
1976 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
1977 {
1978     Node* node = evt->target()->toNode();
1979     ASSERT(node);
1980     Frame* frame = node->document()->frame();
1981     ASSERT(frame);
1982
1983     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
1984     if (!keyEvent)
1985         return false;
1986
1987     Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
1988
1989     if (keyEvent->type() == PlatformEvent::RawKeyDown) {
1990         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
1991         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
1992         // (e.g. Tab that inserts a Tab character, or Enter).
1993         return !command.isTextInsertion() && command.execute(evt);
1994     }
1995
1996     if (command.execute(evt))
1997         return true;
1998
1999     // Don't insert null or control characters as they can result in unexpected behaviour
2000     if (evt->charCode() < ' ')
2001         return false;
2002
2003     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
2004 }
2005 #endif
2006
2007 #if PLATFORM(WIN)
2008 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
2009 {
2010     if (!m_page) {
2011         send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
2012         return;
2013     }
2014
2015     DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
2016     switch (action) {
2017     case DragControllerActionEntered:
2018         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
2019         break;
2020
2021     case DragControllerActionUpdated:
2022         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
2023         break;
2024         
2025     case DragControllerActionExited:
2026         m_page->dragController()->dragExited(&dragData);
2027         break;
2028         
2029     case DragControllerActionPerformDrag:
2030         m_page->dragController()->performDrag(&dragData);
2031         break;
2032         
2033     default:
2034         ASSERT_NOT_REACHED();
2035     }
2036 }
2037
2038 #elif PLATFORM(QT) || PLATFORM(GTK)
2039 void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
2040 {
2041     if (!m_page) {
2042         send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
2043 #if PLATFORM(QT)
2044         QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
2045 #elif PLATFORM(GTK)
2046         DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2047 #endif
2048         delete data;
2049         return;
2050     }
2051
2052     switch (action) {
2053     case DragControllerActionEntered:
2054         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
2055         break;
2056
2057     case DragControllerActionUpdated:
2058         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
2059         break;
2060
2061     case DragControllerActionExited:
2062         m_page->dragController()->dragExited(&dragData);
2063         break;
2064
2065     case DragControllerActionPerformDrag: {
2066         m_page->dragController()->performDrag(&dragData);
2067         break;
2068     }
2069
2070     default:
2071         ASSERT_NOT_REACHED();
2072     }
2073     // DragData does not delete its platformData so we need to do that here.
2074 #if PLATFORM(QT)
2075     QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
2076 #elif PLATFORM(GTK)
2077     DataObjectGtk* data = const_cast<DataObjectGtk*>(dragData.platformData());
2078 #endif
2079     delete data;
2080 }
2081
2082 #else
2083 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)
2084 {
2085     if (!m_page) {
2086         send(Messages::WebPageProxy::DidPerformDragControllerAction(WebCore::DragSession()));
2087         return;
2088     }
2089
2090     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
2091     switch (action) {
2092     case DragControllerActionEntered:
2093         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
2094         break;
2095
2096     case DragControllerActionUpdated:
2097         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
2098         break;
2099         
2100     case DragControllerActionExited:
2101         m_page->dragController()->dragExited(&dragData);
2102         break;
2103         
2104     case DragControllerActionPerformDrag: {
2105         ASSERT(!m_pendingDropSandboxExtension);
2106
2107         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
2108
2109         m_page->dragController()->performDrag(&dragData);
2110
2111         // If we started loading a local file, the sandbox extension tracker would have adopted this
2112         // pending drop sandbox extension. If not, we'll play it safe and invalidate it.
2113         if (m_pendingDropSandboxExtension) {
2114             m_pendingDropSandboxExtension->invalidate();
2115             m_pendingDropSandboxExtension = nullptr;
2116         }
2117
2118         break;
2119     }
2120
2121     default:
2122         ASSERT_NOT_REACHED();
2123     }
2124 }
2125 #endif
2126
2127 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
2128 {
2129     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y());
2130     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y());
2131
2132     m_page->dragController()->dragEnded();
2133     FrameView* view = m_page->mainFrame()->view();
2134     if (!view)
2135         return;
2136     // FIXME: These are fake modifier keys here, but they should be real ones instead.
2137     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, PlatformEvent::MouseMoved, 0, false, false, false, false, currentTime());
2138     m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
2139 }
2140
2141 void WebPage::willPerformLoadDragDestinationAction()
2142 {
2143     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
2144 }
2145
2146 WebUndoStep* WebPage::webUndoStep(uint64_t stepID)
2147 {
2148     return m_undoStepMap.get(stepID).get();
2149 }
2150
2151 void WebPage::addWebUndoStep(uint64_t stepID, WebUndoStep* entry)
2152 {
2153     m_undoStepMap.set(stepID, entry);
2154 }
2155
2156 void WebPage::removeWebEditCommand(uint64_t stepID)
2157 {
2158     m_undoStepMap.remove(stepID);
2159 }
2160
2161 void WebPage::unapplyEditCommand(uint64_t stepID)
2162 {
2163     WebUndoStep* step = webUndoStep(stepID);
2164     if (!step)
2165         return;
2166
2167     step->step()->unapply();
2168 }
2169
2170 void WebPage::reapplyEditCommand(uint64_t stepID)
2171 {
2172     WebUndoStep* step = webUndoStep(stepID);
2173     if (!step)
2174         return;
2175
2176     m_isInRedo = true;
2177     step->step()->reapply();
2178     m_isInRedo = false;
2179 }
2180
2181 void WebPage::didRemoveEditCommand(uint64_t commandID)
2182 {
2183     removeWebEditCommand(commandID);
2184 }
2185
2186 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
2187 {
2188     m_activePopupMenu = menu;
2189 }
2190
2191 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
2192 {
2193     m_activeOpenPanelResultListener = openPanelResultListener;
2194 }
2195
2196 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
2197 {
2198     return m_page->findString(target, options);
2199 }
2200
2201 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
2202 {
2203     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
2204 }
2205
2206 void WebPage::hideFindUI()
2207 {
2208     m_findController.hideFindUI();
2209 }
2210
2211 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
2212 {
2213     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
2214 }
2215
2216 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
2217 {
2218     if (!m_activePopupMenu)
2219         return;
2220
2221     m_activePopupMenu->didChangeSelectedIndex(newIndex);
2222     m_activePopupMenu = 0;
2223 }
2224
2225 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
2226 {
2227     if (!m_activeOpenPanelResultListener)
2228         return;
2229
2230     m_activeOpenPanelResultListener->didChooseFiles(files);
2231     m_activeOpenPanelResultListener = 0;
2232 }
2233
2234 void WebPage::didCancelForOpenPanel()
2235 {
2236     m_activeOpenPanelResultListener = 0;
2237 }
2238
2239 #if ENABLE(WEB_PROCESS_SANDBOX)
2240 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
2241 {
2242     SandboxExtension::create(handle)->consumePermanently();
2243 }
2244 #endif
2245
2246 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
2247 {
2248     m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
2249 }
2250
2251 void WebPage::didReceiveNotificationPermissionDecision(uint64_t notificationID, bool allowed)
2252 {
2253     notificationPermissionRequestManager()->didReceiveNotificationPermissionDecision(notificationID, allowed);
2254 }
2255
2256 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
2257 {
2258     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2259     frame->editor()->advanceToNextMisspelling(startBeforeSelection);
2260 }
2261
2262 void WebPage::changeSpellingToWord(const String& word)
2263 {
2264     replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word);
2265 }
2266
2267 void WebPage::unmarkAllMisspellings()
2268 {
2269     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
2270         if (Document* document = frame->document())
2271             document->markers()->removeMarkers(DocumentMarker::Spelling);
2272     }
2273 }
2274
2275 void WebPage::unmarkAllBadGrammar()
2276 {
2277     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
2278         if (Document* document = frame->document())
2279             document->markers()->removeMarkers(DocumentMarker::Grammar);
2280     }
2281 }
2282
2283 #if PLATFORM(MAC)
2284 void WebPage::uppercaseWord()
2285 {
2286     m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord();
2287 }
2288
2289 void WebPage::lowercaseWord()
2290 {
2291     m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord();
2292 }
2293
2294 void WebPage::capitalizeWord()
2295 {
2296     m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord();
2297 }
2298 #endif
2299     
2300 void WebPage::setTextForActivePopupMenu(int32_t index)
2301 {
2302     if (!m_activePopupMenu)
2303         return;
2304
2305     m_activePopupMenu->setTextForIndex(index);
2306 }
2307
2308 #if PLATFORM(GTK)
2309 void WebPage::failedToShowPopupMenu()
2310 {
2311     if (!m_activePopupMenu)
2312         return;
2313
2314     m_activePopupMenu->client()->popupDidHide();
2315 }
2316 #endif
2317
2318 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
2319 {
2320     if (!m_contextMenu)
2321         return;
2322
2323     m_contextMenu->itemSelected(item);
2324     m_contextMenu = 0;
2325 }
2326
2327 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
2328 {
2329     bool selectReplacement = true;
2330     bool smartReplace = false;
2331     return frame->editor()->replaceSelectionWithText(text, selectReplacement, smartReplace);
2332 }
2333
2334 void WebPage::clearSelection()
2335 {
2336     m_page->focusController()->focusedOrMainFrame()->selection()->clear();
2337 }
2338
2339 bool WebPage::mainFrameHasCustomRepresentation() const
2340 {
2341     if (Frame* frame = mainFrame())
2342         return static_cast<WebFrameLoaderClient*>(frame->loader()->client())->frameHasCustomRepresentation();
2343
2344     return false;
2345 }
2346
2347 void WebPage::didChangeScrollOffsetForMainFrame()
2348 {
2349     Frame* frame = m_page->mainFrame();
2350     IntPoint scrollPosition = frame->view()->scrollPosition();
2351     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
2352     IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition();
2353
2354     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
2355     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
2356
2357     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) {
2358         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide));
2359         
2360         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
2361         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
2362     }
2363 }
2364
2365 void WebPage::mainFrameDidLayout()
2366 {
2367     unsigned pageCount = m_page->pageCount();
2368     if (pageCount != m_cachedPageCount) {
2369         send(Messages::WebPageProxy::DidChangePageCount(pageCount));
2370         m_cachedPageCount = pageCount;
2371     }
2372 }
2373
2374 #if PLATFORM(MAC)
2375
2376 void WebPage::addPluginView(PluginView* pluginView)
2377 {
2378     ASSERT(!m_pluginViews.contains(pluginView));
2379
2380     m_pluginViews.add(pluginView);
2381 }
2382
2383 void WebPage::removePluginView(PluginView* pluginView)
2384 {
2385     ASSERT(m_pluginViews.contains(pluginView));
2386
2387     m_pluginViews.remove(pluginView);
2388 }
2389
2390 void WebPage::setWindowIsVisible(bool windowIsVisible)
2391 {
2392     m_windowIsVisible = windowIsVisible;
2393
2394     corePage()->focusController()->setContainingWindowIsVisible(windowIsVisible);
2395
2396     // Tell all our plug-in views that the window visibility changed.
2397     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
2398         (*it)->setWindowIsVisible(windowIsVisible);
2399 }
2400
2401 void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates)
2402 {
2403     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
2404     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
2405     m_accessibilityPosition = accessibilityViewCoordinates;
2406     
2407     // Tell all our plug-in views that the window and view frames have changed.
2408     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
2409         (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates);
2410 }
2411
2412 #endif
2413
2414 bool WebPage::windowIsFocused() const
2415 {
2416 #if PLATFORM(MAC)
2417     if (!m_windowIsVisible)
2418         return false;
2419 #endif
2420     return m_page->focusController()->isFocused() && m_page->focusController()->isActive();
2421 }    
2422
2423 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
2424 {
2425     if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
2426         if (m_drawingArea)
2427             m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments);
2428         return;
2429     }
2430
2431 #if USE(TILED_BACKING_STORE) && USE(ACCELERATED_COMPOSITING)
2432     if (messageID.is<CoreIPC::MessageClassLayerTreeHost>()) {
2433         if (m_drawingArea)
2434             m_drawingArea->didReceiveLayerTreeHostMessage(connection, messageID, arguments);
2435         return;
2436     }
2437 #endif
2438     
2439 #if ENABLE(INSPECTOR)
2440     if (messageID.is<CoreIPC::MessageClassWebInspector>()) {
2441         if (WebInspector* inspector = this->inspector())
2442             inspector->didReceiveWebInspectorMessage(connection, messageID, arguments);
2443         return;
2444     }
2445 #endif
2446
2447 #if ENABLE(FULLSCREEN_API)
2448     if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) {
2449         fullScreenManager()->didReceiveMessage(connection, messageID, arguments);
2450         return;
2451     }
2452 #endif
2453
2454     didReceiveWebPageMessage(connection, messageID, arguments);
2455 }
2456
2457 void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
2458 {   
2459     didReceiveSyncWebPageMessage(connection, messageID, arguments, reply);
2460 }
2461     
2462 InjectedBundleBackForwardList* WebPage::backForwardList()
2463 {
2464     if (!m_backForwardList)
2465         m_backForwardList = InjectedBundleBackForwardList::create(this);
2466     return m_backForwardList.get();
2467 }
2468
2469 #if PLATFORM(QT)
2470 void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point)
2471 {
2472     Frame* mainframe = m_mainFrame->coreFrame();
2473     HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
2474
2475     Node* node = result.innerNode();
2476
2477     if (!node)
2478         return;
2479
2480     IntRect zoomableArea = node->getRect();
2481
2482     while (true) {
2483         bool found = !node->isTextNode() && !node->isShadowRoot();
2484
2485         // No candidate found, bail out.
2486         if (!found && !node->parentNode())
2487             return;
2488
2489         // Candidate found, and it is a better candidate than its parent.
2490         // NB: A parent is considered a better candidate iff the node is
2491         // contained by it and it is the only child.
2492         if (found && (!node->parentNode() || node->parentNode()->childNodeCount() != 1))
2493             break;
2494
2495         node = node->parentNode();
2496         zoomableArea.unite(node->getRect());
2497     }
2498
2499     if (node->document() && node->document()->frame() && node->document()->frame()->view()) {
2500         const ScrollView* view = node->document()->frame()->view();
2501         zoomableArea = view->contentsToWindow(zoomableArea);
2502     }
2503
2504     send(Messages::WebPageProxy::DidFindZoomableArea(point, zoomableArea));
2505 }
2506 #endif
2507
2508 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
2509 {
2510     invalidate();
2511 }
2512
2513 void WebPage::SandboxExtensionTracker::invalidate()
2514 {
2515     if (m_pendingProvisionalSandboxExtension) {
2516         m_pendingProvisionalSandboxExtension->invalidate();
2517         m_pendingProvisionalSandboxExtension = 0;
2518     }
2519
2520     if (m_provisionalSandboxExtension) {
2521         m_provisionalSandboxExtension->invalidate();
2522         m_provisionalSandboxExtension = 0;
2523     }
2524
2525     if (m_committedSandboxExtension) {
2526         m_committedSandboxExtension->invalidate();
2527         m_committedSandboxExtension = 0;
2528     }
2529 }
2530
2531 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
2532 {
2533     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
2534 }
2535
2536 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
2537 {
2538     ASSERT(frame->isMainFrame());
2539
2540     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
2541 }
2542
2543 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
2544 {
2545     // If we get two beginLoad calls in succession, without a provisional load starting, then
2546     // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case.
2547     if (m_pendingProvisionalSandboxExtension) {
2548         m_pendingProvisionalSandboxExtension->invalidate();
2549         m_pendingProvisionalSandboxExtension = nullptr;
2550     }
2551     
2552     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;    
2553 }
2554
2555 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
2556 {
2557     ASSERT(frame->isMainFrame());
2558
2559     FrameLoader* frameLoader = frame->coreFrame()->loader();
2560     FrameLoadType frameLoadType = frameLoader->loadType();
2561
2562     // If the page is being reloaded, it should reuse whatever extension is committed.
2563     if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
2564         return true;
2565
2566     DocumentLoader* documentLoader = frameLoader->documentLoader();
2567     DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
2568     if (!documentLoader || !provisionalDocumentLoader)
2569         return false;
2570
2571     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
2572         return true;
2573
2574     return false;
2575 }
2576
2577 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
2578 {
2579     if (!frame->isMainFrame())
2580         return;
2581
2582     // We should only reuse the commited sandbox extension if it is not null. It can be
2583     // null if the last load was for an error page.
2584     if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) {
2585         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release();
2586         ASSERT(!m_committedSandboxExtension);
2587     }
2588
2589     ASSERT(!m_provisionalSandboxExtension);
2590
2591     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
2592     if (!m_provisionalSandboxExtension)
2593         return;
2594
2595     m_provisionalSandboxExtension->consume();
2596 }
2597
2598 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
2599 {
2600     if (!frame->isMainFrame())
2601         return;
2602     
2603     ASSERT(!m_pendingProvisionalSandboxExtension);
2604
2605     // The provisional load has been committed. Invalidate the currently committed sandbox
2606     // extension and make the provisional sandbox extension the committed sandbox extension.
2607     if (m_committedSandboxExtension)
2608         m_committedSandboxExtension->invalidate();
2609
2610     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
2611 }
2612
2613 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
2614 {
2615     if (!frame->isMainFrame())
2616         return;
2617
2618     if (!m_provisionalSandboxExtension)
2619         return;
2620
2621     m_provisionalSandboxExtension->invalidate();
2622     m_provisionalSandboxExtension = nullptr;
2623 }
2624
2625 bool WebPage::hasLocalDataForURL(const KURL& url)
2626 {
2627     if (url.isLocalFile())
2628         return true;
2629
2630     FrameLoader* frameLoader = m_page->mainFrame()->loader();
2631     DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
2632     if (documentLoader && documentLoader->subresource(url))
2633         return true;
2634
2635     return platformHasLocalDataForURL(url);
2636 }
2637
2638 void WebPage::setCustomTextEncodingName(const String& encoding)
2639 {
2640     m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
2641 }
2642
2643 void WebPage::didRemoveBackForwardItem(uint64_t itemID)
2644 {
2645     WebBackForwardListProxy::removeItem(itemID);
2646 }
2647
2648 #if PLATFORM(MAC)
2649
2650 bool WebPage::isSpeaking()
2651 {
2652     bool result;
2653     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
2654 }
2655
2656 void WebPage::speak(const String& string)
2657 {
2658     send(Messages::WebPageProxy::Speak(string));
2659 }
2660
2661 void WebPage::stopSpeaking()
2662 {
2663     send(Messages::WebPageProxy::StopSpeaking());
2664 }
2665
2666 #endif
2667
2668 #if USE(CG)
2669 static RetainPtr<CGPDFDocumentRef> pdfDocumentForPrintingFrame(Frame* coreFrame)
2670 {
2671     Document* document = coreFrame->document();
2672     if (!document)
2673         return 0;
2674
2675     if (!document->isPluginDocument())
2676         return 0;
2677
2678     PluginView* pluginView = static_cast<PluginView*>(toPluginDocument(document)->pluginWidget());
2679     if (!pluginView)
2680         return 0;
2681
2682     return pluginView->pdfDocumentForPrinting();
2683 }
2684 #endif // USE(CG)
2685
2686 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
2687 {
2688     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2689     if (!frame)
2690         return;
2691
2692     Frame* coreFrame = frame->coreFrame();
2693     if (!coreFrame)
2694         return;
2695
2696 #if USE(CG)
2697     if (pdfDocumentForPrintingFrame(coreFrame))
2698         return;
2699 #endif // USE(CG)
2700
2701     if (!m_printContext)
2702         m_printContext = adoptPtr(new PrintContext(coreFrame));
2703
2704     drawingArea()->setLayerTreeStateIsFrozen(true);
2705     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
2706
2707     float fullPageHeight;
2708     m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
2709
2710 #if PLATFORM(GTK)
2711     if (!m_printOperation)
2712         m_printOperation = WebPrintOperationGtk::create(this, printInfo);
2713 #endif
2714 }
2715
2716 void WebPage::endPrinting()
2717 {
2718     drawingArea()->setLayerTreeStateIsFrozen(false);
2719 #if PLATFORM(GTK)
2720     m_printOperation = 0;
2721 #endif
2722     m_printContext = nullptr;
2723 }
2724
2725 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
2726 {
2727     Vector<IntRect> resultPageRects;
2728     double resultTotalScaleFactorForPrinting = 1;
2729
2730     beginPrinting(frameID, printInfo);
2731
2732     if (m_printContext) {
2733         resultPageRects = m_printContext->pageRects();
2734         resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
2735     }
2736 #if USE(CG)
2737     else {
2738         WebFrame* frame = WebProcess::shared().webFrame(frameID);
2739         Frame* coreFrame = frame ? frame->coreFrame() : 0;
2740         RetainPtr<CGPDFDocumentRef> pdfDocument = coreFrame ? pdfDocumentForPrintingFrame(coreFrame) : 0;
2741         if (pdfDocument && CGPDFDocumentAllowsPrinting(pdfDocument.get())) {
2742             CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get());
2743             IntRect pageRect(0, 0, ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight));
2744             for (CFIndex i = 1; i <= pageCount; ++i) {
2745                 resultPageRects.append(pageRect);
2746                 pageRect.move(0, pageRect.height());
2747             }
2748         }
2749     }
2750 #endif // USE(CG)
2751
2752     // If we're asked to print, we should actually print at least a blank page.
2753     if (resultPageRects.isEmpty())
2754         resultPageRects.append(IntRect(0, 0, 1, 1));
2755
2756     send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
2757 }
2758
2759 #if USE(CG)
2760 static inline CGFloat roundCGFloat(CGFloat f)
2761 {
2762     if (sizeof(CGFloat) == sizeof(float))
2763         return roundf(static_cast<float>(f));
2764     return static_cast<CGFloat>(round(f));
2765 }
2766
2767 static void drawPDFPage(CGPDFDocumentRef pdfDocument, CFIndex pageIndex, CGContextRef context, CGFloat pageSetupScaleFactor, CGSize paperSize)
2768 {
2769     CGContextSaveGState(context);
2770
2771     CGContextScaleCTM(context, pageSetupScaleFactor, pageSetupScaleFactor);
2772
2773     CGPDFPageRef page = CGPDFDocumentGetPage(pdfDocument, pageIndex + 1);
2774     CGRect cropBox = CGPDFPageGetBoxRect(page, kCGPDFCropBox);
2775     if (CGRectIsEmpty(cropBox))
2776         cropBox = CGRectIntersection(cropBox, CGPDFPageGetBoxRect(page, kCGPDFMediaBox));
2777     else
2778         cropBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
2779
2780     bool shouldRotate = (paperSize.width < paperSize.height) != (cropBox.size.width < cropBox.size.height);
2781     if (shouldRotate)
2782         swap(cropBox.size.width, cropBox.size.height);
2783
2784     // Center.
2785     CGFloat widthDifference = paperSize.width / pageSetupScaleFactor - cropBox.size.width;
2786     CGFloat heightDifference = paperSize.height / pageSetupScaleFactor - cropBox.size.height;
2787     if (widthDifference || heightDifference)
2788         CGContextTranslateCTM(context, roundCGFloat(widthDifference / 2), roundCGFloat(heightDifference / 2));
2789
2790     if (shouldRotate) {
2791         CGContextRotateCTM(context, static_cast<CGFloat>(piOverTwoDouble));
2792         CGContextTranslateCTM(context, 0, -cropBox.size.width);
2793     }
2794
2795     CGContextDrawPDFPage(context, page);
2796
2797     CGContextRestoreGState(context);
2798 }
2799 #endif // USE(CG)
2800
2801 #if PLATFORM(MAC) || PLATFORM(WIN)
2802 void WebPage::drawRectToPDF(uint64_t frameID, const PrintInfo& printInfo, const WebCore::IntRect& rect, uint64_t callbackID)
2803 {
2804     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2805     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2806
2807     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2808
2809     if (coreFrame) {
2810 #if !USE(CG)
2811         UNUSED_PARAM(printInfo);
2812
2813         ASSERT(coreFrame->document()->printing());
2814 #else
2815         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
2816
2817         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2818         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2819
2820         CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
2821         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2822         RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2823         CGPDFContextBeginPage(context.get(), pageInfo.get());
2824
2825         if (RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame)) {
2826             CFIndex pageCount = CGPDFDocumentGetNumberOfPages(pdfDocument.get());
2827             IntSize paperSize(ceilf(printInfo.availablePaperWidth), ceilf(printInfo.availablePaperHeight));
2828             IntRect pageRect(IntPoint(), paperSize);
2829             for (CFIndex i = 0; i < pageCount; ++i) {
2830                 if (pageRect.intersects(rect)) {
2831                     CGContextSaveGState(context.get());
2832
2833                     CGContextTranslateCTM(context.get(), pageRect.x() - rect.x(), pageRect.y() - rect.y());
2834                     drawPDFPage(pdfDocument.get(), i, context.get(), printInfo.pageSetupScaleFactor, paperSize);
2835
2836                     CGContextRestoreGState(context.get());
2837                 }
2838                 pageRect.move(0, pageRect.height());
2839             }
2840         } else {
2841             GraphicsContext ctx(context.get());
2842             ctx.scale(FloatSize(1, -1));
2843             ctx.translate(0, -rect.height());
2844             m_printContext->spoolRect(ctx, rect);
2845         }
2846
2847         CGPDFContextEndPage(context.get());
2848         CGPDFContextClose(context.get());
2849 #endif
2850     }
2851
2852     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2853 }
2854
2855 void WebPage::drawPagesToPDF(uint64_t frameID, const PrintInfo& printInfo, uint32_t first, uint32_t count, uint64_t callbackID)
2856 {
2857     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2858     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2859
2860     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2861
2862     if (coreFrame) {
2863
2864 #if !USE(CG)
2865         ASSERT(coreFrame->document()->printing());
2866 #else
2867         ASSERT(coreFrame->document()->printing() || pdfDocumentForPrintingFrame(coreFrame));
2868
2869         RetainPtr<CGPDFDocumentRef> pdfDocument = pdfDocumentForPrintingFrame(coreFrame);
2870
2871         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2872         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2873
2874         CGRect mediaBox = m_printContext && m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight);
2875         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2876         size_t pageCount = m_printContext ? m_printContext->pageCount() : CGPDFDocumentGetNumberOfPages(pdfDocument.get());
2877         for (uint32_t page = first; page < first + count; ++page) {
2878             if (page >= pageCount)
2879                 break;
2880
2881             RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2882             CGPDFContextBeginPage(context.get(), pageInfo.get());
2883
2884             if (pdfDocument)
2885                 drawPDFPage(pdfDocument.get(), page, context.get(), printInfo.pageSetupScaleFactor, CGSizeMake(printInfo.availablePaperWidth, printInfo.availablePaperHeight));
2886             else {
2887                 GraphicsContext ctx(context.get());
2888                 ctx.scale(FloatSize(1, -1));
2889                 ctx.translate(0, -m_printContext->pageRect(page).height());
2890                 m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
2891             }
2892
2893             CGPDFContextEndPage(context.get());
2894         }
2895         CGPDFContextClose(context.get());
2896 #endif
2897     }
2898
2899     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2900 }
2901 #elif PLATFORM(GTK)
2902 void WebPage::drawPagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
2903 {
2904     beginPrinting(frameID, printInfo);
2905     if (m_printContext && m_printOperation) {
2906         m_printOperation->startPrint(m_printContext.get(), callbackID);
2907         return;
2908     }
2909
2910     send(Messages::WebPageProxy::VoidCallback(callbackID));
2911 }
2912 #endif
2913
2914 void WebPage::setMediaVolume(float volume)
2915 {
2916     m_page->setMediaVolume(volume);
2917 }
2918
2919 void WebPage::runModal()
2920 {
2921     if (m_isClosed)
2922         return;
2923     if (m_isRunningModal)
2924         return;
2925
2926     m_isRunningModal = true;
2927     send(Messages::WebPageProxy::RunModal());
2928     RunLoop::run();
2929     ASSERT(!m_isRunningModal);
2930 }
2931
2932 void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
2933 {
2934     m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled);
2935 }
2936
2937 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
2938 {
2939     if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
2940         return true;
2941     return platformCanHandleRequest(request);
2942 }
2943
2944 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
2945 void WebPage::handleCorrectionPanelResult(const String& result)
2946 {
2947     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2948     if (!frame)
2949         return;
2950     frame->editor()->handleCorrectionPanelResult(result);
2951 }
2952 #endif
2953
2954 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2955 {
2956     mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2957 }
2958
2959 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2960 {
2961     mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2962 }
2963
2964 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
2965 {
2966     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
2967 }
2968
2969 String WebPage::viewportConfigurationAsText(int deviceDPI, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight)
2970 {
2971     ViewportArguments arguments = mainFrame()->document()->viewportArguments();
2972     ViewportAttributes attrs = WebCore::computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight));
2973     WebCore::restrictMinimumScaleFactorToViewportSize(attrs, IntSize(availableWidth, availableHeight));
2974     WebCore::restrictScaleFactorToInitialScaleIfNotUserScalable(attrs);
2975     return String::format("viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale, attrs.userScalable);
2976 }
2977
2978 void WebPage::setCompositionForTesting(const String& compositionString, uint64_t from, uint64_t length)
2979 {
2980     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2981     if (!frame || !frame->editor()->canEdit())
2982         return;
2983
2984     Vector<CompositionUnderline> underlines;
2985     underlines.append(CompositionUnderline(0, compositionString.length(), Color(Color::black), false));
2986     frame->editor()->setComposition(compositionString, underlines, from, from + length);
2987 }
2988
2989 bool WebPage::hasCompositionForTesting()
2990 {
2991     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2992     return frame && frame->editor()->hasComposition();
2993 }
2994
2995 void WebPage::confirmCompositionForTesting(const String& compositionString)
2996 {
2997     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2998     if (!frame || !frame->editor()->canEdit())
2999         return;
3000
3001     if (compositionString.isNull())
3002         frame->editor()->confirmComposition();
3003     frame->editor()->confirmComposition(compositionString);
3004 }
3005
3006 void WebPage::numWheelEventHandlersChanged(unsigned numWheelEventHandlers)
3007 {
3008     if (m_numWheelEventHandlers == numWheelEventHandlers)
3009         return;
3010
3011     m_numWheelEventHandlers = numWheelEventHandlers;
3012     recomputeShortCircuitHorizontalWheelEventsState();
3013 }
3014
3015 static bool hasEnabledHorizontalScrollbar(ScrollableArea* scrollableArea)
3016 {
3017     if (Scrollbar* scrollbar = scrollableArea->horizontalScrollbar())
3018         return scrollbar->enabled();
3019
3020     return false;
3021 }
3022
3023 static bool pageContainsAnyHorizontalScrollbars(Frame* mainFrame)
3024 {
3025     if (FrameView* frameView = mainFrame->view()) {
3026         if (hasEnabledHorizontalScrollbar(frameView))
3027             return true;
3028     }
3029
3030     for (Frame* frame = mainFrame; frame; frame = frame->tree()->traverseNext()) {
3031         FrameView* frameView = frame->view();
3032         if (!frameView)
3033             continue;
3034
3035         const HashSet<ScrollableArea*>* scrollableAreas = frameView->scrollableAreas();
3036         if (!scrollableAreas)
3037             continue;
3038
3039         for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(), end = scrollableAreas->end(); it != end; ++it) {
3040             ScrollableArea* scrollableArea = *it;
3041             ASSERT(scrollableArea->isOnActivePage());
3042
3043             if (hasEnabledHorizontalScrollbar(scrollableArea))
3044                 return true;
3045         }
3046     }
3047
3048     return false;
3049 }
3050
3051 void WebPage::recomputeShortCircuitHorizontalWheelEventsState()
3052 {
3053     bool canShortCircuitHorizontalWheelEvents = !m_numWheelEventHandlers;
3054
3055     if (canShortCircuitHorizontalWheelEvents) {
3056         // Check if we have any horizontal scroll bars on the page.
3057         if (pageContainsAnyHorizontalScrollbars(mainFrame()))
3058             canShortCircuitHorizontalWheelEvents = false;
3059     }
3060
3061     if (m_canShortCircuitHorizontalWheelEvents == canShortCircuitHorizontalWheelEvents)
3062         return;
3063
3064     m_canShortCircuitHorizontalWheelEvents = canShortCircuitHorizontalWheelEvents;
3065     send(Messages::WebPageProxy::SetCanShortCircuitHorizontalWheelEvents(m_canShortCircuitHorizontalWheelEvents));
3066 }
3067
3068 Frame* WebPage::mainFrame() const
3069 {
3070     return m_page ? m_page->mainFrame() : 0;
3071 }
3072
3073 FrameView* WebPage::mainFrameView() const
3074 {
3075     if (Frame* frame = mainFrame())
3076         return frame->view();
3077     
3078     return 0;
3079 }
3080
3081 } // namespace WebKit