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