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