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