<https://bugs.webkit.org/show_bug.cgi?id=62666>
[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 "PageOverlay.h"
39 #include "PluginProxy.h"
40 #include "PluginView.h"
41 #include "PrintInfo.h"
42 #include "RunLoop.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 "WebImage.h"
61 #include "WebInspector.h"
62 #include "WebInspectorClient.h"
63 #include "WebOpenPanelResultListener.h"
64 #include "WebPageCreationParameters.h"
65 #include "WebPageGroupProxy.h"
66 #include "WebPageProxyMessages.h"
67 #include "WebPopupMenu.h"
68 #include "WebPreferencesStore.h"
69 #include "WebProcess.h"
70 #include "WebProcessProxyMessages.h"
71 #include <JavaScriptCore/APICast.h>
72 #include <WebCore/AbstractDatabase.h>
73 #include <WebCore/ArchiveResource.h>
74 #include <WebCore/Chrome.h>
75 #include <WebCore/ContextMenuController.h>
76 #include <WebCore/DocumentFragment.h>
77 #include <WebCore/DocumentLoader.h>
78 #include <WebCore/DocumentMarkerController.h>
79 #include <WebCore/DragController.h>
80 #include <WebCore/DragData.h>
81 #include <WebCore/EventHandler.h>
82 #include <WebCore/FocusController.h>
83 #include <WebCore/FormState.h>
84 #include <WebCore/Frame.h>
85 #include <WebCore/FrameLoadRequest.h>
86 #include <WebCore/FrameLoaderTypes.h>
87 #include <WebCore/FrameView.h>
88 #include <WebCore/HTMLFormElement.h>
89 #include <WebCore/HistoryItem.h>
90 #include <WebCore/KeyboardEvent.h>
91 #include <WebCore/MouseEvent.h>
92 #include <WebCore/Page.h>
93 #include <WebCore/PlatformKeyboardEvent.h>
94 #include <WebCore/PrintContext.h>
95 #include <WebCore/RenderArena.h>
96 #include <WebCore/RenderLayer.h>
97 #include <WebCore/RenderTreeAsText.h>
98 #include <WebCore/RenderView.h>
99 #include <WebCore/ReplaceSelectionCommand.h>
100 #include <WebCore/ResourceRequest.h>
101 #include <WebCore/SchemeRegistry.h>
102 #include <WebCore/ScriptValue.h>
103 #include <WebCore/SerializedScriptValue.h>
104 #include <WebCore/Settings.h>
105 #include <WebCore/SharedBuffer.h>
106 #include <WebCore/SubstituteData.h>
107 #include <WebCore/TextIterator.h>
108 #include <WebCore/markup.h>
109 #include <runtime/JSLock.h>
110 #include <runtime/JSValue.h>
111
112 #include <WebCore/Range.h>
113 #include <WebCore/VisiblePosition.h>
114
115 #if PLATFORM(MAC) || PLATFORM(WIN)
116 #include <WebCore/LegacyWebArchive.h>
117 #endif
118
119 #if ENABLE(PLUGIN_PROCESS)
120 #if PLATFORM(MAC)
121 #include "MachPort.h"
122 #endif
123 #endif
124
125 #if PLATFORM(QT)
126 #include "HitTestResult.h"
127 #endif
128
129 #ifndef NDEBUG
130 #include <wtf/RefCountedLeakCounter.h>
131 #endif
132
133 using namespace JSC;
134 using namespace WebCore;
135
136 namespace WebKit {
137
138 class SendStopResponsivenessTimer {
139 public:
140     SendStopResponsivenessTimer(WebPage* page)
141         : m_page(page)
142     {
143     }
144     
145     ~SendStopResponsivenessTimer()
146     {
147         m_page->send(Messages::WebPageProxy::StopResponsivenessTimer());
148     }
149
150 private:
151     WebPage* m_page;
152 };
153     
154 #ifndef NDEBUG
155 static WTF::RefCountedLeakCounter webPageCounter("WebPage");
156 #endif
157
158 PassRefPtr<WebPage> WebPage::create(uint64_t pageID, const WebPageCreationParameters& parameters)
159 {
160     RefPtr<WebPage> page = adoptRef(new WebPage(pageID, parameters));
161
162     if (page->pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
163         WebProcess::shared().injectedBundle()->didCreatePage(page.get());
164
165     return page.release();
166 }
167
168 WebPage::WebPage(uint64_t pageID, const WebPageCreationParameters& parameters)
169     : m_viewSize(parameters.viewSize)
170     , m_drawsBackground(true)
171     , m_drawsTransparentBackground(false)
172     , m_isInRedo(false)
173     , m_isClosed(false)
174     , m_tabToLinks(false)
175 #if PLATFORM(MAC)
176     , m_windowIsVisible(false)
177     , m_isSmartInsertDeleteEnabled(parameters.isSmartInsertDeleteEnabled)
178     , m_keyboardEventBeingInterpreted(0)
179 #elif PLATFORM(WIN)
180     , m_nativeWindow(parameters.nativeWindow)
181 #endif
182     , m_setCanStartMediaTimer(WebProcess::shared().runLoop(), this, &WebPage::setCanStartMediaTimerFired)
183     , m_findController(this)
184     , m_geolocationPermissionRequestManager(this)
185     , m_pageID(pageID)
186     , m_canRunBeforeUnloadConfirmPanel(parameters.canRunBeforeUnloadConfirmPanel)
187     , m_canRunModal(parameters.canRunModal)
188     , m_isRunningModal(false)
189     , m_userSpaceScaleFactor(parameters.userSpaceScaleFactor)
190     , m_cachedMainFrameIsPinnedToLeftSide(false)
191     , m_cachedMainFrameIsPinnedToRightSide(false)
192     , m_isShowingContextMenu(false)
193 #if PLATFORM(WIN)
194     , m_gestureReachedScrollingLimit(false)
195 #endif
196 {
197     ASSERT(m_pageID);
198     // FIXME: This is a non-ideal location for this Setting and
199     // 4ms should be adopted project-wide now, https://bugs.webkit.org/show_bug.cgi?id=61214
200     Settings::setDefaultMinDOMTimerInterval(0.004);
201
202     Page::PageClients pageClients;
203     pageClients.chromeClient = new WebChromeClient(this);
204     pageClients.contextMenuClient = new WebContextMenuClient(this);
205     pageClients.editorClient = new WebEditorClient(this);
206     pageClients.dragClient = new WebDragClient(this);
207     pageClients.backForwardClient = WebBackForwardListProxy::create(this);
208 #if ENABLE(CLIENT_BASED_GEOLOCATION)
209     pageClients.geolocationClient = new WebGeolocationClient(this);
210 #endif
211 #if ENABLE(INSPECTOR)
212     pageClients.inspectorClient = new WebInspectorClient(this);
213 #endif
214     m_page = adoptPtr(new Page(pageClients));
215
216     // Qt does not yet call setIsInWindow. Until it does, just leave
217     // this line out so plug-ins and video will work. Eventually all platforms
218     // should call setIsInWindow and this comment and #if should be removed,
219     // leaving behind the setCanStartMedia call.
220 #if !PLATFORM(QT)
221     m_page->setCanStartMedia(false);
222 #endif
223
224     updatePreferences(parameters.store);
225
226     m_pageGroup = WebProcess::shared().webPageGroup(parameters.pageGroupData);
227     m_page->setGroupName(m_pageGroup->identifier());
228
229     platformInitialize();
230
231     m_drawingArea = DrawingArea::create(this, parameters);
232     m_mainFrame = WebFrame::createMainFrame(this);
233
234     setDrawsBackground(parameters.drawsBackground);
235     setDrawsTransparentBackground(parameters.drawsTransparentBackground);
236
237     setMemoryCacheMessagesEnabled(parameters.areMemoryCacheClientCallsEnabled);
238
239     setActive(parameters.isActive);
240     setFocused(parameters.isFocused);
241     setIsInWindow(parameters.isInWindow);
242
243     m_userAgent = parameters.userAgent;
244
245     WebBackForwardListProxy::setHighestItemIDFromUIProcess(parameters.highestUsedBackForwardItemID);
246     
247     if (!parameters.sessionState.isEmpty())
248         restoreSession(parameters.sessionState);
249
250 #ifndef NDEBUG
251     webPageCounter.increment();
252 #endif
253 }
254
255 WebPage::~WebPage()
256 {
257     if (m_backForwardList)
258         m_backForwardList->detach();
259
260     ASSERT(!m_page);
261
262     m_sandboxExtensionTracker.invalidate();
263
264 #if PLATFORM(MAC)
265     ASSERT(m_pluginViews.isEmpty());
266 #endif
267
268 #ifndef NDEBUG
269     webPageCounter.decrement();
270 #endif
271 }
272
273 void WebPage::dummy(bool&)
274 {
275 }
276
277 CoreIPC::Connection* WebPage::connection() const
278 {
279     return WebProcess::shared().connection();
280 }
281
282 void WebPage::initializeInjectedBundleContextMenuClient(WKBundlePageContextMenuClient* client)
283 {
284     m_contextMenuClient.initialize(client);
285 }
286
287 void WebPage::initializeInjectedBundleEditorClient(WKBundlePageEditorClient* client)
288 {
289     m_editorClient.initialize(client);
290 }
291
292 void WebPage::initializeInjectedBundleFormClient(WKBundlePageFormClient* client)
293 {
294     m_formClient.initialize(client);
295 }
296
297 void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* client)
298 {
299     m_loaderClient.initialize(client);
300 }
301
302 void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client)
303 {
304     m_policyClient.initialize(client);
305 }
306
307 void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client)
308 {
309     m_resourceLoadClient.initialize(client);
310 }
311
312 void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
313 {
314     m_uiClient.initialize(client);
315 }
316
317 #if ENABLE(FULLSCREEN_API)
318 void WebPage::initializeInjectedBundleFullScreenClient(WKBundlePageFullScreenClient* client)
319 {
320     m_fullScreenClient.initialize(client);
321 }
322 #endif
323
324 PassRefPtr<Plugin> WebPage::createPlugin(const Plugin::Parameters& parameters)
325 {
326     String pluginPath;
327
328     if (!WebProcess::shared().connection()->sendSync(
329             Messages::WebContext::GetPluginPath(parameters.mimeType, parameters.url.string()), 
330             Messages::WebContext::GetPluginPath::Reply(pluginPath), 0)) {
331         return 0;
332     }
333
334     if (pluginPath.isNull())
335         return 0;
336
337 #if ENABLE(PLUGIN_PROCESS)
338     return PluginProxy::create(pluginPath);
339 #else
340     return NetscapePlugin::create(NetscapePluginModule::getOrCreate(pluginPath));
341 #endif
342 }
343
344 EditorState WebPage::editorState() const
345 {
346     Frame* frame = m_page->focusController()->focusedOrMainFrame();
347     ASSERT(frame);
348
349     EditorState result;
350     result.selectionIsNone = frame->selection()->isNone();
351     result.selectionIsRange = frame->selection()->isRange();
352     result.isContentEditable = frame->selection()->isContentEditable();
353     result.isContentRichlyEditable = frame->selection()->isContentRichlyEditable();
354     result.isInPasswordField = frame->selection()->isInPasswordField();
355     result.hasComposition = frame->editor()->hasComposition();
356     result.shouldIgnoreCompositionSelectionChange = frame->editor()->ignoreCompositionSelectionChange();
357     
358     return result;
359 }
360
361 String WebPage::renderTreeExternalRepresentation() const
362 {
363     return externalRepresentation(m_mainFrame->coreFrame(), RenderAsTextBehaviorNormal);
364 }
365
366 uint64_t WebPage::renderTreeSize() const
367 {
368     if (!m_page)
369         return 0;
370
371     Frame* mainFrame = m_page->mainFrame();
372     if (!mainFrame)
373         return 0;
374
375     uint64_t size = 0;
376     for (Frame* coreFrame = mainFrame; coreFrame; coreFrame = coreFrame->tree()->traverseNext())
377         size += coreFrame->document()->renderArena()->totalRenderArenaSize();
378
379     return size;
380 }
381
382 void WebPage::executeEditingCommand(const String& commandName, const String& argument)
383 {
384     Frame* frame = m_page->focusController()->focusedOrMainFrame();
385     if (!frame)
386         return;
387     frame->editor()->command(commandName).execute(argument);
388 }
389
390 bool WebPage::isEditingCommandEnabled(const String& commandName)
391 {
392     Frame* frame = m_page->focusController()->focusedOrMainFrame();
393     if (!frame)
394         return false;
395     
396     Editor::Command command = frame->editor()->command(commandName);
397     return command.isSupported() && command.isEnabled();
398 }
399     
400 void WebPage::clearMainFrameName()
401 {
402     mainFrame()->coreFrame()->tree()->clearName();
403 }
404
405 #if USE(ACCELERATED_COMPOSITING)
406 void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
407 {
408     m_drawingArea->setRootCompositingLayer(layer);
409 }
410
411 void WebPage::exitAcceleratedCompositingMode()
412 {
413     m_drawingArea->setRootCompositingLayer(0);
414 }
415 #endif
416
417 void WebPage::close()
418 {
419     if (m_isClosed)
420         return;
421
422     m_isClosed = true;
423
424     if (pageGroup()->isVisibleToInjectedBundle() && WebProcess::shared().injectedBundle())
425         WebProcess::shared().injectedBundle()->willDestroyPage(this);
426
427 #if ENABLE(INSPECTOR)
428     m_inspector = 0;
429 #endif
430 #if ENABLE(FULLSCREEN_API)
431     m_fullScreenManager = 0;
432 #endif
433
434     if (m_activePopupMenu) {
435         m_activePopupMenu->disconnectFromPage();
436         m_activePopupMenu = 0;
437     }
438
439     if (m_activeOpenPanelResultListener) {
440         m_activeOpenPanelResultListener->disconnectFromPage();
441         m_activeOpenPanelResultListener = 0;
442     }
443
444     m_sandboxExtensionTracker.invalidate();
445
446     m_underlayPage = nullptr;
447     m_printContext = nullptr;
448     m_mainFrame->coreFrame()->loader()->detachFromParent();
449     m_page = nullptr;
450     m_drawingArea = nullptr;
451
452     bool isRunningModal = m_isRunningModal;
453     m_isRunningModal = false;
454
455     // The WebPage can be destroyed by this call.
456     WebProcess::shared().removeWebPage(m_pageID);
457
458     if (isRunningModal)
459         WebProcess::shared().runLoop()->stop();
460 }
461
462 void WebPage::tryClose()
463 {
464     SendStopResponsivenessTimer stopper(this);
465
466     if (!m_mainFrame->coreFrame()->loader()->shouldClose()) {
467         send(Messages::WebPageProxy::StopResponsivenessTimer());
468         return;
469     }
470
471     send(Messages::WebPageProxy::ClosePage(true));
472 }
473
474 void WebPage::sendClose()
475 {
476     send(Messages::WebPageProxy::ClosePage(false));
477 }
478
479 void WebPage::loadURL(const String& url, const SandboxExtension::Handle& sandboxExtensionHandle)
480 {
481     loadURLRequest(ResourceRequest(KURL(KURL(), url)), sandboxExtensionHandle);
482 }
483
484 void WebPage::loadURLRequest(const ResourceRequest& request, const SandboxExtension::Handle& sandboxExtensionHandle)
485 {
486     SendStopResponsivenessTimer stopper(this);
487
488     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
489     m_mainFrame->coreFrame()->loader()->load(request, false);
490 }
491
492 void WebPage::loadData(PassRefPtr<SharedBuffer> sharedBuffer, const String& MIMEType, const String& encodingName, const KURL& baseURL, const KURL& unreachableURL)
493 {
494     SendStopResponsivenessTimer stopper(this);
495
496     ResourceRequest request(baseURL);
497     SubstituteData substituteData(sharedBuffer, MIMEType, encodingName, unreachableURL);
498     m_mainFrame->coreFrame()->loader()->load(request, substituteData, false);
499 }
500
501 void WebPage::loadHTMLString(const String& htmlString, const String& baseURLString)
502 {
503     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
504     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
505     loadData(sharedBuffer, "text/html", "utf-16", baseURL, KURL());
506 }
507
508 void WebPage::loadAlternateHTMLString(const String& htmlString, const String& baseURLString, const String& unreachableURLString)
509 {
510     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(htmlString.characters()), htmlString.length() * sizeof(UChar));
511     KURL baseURL = baseURLString.isEmpty() ? blankURL() : KURL(KURL(), baseURLString);
512     KURL unreachableURL = unreachableURLString.isEmpty() ? KURL() : KURL(KURL(), unreachableURLString);
513     loadData(sharedBuffer, "text/html", "utf-16", baseURL, unreachableURL);
514 }
515
516 void WebPage::loadPlainTextString(const String& string)
517 {
518     RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(reinterpret_cast<const char*>(string.characters()), string.length() * sizeof(UChar));
519     loadData(sharedBuffer, "text/plain", "utf-16", blankURL(), KURL());
520 }
521
522 void WebPage::linkClicked(const String& url, const WebMouseEvent& event)
523 {
524     Frame* frame = m_page->mainFrame();
525     if (!frame)
526         return;
527
528     RefPtr<Event> coreEvent;
529     if (event.type() != WebEvent::NoType)
530         coreEvent = MouseEvent::create(eventNames().clickEvent, frame->document()->defaultView(), platform(event), 0, 0);
531
532     frame->loader()->loadFrameRequest(FrameLoadRequest(frame->document()->securityOrigin(), ResourceRequest(url)), 
533         false, false, coreEvent.get(), 0, SendReferrer);
534 }
535
536 void WebPage::stopLoadingFrame(uint64_t frameID)
537 {
538     WebFrame* frame = WebProcess::shared().webFrame(frameID);
539     if (!frame)
540         return;
541
542     frame->coreFrame()->loader()->stopForUserCancel();
543 }
544
545 void WebPage::stopLoading()
546 {
547     SendStopResponsivenessTimer stopper(this);
548
549     m_mainFrame->coreFrame()->loader()->stopForUserCancel();
550 }
551
552 void WebPage::setDefersLoading(bool defersLoading)
553 {
554     m_page->setDefersLoading(defersLoading);
555 }
556
557 void WebPage::reload(bool reloadFromOrigin)
558 {
559     SendStopResponsivenessTimer stopper(this);
560
561     m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
562 }
563
564 void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
565 {
566     SendStopResponsivenessTimer stopper(this);
567
568     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
569     ASSERT(item);
570     if (!item)
571         return;
572
573     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
574     m_page->goToItem(item, FrameLoadTypeForward);
575 }
576
577 void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
578 {
579     SendStopResponsivenessTimer stopper(this);
580
581     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
582     ASSERT(item);
583     if (!item)
584         return;
585
586     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
587     m_page->goToItem(item, FrameLoadTypeBack);
588 }
589
590 void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
591 {
592     SendStopResponsivenessTimer stopper(this);
593
594     HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
595     ASSERT(item);
596     if (!item)
597         return;
598
599     m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
600     m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
601 }
602
603 void WebPage::tryRestoreScrollPosition()
604 {
605     m_page->mainFrame()->loader()->history()->restoreScrollPositionAndViewState();
606 }
607
608 void WebPage::layoutIfNeeded()
609 {
610     if (m_mainFrame->coreFrame()->view())
611         m_mainFrame->coreFrame()->view()->updateLayoutAndStyleIfNeededRecursive();
612
613     if (m_underlayPage) {
614         if (FrameView *frameView = m_underlayPage->mainFrame()->coreFrame()->view())
615             frameView->updateLayoutAndStyleIfNeededRecursive();
616     }
617 }
618
619 void WebPage::setSize(const WebCore::IntSize& viewSize)
620 {
621 #if ENABLE(TILED_BACKING_STORE)
622     // If we are resizing to content ignore external attempts.
623     if (!m_resizesToContentsLayoutSize.isEmpty())
624         return;
625 #endif
626
627     if (m_viewSize == viewSize)
628         return;
629
630     Frame* frame = m_page->mainFrame();
631     
632     frame->view()->resize(viewSize);
633     frame->view()->setNeedsLayout();
634     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), viewSize));
635     
636     m_viewSize = viewSize;
637 }
638
639 #if ENABLE(TILED_BACKING_STORE)
640 void WebPage::setActualVisibleContentRect(const IntRect& rect)
641 {
642     Frame* frame = m_page->mainFrame();
643
644     frame->view()->setActualVisibleContentRect(rect);
645 }
646
647 void WebPage::setResizesToContentsUsingLayoutSize(const IntSize& targetLayoutSize)
648 {
649     if (m_resizesToContentsLayoutSize == targetLayoutSize)
650         return;
651
652     m_resizesToContentsLayoutSize = targetLayoutSize;
653
654     Frame* frame = m_page->mainFrame();
655     if (m_resizesToContentsLayoutSize.isEmpty()) {
656         frame->view()->setDelegatesScrolling(false);
657         frame->view()->setUseFixedLayout(false);
658         frame->view()->setPaintsEntireContents(false);
659     } else {
660         frame->view()->setDelegatesScrolling(true);
661         frame->view()->setUseFixedLayout(true);
662         frame->view()->setPaintsEntireContents(true);
663         frame->view()->setFixedLayoutSize(m_resizesToContentsLayoutSize);
664     }
665     frame->view()->forceLayout();
666 }
667
668 void WebPage::resizeToContentsIfNeeded()
669 {
670     if (m_resizesToContentsLayoutSize.isEmpty())
671         return;
672
673     Frame* frame = m_page->mainFrame();
674
675     IntSize contentSize = frame->view()->contentsSize();
676     if (contentSize == m_viewSize)
677         return;
678
679     m_viewSize = contentSize;
680     frame->view()->resize(m_viewSize);
681     frame->view()->setNeedsLayout();
682 }
683 #endif
684
685 void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
686 {
687     Frame* frame = m_page->mainFrame();
688
689     IntPoint scrollPosition = frame->view()->scrollPosition();
690     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
691
692     // If the current scroll position in a direction is the max scroll position 
693     // we don't want to scroll at all.
694     IntSize newScrollOffset;
695     if (scrollPosition.x() < maximumScrollPosition.x())
696         newScrollOffset.setWidth(scrollOffset.width());
697     if (scrollPosition.y() < maximumScrollPosition.y())
698         newScrollOffset.setHeight(scrollOffset.height());
699
700     if (newScrollOffset.isZero())
701         return;
702
703     frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset);
704 }
705
706 void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
707 {
708     GraphicsContextStateSaver stateSaver(graphicsContext);
709     graphicsContext.clip(rect);
710
711     if (m_underlayPage) {
712         m_underlayPage->drawRect(graphicsContext, rect);
713
714         graphicsContext.beginTransparencyLayer(1);
715         m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
716         graphicsContext.endTransparencyLayer();
717         return;
718     }
719
720     m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
721 }
722
723 void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect)
724 {
725     ASSERT(m_pageOverlay);
726
727     GraphicsContextStateSaver stateSaver(graphicsContext);
728     graphicsContext.clip(rect);
729     m_pageOverlay->drawRect(graphicsContext, rect);
730 }
731
732 double WebPage::textZoomFactor() const
733 {
734     Frame* frame = m_mainFrame->coreFrame();
735     if (!frame)
736         return 1;
737     return frame->textZoomFactor();
738 }
739
740 void WebPage::setTextZoomFactor(double zoomFactor)
741 {
742     Frame* frame = m_mainFrame->coreFrame();
743     if (!frame)
744         return;
745     frame->setTextZoomFactor(static_cast<float>(zoomFactor));
746 }
747
748 double WebPage::pageZoomFactor() const
749 {
750     Frame* frame = m_mainFrame->coreFrame();
751     if (!frame)
752         return 1;
753     return frame->pageZoomFactor();
754 }
755
756 void WebPage::setPageZoomFactor(double zoomFactor)
757 {
758     Frame* frame = m_mainFrame->coreFrame();
759     if (!frame)
760         return;
761     frame->setPageZoomFactor(static_cast<float>(zoomFactor));
762 }
763
764 void WebPage::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
765 {
766     Frame* frame = m_mainFrame->coreFrame();
767     if (!frame)
768         return;
769     return frame->setPageAndTextZoomFactors(static_cast<float>(pageZoomFactor), static_cast<float>(textZoomFactor));
770 }
771
772 void WebPage::scaleWebView(double scale, const IntPoint& origin)
773 {
774     Frame* frame = m_mainFrame->coreFrame();
775     if (!frame)
776         return;
777     frame->scalePage(scale, origin);
778
779     send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
780 }
781
782 double WebPage::viewScaleFactor() const
783 {
784     Frame* frame = m_mainFrame->coreFrame();
785     if (!frame)
786         return 1;
787     return frame->pageScaleFactor();
788 }
789
790 void WebPage::setUseFixedLayout(bool fixed)
791 {
792     Frame* frame = m_mainFrame->coreFrame();
793     if (!frame)
794         return;
795
796     FrameView* view = frame->view();
797     if (!view)
798         return;
799
800     view->setUseFixedLayout(fixed);
801     if (!fixed)
802         view->setFixedLayoutSize(IntSize());
803 }
804
805 void WebPage::setFixedLayoutSize(const IntSize& size)
806 {
807     Frame* frame = m_mainFrame->coreFrame();
808     if (!frame)
809         return;
810     
811     FrameView* view = frame->view();
812     if (!view)
813         return;
814
815     view->setFixedLayoutSize(size);
816     view->forceLayout();
817 }
818
819 void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
820 {
821     bool shouldFadeIn = true;
822     
823     if (m_pageOverlay) {
824         m_pageOverlay->setPage(0);
825
826         if (pageOverlay) {
827             // We're installing a page overlay when a page overlay is already active.
828             // In this case we don't want to fade in the new overlay.
829             shouldFadeIn = false;
830         }
831     }
832
833     m_pageOverlay = pageOverlay;
834     m_pageOverlay->setPage(this);
835
836     if (shouldFadeIn)
837         m_pageOverlay->startFadeInAnimation();
838
839     m_drawingArea->didInstallPageOverlay();
840 #if PLATFORM(WIN)
841     send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(true));
842 #endif
843
844     m_pageOverlay->setNeedsDisplay();
845 }
846
847 void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay, bool fadeOut)
848 {
849     if (pageOverlay != m_pageOverlay)
850         return;
851
852     if (fadeOut) {
853         m_pageOverlay->startFadeOutAnimation();
854         return;
855     }
856
857     m_pageOverlay->setPage(0);
858     m_pageOverlay = nullptr;
859
860     m_drawingArea->didUninstallPageOverlay();
861 #if PLATFORM(WIN)
862     send(Messages::WebPageProxy::DidInstallOrUninstallPageOverlay(false));
863 #endif
864 }
865
866 PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
867 {
868     FrameView* frameView = m_mainFrame->coreFrame()->view();
869     if (!frameView)
870         return 0;
871
872     frameView->updateLayoutAndStyleIfNeededRecursive();
873
874     PaintBehavior oldBehavior = frameView->paintBehavior();
875     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
876
877     RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options);
878     if (!snapshot->bitmap())
879         return 0;
880     
881     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
882
883     graphicsContext->save();
884     graphicsContext->translate(-rect.x(), -rect.y());
885     frameView->paint(graphicsContext.get(), rect);
886     graphicsContext->restore();
887
888     frameView->setPaintBehavior(oldBehavior);
889
890     return snapshot.release();
891 }
892
893 PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
894 {
895     FrameView* frameView = m_mainFrame->coreFrame()->view();
896     if (!frameView)
897         return 0;
898
899     frameView->updateLayoutAndStyleIfNeededRecursive();
900
901     PaintBehavior oldBehavior = frameView->paintBehavior();
902     frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
903
904     bool scale = scaleFactor != 1;
905     IntSize size = rect.size();
906     if (scale) 
907         size = IntSize(ceil(rect.width() * scaleFactor), ceil(rect.height() * scaleFactor));
908
909     RefPtr<WebImage> snapshot = WebImage::create(size, options);
910     if (!snapshot->bitmap())
911         return 0;
912     
913     OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
914     graphicsContext->save();
915     
916     if (scale)
917         graphicsContext->scale(FloatSize(scaleFactor, scaleFactor));
918     
919     graphicsContext->translate(-rect.x(), -rect.y());
920     frameView->paintContents(graphicsContext.get(), rect);
921     graphicsContext->restore();
922
923     frameView->setPaintBehavior(oldBehavior);
924
925     return snapshot.release();
926 }
927
928 PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
929 {
930     return scaledSnapshotInDocumentCoordinates(rect, 1, options);
931 }
932
933 void WebPage::createSnapshotOfVisibleContent(ShareableBitmap::Handle& snapshotHandle)
934 {
935     FrameView* frameView = m_mainFrame->coreFrame()->view();
936     if (!frameView)
937         return;
938     
939     IntRect contentRect = frameView->visibleContentRect(false);
940     RefPtr<WebImage> snapshotImage = scaledSnapshotInDocumentCoordinates(contentRect, 1, ImageOptionsShareable);
941     if (!snapshotImage->bitmap())
942         return;
943     
944     snapshotImage->bitmap()->createHandle(snapshotHandle);
945 }
946
947 void WebPage::pageDidScroll()
948 {
949     // Hide the find indicator.
950     m_findController.hideFindIndicator();
951
952     m_uiClient.pageDidScroll(this);
953
954     send(Messages::WebPageProxy::PageDidScroll());
955 }
956
957 #if ENABLE(TILED_BACKING_STORE)
958 void WebPage::pageDidRequestScroll(const IntPoint& point)
959 {
960     send(Messages::WebPageProxy::PageDidRequestScroll(point));
961 }
962 #endif
963
964 WebContextMenu* WebPage::contextMenu()
965 {
966     if (!m_contextMenu)
967         m_contextMenu = WebContextMenu::create(this);
968     return m_contextMenu.get();
969 }
970
971 // Events 
972
973 static const WebEvent* g_currentEvent = 0;
974
975 // FIXME: WebPage::currentEvent is used by the plug-in code to avoid having to convert from DOM events back to
976 // WebEvents. When we get the event handling sorted out, this should go away and the Widgets should get the correct
977 // platform events passed to the event handler code.
978 const WebEvent* WebPage::currentEvent()
979 {
980     return g_currentEvent;
981 }
982
983 class CurrentEvent {
984 public:
985     explicit CurrentEvent(const WebEvent& event)
986         : m_previousCurrentEvent(g_currentEvent)
987     {
988         g_currentEvent = &event;
989     }
990
991     ~CurrentEvent()
992     {
993         g_currentEvent = m_previousCurrentEvent;
994     }
995
996 private:
997     const WebEvent* m_previousCurrentEvent;
998 };
999
1000 static bool isContextClick(const PlatformMouseEvent& event)
1001 {
1002     if (event.button() == WebCore::RightButton)
1003         return true;
1004
1005 #if PLATFORM(MAC)
1006     // FIXME: this really should be about OSX-style UI, not about the Mac port
1007     if (event.button() == WebCore::LeftButton && event.ctrlKey())
1008         return true;
1009 #endif
1010
1011     return false;
1012 }
1013
1014 static bool handleContextMenuEvent(const PlatformMouseEvent& platformMouseEvent, Page* page)
1015 {
1016     IntPoint point = page->mainFrame()->view()->windowToContents(platformMouseEvent.pos());
1017     HitTestResult result = page->mainFrame()->eventHandler()->hitTestResultAtPoint(point, false);
1018
1019     Frame* frame = page->mainFrame();
1020     if (result.innerNonSharedNode())
1021         frame = result.innerNonSharedNode()->document()->frame();
1022     
1023     bool handled = frame->eventHandler()->sendContextMenuEvent(platformMouseEvent);
1024     if (handled)
1025         page->chrome()->showContextMenu();
1026
1027     return handled;
1028 }
1029
1030 static bool handleMouseEvent(const WebMouseEvent& mouseEvent, Page* page)
1031 {
1032     Frame* frame = page->mainFrame();
1033     if (!frame->view())
1034         return false;
1035
1036     PlatformMouseEvent platformMouseEvent = platform(mouseEvent);
1037
1038     switch (platformMouseEvent.eventType()) {
1039         case WebCore::MouseEventPressed:
1040         {
1041             if (isContextClick(platformMouseEvent))
1042                 page->contextMenuController()->clearContextMenu();
1043             
1044             bool handled = frame->eventHandler()->handleMousePressEvent(platformMouseEvent);
1045             if (isContextClick(platformMouseEvent))
1046                 handled = handleContextMenuEvent(platformMouseEvent, page);
1047
1048             return handled;
1049         }
1050         case WebCore::MouseEventReleased:
1051             return frame->eventHandler()->handleMouseReleaseEvent(platformMouseEvent);
1052         case WebCore::MouseEventMoved:
1053             return frame->eventHandler()->mouseMoved(platformMouseEvent);
1054
1055         default:
1056             ASSERT_NOT_REACHED();
1057             return false;
1058     }
1059 }
1060
1061 void WebPage::mouseEvent(const WebMouseEvent& mouseEvent)
1062 {
1063     // Don't try to handle any pending mouse events if a context menu is showing.
1064     if (m_isShowingContextMenu) {
1065         send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), false));
1066         return;
1067     }
1068     
1069     bool handled = false;
1070     
1071     if (m_pageOverlay) {
1072         // Let the page overlay handle the event.
1073         handled = m_pageOverlay->mouseEvent(mouseEvent);
1074     }
1075
1076     if (!handled) {
1077         CurrentEvent currentEvent(mouseEvent);
1078
1079         handled = handleMouseEvent(mouseEvent, m_page.get());
1080     }
1081
1082     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(mouseEvent.type()), handled));
1083 }
1084
1085 static bool handleWheelEvent(const WebWheelEvent& wheelEvent, Page* page)
1086 {
1087     Frame* frame = page->mainFrame();
1088     if (!frame->view())
1089         return false;
1090
1091     PlatformWheelEvent platformWheelEvent = platform(wheelEvent);
1092     return frame->eventHandler()->handleWheelEvent(platformWheelEvent);
1093 }
1094
1095 void WebPage::wheelEvent(const WebWheelEvent& wheelEvent)
1096 {
1097     CurrentEvent currentEvent(wheelEvent);
1098
1099 #if PLATFORM(MAC)
1100     if (wheelEvent.momentumPhase() == WebWheelEvent::PhaseBegan || wheelEvent.phase() == WebWheelEvent::PhaseBegan)
1101         m_drawingArea->disableDisplayThrottling();
1102     else if (wheelEvent.momentumPhase() == WebWheelEvent::PhaseEnded || wheelEvent.phase() == WebWheelEvent::PhaseEnded)
1103         m_drawingArea->enableDisplayThrottling();
1104 #endif
1105
1106     bool handled = handleWheelEvent(wheelEvent, m_page.get());
1107     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(wheelEvent.type()), handled));
1108 }
1109
1110 static bool handleKeyEvent(const WebKeyboardEvent& keyboardEvent, Page* page)
1111 {
1112     if (!page->mainFrame()->view())
1113         return false;
1114
1115     if (keyboardEvent.type() == WebEvent::Char && keyboardEvent.isSystemKey())
1116         return page->focusController()->focusedOrMainFrame()->eventHandler()->handleAccessKey(platform(keyboardEvent));
1117     return page->focusController()->focusedOrMainFrame()->eventHandler()->keyEvent(platform(keyboardEvent));
1118 }
1119
1120 void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
1121 {
1122     CurrentEvent currentEvent(keyboardEvent);
1123
1124     bool handled = handleKeyEvent(keyboardEvent, m_page.get());
1125     // FIXME: Platform default behaviors should be performed during normal DOM event dispatch (in most cases, in default keydown event handler).
1126     if (!handled)
1127         handled = performDefaultBehaviorForKeyEvent(keyboardEvent);
1128
1129     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
1130 }
1131
1132 #if ENABLE(GESTURE_EVENTS)
1133 static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page)
1134 {
1135     Frame* frame = page->mainFrame();
1136     if (!frame->view())
1137         return false;
1138
1139     PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
1140     return frame->eventHandler()->handleGestureEvent(platformGestureEvent);
1141 }
1142
1143 void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
1144 {
1145     CurrentEvent currentEvent(gestureEvent);
1146
1147     bool handled = handleGestureEvent(gestureEvent, m_page.get());
1148     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
1149 }
1150 #endif
1151
1152 void WebPage::validateCommand(const String& commandName, uint64_t callbackID)
1153 {
1154     bool isEnabled = false;
1155     int32_t state = 0;
1156     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1157     if (frame) {
1158         Editor::Command command = frame->editor()->command(commandName);
1159         state = command.state();
1160         isEnabled = command.isSupported() && command.isEnabled();
1161     }
1162
1163     send(Messages::WebPageProxy::ValidateCommandCallback(commandName, isEnabled, state, callbackID));
1164 }
1165
1166 void WebPage::executeEditCommand(const String& commandName)
1167 {
1168     executeEditingCommand(commandName, String());
1169 }
1170
1171 uint64_t WebPage::restoreSession(const SessionState& sessionState)
1172 {
1173     const BackForwardListItemVector& list = sessionState.list();
1174     size_t size = list.size();
1175     uint64_t currentItemID = 0;
1176     for (size_t i = 0; i < size; ++i) {
1177         WebBackForwardListItem* webItem = list[i].get();
1178         DecoderAdapter decoder(webItem->backForwardData().data(), webItem->backForwardData().size());
1179         
1180         RefPtr<HistoryItem> item = HistoryItem::decodeBackForwardTree(webItem->url(), webItem->title(), webItem->originalURL(), decoder);
1181         if (!item) {
1182             LOG_ERROR("Failed to decode a HistoryItem from session state data.");
1183             return 0;
1184         }
1185         
1186         if (i == sessionState.currentIndex())
1187             currentItemID = webItem->itemID();
1188         
1189         WebBackForwardListProxy::addItemFromUIProcess(list[i]->itemID(), item.release());
1190     }    
1191     ASSERT(currentItemID);
1192     return currentItemID;
1193 }
1194
1195 void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState, const SandboxExtension::Handle& sandboxExtensionHandle)
1196 {
1197     if (uint64_t currentItemID = restoreSession(sessionState))
1198         goToBackForwardItem(currentItemID, sandboxExtensionHandle);
1199 }
1200
1201 #if ENABLE(TOUCH_EVENTS)
1202 static bool handleTouchEvent(const WebTouchEvent& touchEvent, Page* page)
1203 {
1204     Frame* frame = page->mainFrame();
1205     if (!frame->view())
1206         return false;
1207
1208     return frame->eventHandler()->handleTouchEvent(platform(touchEvent));
1209 }
1210
1211 void WebPage::touchEvent(const WebTouchEvent& touchEvent)
1212 {
1213     CurrentEvent currentEvent(touchEvent);
1214
1215     bool handled = handleTouchEvent(touchEvent, m_page.get());
1216
1217     send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(touchEvent.type()), handled));
1218 }
1219 #endif
1220
1221 void WebPage::scroll(Page* page, ScrollDirection direction, ScrollGranularity granularity)
1222 {
1223     page->focusController()->focusedOrMainFrame()->eventHandler()->scrollRecursively(direction, granularity);
1224 }
1225
1226 void WebPage::logicalScroll(Page* page, ScrollLogicalDirection direction, ScrollGranularity granularity)
1227 {
1228     page->focusController()->focusedOrMainFrame()->eventHandler()->logicalScrollRecursively(direction, granularity);
1229 }
1230
1231 void WebPage::scrollBy(uint32_t scrollDirection, uint32_t scrollGranularity)
1232 {
1233     scroll(m_page.get(), static_cast<ScrollDirection>(scrollDirection), static_cast<ScrollGranularity>(scrollGranularity));
1234 }
1235
1236 void WebPage::setActive(bool isActive)
1237 {
1238     m_page->focusController()->setActive(isActive);
1239
1240 #if PLATFORM(MAC)    
1241     // Tell all our plug-in views that the window focus changed.
1242     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1243         (*it)->setWindowIsFocused(isActive);
1244 #endif
1245 }
1246
1247 void WebPage::setDrawsBackground(bool drawsBackground)
1248 {
1249     if (m_drawsBackground == drawsBackground)
1250         return;
1251
1252     m_drawsBackground = drawsBackground;
1253
1254     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1255         if (FrameView* view = coreFrame->view())
1256             view->setTransparent(!drawsBackground);
1257     }
1258
1259     m_drawingArea->pageBackgroundTransparencyChanged();
1260     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1261 }
1262
1263 void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
1264 {
1265     if (m_drawsTransparentBackground == drawsTransparentBackground)
1266         return;
1267
1268     m_drawsTransparentBackground = drawsTransparentBackground;
1269
1270     Color backgroundColor = drawsTransparentBackground ? Color::transparent : Color::white;
1271     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1272         if (FrameView* view = coreFrame->view())
1273             view->setBaseBackgroundColor(backgroundColor);
1274     }
1275
1276     m_drawingArea->pageBackgroundTransparencyChanged();
1277     m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
1278 }
1279
1280 void WebPage::viewWillStartLiveResize()
1281 {
1282     if (!m_page)
1283         return;
1284
1285     // FIXME: This should propagate to all ScrollableAreas.
1286     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1287         if (FrameView* view = frame->view())
1288             view->willStartLiveResize();
1289     }
1290 }
1291
1292 void WebPage::viewWillEndLiveResize()
1293 {
1294     if (!m_page)
1295         return;
1296
1297     // FIXME: This should propagate to all ScrollableAreas.
1298     if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
1299         if (FrameView* view = frame->view())
1300             view->willEndLiveResize();
1301     }
1302 }
1303
1304 void WebPage::setFocused(bool isFocused)
1305 {
1306     m_page->focusController()->setFocused(isFocused);
1307 }
1308
1309 void WebPage::setInitialFocus(bool forward)
1310 {
1311     if (!m_page || !m_page->focusController())
1312         return;
1313
1314     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1315     frame->document()->setFocusedNode(0);
1316     m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
1317 }
1318
1319 void WebPage::setWindowResizerSize(const IntSize& windowResizerSize)
1320 {
1321     if (m_windowResizerSize == windowResizerSize)
1322         return;
1323
1324     m_windowResizerSize = windowResizerSize;
1325
1326     for (Frame* coreFrame = m_mainFrame->coreFrame(); coreFrame; coreFrame = coreFrame->tree()->traverseNext()) {
1327         FrameView* view = coreFrame->view();
1328         if (view)
1329             view->windowResizerRectChanged();
1330     }
1331 }
1332
1333 void WebPage::setCanStartMediaTimerFired()
1334 {
1335     if (m_page)
1336         m_page->setCanStartMedia(true);
1337 }
1338
1339 void WebPage::setIsInWindow(bool isInWindow)
1340 {
1341     if (!isInWindow) {
1342         m_setCanStartMediaTimer.stop();
1343         m_page->setCanStartMedia(false);
1344         m_page->willMoveOffscreen();
1345     } else {
1346         // Defer the call to Page::setCanStartMedia() since it ends up sending a syncrhonous messages to the UI process
1347         // in order to get plug-in connections, and the UI process will be waiting for the Web process to update the backing
1348         // store after moving the view into a window, until it times out and paints white. See <rdar://problem/9242771>.
1349         m_setCanStartMediaTimer.startOneShot(0);
1350         m_page->didMoveOnscreen();
1351     }
1352 }
1353
1354 void WebPage::didReceivePolicyDecision(uint64_t frameID, uint64_t listenerID, uint32_t policyAction, uint64_t downloadID)
1355 {
1356     WebFrame* frame = WebProcess::shared().webFrame(frameID);
1357     if (!frame)
1358         return;
1359     frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
1360 }
1361
1362 void WebPage::show()
1363 {
1364     send(Messages::WebPageProxy::ShowPage());
1365 }
1366
1367 void WebPage::setUserAgent(const String& userAgent)
1368 {
1369     m_userAgent = userAgent;
1370 }
1371   
1372 IntPoint WebPage::screenToWindow(const IntPoint& point)
1373 {
1374     IntPoint windowPoint;
1375     sendSync(Messages::WebPageProxy::ScreenToWindow(point), Messages::WebPageProxy::ScreenToWindow::Reply(windowPoint));
1376     return windowPoint;
1377 }
1378     
1379 IntRect WebPage::windowToScreen(const IntRect& rect)
1380 {
1381     IntRect screenRect;
1382     sendSync(Messages::WebPageProxy::WindowToScreen(rect), Messages::WebPageProxy::WindowToScreen::Reply(screenRect));
1383     return screenRect;
1384 }
1385
1386 IntRect WebPage::windowResizerRect() const
1387 {
1388     if (m_windowResizerSize.isEmpty())
1389         return IntRect();
1390
1391     IntSize frameViewSize;
1392     if (Frame* coreFrame = m_mainFrame->coreFrame()) {
1393         if (FrameView* view = coreFrame->view())
1394             frameViewSize = view->size();
1395     }
1396
1397     return IntRect(frameViewSize.width() - m_windowResizerSize.width(), frameViewSize.height() - m_windowResizerSize.height(), 
1398                    m_windowResizerSize.width(), m_windowResizerSize.height());
1399 }
1400
1401 KeyboardUIMode WebPage::keyboardUIMode()
1402 {
1403     bool fullKeyboardAccessEnabled = WebProcess::shared().fullKeyboardAccessEnabled();
1404     return static_cast<KeyboardUIMode>((fullKeyboardAccessEnabled ? KeyboardAccessFull : KeyboardAccessDefault) | (m_tabToLinks ? KeyboardAccessTabsToLinks : 0));
1405 }
1406
1407 void WebPage::runJavaScriptInMainFrame(const String& script, uint64_t callbackID)
1408 {
1409     // NOTE: We need to be careful when running scripts that the objects we depend on don't
1410     // disappear during script execution.
1411
1412     // Retain the SerializedScriptValue at this level so it (and the internal data) lives
1413     // long enough for the DataReference to be encoded by the sent message.
1414     RefPtr<SerializedScriptValue> serializedResultValue;
1415     CoreIPC::DataReference dataReference;
1416
1417     JSLock lock(SilenceAssertionsOnly);
1418     if (JSValue resultValue = m_mainFrame->coreFrame()->script()->executeScript(script, true).jsValue()) {
1419         if ((serializedResultValue = SerializedScriptValue::create(m_mainFrame->jsContext(), 
1420             toRef(m_mainFrame->coreFrame()->script()->globalObject(mainThreadNormalWorld())->globalExec(), resultValue), 0)))
1421             dataReference = CoreIPC::DataReference(serializedResultValue->data().data(), serializedResultValue->data().size());
1422     }
1423
1424     send(Messages::WebPageProxy::ScriptValueCallback(dataReference, callbackID));
1425 }
1426
1427 void WebPage::getContentsAsString(uint64_t callbackID)
1428 {
1429     String resultString = m_mainFrame->contentsAsString();
1430     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1431 }
1432
1433 void WebPage::getRenderTreeExternalRepresentation(uint64_t callbackID)
1434 {
1435     String resultString = renderTreeExternalRepresentation();
1436     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1437 }
1438
1439 void WebPage::getSelectionOrContentsAsString(uint64_t callbackID)
1440 {
1441     String resultString = m_mainFrame->selectionAsString();
1442     if (resultString.isEmpty())
1443         resultString = m_mainFrame->contentsAsString();
1444     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1445 }
1446
1447 void WebPage::getSourceForFrame(uint64_t frameID, uint64_t callbackID)
1448 {
1449     String resultString;
1450     if (WebFrame* frame = WebProcess::shared().webFrame(frameID))
1451        resultString = frame->source();
1452
1453     send(Messages::WebPageProxy::StringCallback(resultString, callbackID));
1454 }
1455
1456 void WebPage::getMainResourceDataOfFrame(uint64_t frameID, uint64_t callbackID)
1457 {
1458     CoreIPC::DataReference dataReference;
1459
1460     RefPtr<SharedBuffer> buffer;
1461     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1462         if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
1463             if ((buffer = loader->mainResourceData()))
1464                 dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1465         }
1466     }
1467
1468     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1469 }
1470
1471 static PassRefPtr<SharedBuffer> resourceDataForFrame(Frame* frame, const KURL& resourceURL)
1472 {
1473     DocumentLoader* loader = frame->loader()->documentLoader();
1474     if (!loader)
1475         return 0;
1476
1477     RefPtr<ArchiveResource> subresource = loader->subresource(resourceURL);
1478     if (!subresource)
1479         return 0;
1480
1481     return subresource->data();
1482 }
1483
1484 void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceURLString, uint64_t callbackID)
1485 {
1486     CoreIPC::DataReference dataReference;
1487     KURL resourceURL(KURL(), resourceURLString);
1488
1489     RefPtr<SharedBuffer> buffer;
1490     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1491         buffer = resourceDataForFrame(frame->coreFrame(), resourceURL);
1492         if (!buffer) {
1493             // Try to get the resource data from the cache.
1494             buffer = cachedResponseDataForURL(resourceURL);
1495         }
1496
1497         if (buffer)
1498             dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
1499     }
1500
1501     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1502 }
1503
1504 void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
1505 {
1506     CoreIPC::DataReference dataReference;
1507
1508 #if PLATFORM(MAC) || PLATFORM(WIN)
1509     RetainPtr<CFDataRef> data;
1510     if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
1511         if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(frame->coreFrame()->document())) {
1512             if ((data = archive->rawDataRepresentation()))
1513                 dataReference = CoreIPC::DataReference(CFDataGetBytePtr(data.get()), CFDataGetLength(data.get()));
1514         }
1515     }
1516 #endif
1517
1518     send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
1519 }
1520
1521 void WebPage::forceRepaintWithoutCallback()
1522 {
1523     m_drawingArea->forceRepaint();
1524 }
1525
1526 void WebPage::forceRepaint(uint64_t callbackID)
1527 {
1528     forceRepaintWithoutCallback();
1529     send(Messages::WebPageProxy::VoidCallback(callbackID));
1530 }
1531
1532 void WebPage::preferencesDidChange(const WebPreferencesStore& store)
1533 {
1534     WebPreferencesStore::removeTestRunnerOverrides();
1535     updatePreferences(store);
1536 }
1537
1538 void WebPage::updatePreferences(const WebPreferencesStore& store)
1539 {
1540     Settings* settings = m_page->settings();
1541
1542     m_tabToLinks = store.getBoolValueForKey(WebPreferencesKey::tabsToLinksKey());
1543
1544     // FIXME: This should be generated from macro expansion for all preferences,
1545     // but we currently don't match the naming of WebCore exactly so we are
1546     // handrolling the boolean and integer preferences until that is fixed.
1547
1548 #define INITIALIZE_SETTINGS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) settings->set##KeyUpper(store.get##TypeName##ValueForKey(WebPreferencesKey::KeyLower##Key()));
1549
1550     FOR_EACH_WEBKIT_STRING_PREFERENCE(INITIALIZE_SETTINGS)
1551
1552 #undef INITIALIZE_SETTINGS
1553
1554     settings->setJavaScriptEnabled(store.getBoolValueForKey(WebPreferencesKey::javaScriptEnabledKey()));
1555     settings->setLoadsImagesAutomatically(store.getBoolValueForKey(WebPreferencesKey::loadsImagesAutomaticallyKey()));
1556     settings->setLoadsSiteIconsIgnoringImageLoadingSetting(store.getBoolValueForKey(WebPreferencesKey::loadsSiteIconsIgnoringImageLoadingPreferenceKey()));
1557     settings->setPluginsEnabled(store.getBoolValueForKey(WebPreferencesKey::pluginsEnabledKey()));
1558     settings->setJavaEnabled(store.getBoolValueForKey(WebPreferencesKey::javaEnabledKey()));
1559     settings->setOfflineWebApplicationCacheEnabled(store.getBoolValueForKey(WebPreferencesKey::offlineWebApplicationCacheEnabledKey()));
1560     settings->setLocalStorageEnabled(store.getBoolValueForKey(WebPreferencesKey::localStorageEnabledKey()));
1561     settings->setXSSAuditorEnabled(store.getBoolValueForKey(WebPreferencesKey::xssAuditorEnabledKey()));
1562     settings->setFrameFlatteningEnabled(store.getBoolValueForKey(WebPreferencesKey::frameFlatteningEnabledKey()));
1563     settings->setPrivateBrowsingEnabled(store.getBoolValueForKey(WebPreferencesKey::privateBrowsingEnabledKey()));
1564     settings->setDeveloperExtrasEnabled(store.getBoolValueForKey(WebPreferencesKey::developerExtrasEnabledKey()));
1565     settings->setTextAreasAreResizable(store.getBoolValueForKey(WebPreferencesKey::textAreasAreResizableKey()));
1566     settings->setNeedsSiteSpecificQuirks(store.getBoolValueForKey(WebPreferencesKey::needsSiteSpecificQuirksKey()));
1567     settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
1568     settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
1569     settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
1570 #if ENABLE(WEB_ARCHIVE)
1571     settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
1572 #endif
1573     settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
1574     settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
1575     settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
1576     settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
1577     settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
1578     settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
1579     settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
1580     settings->setWebSecurityEnabled(store.getBoolValueForKey(WebPreferencesKey::webSecurityEnabledKey()));
1581     settings->setAllowUniversalAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowUniversalAccessFromFileURLsKey()));
1582     settings->setAllowFileAccessFromFileURLs(store.getBoolValueForKey(WebPreferencesKey::allowFileAccessFromFileURLsKey()));
1583
1584     settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
1585     settings->setMinimumLogicalFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumLogicalFontSizeKey()));
1586     settings->setDefaultFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFontSizeKey()));
1587     settings->setDefaultFixedFontSize(store.getUInt32ValueForKey(WebPreferencesKey::defaultFixedFontSizeKey()));
1588     settings->setEditableLinkBehavior(static_cast<WebCore::EditableLinkBehavior>(store.getUInt32ValueForKey(WebPreferencesKey::editableLinkBehaviorKey())));
1589
1590     settings->setAcceleratedCompositingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedCompositingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1591     settings->setAcceleratedDrawingEnabled(store.getBoolValueForKey(WebPreferencesKey::acceleratedDrawingEnabledKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1592     settings->setCanvasUsesAcceleratedDrawing(store.getBoolValueForKey(WebPreferencesKey::canvasUsesAcceleratedDrawingKey()) && LayerTreeHost::supportsAcceleratedCompositing());
1593     settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
1594     settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
1595     settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
1596
1597 #if ENABLE(DATABASE)
1598     AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
1599 #endif
1600
1601 #if ENABLE(FULLSCREEN_API)
1602     settings->setFullScreenEnabled(store.getBoolValueForKey(WebPreferencesKey::fullScreenEnabledKey()));
1603 #endif
1604
1605 #if ENABLE(DOM_STORAGE)
1606     settings->setLocalStorageDatabasePath(WebProcess::shared().localStorageDirectory());
1607 #endif
1608
1609 #if USE(AVFOUNDATION)
1610     settings->setAVFoundationEnabled(store.getBoolValueForKey(WebPreferencesKey::isAVFoundationEnabledKey()));
1611 #endif
1612
1613     platformPreferencesDidChange(store);
1614 }
1615
1616 #if ENABLE(INSPECTOR)
1617 WebInspector* WebPage::inspector()
1618 {
1619     if (m_isClosed)
1620         return 0;
1621     if (!m_inspector)
1622         m_inspector = WebInspector::create(this);
1623     return m_inspector.get();
1624 }
1625 #endif
1626
1627 #if ENABLE(FULLSCREEN_API)
1628 WebFullScreenManager* WebPage::fullScreenManager()
1629 {
1630     if (!m_fullScreenManager)
1631         m_fullScreenManager = WebFullScreenManager::create(this);
1632     return m_fullScreenManager.get();
1633 }
1634 #endif
1635
1636 #if !PLATFORM(GTK) && !PLATFORM(MAC)
1637 bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
1638 {
1639     Node* node = evt->target()->toNode();
1640     ASSERT(node);
1641     Frame* frame = node->document()->frame();
1642     ASSERT(frame);
1643
1644     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
1645     if (!keyEvent)
1646         return false;
1647
1648     Editor::Command command = frame->editor()->command(interpretKeyEvent(evt));
1649
1650     if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
1651         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
1652         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
1653         // (e.g. Tab that inserts a Tab character, or Enter).
1654         return !command.isTextInsertion() && command.execute(evt);
1655     }
1656
1657     if (command.execute(evt))
1658         return true;
1659
1660     // Don't insert null or control characters as they can result in unexpected behaviour
1661     if (evt->charCode() < ' ')
1662         return false;
1663
1664     return frame->editor()->insertText(evt->keyEvent()->text(), evt);
1665 }
1666 #endif
1667
1668 #if PLATFORM(WIN)
1669 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
1670 {
1671     if (!m_page) {
1672         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
1673         return;
1674     }
1675
1676     DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
1677     switch (action) {
1678     case DragControllerActionEntered:
1679         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
1680         break;
1681
1682     case DragControllerActionUpdated:
1683         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
1684         break;
1685         
1686     case DragControllerActionExited:
1687         m_page->dragController()->dragExited(&dragData);
1688         break;
1689         
1690     case DragControllerActionPerformDrag:
1691         m_page->dragController()->performDrag(&dragData);
1692         break;
1693         
1694     default:
1695         ASSERT_NOT_REACHED();
1696     }
1697 }
1698 #else
1699 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)
1700 {
1701     if (!m_page) {
1702         send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
1703         return;
1704     }
1705
1706     DragData dragData(dragStorageName, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
1707     switch (action) {
1708     case DragControllerActionEntered:
1709         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
1710         break;
1711
1712     case DragControllerActionUpdated:
1713         send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
1714         break;
1715         
1716     case DragControllerActionExited:
1717         m_page->dragController()->dragExited(&dragData);
1718         break;
1719         
1720     case DragControllerActionPerformDrag: {
1721         ASSERT(!m_pendingDropSandboxExtension);
1722
1723         m_pendingDropSandboxExtension = SandboxExtension::create(sandboxExtensionHandle);
1724
1725         m_page->dragController()->performDrag(&dragData);
1726
1727         // If we started loading a local file, the sandbox extension tracker would have adopted this
1728         // pending drop sandbox extension. If not, we'll play it safe and invalidate it.
1729         if (m_pendingDropSandboxExtension) {
1730             m_pendingDropSandboxExtension->invalidate();
1731             m_pendingDropSandboxExtension = nullptr;
1732         }
1733
1734         break;
1735     }
1736
1737     default:
1738         ASSERT_NOT_REACHED();
1739     }
1740 }
1741 #endif
1742
1743 void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
1744 {
1745     IntPoint adjustedClientPosition(clientPosition.x() + m_page->dragController()->dragOffset().x(), clientPosition.y() + m_page->dragController()->dragOffset().y());
1746     IntPoint adjustedGlobalPosition(globalPosition.x() + m_page->dragController()->dragOffset().x(), globalPosition.y() + m_page->dragController()->dragOffset().y());
1747     
1748     platformDragEnded();
1749     m_page->dragController()->dragEnded();
1750     FrameView* view = m_page->mainFrame()->view();
1751     if (!view)
1752         return;
1753     // FIXME: These are fake modifier keys here, but they should be real ones instead.
1754     PlatformMouseEvent event(adjustedClientPosition, adjustedGlobalPosition, LeftButton, MouseEventMoved, 0, false, false, false, false, currentTime());
1755     m_page->mainFrame()->eventHandler()->dragSourceEndedAt(event, (DragOperation)operation);
1756 }
1757
1758 void WebPage::willPerformLoadDragDestinationAction()
1759 {
1760     m_sandboxExtensionTracker.willPerformLoadDragDestinationAction(m_pendingDropSandboxExtension.release());
1761 }
1762
1763 WebEditCommand* WebPage::webEditCommand(uint64_t commandID)
1764 {
1765     return m_editCommandMap.get(commandID).get();
1766 }
1767
1768 void WebPage::addWebEditCommand(uint64_t commandID, WebEditCommand* command)
1769 {
1770     m_editCommandMap.set(commandID, command);
1771 }
1772
1773 void WebPage::removeWebEditCommand(uint64_t commandID)
1774 {
1775     m_editCommandMap.remove(commandID);
1776 }
1777
1778 void WebPage::unapplyEditCommand(uint64_t commandID)
1779 {
1780     WebEditCommand* command = webEditCommand(commandID);
1781     if (!command)
1782         return;
1783
1784     command->command()->unapply();
1785 }
1786
1787 void WebPage::reapplyEditCommand(uint64_t commandID)
1788 {
1789     WebEditCommand* command = webEditCommand(commandID);
1790     if (!command)
1791         return;
1792
1793     m_isInRedo = true;
1794     command->command()->reapply();
1795     m_isInRedo = false;
1796 }
1797
1798 void WebPage::didRemoveEditCommand(uint64_t commandID)
1799 {
1800     removeWebEditCommand(commandID);
1801 }
1802
1803 void WebPage::setActivePopupMenu(WebPopupMenu* menu)
1804 {
1805     m_activePopupMenu = menu;
1806 }
1807
1808 void WebPage::setActiveOpenPanelResultListener(PassRefPtr<WebOpenPanelResultListener> openPanelResultListener)
1809 {
1810     m_activeOpenPanelResultListener = openPanelResultListener;
1811 }
1812
1813 bool WebPage::findStringFromInjectedBundle(const String& target, FindOptions options)
1814 {
1815     return m_page->findString(target, options);
1816 }
1817
1818 void WebPage::findString(const String& string, uint32_t options, uint32_t maxMatchCount)
1819 {
1820     m_findController.findString(string, static_cast<FindOptions>(options), maxMatchCount);
1821 }
1822
1823 void WebPage::hideFindUI()
1824 {
1825     m_findController.hideFindUI();
1826 }
1827
1828 void WebPage::countStringMatches(const String& string, uint32_t options, uint32_t maxMatchCount)
1829 {
1830     m_findController.countStringMatches(string, static_cast<FindOptions>(options), maxMatchCount);
1831 }
1832
1833 void WebPage::didChangeSelectedIndexForActivePopupMenu(int32_t newIndex)
1834 {
1835     if (!m_activePopupMenu)
1836         return;
1837
1838     m_activePopupMenu->didChangeSelectedIndex(newIndex);
1839     m_activePopupMenu = 0;
1840 }
1841
1842 void WebPage::didChooseFilesForOpenPanel(const Vector<String>& files)
1843 {
1844     if (!m_activeOpenPanelResultListener)
1845         return;
1846
1847     m_activeOpenPanelResultListener->didChooseFiles(files);
1848     m_activeOpenPanelResultListener = 0;
1849 }
1850
1851 void WebPage::didCancelForOpenPanel()
1852 {
1853     m_activeOpenPanelResultListener = 0;
1854 }
1855
1856 #if ENABLE(WEB_PROCESS_SANDBOX)
1857 void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
1858 {
1859     SandboxExtension::create(handle)->consumePermanently();
1860 }
1861 #endif
1862
1863 void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
1864 {
1865     m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
1866 }
1867
1868 void WebPage::advanceToNextMisspelling(bool startBeforeSelection)
1869 {
1870     Frame* frame = m_page->focusController()->focusedOrMainFrame();
1871     frame->editor()->advanceToNextMisspelling(startBeforeSelection);
1872 }
1873
1874 void WebPage::changeSpellingToWord(const String& word)
1875 {
1876     replaceSelectionWithText(m_page->focusController()->focusedOrMainFrame(), word);
1877 }
1878
1879 void WebPage::unmarkAllMisspellings()
1880 {
1881     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1882         if (Document* document = frame->document())
1883             document->markers()->removeMarkers(DocumentMarker::Spelling);
1884     }
1885 }
1886
1887 void WebPage::unmarkAllBadGrammar()
1888 {
1889     for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
1890         if (Document* document = frame->document())
1891             document->markers()->removeMarkers(DocumentMarker::Grammar);
1892     }
1893 }
1894
1895 #if PLATFORM(MAC)
1896 void WebPage::uppercaseWord()
1897 {
1898     m_page->focusController()->focusedOrMainFrame()->editor()->uppercaseWord();
1899 }
1900
1901 void WebPage::lowercaseWord()
1902 {
1903     m_page->focusController()->focusedOrMainFrame()->editor()->lowercaseWord();
1904 }
1905
1906 void WebPage::capitalizeWord()
1907 {
1908     m_page->focusController()->focusedOrMainFrame()->editor()->capitalizeWord();
1909 }
1910 #endif
1911     
1912 void WebPage::setTextForActivePopupMenu(int32_t index)
1913 {
1914     if (!m_activePopupMenu)
1915         return;
1916
1917     m_activePopupMenu->setTextForIndex(index);
1918 }
1919
1920 void WebPage::didSelectItemFromActiveContextMenu(const WebContextMenuItemData& item)
1921 {
1922     ASSERT(m_contextMenu);
1923     m_contextMenu->itemSelected(item);
1924     m_contextMenu = 0;
1925 }
1926
1927 void WebPage::replaceSelectionWithText(Frame* frame, const String& text)
1928 {
1929     if (frame->selection()->isNone())
1930         return;
1931
1932     RefPtr<DocumentFragment> textFragment = createFragmentFromText(frame->selection()->toNormalizedRange().get(), text);
1933     applyCommand(ReplaceSelectionCommand::create(frame->document(), textFragment.release(), ReplaceSelectionCommand::SelectReplacement | ReplaceSelectionCommand::MatchStyle | ReplaceSelectionCommand::PreventNesting));
1934     frame->selection()->revealSelection(ScrollAlignment::alignToEdgeIfNeeded);
1935 }
1936
1937 void WebPage::clearSelection()
1938 {
1939     m_page->focusController()->focusedOrMainFrame()->selection()->clear();
1940 }
1941
1942 bool WebPage::mainFrameHasCustomRepresentation() const
1943 {
1944     return static_cast<WebFrameLoaderClient*>(mainFrame()->coreFrame()->loader()->client())->frameHasCustomRepresentation();
1945 }
1946
1947 void WebPage::didChangeScrollOffsetForMainFrame()
1948 {
1949     Frame* frame = m_page->mainFrame();
1950     IntPoint scrollPosition = frame->view()->scrollPosition();
1951     IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
1952     IntPoint minimumScrollPosition = frame->view()->minimumScrollPosition();
1953
1954     bool isPinnedToLeftSide = (scrollPosition.x() <= minimumScrollPosition.x());
1955     bool isPinnedToRightSide = (scrollPosition.x() >= maximumScrollPosition.x());
1956
1957     if (isPinnedToLeftSide != m_cachedMainFrameIsPinnedToLeftSide || isPinnedToRightSide != m_cachedMainFrameIsPinnedToRightSide) {
1958         send(Messages::WebPageProxy::DidChangeScrollOffsetPinningForMainFrame(isPinnedToLeftSide, isPinnedToRightSide));
1959         
1960         m_cachedMainFrameIsPinnedToLeftSide = isPinnedToLeftSide;
1961         m_cachedMainFrameIsPinnedToRightSide = isPinnedToRightSide;
1962     }
1963 }
1964
1965 #if PLATFORM(MAC)
1966
1967 void WebPage::addPluginView(PluginView* pluginView)
1968 {
1969     ASSERT(!m_pluginViews.contains(pluginView));
1970
1971     m_pluginViews.add(pluginView);
1972 }
1973
1974 void WebPage::removePluginView(PluginView* pluginView)
1975 {
1976     ASSERT(m_pluginViews.contains(pluginView));
1977
1978     m_pluginViews.remove(pluginView);
1979 }
1980
1981 void WebPage::setWindowIsVisible(bool windowIsVisible)
1982 {
1983     m_windowIsVisible = windowIsVisible;
1984
1985     // Tell all our plug-in views that the window visibility changed.
1986     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1987         (*it)->setWindowIsVisible(windowIsVisible);
1988 }
1989
1990 void WebPage::windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates, const WebCore::IntPoint& accessibilityViewCoordinates)
1991 {
1992     m_windowFrameInScreenCoordinates = windowFrameInScreenCoordinates;
1993     m_viewFrameInWindowCoordinates = viewFrameInWindowCoordinates;
1994     m_accessibilityPosition = accessibilityViewCoordinates;
1995     
1996     // Tell all our plug-in views that the window and view frames have changed.
1997     for (HashSet<PluginView*>::const_iterator it = m_pluginViews.begin(), end = m_pluginViews.end(); it != end; ++it)
1998         (*it)->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates);
1999 }
2000
2001 #endif
2002
2003 bool WebPage::windowIsFocused() const
2004 {
2005 #if PLATFORM(MAC)
2006     if (!m_windowIsVisible)
2007         return false;
2008 #endif
2009     return m_page->focusController()->isFocused() && m_page->focusController()->isActive();
2010 }    
2011
2012 void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
2013 {
2014     if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
2015         if (m_drawingArea)
2016             m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments);
2017         return;
2018     }
2019     
2020 #if ENABLE(INSPECTOR)
2021     if (messageID.is<CoreIPC::MessageClassWebInspector>()) {
2022         if (WebInspector* inspector = this->inspector())
2023             inspector->didReceiveWebInspectorMessage(connection, messageID, arguments);
2024         return;
2025     }
2026 #endif
2027
2028 #if ENABLE(FULLSCREEN_API)
2029     if (messageID.is<CoreIPC::MessageClassWebFullScreenManager>()) {
2030         fullScreenManager()->didReceiveMessage(connection, messageID, arguments);
2031         return;
2032     }
2033 #endif
2034
2035     didReceiveWebPageMessage(connection, messageID, arguments);
2036 }
2037
2038 void WebPage::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply)
2039 {   
2040     didReceiveSyncWebPageMessage(connection, messageID, arguments, reply);
2041 }
2042     
2043 InjectedBundleBackForwardList* WebPage::backForwardList()
2044 {
2045     if (!m_backForwardList)
2046         m_backForwardList = InjectedBundleBackForwardList::create(this);
2047     return m_backForwardList.get();
2048 }
2049
2050 #if PLATFORM(QT)
2051 void WebPage::findZoomableAreaForPoint(const WebCore::IntPoint& point)
2052 {
2053     const int minimumZoomTargetWidth = 100;
2054
2055     Frame* mainframe = m_mainFrame->coreFrame();
2056     HitTestResult result = mainframe->eventHandler()->hitTestResultAtPoint(mainframe->view()->windowToContents(point), /*allowShadowContent*/ false, /*ignoreClipping*/ true);
2057
2058     Node* node = result.innerNode();
2059     while (node && node->getRect().width() < minimumZoomTargetWidth)
2060         node = node->parentNode();
2061
2062     IntRect zoomableArea;
2063     if (node)
2064         zoomableArea = node->getRect();
2065     send(Messages::WebPageProxy::DidFindZoomableArea(zoomableArea));
2066 }
2067 #endif
2068
2069 WebPage::SandboxExtensionTracker::~SandboxExtensionTracker()
2070 {
2071     invalidate();
2072 }
2073
2074 void WebPage::SandboxExtensionTracker::invalidate()
2075 {
2076     if (m_pendingProvisionalSandboxExtension) {
2077         m_pendingProvisionalSandboxExtension->invalidate();
2078         m_pendingProvisionalSandboxExtension = 0;
2079     }
2080
2081     if (m_provisionalSandboxExtension) {
2082         m_provisionalSandboxExtension->invalidate();
2083         m_provisionalSandboxExtension = 0;
2084     }
2085
2086     if (m_committedSandboxExtension) {
2087         m_committedSandboxExtension->invalidate();
2088         m_committedSandboxExtension = 0;
2089     }
2090 }
2091
2092 void WebPage::SandboxExtensionTracker::willPerformLoadDragDestinationAction(PassRefPtr<SandboxExtension> pendingDropSandboxExtension)
2093 {
2094     setPendingProvisionalSandboxExtension(pendingDropSandboxExtension);
2095 }
2096
2097 void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxExtension::Handle& handle)
2098 {
2099     ASSERT(frame->isMainFrame());
2100
2101     setPendingProvisionalSandboxExtension(SandboxExtension::create(handle));
2102 }
2103
2104 void WebPage::SandboxExtensionTracker::setPendingProvisionalSandboxExtension(PassRefPtr<SandboxExtension> pendingProvisionalSandboxExtension)
2105 {
2106     // If we get two beginLoad calls in succession, without a provisional load starting, then
2107     // m_pendingProvisionalSandboxExtension will be non-null. Invalidate and null out the extension if that is the case.
2108     if (m_pendingProvisionalSandboxExtension) {
2109         m_pendingProvisionalSandboxExtension->invalidate();
2110         m_pendingProvisionalSandboxExtension = nullptr;
2111     }
2112     
2113     m_pendingProvisionalSandboxExtension = pendingProvisionalSandboxExtension;    
2114 }
2115
2116 static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
2117 {
2118     ASSERT(frame->isMainFrame());
2119
2120     FrameLoader* frameLoader = frame->coreFrame()->loader();
2121     FrameLoadType frameLoadType = frameLoader->loadType();
2122
2123     // If the page is being reloaded, it should reuse whatever extension is committed.
2124     if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
2125         return true;
2126
2127     DocumentLoader* documentLoader = frameLoader->documentLoader();
2128     DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
2129     if (!documentLoader || !provisionalDocumentLoader)
2130         return false;
2131
2132     if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile())
2133         return true;
2134
2135     return false;
2136 }
2137
2138 void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
2139 {
2140     if (!frame->isMainFrame())
2141         return;
2142
2143     // We should only reuse the commited sandbox extension if it is not null. It can be
2144     // null if the last load was for an error page.
2145     if (m_committedSandboxExtension && shouldReuseCommittedSandboxExtension(frame)) {
2146         m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release();
2147         ASSERT(!m_committedSandboxExtension);
2148     }
2149
2150     ASSERT(!m_provisionalSandboxExtension);
2151
2152     m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
2153     if (!m_provisionalSandboxExtension)
2154         return;
2155
2156     m_provisionalSandboxExtension->consume();
2157 }
2158
2159 void WebPage::SandboxExtensionTracker::didCommitProvisionalLoad(WebFrame* frame)
2160 {
2161     if (!frame->isMainFrame())
2162         return;
2163     
2164     ASSERT(!m_pendingProvisionalSandboxExtension);
2165
2166     // The provisional load has been committed. Invalidate the currently committed sandbox
2167     // extension and make the provisional sandbox extension the committed sandbox extension.
2168     if (m_committedSandboxExtension)
2169         m_committedSandboxExtension->invalidate();
2170
2171     m_committedSandboxExtension = m_provisionalSandboxExtension.release();
2172 }
2173
2174 void WebPage::SandboxExtensionTracker::didFailProvisionalLoad(WebFrame* frame)
2175 {
2176     if (!frame->isMainFrame())
2177         return;
2178
2179     if (!m_provisionalSandboxExtension)
2180         return;
2181
2182     m_provisionalSandboxExtension->invalidate();
2183     m_provisionalSandboxExtension = nullptr;
2184 }
2185
2186 bool WebPage::hasLocalDataForURL(const KURL& url)
2187 {
2188     if (url.isLocalFile())
2189         return true;
2190
2191     FrameLoader* frameLoader = m_page->mainFrame()->loader();
2192     DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
2193     if (documentLoader && documentLoader->subresource(url))
2194         return true;
2195
2196     return platformHasLocalDataForURL(url);
2197 }
2198
2199 void WebPage::setCustomTextEncodingName(const String& encoding)
2200 {
2201     m_page->mainFrame()->loader()->reloadWithOverrideEncoding(encoding);
2202 }
2203
2204 void WebPage::didRemoveBackForwardItem(uint64_t itemID)
2205 {
2206     WebBackForwardListProxy::removeItem(itemID);
2207 }
2208
2209 #if PLATFORM(MAC)
2210
2211 bool WebPage::isSpeaking()
2212 {
2213     bool result;
2214     return sendSync(Messages::WebPageProxy::GetIsSpeaking(), Messages::WebPageProxy::GetIsSpeaking::Reply(result)) && result;
2215 }
2216
2217 void WebPage::speak(const String& string)
2218 {
2219     send(Messages::WebPageProxy::Speak(string));
2220 }
2221
2222 void WebPage::stopSpeaking()
2223 {
2224     send(Messages::WebPageProxy::StopSpeaking());
2225 }
2226
2227 #endif
2228
2229 void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
2230 {
2231     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2232     if (!frame)
2233         return;
2234
2235     Frame* coreFrame = frame->coreFrame();
2236     if (!coreFrame)
2237         return;
2238
2239     if (!m_printContext)
2240         m_printContext = adoptPtr(new PrintContext(coreFrame));
2241
2242     m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
2243
2244     float fullPageHeight;
2245     m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
2246 }
2247
2248 void WebPage::endPrinting()
2249 {
2250     m_printContext = nullptr;
2251 }
2252
2253 void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
2254 {
2255     Vector<IntRect> resultPageRects;
2256     double resultTotalScaleFactorForPrinting = 1;
2257
2258     beginPrinting(frameID, printInfo);
2259
2260     if (m_printContext) {
2261         resultPageRects = m_printContext->pageRects();
2262         resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
2263     }
2264
2265     // If we're asked to print, we should actually print at least a blank page.
2266     if (resultPageRects.isEmpty())
2267         resultPageRects.append(IntRect(0, 0, 1, 1));
2268
2269     send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
2270 }
2271
2272 #if PLATFORM(MAC) || PLATFORM(WIN)
2273 void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, uint64_t callbackID)
2274 {
2275     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2276     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2277
2278     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2279
2280     if (coreFrame) {
2281         ASSERT(coreFrame->document()->printing());
2282
2283 #if USE(CG)
2284         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2285         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2286
2287         CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
2288         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2289         RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2290         CGPDFContextBeginPage(context.get(), pageInfo.get());
2291
2292         GraphicsContext ctx(context.get());
2293         ctx.scale(FloatSize(1, -1));
2294         ctx.translate(0, -rect.height());
2295         m_printContext->spoolRect(ctx, rect);
2296
2297         CGPDFContextEndPage(context.get());
2298         CGPDFContextClose(context.get());
2299 #endif
2300     }
2301
2302     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2303 }
2304
2305 void WebPage::drawPagesToPDF(uint64_t frameID, uint32_t first, uint32_t count, uint64_t callbackID)
2306 {
2307     WebFrame* frame = WebProcess::shared().webFrame(frameID);
2308     Frame* coreFrame = frame ? frame->coreFrame() : 0;
2309
2310     RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
2311
2312     if (coreFrame) {
2313         ASSERT(coreFrame->document()->printing());
2314
2315 #if USE(CG)
2316         // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
2317         RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
2318
2319         CGRect mediaBox = m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, 1, 1);
2320         RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
2321         for (uint32_t page = first; page < first + count; ++page) {
2322             if (page >= m_printContext->pageCount())
2323                 break;
2324
2325             RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
2326             CGPDFContextBeginPage(context.get(), pageInfo.get());
2327
2328             GraphicsContext ctx(context.get());
2329             ctx.scale(FloatSize(1, -1));
2330             ctx.translate(0, -m_printContext->pageRect(page).height());
2331             m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
2332
2333             CGPDFContextEndPage(context.get());
2334         }
2335         CGPDFContextClose(context.get());
2336 #endif
2337     }
2338
2339     send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
2340 }
2341 #endif
2342
2343 void WebPage::runModal()
2344 {
2345     if (m_isClosed)
2346         return;
2347     if (m_isRunningModal)
2348         return;
2349
2350     m_isRunningModal = true;
2351     send(Messages::WebPageProxy::RunModal());
2352     RunLoop::run();
2353     ASSERT(!m_isRunningModal);
2354 }
2355
2356 void WebPage::setMemoryCacheMessagesEnabled(bool memoryCacheMessagesEnabled)
2357 {
2358     m_page->setMemoryCacheClientCallsEnabled(memoryCacheMessagesEnabled);
2359 }
2360
2361 #if !PLATFORM(MAC)
2362 void WebPage::platformDragEnded()
2363 {
2364 }
2365 #endif
2366
2367 bool WebPage::canHandleRequest(const WebCore::ResourceRequest& request)
2368 {
2369     if (SchemeRegistry::shouldLoadURLSchemeAsEmptyDocument(request.url().protocol()))
2370         return true;
2371     return platformCanHandleRequest(request);
2372 }
2373
2374 #if PLATFORM(MAC) && !defined(BUILDING_ON_SNOW_LEOPARD)
2375 void WebPage::handleCorrectionPanelResult(const String& result)
2376 {
2377     Frame* frame = m_page->focusController()->focusedOrMainFrame();
2378     if (!frame)
2379         return;
2380     frame->editor()->handleCorrectionPanelResult(result);
2381 }
2382 #endif
2383
2384 void WebPage::simulateMouseDown(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2385 {
2386     mouseEvent(WebMouseEvent(WebMouseEvent::MouseDown, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2387 }
2388
2389 void WebPage::simulateMouseUp(int button, WebCore::IntPoint position, int clickCount, WKEventModifiers modifiers, double time)
2390 {
2391     mouseEvent(WebMouseEvent(WebMouseEvent::MouseUp, static_cast<WebMouseEvent::Button>(button), position, position, 0, 0, 0, clickCount, static_cast<WebMouseEvent::Modifiers>(modifiers), time));
2392 }
2393
2394 void WebPage::simulateMouseMotion(WebCore::IntPoint position, double time)
2395 {
2396     mouseEvent(WebMouseEvent(WebMouseEvent::MouseMove, WebMouseEvent::NoButton, position, position, 0, 0, 0, 0, WebMouseEvent::Modifiers(), time));
2397 }
2398
2399 } // namespace WebKit