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