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