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