851734055be249f2e5d009283ec0d55f6b5ca116
[WebKit-https.git] / Source / WebKit2 / UIProcess / WebPageProxy.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 "WebPageProxy.h"
29
30 #include "AuthenticationChallengeProxy.h"
31 #include "AuthenticationDecisionListener.h"
32 #include "DataReference.h"
33 #include "DownloadProxy.h"
34 #include "DrawingAreaProxy.h"
35 #include "DrawingAreaProxyMessages.h"
36 #include "EventDispatcherMessages.h"
37 #include "FindIndicator.h"
38 #include "ImmutableArray.h"
39 #include "Logging.h"
40 #include "NativeWebKeyboardEvent.h"
41 #include "NativeWebMouseEvent.h"
42 #include "NativeWebWheelEvent.h"
43 #include "NotificationPermissionRequest.h"
44 #include "NotificationPermissionRequestManager.h"
45 #include "PageClient.h"
46 #include "PrintInfo.h"
47 #include "SessionState.h"
48 #include "TextChecker.h"
49 #include "TextCheckerState.h"
50 #include "WKContextPrivate.h"
51 #include "WebBackForwardList.h"
52 #include "WebBackForwardListItem.h"
53 #include "WebCertificateInfo.h"
54 #include "WebColorPickerResultListenerProxy.h"
55 #include "WebContext.h"
56 #include "WebContextMenuProxy.h"
57 #include "WebContextUserMessageCoders.h"
58 #include "WebCoreArgumentCoders.h"
59 #include "WebData.h"
60 #include "WebEditCommandProxy.h"
61 #include "WebEvent.h"
62 #include "WebFormSubmissionListenerProxy.h"
63 #include "WebFramePolicyListenerProxy.h"
64 #include "WebFullScreenManagerProxy.h"
65 #include "WebFullScreenManagerProxyMessages.h"
66 #include "WebInspectorProxy.h"
67 #include "WebInspectorProxyMessages.h"
68 #include "WebNotificationManagerProxy.h"
69 #include "WebOpenPanelResultListenerProxy.h"
70 #include "WebPageCreationParameters.h"
71 #include "WebPageGroup.h"
72 #include "WebPageGroupData.h"
73 #include "WebPageMessages.h"
74 #include "WebPageProxyMessages.h"
75 #include "WebPopupItem.h"
76 #include "WebPopupMenuProxy.h"
77 #include "WebPreferences.h"
78 #include "WebProcessMessages.h"
79 #include "WebProcessProxy.h"
80 #include "WebProtectionSpace.h"
81 #include "WebSecurityOrigin.h"
82 #include "WebURLRequest.h"
83 #include <WebCore/DragController.h>
84 #include <WebCore/DragData.h>
85 #include <WebCore/DragSession.h>
86 #include <WebCore/FloatRect.h>
87 #include <WebCore/FocusDirection.h>
88 #include <WebCore/MIMETypeRegistry.h>
89 #include <WebCore/RenderEmbeddedObject.h>
90 #include <WebCore/TextCheckerClient.h>
91 #include <WebCore/WindowFeatures.h>
92 #include <stdio.h>
93
94 #if USE(COORDINATED_GRAPHICS)
95 #include "CoordinatedLayerTreeHostProxyMessages.h"
96 #endif
97
98 #if PLATFORM(QT)
99 #include "ArgumentCodersQt.h"
100 #endif
101
102 #if PLATFORM(GTK)
103 #include "ArgumentCodersGtk.h"
104 #endif
105
106 #if USE(SOUP)
107 #include "WebSoupRequestManagerProxy.h"
108 #endif
109
110 #if ENABLE(VIBRATION)
111 #include "WebVibrationProxy.h"
112 #endif
113
114 #ifndef NDEBUG
115 #include <wtf/RefCountedLeakCounter.h>
116 #endif
117
118 // This controls what strategy we use for mouse wheel coalescing.
119 #define MERGE_WHEEL_EVENTS 1
120
121 #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, m_process->connection())
122 #define MESSAGE_CHECK_URL(url) MESSAGE_CHECK_BASE(m_process->checkURLReceivedFromWebProcess(url), m_process->connection())
123
124 using namespace WebCore;
125
126 // Represents the number of wheel events we can hold in the queue before we start pushing them preemptively.
127 static const unsigned wheelEventQueueSizeThreshold = 10;
128
129 namespace WebKit {
130
131 WKPageDebugPaintFlags WebPageProxy::s_debugPaintFlags = 0;
132
133 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webPageProxyCounter, ("WebPageProxy"));
134
135 class ExceededDatabaseQuotaRecords {
136     WTF_MAKE_NONCOPYABLE(ExceededDatabaseQuotaRecords); WTF_MAKE_FAST_ALLOCATED;
137 public:
138     struct Record {
139         uint64_t frameID;
140         String originIdentifier;
141         String databaseName;
142         String displayName;
143         uint64_t currentQuota;
144         uint64_t currentOriginUsage;
145         uint64_t currentDatabaseUsage;
146         uint64_t expectedUsage;
147         RefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply;
148     };
149
150     static ExceededDatabaseQuotaRecords& shared();
151
152     PassOwnPtr<Record> createRecord(uint64_t frameID, String originIdentifier,
153         String databaseName, String displayName, uint64_t currentQuota,
154         uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, 
155         PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply>);
156
157     void add(PassOwnPtr<Record>);
158     bool areBeingProcessed() const { return m_currentRecord; }
159     Record* next();
160
161 private:
162     ExceededDatabaseQuotaRecords() { }
163     ~ExceededDatabaseQuotaRecords() { }
164
165     Deque<OwnPtr<Record> > m_records;
166     OwnPtr<Record> m_currentRecord;
167 };
168
169 ExceededDatabaseQuotaRecords& ExceededDatabaseQuotaRecords::shared()
170 {
171     DEFINE_STATIC_LOCAL(ExceededDatabaseQuotaRecords, records, ());
172     return records;
173 }
174
175 PassOwnPtr<ExceededDatabaseQuotaRecords::Record> ExceededDatabaseQuotaRecords::createRecord(
176     uint64_t frameID, String originIdentifier, String databaseName, String displayName,
177     uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage,
178     uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
179 {
180     OwnPtr<Record> record = adoptPtr(new Record);
181     record->frameID = frameID;
182     record->originIdentifier = originIdentifier;
183     record->databaseName = databaseName;
184     record->displayName = displayName;
185     record->currentQuota = currentQuota;
186     record->currentOriginUsage = currentOriginUsage;
187     record->currentDatabaseUsage = currentDatabaseUsage;
188     record->expectedUsage = expectedUsage;
189     record->reply = reply;
190     return record.release();
191 }
192
193 void ExceededDatabaseQuotaRecords::add(PassOwnPtr<ExceededDatabaseQuotaRecords::Record> record)
194 {
195     m_records.append(record);
196 }
197
198 ExceededDatabaseQuotaRecords::Record* ExceededDatabaseQuotaRecords::next()
199 {
200     m_currentRecord.clear();
201     if (!m_records.isEmpty())
202         m_currentRecord = m_records.takeFirst();
203     return m_currentRecord.get();
204 }
205
206 #if !LOG_DISABLED
207 static const char* webKeyboardEventTypeString(WebEvent::Type type)
208 {
209     switch (type) {
210     case WebEvent::KeyDown:
211         return "KeyDown";
212     
213     case WebEvent::KeyUp:
214         return "KeyUp";
215     
216     case WebEvent::RawKeyDown:
217         return "RawKeyDown";
218     
219     case WebEvent::Char:
220         return "Char";
221     
222     default:
223         ASSERT_NOT_REACHED();
224         return "<unknown>";
225     }
226 }
227 #endif // !LOG_DISABLED
228
229 PassRefPtr<WebPageProxy> WebPageProxy::create(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID)
230 {
231     return adoptRef(new WebPageProxy(pageClient, process, pageGroup, pageID));
232 }
233
234 WebPageProxy::WebPageProxy(PageClient* pageClient, PassRefPtr<WebProcessProxy> process, WebPageGroup* pageGroup, uint64_t pageID)
235     : m_pageClient(pageClient)
236     , m_process(process)
237     , m_pageGroup(pageGroup)
238     , m_mainFrame(0)
239     , m_userAgent(standardUserAgent())
240     , m_geolocationPermissionRequestManager(this)
241     , m_notificationPermissionRequestManager(this)
242     , m_estimatedProgress(0)
243     , m_isInWindow(m_pageClient->isViewInWindow())
244     , m_isVisible(m_pageClient->isViewVisible())
245     , m_backForwardList(WebBackForwardList::create(this))
246     , m_loadStateAtProcessExit(WebFrameProxy::LoadStateFinished)
247     , m_textZoomFactor(1)
248     , m_pageZoomFactor(1)
249     , m_pageScaleFactor(1)
250     , m_intrinsicDeviceScaleFactor(1)
251     , m_customDeviceScaleFactor(0)
252 #if HAVE(LAYER_HOSTING_IN_WINDOW_SERVER)
253     , m_layerHostingMode(LayerHostingModeInWindowServer)
254 #else
255     , m_layerHostingMode(LayerHostingModeDefault)
256 #endif
257     , m_drawsBackground(true)
258     , m_drawsTransparentBackground(false)
259     , m_areMemoryCacheClientCallsEnabled(true)
260     , m_useFixedLayout(false)
261     , m_suppressScrollbarAnimations(false)
262     , m_paginationMode(Pagination::Unpaginated)
263     , m_paginationBehavesLikeColumns(false)
264     , m_pageLength(0)
265     , m_gapBetweenPages(0)
266     , m_isValid(true)
267     , m_isClosed(false)
268     , m_canRunModal(false)
269     , m_isInPrintingMode(false)
270     , m_isPerformingDOMPrintOperation(false)
271     , m_inDecidePolicyForResponse(false)
272     , m_decidePolicyForResponseRequest(0)
273     , m_syncMimeTypePolicyActionIsValid(false)
274     , m_syncMimeTypePolicyAction(PolicyUse)
275     , m_syncMimeTypePolicyDownloadID(0)
276     , m_inDecidePolicyForNavigationAction(false)
277     , m_syncNavigationActionPolicyActionIsValid(false)
278     , m_syncNavigationActionPolicyAction(PolicyUse)
279     , m_syncNavigationActionPolicyDownloadID(0)
280     , m_processingMouseMoveEvent(false)
281 #if ENABLE(TOUCH_EVENTS)
282     , m_needTouchEvents(false)
283 #endif
284     , m_pageID(pageID)
285     , m_isPageSuspended(false)
286 #if PLATFORM(MAC)
287     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
288 #endif
289     , m_spellDocumentTag(0)
290     , m_hasSpellDocumentTag(false)
291     , m_pendingLearnOrIgnoreWordMessageCount(0)
292     , m_mainFrameHasCustomRepresentation(false)
293     , m_mainFrameHasHorizontalScrollbar(false)
294     , m_mainFrameHasVerticalScrollbar(false)
295     , m_canShortCircuitHorizontalWheelEvents(true)
296     , m_mainFrameIsPinnedToLeftSide(false)
297     , m_mainFrameIsPinnedToRightSide(false)
298     , m_mainFrameIsPinnedToTopSide(false)
299     , m_mainFrameIsPinnedToBottomSide(false)
300     , m_rubberBandsAtBottom(false)
301     , m_rubberBandsAtTop(false)
302     , m_mainFrameInViewSourceMode(false)
303     , m_overridePrivateBrowsingEnabled(false)
304     , m_pageCount(0)
305     , m_renderTreeSize(0)
306     , m_shouldSendEventsSynchronously(false)
307     , m_suppressVisibilityUpdates(false)
308     , m_minimumLayoutWidth(0)
309     , m_mediaVolume(1)
310     , m_mayStartMediaWhenInWindow(true)
311 #if ENABLE(PAGE_VISIBILITY_API)
312     , m_visibilityState(PageVisibilityStateVisible)
313 #endif
314 {
315 #if ENABLE(PAGE_VISIBILITY_API)
316     if (!m_isVisible)
317         m_visibilityState = PageVisibilityStateHidden;
318 #endif
319 #ifndef NDEBUG
320     webPageProxyCounter.increment();
321 #endif
322
323     WebContext::statistics().wkPageCount++;
324
325     m_pageGroup->addPage(this);
326
327 #if ENABLE(INSPECTOR)
328     m_inspector = WebInspectorProxy::create(this);
329 #endif
330 #if ENABLE(FULLSCREEN_API)
331     m_fullScreenManager = WebFullScreenManagerProxy::create(this);
332 #endif
333 #if ENABLE(VIBRATION)
334     m_vibration = WebVibrationProxy::create(this);
335 #endif
336 #if ENABLE(THREADED_SCROLLING)
337     m_rubberBandsAtBottom = true;
338     m_rubberBandsAtTop = true;
339 #endif
340
341     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, this);
342
343     // FIXME: If we ever expose the session storage size as a preference, we need to pass it here.
344     m_process->context()->storageManager().createSessionStorageNamespace(m_pageID, m_process->isValid() ? m_process->connection() : 0, std::numeric_limits<unsigned>::max());
345 }
346
347 WebPageProxy::~WebPageProxy()
348 {
349     if (!m_isClosed)
350         close();
351
352     WebContext::statistics().wkPageCount--;
353
354     if (m_hasSpellDocumentTag)
355         TextChecker::closeSpellDocumentWithTag(m_spellDocumentTag);
356
357     m_pageGroup->removePage(this);
358
359 #ifndef NDEBUG
360     webPageProxyCounter.decrement();
361 #endif
362 }
363
364 WebProcessProxy* WebPageProxy::process() const
365 {
366     return m_process.get();
367 }
368
369 PlatformProcessIdentifier WebPageProxy::processIdentifier() const
370 {
371     if (!m_process)
372         return 0;
373
374     return m_process->processIdentifier();
375 }
376
377 bool WebPageProxy::isValid()
378 {
379     // A page that has been explicitly closed is never valid.
380     if (m_isClosed)
381         return false;
382
383     return m_isValid;
384 }
385
386 PassRefPtr<ImmutableArray> WebPageProxy::relatedPages() const
387 {
388     // pages() returns a list of pages in WebProcess, so this page may or may not be among them - a client can use a reference to WebPageProxy after the page has closed.
389     Vector<WebPageProxy*> pages = m_process->pages();
390
391     Vector<RefPtr<APIObject> > result;
392     result.reserveCapacity(pages.size());
393     for (size_t i = 0; i < pages.size(); ++i) {
394         if (pages[i] != this)
395             result.append(pages[i]);
396     }
397
398     return ImmutableArray::adopt(result);
399 }
400
401 void WebPageProxy::initializeLoaderClient(const WKPageLoaderClient* loadClient)
402 {
403     m_loaderClient.initialize(loadClient);
404     
405     if (!loadClient)
406         return;
407
408     // It would be nice to get rid of this code and transition all clients to using didLayout instead of
409     // didFirstLayoutInFrame and didFirstVisuallyNonEmptyLayoutInFrame. In the meantime, this is required
410     // for backwards compatibility.
411     WebCore::LayoutMilestones milestones = 0;
412     if (loadClient->didFirstLayoutForFrame)
413         milestones |= WebCore::DidFirstLayout;
414     if (loadClient->didFirstVisuallyNonEmptyLayoutForFrame)
415         milestones |= WebCore::DidFirstVisuallyNonEmptyLayout;
416     if (loadClient->didNewFirstVisuallyNonEmptyLayout)
417         milestones |= WebCore::DidHitRelevantRepaintedObjectsAreaThreshold;
418
419     if (milestones)
420         m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
421
422     m_process->send(Messages::WebPage::SetWillGoToBackForwardItemCallbackEnabled(loadClient->version > 0), m_pageID);
423 }
424
425 void WebPageProxy::initializePolicyClient(const WKPagePolicyClient* policyClient)
426 {
427     m_policyClient.initialize(policyClient);
428 }
429
430 void WebPageProxy::initializeFormClient(const WKPageFormClient* formClient)
431 {
432     m_formClient.initialize(formClient);
433 }
434
435 void WebPageProxy::initializeUIClient(const WKPageUIClient* client)
436 {
437     if (!isValid())
438         return;
439
440     m_uiClient.initialize(client);
441
442     m_process->send(Messages::WebPage::SetCanRunBeforeUnloadConfirmPanel(m_uiClient.canRunBeforeUnloadConfirmPanel()), m_pageID);
443     setCanRunModal(m_uiClient.canRunModal());
444 }
445
446 void WebPageProxy::initializeFindClient(const WKPageFindClient* client)
447 {
448     m_findClient.initialize(client);
449 }
450
451 void WebPageProxy::initializeFindMatchesClient(const WKPageFindMatchesClient* client)
452 {
453     m_findMatchesClient.initialize(client);
454 }
455
456 #if ENABLE(CONTEXT_MENUS)
457 void WebPageProxy::initializeContextMenuClient(const WKPageContextMenuClient* client)
458 {
459     m_contextMenuClient.initialize(client);
460 }
461 #endif
462
463 void WebPageProxy::reattachToWebProcess()
464 {
465     ASSERT(!isValid());
466     ASSERT(m_process);
467     ASSERT(!m_process->isValid());
468     ASSERT(!m_process->isLaunching());
469
470     m_isValid = true;
471
472     if (m_process->context()->processModel() == ProcessModelSharedSecondaryProcess)
473         m_process = m_process->context()->ensureSharedWebProcess();
474     else
475         m_process = m_process->context()->createNewWebProcessRespectingProcessCountLimit();
476     m_process->addExistingWebPage(this, m_pageID);
477     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID, this);
478
479 #if ENABLE(INSPECTOR)
480     m_inspector = WebInspectorProxy::create(this);
481 #endif
482 #if ENABLE(FULLSCREEN_API)
483     m_fullScreenManager = WebFullScreenManagerProxy::create(this);
484 #endif
485
486     initializeWebPage();
487
488     m_pageClient->didRelaunchProcess();
489     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
490 }
491
492 void WebPageProxy::reattachToWebProcessWithItem(WebBackForwardListItem* item)
493 {
494     if (item && item != m_backForwardList->currentItem())
495         m_backForwardList->goToItem(item);
496     
497     reattachToWebProcess();
498
499     if (!item)
500         return;
501
502     m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
503     m_process->responsivenessTimer()->start();
504 }
505
506 void WebPageProxy::initializeWebPage()
507 {
508     ASSERT(isValid());
509
510     BackForwardListItemVector items = m_backForwardList->entries();
511     for (size_t i = 0; i < items.size(); ++i)
512         m_process->registerNewWebBackForwardListItem(items[i].get());
513
514     m_drawingArea = m_pageClient->createDrawingAreaProxy();
515     ASSERT(m_drawingArea);
516
517 #if ENABLE(INSPECTOR_SERVER)
518     if (m_pageGroup->preferences()->developerExtrasEnabled())
519         inspector()->enableRemoteInspection();
520 #endif
521
522     m_process->send(Messages::WebProcess::CreateWebPage(m_pageID, creationParameters()), 0);
523
524 #if ENABLE(PAGE_VISIBILITY_API)
525     m_process->send(Messages::WebPage::SetVisibilityState(m_visibilityState, /* isInitialState */ true), m_pageID);
526 #elif ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING)
527     m_process->send(Messages::WebPage::SetVisibilityState(m_isVisible ? PageVisibilityStateVisible : PageVisibilityStateHidden, /* isInitialState */ true), m_pageID);
528 #endif
529
530 #if PLATFORM(MAC)
531     m_process->send(Messages::WebPage::SetSmartInsertDeleteEnabled(m_isSmartInsertDeleteEnabled), m_pageID);
532 #endif
533 }
534
535 void WebPageProxy::close()
536 {
537     if (!isValid())
538         return;
539
540     m_isClosed = true;
541
542     m_backForwardList->pageClosed();
543     m_pageClient->pageClosed();
544
545     m_process->disconnectFramesFromPage(this);
546     m_mainFrame = 0;
547
548 #if ENABLE(INSPECTOR)
549     if (m_inspector) {
550         m_inspector->invalidate();
551         m_inspector = 0;
552     }
553 #endif
554
555 #if ENABLE(FULLSCREEN_API)
556     if (m_fullScreenManager) {
557         m_fullScreenManager->invalidate();
558         m_fullScreenManager = 0;
559     }
560 #endif
561
562 #if ENABLE(VIBRATION)
563     m_vibration->invalidate();
564 #endif
565
566     if (m_openPanelResultListener) {
567         m_openPanelResultListener->invalidate();
568         m_openPanelResultListener = 0;
569     }
570
571 #if ENABLE(INPUT_TYPE_COLOR)
572     if (m_colorChooser) {
573         m_colorChooser->invalidate();
574         m_colorChooser = nullptr;
575     }
576
577     if (m_colorPickerResultListener) {
578         m_colorPickerResultListener->invalidate();
579         m_colorPickerResultListener = nullptr;
580     }
581 #endif
582
583 #if ENABLE(GEOLOCATION)
584     m_geolocationPermissionRequestManager.invalidateRequests();
585 #endif
586
587     m_notificationPermissionRequestManager.invalidateRequests();
588
589     m_toolTip = String();
590
591     m_mainFrameHasHorizontalScrollbar = false;
592     m_mainFrameHasVerticalScrollbar = false;
593
594     m_mainFrameIsPinnedToLeftSide = false;
595     m_mainFrameIsPinnedToRightSide = false;
596     m_mainFrameIsPinnedToTopSide = false;
597     m_mainFrameIsPinnedToBottomSide = false;
598
599     m_visibleScrollerThumbRect = IntRect();
600
601     invalidateCallbackMap(m_voidCallbacks);
602     invalidateCallbackMap(m_dataCallbacks);
603     invalidateCallbackMap(m_imageCallbacks);
604     invalidateCallbackMap(m_stringCallbacks);
605     m_loadDependentStringCallbackIDs.clear();
606     invalidateCallbackMap(m_scriptValueCallbacks);
607     invalidateCallbackMap(m_computedPagesCallbacks);
608 #if PLATFORM(GTK)
609     invalidateCallbackMap(m_printFinishedCallbacks);
610 #endif
611
612     Vector<WebEditCommandProxy*> editCommandVector;
613     copyToVector(m_editCommandSet, editCommandVector);
614     m_editCommandSet.clear();
615     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
616         editCommandVector[i]->invalidate();
617
618     m_activePopupMenu = 0;
619
620     m_estimatedProgress = 0.0;
621     
622     m_loaderClient.initialize(0);
623     m_policyClient.initialize(0);
624     m_uiClient.initialize(0);
625 #if PLATFORM(EFL)
626     m_uiPopupMenuClient.initialize(0);
627 #endif
628
629     m_drawingArea = nullptr;
630
631     m_process->send(Messages::WebPage::Close(), m_pageID);
632     m_process->removeWebPage(m_pageID);
633     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
634     m_process->context()->storageManager().destroySessionStorageNamespace(m_pageID);
635 }
636
637 bool WebPageProxy::tryClose()
638 {
639     if (!isValid())
640         return true;
641
642     m_process->send(Messages::WebPage::TryClose(), m_pageID);
643     m_process->responsivenessTimer()->start();
644     return false;
645 }
646
647 bool WebPageProxy::maybeInitializeSandboxExtensionHandle(const KURL& url, SandboxExtension::Handle& sandboxExtensionHandle)
648 {
649     if (!url.isLocalFile())
650         return false;
651
652 #if ENABLE(INSPECTOR)
653     // Don't give the inspector full access to the file system.
654     if (WebInspectorProxy::isInspectorPage(this))
655         return false;
656 #endif
657
658     SandboxExtension::createHandle("/", SandboxExtension::ReadOnly, sandboxExtensionHandle);
659     return true;
660 }
661
662 void WebPageProxy::loadURL(const String& url)
663 {
664     setPendingAPIRequestURL(url);
665
666     if (!isValid())
667         reattachToWebProcess();
668
669     SandboxExtension::Handle sandboxExtensionHandle;
670     bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
671     if (createdExtension)
672         m_process->willAcquireUniversalFileReadSandboxExtension();
673     m_process->send(Messages::WebPage::LoadURL(url, sandboxExtensionHandle), m_pageID);
674     m_process->responsivenessTimer()->start();
675 }
676
677 void WebPageProxy::loadURLRequest(WebURLRequest* urlRequest)
678 {
679     setPendingAPIRequestURL(urlRequest->resourceRequest().url());
680
681     if (!isValid())
682         reattachToWebProcess();
683
684     SandboxExtension::Handle sandboxExtensionHandle;
685     bool createdExtension = maybeInitializeSandboxExtensionHandle(urlRequest->resourceRequest().url(), sandboxExtensionHandle);
686     if (createdExtension)
687         m_process->willAcquireUniversalFileReadSandboxExtension();
688     m_process->send(Messages::WebPage::LoadURLRequest(urlRequest->resourceRequest(), sandboxExtensionHandle), m_pageID);
689     m_process->responsivenessTimer()->start();
690 }
691
692 void WebPageProxy::loadHTMLString(const String& htmlString, const String& baseURL)
693 {
694     if (!isValid())
695         reattachToWebProcess();
696
697     m_process->assumeReadAccessToBaseURL(baseURL);
698     m_process->send(Messages::WebPage::LoadHTMLString(htmlString, baseURL), m_pageID);
699     m_process->responsivenessTimer()->start();
700 }
701
702 void WebPageProxy::loadAlternateHTMLString(const String& htmlString, const String& baseURL, const String& unreachableURL)
703 {
704     if (!isValid())
705         reattachToWebProcess();
706
707     if (m_mainFrame)
708         m_mainFrame->setUnreachableURL(unreachableURL);
709
710     m_process->assumeReadAccessToBaseURL(baseURL);
711     m_process->send(Messages::WebPage::LoadAlternateHTMLString(htmlString, baseURL, unreachableURL), m_pageID);
712     m_process->responsivenessTimer()->start();
713 }
714
715 void WebPageProxy::loadPlainTextString(const String& string)
716 {
717     if (!isValid())
718         reattachToWebProcess();
719
720     m_process->send(Messages::WebPage::LoadPlainTextString(string), m_pageID);
721     m_process->responsivenessTimer()->start();
722 }
723
724 void WebPageProxy::loadWebArchiveData(const WebData* webArchiveData)
725 {
726     if (!isValid())
727         reattachToWebProcess();
728
729     m_process->send(Messages::WebPage::LoadWebArchiveData(webArchiveData->dataReference()), m_pageID);
730     m_process->responsivenessTimer()->start();
731 }
732
733 void WebPageProxy::stopLoading()
734 {
735     if (!isValid())
736         return;
737
738     m_process->send(Messages::WebPage::StopLoading(), m_pageID);
739     m_process->responsivenessTimer()->start();
740 }
741
742 void WebPageProxy::reload(bool reloadFromOrigin)
743 {
744     SandboxExtension::Handle sandboxExtensionHandle;
745
746     if (m_backForwardList->currentItem()) {
747         String url = m_backForwardList->currentItem()->url();
748         setPendingAPIRequestURL(url);
749
750         // We may not have an extension yet if back/forward list was reinstated after a WebProcess crash or a browser relaunch
751         bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), url), sandboxExtensionHandle);
752         if (createdExtension)
753             m_process->willAcquireUniversalFileReadSandboxExtension();
754     }
755
756     if (!isValid()) {
757         reattachToWebProcessWithItem(m_backForwardList->currentItem());
758         return;
759     }
760
761     m_process->send(Messages::WebPage::Reload(reloadFromOrigin, sandboxExtensionHandle), m_pageID);
762     m_process->responsivenessTimer()->start();
763 }
764
765 void WebPageProxy::goForward()
766 {
767     if (isValid() && !canGoForward())
768         return;
769
770     WebBackForwardListItem* forwardItem = m_backForwardList->forwardItem();
771     if (!forwardItem)
772         return;
773
774     setPendingAPIRequestURL(forwardItem->url());
775
776     if (!isValid()) {
777         reattachToWebProcessWithItem(forwardItem);
778         return;
779     }
780
781     m_process->send(Messages::WebPage::GoForward(forwardItem->itemID()), m_pageID);
782     m_process->responsivenessTimer()->start();
783 }
784
785 bool WebPageProxy::canGoForward() const
786 {
787     return m_backForwardList->forwardItem();
788 }
789
790 void WebPageProxy::goBack()
791 {
792     if (isValid() && !canGoBack())
793         return;
794
795     WebBackForwardListItem* backItem = m_backForwardList->backItem();
796     if (!backItem)
797         return;
798
799     setPendingAPIRequestURL(backItem->url());
800
801     if (!isValid()) {
802         reattachToWebProcessWithItem(backItem);
803         return;
804     }
805
806     m_process->send(Messages::WebPage::GoBack(backItem->itemID()), m_pageID);
807     m_process->responsivenessTimer()->start();
808 }
809
810 bool WebPageProxy::canGoBack() const
811 {
812     return m_backForwardList->backItem();
813 }
814
815 void WebPageProxy::goToBackForwardItem(WebBackForwardListItem* item)
816 {
817     if (!isValid()) {
818         reattachToWebProcessWithItem(item);
819         return;
820     }
821     
822     setPendingAPIRequestURL(item->url());
823
824     m_process->send(Messages::WebPage::GoToBackForwardItem(item->itemID()), m_pageID);
825     m_process->responsivenessTimer()->start();
826 }
827
828 void WebPageProxy::tryRestoreScrollPosition()
829 {
830     if (!isValid())
831         return;
832
833     m_process->send(Messages::WebPage::TryRestoreScrollPosition(), m_pageID);
834 }
835
836 void WebPageProxy::didChangeBackForwardList(WebBackForwardListItem* added, Vector<RefPtr<APIObject> >* removed)
837 {
838     m_loaderClient.didChangeBackForwardList(this, added, removed);
839 }
840
841 void WebPageProxy::shouldGoToBackForwardListItem(uint64_t itemID, bool& shouldGoToBackForwardItem)
842 {
843     WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
844     shouldGoToBackForwardItem = item && m_loaderClient.shouldGoToBackForwardListItem(this, item);
845 }
846
847 void WebPageProxy::willGoToBackForwardListItem(uint64_t itemID, CoreIPC::MessageDecoder& decoder)
848 {
849     RefPtr<APIObject> userData;
850     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
851     if (!decoder.decode(messageDecoder))
852         return;
853
854     if (WebBackForwardListItem* item = m_process->webBackForwardItem(itemID))
855         m_loaderClient.willGoToBackForwardListItem(this, item, userData.get());
856 }
857
858 String WebPageProxy::activeURL() const
859 {
860     // If there is a currently pending url, it is the active URL,
861     // even when there's no main frame yet, as it might be the
862     // first API request.
863     if (!m_pendingAPIRequestURL.isNull())
864         return m_pendingAPIRequestURL;
865
866     if (!m_mainFrame)
867         return String();
868
869     if (!m_mainFrame->unreachableURL().isEmpty())
870         return m_mainFrame->unreachableURL();
871
872     switch (m_mainFrame->loadState()) {
873     case WebFrameProxy::LoadStateProvisional:
874         return m_mainFrame->provisionalURL();
875     case WebFrameProxy::LoadStateCommitted:
876     case WebFrameProxy::LoadStateFinished:
877         return m_mainFrame->url();
878     }
879
880     ASSERT_NOT_REACHED();
881     return String();
882 }
883
884 String WebPageProxy::provisionalURL() const
885 {
886     if (!m_mainFrame)
887         return String();
888     return m_mainFrame->provisionalURL();
889 }
890
891 String WebPageProxy::committedURL() const
892 {
893     if (!m_mainFrame)
894         return String();
895
896     return m_mainFrame->url();
897 }
898
899 bool WebPageProxy::canShowMIMEType(const String& mimeType) const
900 {
901     if (MIMETypeRegistry::canShowMIMEType(mimeType))
902         return true;
903
904 #if ENABLE(NETSCAPE_PLUGIN_API)
905     String newMimeType = mimeType;
906     PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL());
907     if (!plugin.path.isNull() && m_pageGroup->preferences()->pluginsEnabled())
908         return true;
909 #endif // ENABLE(NETSCAPE_PLUGIN_API)
910     return false;
911 }
912
913 void WebPageProxy::setDrawsBackground(bool drawsBackground)
914 {
915     if (m_drawsBackground == drawsBackground)
916         return;
917
918     m_drawsBackground = drawsBackground;
919
920     if (isValid())
921         m_process->send(Messages::WebPage::SetDrawsBackground(drawsBackground), m_pageID);
922 }
923
924 void WebPageProxy::setDrawsTransparentBackground(bool drawsTransparentBackground)
925 {
926     if (m_drawsTransparentBackground == drawsTransparentBackground)
927         return;
928
929     m_drawsTransparentBackground = drawsTransparentBackground;
930
931     if (isValid())
932         m_process->send(Messages::WebPage::SetDrawsTransparentBackground(drawsTransparentBackground), m_pageID);
933 }
934
935 void WebPageProxy::setUnderlayColor(const Color& color)
936 {
937     if (m_underlayColor == color)
938         return;
939
940     m_underlayColor = color;
941
942     if (isValid())
943         m_process->send(Messages::WebPage::SetUnderlayColor(color), m_pageID);
944 }
945
946 void WebPageProxy::viewWillStartLiveResize()
947 {
948     if (!isValid())
949         return;
950     m_process->send(Messages::WebPage::ViewWillStartLiveResize(), m_pageID);
951 }
952
953 void WebPageProxy::viewWillEndLiveResize()
954 {
955     if (!isValid())
956         return;
957     m_process->send(Messages::WebPage::ViewWillEndLiveResize(), m_pageID);
958 }
959
960 void WebPageProxy::setViewNeedsDisplay(const IntRect& rect)
961 {
962     m_pageClient->setViewNeedsDisplay(rect);
963 }
964
965 void WebPageProxy::displayView()
966 {
967     m_pageClient->displayView();
968 }
969
970 bool WebPageProxy::canScrollView()
971 {
972     return m_pageClient->canScrollView();
973 }
974
975 void WebPageProxy::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
976 {
977     m_pageClient->scrollView(scrollRect, scrollOffset);
978 }
979
980 void WebPageProxy::viewStateDidChange(ViewStateFlags flags)
981 {
982     if (!isValid())
983         return;
984
985     if (flags & ViewIsFocused)
986         m_process->send(Messages::WebPage::SetFocused(m_pageClient->isViewFocused()), m_pageID);
987
988     if (flags & ViewWindowIsActive)
989         m_process->send(Messages::WebPage::SetActive(m_pageClient->isViewWindowActive()), m_pageID);
990
991     if (flags & ViewIsVisible) {
992         bool isVisible = m_pageClient->isViewVisible();
993         if (isVisible != m_isVisible) {
994             m_isVisible = isVisible;
995             m_process->pageVisibilityChanged(this);
996             m_drawingArea->visibilityDidChange();
997
998             if (!m_isVisible) {
999                 // If we've started the responsiveness timer as part of telling the web process to update the backing store
1000                 // state, it might not send back a reply (since it won't paint anything if the web page is hidden) so we
1001                 // stop the unresponsiveness timer here.
1002                 m_process->responsivenessTimer()->stop();
1003             }
1004
1005 #if ENABLE(HIDDEN_PAGE_DOM_TIMER_THROTTLING) && !ENABLE(PAGE_VISIBILITY_API)
1006             PageVisibilityState visibilityState = m_isVisible ? PageVisibilityStateVisible : PageVisibilityStateHidden;
1007             m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, false), m_pageID);
1008 #endif
1009         }
1010     }
1011
1012     if (flags & ViewIsInWindow) {
1013         bool isInWindow = m_pageClient->isViewInWindow();
1014         if (m_isInWindow != isInWindow) {
1015             m_isInWindow = isInWindow;
1016             m_process->send(Messages::WebPage::SetIsInWindow(isInWindow), m_pageID);
1017         }
1018
1019         if (isInWindow) {
1020             LayerHostingMode layerHostingMode = m_pageClient->viewLayerHostingMode();
1021             if (m_layerHostingMode != layerHostingMode) {
1022                 m_layerHostingMode = layerHostingMode;
1023                 m_drawingArea->layerHostingModeDidChange();
1024             }
1025         }
1026     }
1027
1028 #if ENABLE(PAGE_VISIBILITY_API)
1029     PageVisibilityState visibilityState = PageVisibilityStateHidden;
1030
1031     if (m_isVisible)
1032         visibilityState = PageVisibilityStateVisible;
1033
1034     if (visibilityState != m_visibilityState) {
1035         m_visibilityState = visibilityState;
1036         m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, false), m_pageID);
1037     }
1038 #endif
1039
1040     updateBackingStoreDiscardableState();
1041 }
1042
1043 IntSize WebPageProxy::viewSize() const
1044 {
1045     return m_pageClient->viewSize();
1046 }
1047
1048 void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
1049 {
1050     if (!isValid())
1051         return;
1052     m_process->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
1053 }
1054
1055 void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
1056 {
1057     if (!isValid())
1058         return;
1059     m_process->send(Messages::WebPage::SetWindowResizerSize(windowResizerSize), m_pageID);
1060 }
1061     
1062 void WebPageProxy::clearSelection()
1063 {
1064     if (!isValid())
1065         return;
1066     m_process->send(Messages::WebPage::ClearSelection(), m_pageID);
1067 }
1068
1069 void WebPageProxy::validateCommand(const String& commandName, PassRefPtr<ValidateCommandCallback> callback)
1070 {
1071     if (!isValid()) {
1072         callback->invalidate();
1073         return;
1074     }
1075
1076     uint64_t callbackID = callback->callbackID();
1077     m_validateCommandCallbacks.set(callbackID, callback.get());
1078     m_process->send(Messages::WebPage::ValidateCommand(commandName, callbackID), m_pageID);
1079 }
1080
1081 void WebPageProxy::setMaintainsInactiveSelection(bool newValue)
1082 {
1083     m_maintainsInactiveSelection = newValue;
1084 }
1085     
1086 void WebPageProxy::executeEditCommand(const String& commandName)
1087 {
1088     if (!isValid())
1089         return;
1090
1091     DEFINE_STATIC_LOCAL(String, ignoreSpellingCommandName, (ASCIILiteral("ignoreSpelling")));
1092     if (commandName == ignoreSpellingCommandName)
1093         ++m_pendingLearnOrIgnoreWordMessageCount;
1094
1095     m_process->send(Messages::WebPage::ExecuteEditCommand(commandName), m_pageID);
1096 }
1097     
1098 #if USE(TILED_BACKING_STORE)
1099 void WebPageProxy::commitPageTransitionViewport()
1100 {
1101     if (!isValid())
1102         return;
1103
1104     process()->send(Messages::WebPage::CommitPageTransitionViewport(), m_pageID);
1105 }
1106 #endif
1107
1108 #if ENABLE(DRAG_SUPPORT)
1109 void WebPageProxy::dragEntered(DragData* dragData, const String& dragStorageName)
1110 {
1111     SandboxExtension::Handle sandboxExtensionHandle;
1112     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1113     performDragControllerAction(DragControllerActionEntered, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1114 }
1115
1116 void WebPageProxy::dragUpdated(DragData* dragData, const String& dragStorageName)
1117 {
1118     SandboxExtension::Handle sandboxExtensionHandle;
1119     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1120     performDragControllerAction(DragControllerActionUpdated, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1121 }
1122
1123 void WebPageProxy::dragExited(DragData* dragData, const String& dragStorageName)
1124 {
1125     SandboxExtension::Handle sandboxExtensionHandle;
1126     SandboxExtension::HandleArray sandboxExtensionHandleEmptyArray;
1127     performDragControllerAction(DragControllerActionExited, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionHandleEmptyArray);
1128 }
1129
1130 void WebPageProxy::performDrag(DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1131 {
1132     performDragControllerAction(DragControllerActionPerformDrag, dragData, dragStorageName, sandboxExtensionHandle, sandboxExtensionsForUpload);
1133 }
1134
1135 void WebPageProxy::performDragControllerAction(DragControllerAction action, DragData* dragData, const String& dragStorageName, const SandboxExtension::Handle& sandboxExtensionHandle, const SandboxExtension::HandleArray& sandboxExtensionsForUpload)
1136 {
1137     if (!isValid())
1138         return;
1139 #if PLATFORM(QT) || PLATFORM(GTK)
1140     m_process->send(Messages::WebPage::PerformDragControllerAction(action, *dragData), m_pageID);
1141 #else
1142     m_process->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags(), sandboxExtensionHandle, sandboxExtensionsForUpload), m_pageID);
1143 #endif
1144 }
1145
1146 void WebPageProxy::didPerformDragControllerAction(WebCore::DragSession dragSession)
1147 {
1148     m_currentDragSession = dragSession;
1149 }
1150
1151 #if PLATFORM(QT) || PLATFORM(GTK)
1152 void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
1153 {
1154     RefPtr<ShareableBitmap> dragImage = 0;
1155     if (!dragImageHandle.isNull()) {
1156         dragImage = ShareableBitmap::create(dragImageHandle);
1157         if (!dragImage)
1158             return;
1159     }
1160
1161     m_pageClient->startDrag(dragData, dragImage.release());
1162 }
1163 #endif
1164
1165 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
1166 {
1167     if (!isValid())
1168         return;
1169     m_process->send(Messages::WebPage::DragEnded(clientPosition, globalPosition, operation), m_pageID);
1170 }
1171 #endif // ENABLE(DRAG_SUPPORT)
1172
1173 void WebPageProxy::handleMouseEvent(const NativeWebMouseEvent& event)
1174 {
1175     if (!isValid())
1176         return;
1177
1178     // NOTE: This does not start the responsiveness timer because mouse move should not indicate interaction.
1179     if (event.type() != WebEvent::MouseMove)
1180         m_process->responsivenessTimer()->start();
1181     else {
1182         if (m_processingMouseMoveEvent) {
1183             m_nextMouseMoveEvent = adoptPtr(new NativeWebMouseEvent(event));
1184             return;
1185         }
1186
1187         m_processingMouseMoveEvent = true;
1188     }
1189
1190     // <https://bugs.webkit.org/show_bug.cgi?id=57904> We need to keep track of the mouse down event in the case where we
1191     // display a popup menu for select elements. When the user changes the selected item,
1192     // we fake a mouse up event by using this stored down event. This event gets cleared
1193     // when the mouse up message is received from WebProcess.
1194     if (event.type() == WebEvent::MouseDown)
1195         m_currentlyProcessedMouseDownEvent = adoptPtr(new NativeWebMouseEvent(event));
1196
1197     if (m_shouldSendEventsSynchronously) {
1198         bool handled = false;
1199         m_process->sendSync(Messages::WebPage::MouseEventSyncForTesting(event), Messages::WebPage::MouseEventSyncForTesting::Reply(handled), m_pageID);
1200         didReceiveEvent(event.type(), handled);
1201     } else
1202         m_process->send(Messages::WebPage::MouseEvent(event), m_pageID);
1203 }
1204
1205 #if MERGE_WHEEL_EVENTS
1206 static bool canCoalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1207 {
1208     if (a.position() != b.position())
1209         return false;
1210     if (a.globalPosition() != b.globalPosition())
1211         return false;
1212     if (a.modifiers() != b.modifiers())
1213         return false;
1214     if (a.granularity() != b.granularity())
1215         return false;
1216 #if PLATFORM(MAC)
1217     if (a.phase() != b.phase())
1218         return false;
1219     if (a.momentumPhase() != b.momentumPhase())
1220         return false;
1221     if (a.hasPreciseScrollingDeltas() != b.hasPreciseScrollingDeltas())
1222         return false;
1223 #endif
1224
1225     return true;
1226 }
1227
1228 static WebWheelEvent coalesce(const WebWheelEvent& a, const WebWheelEvent& b)
1229 {
1230     ASSERT(canCoalesce(a, b));
1231
1232     FloatSize mergedDelta = a.delta() + b.delta();
1233     FloatSize mergedWheelTicks = a.wheelTicks() + b.wheelTicks();
1234
1235 #if PLATFORM(MAC)
1236     FloatSize mergedUnacceleratedScrollingDelta = a.unacceleratedScrollingDelta() + b.unacceleratedScrollingDelta();
1237
1238     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.directionInvertedFromDevice(), b.phase(), b.momentumPhase(), b.hasPreciseScrollingDeltas(), b.scrollCount(), mergedUnacceleratedScrollingDelta, b.modifiers(), b.timestamp());
1239 #else
1240     return WebWheelEvent(WebEvent::Wheel, b.position(), b.globalPosition(), mergedDelta, mergedWheelTicks, b.granularity(), b.modifiers(), b.timestamp());
1241 #endif
1242 }
1243 #endif // MERGE_WHEEL_EVENTS
1244
1245 static WebWheelEvent coalescedWheelEvent(Deque<NativeWebWheelEvent>& queue, Vector<NativeWebWheelEvent>& coalescedEvents)
1246 {
1247     ASSERT(!queue.isEmpty());
1248     ASSERT(coalescedEvents.isEmpty());
1249
1250 #if MERGE_WHEEL_EVENTS
1251     NativeWebWheelEvent firstEvent = queue.takeFirst();
1252     coalescedEvents.append(firstEvent);
1253
1254     WebWheelEvent event = firstEvent;
1255     while (!queue.isEmpty() && canCoalesce(event, queue.first())) {
1256         NativeWebWheelEvent firstEvent = queue.takeFirst();
1257         coalescedEvents.append(firstEvent);
1258         event = coalesce(event, firstEvent);
1259     }
1260
1261     return event;
1262 #else
1263     while (!queue.isEmpty())
1264         coalescedEvents.append(queue.takeFirst());
1265     return coalescedEvents.last();
1266 #endif
1267 }
1268
1269 void WebPageProxy::handleWheelEvent(const NativeWebWheelEvent& event)
1270 {
1271     if (!isValid())
1272         return;
1273
1274     if (!m_currentlyProcessedWheelEvents.isEmpty()) {
1275         m_wheelEventQueue.append(event);
1276         if (m_wheelEventQueue.size() < wheelEventQueueSizeThreshold)
1277             return;
1278         // The queue has too many wheel events, so push a new event.
1279     }
1280
1281     if (!m_wheelEventQueue.isEmpty()) {
1282         processNextQueuedWheelEvent();
1283         return;
1284     }
1285
1286     OwnPtr<Vector<NativeWebWheelEvent> > coalescedWheelEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
1287     coalescedWheelEvent->append(event);
1288     m_currentlyProcessedWheelEvents.append(coalescedWheelEvent.release());
1289     sendWheelEvent(event);
1290 }
1291
1292 void WebPageProxy::processNextQueuedWheelEvent()
1293 {
1294     OwnPtr<Vector<NativeWebWheelEvent> > nextCoalescedEvent = adoptPtr(new Vector<NativeWebWheelEvent>);
1295     WebWheelEvent nextWheelEvent = coalescedWheelEvent(m_wheelEventQueue, *nextCoalescedEvent.get());
1296     m_currentlyProcessedWheelEvents.append(nextCoalescedEvent.release());
1297     sendWheelEvent(nextWheelEvent);
1298 }
1299
1300 void WebPageProxy::sendWheelEvent(const WebWheelEvent& event)
1301 {
1302     m_process->responsivenessTimer()->start();
1303
1304     if (m_shouldSendEventsSynchronously) {
1305         bool handled = false;
1306         m_process->sendSync(Messages::WebPage::WheelEventSyncForTesting(event), Messages::WebPage::WheelEventSyncForTesting::Reply(handled), m_pageID);
1307         didReceiveEvent(event.type(), handled);
1308         return;
1309     }
1310
1311     m_process->send(Messages::EventDispatcher::WheelEvent(m_pageID, event, canGoBack(), canGoForward()), 0);
1312 }
1313
1314 void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event)
1315 {
1316     if (!isValid())
1317         return;
1318     
1319     LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type()));
1320
1321     m_keyEventQueue.append(event);
1322
1323     m_process->responsivenessTimer()->start();
1324     if (m_shouldSendEventsSynchronously) {
1325         bool handled = false;
1326         m_process->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID);
1327         didReceiveEvent(event.type(), handled);
1328     } else if (m_keyEventQueue.size() == 1) // Otherwise, sent from DidReceiveEvent message handler.
1329         m_process->send(Messages::WebPage::KeyEvent(event), m_pageID);
1330 }
1331
1332 #if ENABLE(NETSCAPE_PLUGIN_API)
1333 void WebPageProxy::getPluginPath(const String& mimeType, const String& urlString, const String& frameURLString, const String& pageURLString, String& pluginPath, uint32_t& pluginLoadPolicy)
1334 {
1335     MESSAGE_CHECK_URL(urlString);
1336
1337     String newMimeType = mimeType.lower();
1338
1339     pluginLoadPolicy = PluginModuleLoadNormally;
1340     PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), urlString));
1341     if (!plugin.path)
1342         return;
1343
1344     pluginLoadPolicy = PluginInfoStore::policyForPlugin(plugin);
1345
1346 #if PLATFORM(MAC)
1347     PluginModuleLoadPolicy currentPluginLoadPolicy = static_cast<PluginModuleLoadPolicy>(pluginLoadPolicy);
1348     pluginLoadPolicy = m_loaderClient.pluginLoadPolicy(this, plugin.bundleIdentifier, plugin.versionString, plugin.info.name, frameURLString, pageURLString, currentPluginLoadPolicy);
1349 #else
1350     UNUSED_PARAM(frameURLString);
1351     UNUSED_PARAM(pageURLString);
1352 #endif
1353
1354     if (pluginLoadPolicy != PluginModuleLoadNormally)
1355         return;
1356
1357     pluginPath = plugin.path;
1358 }
1359 #endif // ENABLE(NETSCAPE_PLUGIN_API)
1360
1361 #if ENABLE(GESTURE_EVENTS)
1362 void WebPageProxy::handleGestureEvent(const WebGestureEvent& event)
1363 {
1364     if (!isValid())
1365         return;
1366
1367     m_gestureEventQueue.append(event);
1368
1369     m_process->responsivenessTimer()->start();
1370     m_process->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0);
1371 }
1372 #endif
1373
1374 #if ENABLE(TOUCH_EVENTS)
1375 #if PLATFORM(QT)
1376 void WebPageProxy::handlePotentialActivation(const IntPoint& touchPoint, const IntSize& touchArea)
1377 {
1378     m_process->send(Messages::WebPage::HighlightPotentialActivation(touchPoint, touchArea), m_pageID);
1379 }
1380 #endif
1381
1382 void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event)
1383 {
1384     if (!isValid())
1385         return;
1386
1387     // If the page is suspended, which should be the case during panning, pinching
1388     // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then
1389     // we do not send any of the events to the page even if is has listeners.
1390     if (m_needTouchEvents && !m_isPageSuspended) {
1391         m_touchEventQueue.append(event);
1392         m_process->responsivenessTimer()->start();
1393         if (m_shouldSendEventsSynchronously) {
1394             bool handled = false;
1395             m_process->sendSync(Messages::WebPage::TouchEventSyncForTesting(event), Messages::WebPage::TouchEventSyncForTesting::Reply(handled), m_pageID);
1396             didReceiveEvent(event.type(), handled);
1397         } else
1398             m_process->send(Messages::WebPage::TouchEvent(event), m_pageID);
1399     } else {
1400         if (m_touchEventQueue.isEmpty()) {
1401             bool isEventHandled = false;
1402             m_pageClient->doneWithTouchEvent(event, isEventHandled);
1403         } else {
1404             // We attach the incoming events to the newest queued event so that all
1405             // the events are delivered in the correct order when the event is dequed.
1406             QueuedTouchEvents& lastEvent = m_touchEventQueue.last();
1407             lastEvent.deferredTouchEvents.append(event);
1408         }
1409     }
1410 }
1411 #endif
1412
1413 void WebPageProxy::scrollBy(ScrollDirection direction, ScrollGranularity granularity)
1414 {
1415     if (!isValid())
1416         return;
1417
1418     m_process->send(Messages::WebPage::ScrollBy(direction, granularity), m_pageID);
1419 }
1420
1421 void WebPageProxy::centerSelectionInVisibleArea()
1422 {
1423     if (!isValid())
1424         return;
1425
1426     m_process->send(Messages::WebPage::CenterSelectionInVisibleArea(), m_pageID);
1427 }
1428
1429 void WebPageProxy::receivedPolicyDecision(PolicyAction action, WebFrameProxy* frame, uint64_t listenerID)
1430 {
1431     if (!isValid())
1432         return;
1433
1434 #if ENABLE(NETWORK_PROCESS)
1435     // FIXME (NetworkProcess): Instead of canceling the load and then starting a separate download, we should
1436     // just convert the connection to a download connection. See <rdar://problem/12890184>.
1437     if (m_inDecidePolicyForResponse && action == PolicyDownload && m_process->context()->usesNetworkProcess()) {
1438         action = PolicyIgnore;
1439
1440         m_process->context()->download(this, *m_decidePolicyForResponseRequest);
1441     }
1442 #endif
1443
1444     if (action == PolicyIgnore)
1445         clearPendingAPIRequestURL();
1446
1447     uint64_t downloadID = 0;
1448     if (action == PolicyDownload) {
1449         // Create a download proxy.
1450         DownloadProxy* download = m_process->context()->createDownloadProxy();
1451         downloadID = download->downloadID();
1452 #if PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK)
1453         // Our design does not suppport downloads without a WebPage.
1454         handleDownloadRequest(download);
1455 #endif
1456     }
1457
1458     // If we received a policy decision while in decidePolicyForResponse the decision will
1459     // be sent back to the web process by decidePolicyForResponse.
1460     if (m_inDecidePolicyForResponse) {
1461         m_syncMimeTypePolicyActionIsValid = true;
1462         m_syncMimeTypePolicyAction = action;
1463         m_syncMimeTypePolicyDownloadID = downloadID;
1464         return;
1465     }
1466
1467     // If we received a policy decision while in decidePolicyForNavigationAction the decision will 
1468     // be sent back to the web process by decidePolicyForNavigationAction. 
1469     if (m_inDecidePolicyForNavigationAction) {
1470         m_syncNavigationActionPolicyActionIsValid = true;
1471         m_syncNavigationActionPolicyAction = action;
1472         m_syncNavigationActionPolicyDownloadID = downloadID;
1473         return;
1474     }
1475     
1476     m_process->send(Messages::WebPage::DidReceivePolicyDecision(frame->frameID(), listenerID, action, downloadID), m_pageID);
1477 }
1478
1479 String WebPageProxy::pageTitle() const
1480 {
1481     // Return the null string if there is no main frame (e.g. nothing has been loaded in the page yet, WebProcess has
1482     // crashed, page has been closed).
1483     if (!m_mainFrame)
1484         return String();
1485
1486     return m_mainFrame->title();
1487 }
1488
1489 void WebPageProxy::setUserAgent(const String& userAgent)
1490 {
1491     if (m_userAgent == userAgent)
1492         return;
1493     m_userAgent = userAgent;
1494
1495     if (!isValid())
1496         return;
1497     m_process->send(Messages::WebPage::SetUserAgent(m_userAgent), m_pageID);
1498 }
1499
1500 void WebPageProxy::setApplicationNameForUserAgent(const String& applicationName)
1501 {
1502     if (m_applicationNameForUserAgent == applicationName)
1503         return;
1504
1505     m_applicationNameForUserAgent = applicationName;
1506     if (!m_customUserAgent.isEmpty())
1507         return;
1508
1509     setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1510 }
1511
1512 void WebPageProxy::setCustomUserAgent(const String& customUserAgent)
1513 {
1514     if (m_customUserAgent == customUserAgent)
1515         return;
1516
1517     m_customUserAgent = customUserAgent;
1518
1519     if (m_customUserAgent.isEmpty()) {
1520         setUserAgent(standardUserAgent(m_applicationNameForUserAgent));
1521         return;
1522     }
1523
1524     setUserAgent(m_customUserAgent);
1525 }
1526
1527 void WebPageProxy::resumeActiveDOMObjectsAndAnimations()
1528 {
1529     if (!isValid() || !m_isPageSuspended)
1530         return;
1531
1532     m_isPageSuspended = false;
1533
1534     m_process->send(Messages::WebPage::ResumeActiveDOMObjectsAndAnimations(), m_pageID);
1535 }
1536
1537 void WebPageProxy::suspendActiveDOMObjectsAndAnimations()
1538 {
1539     if (!isValid() || m_isPageSuspended)
1540         return;
1541
1542     m_isPageSuspended = true;
1543
1544     m_process->send(Messages::WebPage::SuspendActiveDOMObjectsAndAnimations(), m_pageID);
1545 }
1546
1547 bool WebPageProxy::supportsTextEncoding() const
1548 {
1549     return !m_mainFrameHasCustomRepresentation && m_mainFrame && !m_mainFrame->isDisplayingStandaloneImageDocument();
1550 }
1551
1552 void WebPageProxy::setCustomTextEncodingName(const String& encodingName)
1553 {
1554     if (m_customTextEncodingName == encodingName)
1555         return;
1556     m_customTextEncodingName = encodingName;
1557
1558     if (!isValid())
1559         return;
1560     m_process->send(Messages::WebPage::SetCustomTextEncodingName(encodingName), m_pageID);
1561 }
1562
1563 void WebPageProxy::terminateProcess()
1564 {
1565     // NOTE: This uses a check of m_isValid rather than calling isValid() since
1566     // we want this to run even for pages being closed or that already closed.
1567     if (!m_isValid)
1568         return;
1569
1570     m_process->terminate();
1571 }
1572
1573 #if !USE(CF) || defined(BUILDING_QT__)
1574 PassRefPtr<WebData> WebPageProxy::sessionStateData(WebPageProxySessionStateFilterCallback, void* /*context*/) const
1575 {
1576     // FIXME: Return session state data for saving Page state.
1577     return 0;
1578 }
1579
1580 void WebPageProxy::restoreFromSessionStateData(WebData*)
1581 {
1582     // FIXME: Restore the Page from the passed in session state data.
1583 }
1584 #endif
1585
1586 bool WebPageProxy::supportsTextZoom() const
1587 {
1588     if (m_mainFrameHasCustomRepresentation)
1589         return false;
1590
1591     // FIXME: This should also return false for standalone media and plug-in documents.
1592     if (!m_mainFrame || m_mainFrame->isDisplayingStandaloneImageDocument())
1593         return false;
1594
1595     return true;
1596 }
1597  
1598 void WebPageProxy::setTextZoomFactor(double zoomFactor)
1599 {
1600     if (!isValid())
1601         return;
1602
1603     if (m_mainFrameHasCustomRepresentation)
1604         return;
1605
1606     if (m_textZoomFactor == zoomFactor)
1607         return;
1608
1609     m_textZoomFactor = zoomFactor;
1610     m_process->send(Messages::WebPage::SetTextZoomFactor(m_textZoomFactor), m_pageID); 
1611 }
1612
1613 double WebPageProxy::pageZoomFactor() const
1614 {
1615     return m_mainFrameHasCustomRepresentation ? m_pageClient->customRepresentationZoomFactor() : m_pageZoomFactor;
1616 }
1617
1618 void WebPageProxy::setPageZoomFactor(double zoomFactor)
1619 {
1620     if (!isValid())
1621         return;
1622
1623     if (m_mainFrameHasCustomRepresentation) {
1624         m_pageClient->setCustomRepresentationZoomFactor(zoomFactor);
1625         return;
1626     }
1627
1628     if (m_pageZoomFactor == zoomFactor)
1629         return;
1630
1631     m_pageZoomFactor = zoomFactor;
1632     m_process->send(Messages::WebPage::SetPageZoomFactor(m_pageZoomFactor), m_pageID); 
1633 }
1634
1635 void WebPageProxy::setPageAndTextZoomFactors(double pageZoomFactor, double textZoomFactor)
1636 {
1637     if (!isValid())
1638         return;
1639
1640     if (m_mainFrameHasCustomRepresentation) {
1641         m_pageClient->setCustomRepresentationZoomFactor(pageZoomFactor);
1642         return;
1643     }
1644
1645     if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
1646         return;
1647
1648     m_pageZoomFactor = pageZoomFactor;
1649     m_textZoomFactor = textZoomFactor;
1650     m_process->send(Messages::WebPage::SetPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor), m_pageID); 
1651 }
1652
1653 void WebPageProxy::scalePage(double scale, const IntPoint& origin)
1654 {
1655     if (!isValid())
1656         return;
1657
1658     m_process->send(Messages::WebPage::ScalePage(scale, origin), m_pageID);
1659 }
1660
1661 void WebPageProxy::setIntrinsicDeviceScaleFactor(float scaleFactor)
1662 {
1663     if (m_intrinsicDeviceScaleFactor == scaleFactor)
1664         return;
1665
1666     m_intrinsicDeviceScaleFactor = scaleFactor;
1667
1668     if (m_drawingArea)
1669         m_drawingArea->deviceScaleFactorDidChange();
1670 }
1671
1672 void WebPageProxy::windowScreenDidChange(PlatformDisplayID displayID)
1673 {
1674     if (!isValid())
1675         return;
1676
1677     m_process->send(Messages::WebPage::WindowScreenDidChange(displayID), m_pageID);
1678 }
1679
1680 float WebPageProxy::deviceScaleFactor() const
1681 {
1682     if (m_customDeviceScaleFactor)
1683         return m_customDeviceScaleFactor;
1684     return m_intrinsicDeviceScaleFactor;
1685 }
1686
1687 void WebPageProxy::setCustomDeviceScaleFactor(float customScaleFactor)
1688 {
1689     if (!isValid())
1690         return;
1691
1692     if (m_customDeviceScaleFactor == customScaleFactor)
1693         return;
1694
1695     float oldScaleFactor = deviceScaleFactor();
1696
1697     m_customDeviceScaleFactor = customScaleFactor;
1698
1699     if (deviceScaleFactor() != oldScaleFactor)
1700         m_drawingArea->deviceScaleFactorDidChange();
1701 }
1702
1703 void WebPageProxy::setUseFixedLayout(bool fixed)
1704 {
1705     if (!isValid())
1706         return;
1707
1708     // This check is fine as the value is initialized in the web
1709     // process as part of the creation parameters.
1710     if (fixed == m_useFixedLayout)
1711         return;
1712
1713     m_useFixedLayout = fixed;
1714     if (!fixed)
1715         m_fixedLayoutSize = IntSize();
1716     m_process->send(Messages::WebPage::SetUseFixedLayout(fixed), m_pageID);
1717 }
1718
1719 void WebPageProxy::setFixedLayoutSize(const IntSize& size)
1720 {
1721     if (!isValid())
1722         return;
1723
1724     if (size == m_fixedLayoutSize)
1725         return;
1726
1727     m_fixedLayoutSize = size;
1728     m_process->send(Messages::WebPage::SetFixedLayoutSize(size), m_pageID);
1729 }
1730
1731 void WebPageProxy::listenForLayoutMilestones(WebCore::LayoutMilestones milestones)
1732 {
1733     if (!isValid())
1734         return;
1735
1736     m_process->send(Messages::WebPage::ListenForLayoutMilestones(milestones), m_pageID);
1737 }
1738
1739 void WebPageProxy::setVisibilityState(WebCore::PageVisibilityState visibilityState, bool isInitialState)
1740 {
1741     if (!isValid())
1742         return;
1743
1744 #if ENABLE(PAGE_VISIBILITY_API)
1745     if (visibilityState != m_visibilityState || isInitialState) {
1746         m_visibilityState = visibilityState;
1747         m_process->send(Messages::WebPage::SetVisibilityState(visibilityState, isInitialState), m_pageID);
1748     }
1749 #endif
1750 }
1751
1752 void WebPageProxy::setSuppressScrollbarAnimations(bool suppressAnimations)
1753 {
1754     if (!isValid())
1755         return;
1756
1757     if (suppressAnimations == m_suppressScrollbarAnimations)
1758         return;
1759
1760     m_suppressScrollbarAnimations = suppressAnimations;
1761     m_process->send(Messages::WebPage::SetSuppressScrollbarAnimations(suppressAnimations), m_pageID);
1762 }
1763
1764 void WebPageProxy::setRubberBandsAtBottom(bool rubberBandsAtBottom)
1765 {
1766     if (rubberBandsAtBottom == m_rubberBandsAtBottom)
1767         return;
1768
1769     m_rubberBandsAtBottom = rubberBandsAtBottom;
1770
1771     if (!isValid())
1772         return;
1773
1774     m_process->send(Messages::WebPage::SetRubberBandsAtBottom(rubberBandsAtBottom), m_pageID);
1775 }
1776
1777 void WebPageProxy::setRubberBandsAtTop(bool rubberBandsAtTop)
1778 {
1779     if (rubberBandsAtTop == m_rubberBandsAtTop)
1780         return;
1781
1782     m_rubberBandsAtTop = rubberBandsAtTop;
1783
1784     if (!isValid())
1785         return;
1786
1787     m_process->send(Messages::WebPage::SetRubberBandsAtTop(rubberBandsAtTop), m_pageID);
1788 }
1789
1790 void WebPageProxy::setPaginationMode(WebCore::Pagination::Mode mode)
1791 {
1792     if (mode == m_paginationMode)
1793         return;
1794
1795     m_paginationMode = mode;
1796
1797     if (!isValid())
1798         return;
1799     m_process->send(Messages::WebPage::SetPaginationMode(mode), m_pageID);
1800 }
1801
1802 void WebPageProxy::setPaginationBehavesLikeColumns(bool behavesLikeColumns)
1803 {
1804     if (behavesLikeColumns == m_paginationBehavesLikeColumns)
1805         return;
1806
1807     m_paginationBehavesLikeColumns = behavesLikeColumns;
1808
1809     if (!isValid())
1810         return;
1811     m_process->send(Messages::WebPage::SetPaginationBehavesLikeColumns(behavesLikeColumns), m_pageID);
1812 }
1813
1814 void WebPageProxy::setPageLength(double pageLength)
1815 {
1816     if (pageLength == m_pageLength)
1817         return;
1818
1819     m_pageLength = pageLength;
1820
1821     if (!isValid())
1822         return;
1823     m_process->send(Messages::WebPage::SetPageLength(pageLength), m_pageID);
1824 }
1825
1826 void WebPageProxy::setGapBetweenPages(double gap)
1827 {
1828     if (gap == m_gapBetweenPages)
1829         return;
1830
1831     m_gapBetweenPages = gap;
1832
1833     if (!isValid())
1834         return;
1835     m_process->send(Messages::WebPage::SetGapBetweenPages(gap), m_pageID);
1836 }
1837
1838 void WebPageProxy::pageScaleFactorDidChange(double scaleFactor)
1839 {
1840     m_pageScaleFactor = scaleFactor;
1841 }
1842
1843 void WebPageProxy::pageZoomFactorDidChange(double zoomFactor)
1844 {
1845     m_pageZoomFactor = zoomFactor;
1846 }
1847
1848 void WebPageProxy::setMemoryCacheClientCallsEnabled(bool memoryCacheClientCallsEnabled)
1849 {
1850     if (!isValid())
1851         return;
1852
1853     if (m_areMemoryCacheClientCallsEnabled == memoryCacheClientCallsEnabled)
1854         return;
1855
1856     m_areMemoryCacheClientCallsEnabled = memoryCacheClientCallsEnabled;
1857     m_process->send(Messages::WebPage::SetMemoryCacheMessagesEnabled(memoryCacheClientCallsEnabled), m_pageID);
1858 }
1859
1860 void WebPageProxy::findStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
1861 {
1862     if (string.isEmpty()) {
1863         didFindStringMatches(string, Vector<Vector<WebCore::IntRect> > (), 0);
1864         return;
1865     }
1866
1867     m_process->send(Messages::WebPage::FindStringMatches(string, options, maxMatchCount), m_pageID);
1868 }
1869
1870 void WebPageProxy::findString(const String& string, FindOptions options, unsigned maxMatchCount)
1871 {
1872     if (m_mainFrameHasCustomRepresentation)
1873         m_pageClient->findStringInCustomRepresentation(string, options, maxMatchCount);
1874     else
1875         m_process->send(Messages::WebPage::FindString(string, options, maxMatchCount), m_pageID);
1876 }
1877
1878 void WebPageProxy::getImageForFindMatch(int32_t matchIndex)
1879 {
1880     m_process->send(Messages::WebPage::GetImageForFindMatch(matchIndex), m_pageID);
1881 }
1882
1883 void WebPageProxy::selectFindMatch(int32_t matchIndex)
1884 {
1885     m_process->send(Messages::WebPage::SelectFindMatch(matchIndex), m_pageID);
1886 }
1887
1888 void WebPageProxy::hideFindUI()
1889 {
1890     m_process->send(Messages::WebPage::HideFindUI(), m_pageID);
1891 }
1892
1893 void WebPageProxy::countStringMatches(const String& string, FindOptions options, unsigned maxMatchCount)
1894 {
1895     if (m_mainFrameHasCustomRepresentation) {
1896         m_pageClient->countStringMatchesInCustomRepresentation(string, options, maxMatchCount);
1897         return;
1898     }
1899
1900     if (!isValid())
1901         return;
1902
1903     m_process->send(Messages::WebPage::CountStringMatches(string, options, maxMatchCount), m_pageID);
1904 }
1905
1906 void WebPageProxy::runJavaScriptInMainFrame(const String& script, PassRefPtr<ScriptValueCallback> prpCallback)
1907 {
1908     RefPtr<ScriptValueCallback> callback = prpCallback;
1909     if (!isValid()) {
1910         callback->invalidate();
1911         return;
1912     }
1913
1914     uint64_t callbackID = callback->callbackID();
1915     m_scriptValueCallbacks.set(callbackID, callback.get());
1916     m_process->send(Messages::WebPage::RunJavaScriptInMainFrame(script, callbackID), m_pageID);
1917 }
1918
1919 void WebPageProxy::getRenderTreeExternalRepresentation(PassRefPtr<StringCallback> prpCallback)
1920 {
1921     RefPtr<StringCallback> callback = prpCallback;
1922     if (!isValid()) {
1923         callback->invalidate();
1924         return;
1925     }
1926     
1927     uint64_t callbackID = callback->callbackID();
1928     m_stringCallbacks.set(callbackID, callback.get());
1929     m_process->send(Messages::WebPage::GetRenderTreeExternalRepresentation(callbackID), m_pageID);
1930 }
1931
1932 void WebPageProxy::getSourceForFrame(WebFrameProxy* frame, PassRefPtr<StringCallback> prpCallback)
1933 {
1934     RefPtr<StringCallback> callback = prpCallback;
1935     if (!isValid()) {
1936         callback->invalidate();
1937         return;
1938     }
1939     
1940     uint64_t callbackID = callback->callbackID();
1941     m_loadDependentStringCallbackIDs.add(callbackID);
1942     m_stringCallbacks.set(callbackID, callback.get());
1943     m_process->send(Messages::WebPage::GetSourceForFrame(frame->frameID(), callbackID), m_pageID);
1944 }
1945
1946 void WebPageProxy::getContentsAsString(PassRefPtr<StringCallback> prpCallback)
1947 {
1948     RefPtr<StringCallback> callback = prpCallback;
1949     if (!isValid()) {
1950         callback->invalidate();
1951         return;
1952     }
1953     
1954     uint64_t callbackID = callback->callbackID();
1955     m_loadDependentStringCallbackIDs.add(callbackID);
1956     m_stringCallbacks.set(callbackID, callback.get());
1957     m_process->send(Messages::WebPage::GetContentsAsString(callbackID), m_pageID);
1958 }
1959
1960 #if ENABLE(MHTML)
1961 void WebPageProxy::getContentsAsMHTMLData(PassRefPtr<DataCallback> prpCallback, bool useBinaryEncoding)
1962 {
1963     RefPtr<DataCallback> callback = prpCallback;
1964     if (!isValid()) {
1965         callback->invalidate();
1966         return;
1967     }
1968
1969     uint64_t callbackID = callback->callbackID();
1970     m_dataCallbacks.set(callbackID, callback.get());
1971     m_process->send(Messages::WebPage::GetContentsAsMHTMLData(callbackID, useBinaryEncoding), m_pageID);
1972 }
1973 #endif
1974
1975 void WebPageProxy::getSelectionOrContentsAsString(PassRefPtr<StringCallback> prpCallback)
1976 {
1977     RefPtr<StringCallback> callback = prpCallback;
1978     if (!isValid()) {
1979         callback->invalidate();
1980         return;
1981     }
1982     
1983     uint64_t callbackID = callback->callbackID();
1984     m_stringCallbacks.set(callbackID, callback.get());
1985     m_process->send(Messages::WebPage::GetSelectionOrContentsAsString(callbackID), m_pageID);
1986 }
1987
1988 void WebPageProxy::getSelectionAsWebArchiveData(PassRefPtr<DataCallback> prpCallback)
1989 {
1990     RefPtr<DataCallback> callback = prpCallback;
1991     if (!isValid()) {
1992         callback->invalidate();
1993         return;
1994     }
1995     
1996     uint64_t callbackID = callback->callbackID();
1997     m_dataCallbacks.set(callbackID, callback.get());
1998     m_process->send(Messages::WebPage::GetSelectionAsWebArchiveData(callbackID), m_pageID);
1999 }
2000
2001 void WebPageProxy::getMainResourceDataOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
2002 {
2003     RefPtr<DataCallback> callback = prpCallback;
2004     if (!isValid()) {
2005         callback->invalidate();
2006         return;
2007     }
2008     
2009     uint64_t callbackID = callback->callbackID();
2010     m_dataCallbacks.set(callbackID, callback.get());
2011     m_process->send(Messages::WebPage::GetMainResourceDataOfFrame(frame->frameID(), callbackID), m_pageID);
2012 }
2013
2014 void WebPageProxy::getResourceDataFromFrame(WebFrameProxy* frame, WebURL* resourceURL, PassRefPtr<DataCallback> prpCallback)
2015 {
2016     RefPtr<DataCallback> callback = prpCallback;
2017     if (!isValid()) {
2018         callback->invalidate();
2019         return;
2020     }
2021     
2022     uint64_t callbackID = callback->callbackID();
2023     m_dataCallbacks.set(callbackID, callback.get());
2024     m_process->send(Messages::WebPage::GetResourceDataFromFrame(frame->frameID(), resourceURL->string(), callbackID), m_pageID);
2025 }
2026
2027 void WebPageProxy::getWebArchiveOfFrame(WebFrameProxy* frame, PassRefPtr<DataCallback> prpCallback)
2028 {
2029     RefPtr<DataCallback> callback = prpCallback;
2030     if (!isValid()) {
2031         callback->invalidate();
2032         return;
2033     }
2034     
2035     uint64_t callbackID = callback->callbackID();
2036     m_dataCallbacks.set(callbackID, callback.get());
2037     m_process->send(Messages::WebPage::GetWebArchiveOfFrame(frame->frameID(), callbackID), m_pageID);
2038 }
2039
2040 void WebPageProxy::forceRepaint(PassRefPtr<VoidCallback> prpCallback)
2041 {
2042     RefPtr<VoidCallback> callback = prpCallback;
2043     if (!isValid()) {
2044         callback->invalidate();
2045         return;
2046     }
2047
2048     uint64_t callbackID = callback->callbackID();
2049     m_voidCallbacks.set(callbackID, callback.get());
2050     m_drawingArea->waitForBackingStoreUpdateOnNextPaint();
2051     m_process->send(Messages::WebPage::ForceRepaint(callbackID), m_pageID); 
2052 }
2053
2054 void WebPageProxy::preferencesDidChange()
2055 {
2056     if (!isValid())
2057         return;
2058
2059 #if ENABLE(INSPECTOR_SERVER)
2060     if (m_pageGroup->preferences()->developerExtrasEnabled())
2061         inspector()->enableRemoteInspection();
2062 #endif
2063
2064     m_process->pagePreferencesChanged(this);
2065
2066     // FIXME: It probably makes more sense to send individual preference changes.
2067     // However, WebKitTestRunner depends on getting a preference change notification
2068     // even if nothing changed in UI process, so that overrides get removed.
2069
2070     // Preferences need to be updated during synchronous printing to make "print backgrounds" preference work when toggled from a print dialog checkbox.
2071     m_process->send(Messages::WebPage::PreferencesDidChange(pageGroup()->preferences()->store()), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
2072 }
2073
2074 void WebPageProxy::didCreateMainFrame(uint64_t frameID)
2075 {
2076     MESSAGE_CHECK(!m_mainFrame);
2077     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2078
2079     m_mainFrame = WebFrameProxy::create(this, frameID);
2080
2081     // Add the frame to the process wide map.
2082     m_process->frameCreated(frameID, m_mainFrame.get());
2083 }
2084
2085 void WebPageProxy::didCreateSubframe(uint64_t frameID)
2086 {
2087     MESSAGE_CHECK(m_mainFrame);
2088     MESSAGE_CHECK(m_process->canCreateFrame(frameID));
2089     
2090     RefPtr<WebFrameProxy> subFrame = WebFrameProxy::create(this, frameID);
2091
2092     // Add the frame to the process wide map.
2093     m_process->frameCreated(frameID, subFrame.get());
2094 }
2095
2096 // Always start progress at initialProgressValue. This helps provide feedback as
2097 // soon as a load starts.
2098
2099 static const double initialProgressValue = 0.1;
2100
2101 double WebPageProxy::estimatedProgress() const
2102 {
2103     if (!pendingAPIRequestURL().isNull())
2104         return initialProgressValue;
2105     return m_estimatedProgress; 
2106 }
2107
2108 void WebPageProxy::didStartProgress()
2109 {
2110     m_estimatedProgress = initialProgressValue;
2111
2112     m_loaderClient.didStartProgress(this);
2113 }
2114
2115 void WebPageProxy::didChangeProgress(double value)
2116 {
2117     m_estimatedProgress = value;
2118
2119     m_loaderClient.didChangeProgress(this);
2120 }
2121
2122 void WebPageProxy::didFinishProgress()
2123 {
2124     m_estimatedProgress = 1.0;
2125
2126     m_loaderClient.didFinishProgress(this);
2127 }
2128
2129 void WebPageProxy::didStartProvisionalLoadForFrame(uint64_t frameID, const String& url, const String& unreachableURL, CoreIPC::MessageDecoder& decoder)
2130 {
2131     clearPendingAPIRequestURL();
2132
2133     RefPtr<APIObject> userData;
2134     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2135     if (!decoder.decode(messageDecoder))
2136         return;
2137
2138     WebFrameProxy* frame = m_process->webFrame(frameID);
2139     MESSAGE_CHECK(frame);
2140     MESSAGE_CHECK_URL(url);
2141
2142     frame->setUnreachableURL(unreachableURL);
2143
2144     frame->didStartProvisionalLoad(url);
2145     m_loaderClient.didStartProvisionalLoadForFrame(this, frame, userData.get());
2146 }
2147
2148 void WebPageProxy::didReceiveServerRedirectForProvisionalLoadForFrame(uint64_t frameID, const String& url, CoreIPC::MessageDecoder& decoder)
2149 {
2150     RefPtr<APIObject> userData;
2151     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2152     if (!decoder.decode(messageDecoder))
2153         return;
2154
2155     WebFrameProxy* frame = m_process->webFrame(frameID);
2156     MESSAGE_CHECK(frame);
2157     MESSAGE_CHECK_URL(url);
2158
2159     frame->didReceiveServerRedirectForProvisionalLoad(url);
2160
2161     m_loaderClient.didReceiveServerRedirectForProvisionalLoadForFrame(this, frame, userData.get());
2162 }
2163
2164 void WebPageProxy::didFailProvisionalLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder)
2165 {
2166     RefPtr<APIObject> userData;
2167     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2168     if (!decoder.decode(messageDecoder))
2169         return;
2170
2171     WebFrameProxy* frame = m_process->webFrame(frameID);
2172     MESSAGE_CHECK(frame);
2173
2174     frame->didFailProvisionalLoad();
2175
2176     m_loaderClient.didFailProvisionalLoadWithErrorForFrame(this, frame, error, userData.get());
2177 }
2178
2179 void WebPageProxy::clearLoadDependentCallbacks()
2180 {
2181     Vector<uint64_t> callbackIDsCopy;
2182     copyToVector(m_loadDependentStringCallbackIDs, callbackIDsCopy);
2183     m_loadDependentStringCallbackIDs.clear();
2184
2185     for (size_t i = 0; i < callbackIDsCopy.size(); ++i) {
2186         RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackIDsCopy[i]);
2187         if (callback)
2188             callback->invalidate();
2189     }
2190 }
2191
2192 void WebPageProxy::didCommitLoadForFrame(uint64_t frameID, const String& mimeType, bool frameHasCustomRepresentation, uint32_t opaqueFrameLoadType, const PlatformCertificateInfo& certificateInfo, CoreIPC::MessageDecoder& decoder)
2193 {
2194     RefPtr<APIObject> userData;
2195     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2196     if (!decoder.decode(messageDecoder))
2197         return;
2198
2199     WebFrameProxy* frame = m_process->webFrame(frameID);
2200     MESSAGE_CHECK(frame);
2201
2202 #if PLATFORM(MAC)
2203     // FIXME (bug 59111): didCommitLoadForFrame comes too late when restoring a page from b/f cache, making us disable secure event mode in password fields.
2204     // FIXME (bug 59121): A load going on in one frame shouldn't affect typing in sibling frames.
2205     m_pageClient->resetTextInputState();
2206     // FIXME: Should this be moved inside resetTextInputState()?
2207     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2208     m_pageClient->dismissDictionaryLookupPanel();
2209 #endif
2210
2211     clearLoadDependentCallbacks();
2212
2213     frame->didCommitLoad(mimeType, certificateInfo);
2214
2215     if (frame->isMainFrame()) {
2216         m_mainFrameHasCustomRepresentation = frameHasCustomRepresentation;
2217
2218         if (m_mainFrameHasCustomRepresentation) {
2219             // Always assume that the main frame is pinned here, since the custom representation view will handle
2220             // any wheel events and dispatch them to the WKView when necessary.
2221             m_mainFrameIsPinnedToLeftSide = true;
2222             m_mainFrameIsPinnedToRightSide = true;
2223             m_mainFrameIsPinnedToTopSide = true;
2224             m_mainFrameIsPinnedToBottomSide = true;
2225         }
2226         m_pageClient->didCommitLoadForMainFrame(frameHasCustomRepresentation);
2227     }
2228
2229     // Even if WebPage has the default pageScaleFactor (and therefore doesn't reset it),
2230     // WebPageProxy's cache of the value can get out of sync (e.g. in the case where a
2231     // plugin is handling page scaling itself) so we should reset it to the default
2232     // for standard main frame loads.
2233     if (frame->isMainFrame() && static_cast<FrameLoadType>(opaqueFrameLoadType) == FrameLoadTypeStandard)
2234         m_pageScaleFactor = 1;
2235
2236     m_loaderClient.didCommitLoadForFrame(this, frame, userData.get());
2237 }
2238
2239 void WebPageProxy::didFinishDocumentLoadForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2240 {
2241     RefPtr<APIObject> userData;
2242     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2243     if (!decoder.decode(messageDecoder))
2244         return;
2245
2246     WebFrameProxy* frame = m_process->webFrame(frameID);
2247     MESSAGE_CHECK(frame);
2248
2249     m_loaderClient.didFinishDocumentLoadForFrame(this, frame, userData.get());
2250 }
2251
2252 void WebPageProxy::didFinishLoadForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2253 {
2254     RefPtr<APIObject> userData;
2255     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2256     if (!decoder.decode(messageDecoder))
2257         return;
2258
2259     WebFrameProxy* frame = m_process->webFrame(frameID);
2260     MESSAGE_CHECK(frame);
2261
2262     frame->didFinishLoad();
2263
2264     m_loaderClient.didFinishLoadForFrame(this, frame, userData.get());
2265 }
2266
2267 void WebPageProxy::didFailLoadForFrame(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder)
2268 {
2269     RefPtr<APIObject> userData;
2270     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2271     if (!decoder.decode(messageDecoder))
2272         return;
2273
2274     WebFrameProxy* frame = m_process->webFrame(frameID);
2275     MESSAGE_CHECK(frame);
2276
2277     clearLoadDependentCallbacks();
2278
2279     frame->didFailLoad();
2280
2281     m_loaderClient.didFailLoadWithErrorForFrame(this, frame, error, userData.get());
2282 }
2283
2284 void WebPageProxy::didSameDocumentNavigationForFrame(uint64_t frameID, uint32_t opaqueSameDocumentNavigationType, const String& url, CoreIPC::MessageDecoder& decoder)
2285 {
2286     RefPtr<APIObject> userData;
2287     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2288     if (!decoder.decode(messageDecoder))
2289         return;
2290
2291     WebFrameProxy* frame = m_process->webFrame(frameID);
2292     MESSAGE_CHECK(frame);
2293     MESSAGE_CHECK_URL(url);
2294
2295     clearPendingAPIRequestURL();
2296     frame->didSameDocumentNavigation(url);
2297
2298     m_loaderClient.didSameDocumentNavigationForFrame(this, frame, static_cast<SameDocumentNavigationType>(opaqueSameDocumentNavigationType), userData.get());
2299 }
2300
2301 void WebPageProxy::didReceiveTitleForFrame(uint64_t frameID, const String& title, CoreIPC::MessageDecoder& decoder)
2302 {
2303     RefPtr<APIObject> userData;
2304     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2305     if (!decoder.decode(messageDecoder))
2306         return;
2307
2308     WebFrameProxy* frame = m_process->webFrame(frameID);
2309     MESSAGE_CHECK(frame);
2310
2311     frame->didChangeTitle(title);
2312     
2313     m_loaderClient.didReceiveTitleForFrame(this, title, frame, userData.get());
2314 }
2315
2316 void WebPageProxy::didFirstLayoutForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2317 {
2318     RefPtr<APIObject> userData;
2319     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2320     if (!decoder.decode(messageDecoder))
2321         return;
2322
2323     WebFrameProxy* frame = m_process->webFrame(frameID);
2324     MESSAGE_CHECK(frame);
2325
2326     m_loaderClient.didFirstLayoutForFrame(this, frame, userData.get());
2327 }
2328
2329 void WebPageProxy::didFirstVisuallyNonEmptyLayoutForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2330 {
2331     RefPtr<APIObject> userData;
2332     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2333     if (!decoder.decode(messageDecoder))
2334         return;
2335
2336     WebFrameProxy* frame = m_process->webFrame(frameID);
2337     MESSAGE_CHECK(frame);
2338
2339     m_loaderClient.didFirstVisuallyNonEmptyLayoutForFrame(this, frame, userData.get());
2340 }
2341
2342 void WebPageProxy::didNewFirstVisuallyNonEmptyLayout(CoreIPC::MessageDecoder& decoder)
2343 {
2344     RefPtr<APIObject> userData;
2345     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2346     if (!decoder.decode(messageDecoder))
2347         return;
2348
2349     m_loaderClient.didNewFirstVisuallyNonEmptyLayout(this, userData.get());
2350 }
2351
2352 void WebPageProxy::didLayout(uint32_t layoutMilestones, CoreIPC::MessageDecoder& decoder)
2353 {
2354     RefPtr<APIObject> userData;
2355     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2356     if (!decoder.decode(messageDecoder))
2357         return;
2358
2359     m_loaderClient.didLayout(this, static_cast<LayoutMilestones>(layoutMilestones), userData.get());
2360 }
2361
2362 void WebPageProxy::didRemoveFrameFromHierarchy(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2363 {
2364     RefPtr<APIObject> userData;
2365     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2366     if (!decoder.decode(messageDecoder))
2367         return;
2368
2369     WebFrameProxy* frame = m_process->webFrame(frameID);
2370     MESSAGE_CHECK(frame);
2371
2372     m_loaderClient.didRemoveFrameFromHierarchy(this, frame, userData.get());
2373 }
2374
2375 void WebPageProxy::didDisplayInsecureContentForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2376 {
2377     RefPtr<APIObject> userData;
2378     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2379     if (!decoder.decode(messageDecoder))
2380         return;
2381
2382     WebFrameProxy* frame = m_process->webFrame(frameID);
2383     MESSAGE_CHECK(frame);
2384
2385     m_loaderClient.didDisplayInsecureContentForFrame(this, frame, userData.get());
2386 }
2387
2388 void WebPageProxy::didRunInsecureContentForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2389 {
2390     RefPtr<APIObject> userData;
2391     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2392     if (!decoder.decode(messageDecoder))
2393         return;
2394
2395     WebFrameProxy* frame = m_process->webFrame(frameID);
2396     MESSAGE_CHECK(frame);
2397
2398     m_loaderClient.didRunInsecureContentForFrame(this, frame, userData.get());
2399 }
2400
2401 void WebPageProxy::didDetectXSSForFrame(uint64_t frameID, CoreIPC::MessageDecoder& decoder)
2402 {
2403     RefPtr<APIObject> userData;
2404     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2405     if (!decoder.decode(messageDecoder))
2406         return;
2407
2408     WebFrameProxy* frame = m_process->webFrame(frameID);
2409     MESSAGE_CHECK(frame);
2410
2411     m_loaderClient.didDetectXSSForFrame(this, frame, userData.get());
2412 }
2413
2414 void WebPageProxy::frameDidBecomeFrameSet(uint64_t frameID, bool value)
2415 {
2416     WebFrameProxy* frame = m_process->webFrame(frameID);
2417     MESSAGE_CHECK(frame);
2418
2419     frame->setIsFrameSet(value);
2420     if (frame->isMainFrame())
2421         m_frameSetLargestFrame = value ? m_mainFrame : 0;
2422 }
2423
2424 // PolicyClient
2425 void WebPageProxy::decidePolicyForNavigationAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const ResourceRequest& request, uint64_t listenerID, CoreIPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
2426 {
2427     RefPtr<APIObject> userData;
2428     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2429     if (!decoder.decode(messageDecoder))
2430         return;
2431
2432     if (request.url() != pendingAPIRequestURL())
2433         clearPendingAPIRequestURL();
2434
2435     WebFrameProxy* frame = m_process->webFrame(frameID);
2436     MESSAGE_CHECK(frame);
2437     MESSAGE_CHECK_URL(request.url());
2438
2439     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
2440     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
2441     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
2442     
2443     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2444
2445     ASSERT(!m_inDecidePolicyForNavigationAction);
2446
2447     m_inDecidePolicyForNavigationAction = true;
2448     m_syncNavigationActionPolicyActionIsValid = false;
2449     
2450     if (!m_policyClient.decidePolicyForNavigationAction(this, frame, navigationType, modifiers, mouseButton, request, listener.get(), userData.get()))
2451         listener->use();
2452
2453     m_inDecidePolicyForNavigationAction = false;
2454
2455     // Check if we received a policy decision already. If we did, we can just pass it back.
2456     receivedPolicyAction = m_syncNavigationActionPolicyActionIsValid;
2457     if (m_syncNavigationActionPolicyActionIsValid) {
2458         policyAction = m_syncNavigationActionPolicyAction;
2459         downloadID = m_syncNavigationActionPolicyDownloadID;
2460     }
2461 }
2462
2463 void WebPageProxy::decidePolicyForNewWindowAction(uint64_t frameID, uint32_t opaqueNavigationType, uint32_t opaqueModifiers, int32_t opaqueMouseButton, const ResourceRequest& request, const String& frameName, uint64_t listenerID, CoreIPC::MessageDecoder& decoder)
2464 {
2465     RefPtr<APIObject> userData;
2466     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2467     if (!decoder.decode(messageDecoder))
2468         return;
2469
2470     WebFrameProxy* frame = m_process->webFrame(frameID);
2471     MESSAGE_CHECK(frame);
2472     MESSAGE_CHECK_URL(request.url());
2473
2474     NavigationType navigationType = static_cast<NavigationType>(opaqueNavigationType);
2475     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
2476     WebMouseEvent::Button mouseButton = static_cast<WebMouseEvent::Button>(opaqueMouseButton);
2477
2478     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2479     if (!m_policyClient.decidePolicyForNewWindowAction(this, frame, navigationType, modifiers, mouseButton, request, frameName, listener.get(), userData.get()))
2480         listener->use();
2481 }
2482
2483 void WebPageProxy::decidePolicyForResponse(uint64_t frameID, const ResourceResponse& response, const ResourceRequest& request, uint64_t listenerID, CoreIPC::MessageDecoder& decoder, bool& receivedPolicyAction, uint64_t& policyAction, uint64_t& downloadID)
2484 {
2485     RefPtr<APIObject> userData;
2486     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2487     if (!decoder.decode(messageDecoder))
2488         return;
2489
2490     WebFrameProxy* frame = m_process->webFrame(frameID);
2491     MESSAGE_CHECK(frame);
2492     MESSAGE_CHECK_URL(request.url());
2493     MESSAGE_CHECK_URL(response.url());
2494     
2495     RefPtr<WebFramePolicyListenerProxy> listener = frame->setUpPolicyListenerProxy(listenerID);
2496
2497     ASSERT(!m_inDecidePolicyForResponse);
2498
2499     m_inDecidePolicyForResponse = true;
2500     m_decidePolicyForResponseRequest = &request;
2501     m_syncMimeTypePolicyActionIsValid = false;
2502
2503     if (!m_policyClient.decidePolicyForResponse(this, frame, response, request, listener.get(), userData.get()))
2504         listener->use();
2505
2506     m_inDecidePolicyForResponse = false;
2507     m_decidePolicyForResponseRequest = 0;
2508
2509     // Check if we received a policy decision already. If we did, we can just pass it back.
2510     receivedPolicyAction = m_syncMimeTypePolicyActionIsValid;
2511     if (m_syncMimeTypePolicyActionIsValid) {
2512         policyAction = m_syncMimeTypePolicyAction;
2513         downloadID = m_syncMimeTypePolicyDownloadID;
2514     }
2515 }
2516
2517 void WebPageProxy::unableToImplementPolicy(uint64_t frameID, const ResourceError& error, CoreIPC::MessageDecoder& decoder)
2518 {
2519     RefPtr<APIObject> userData;
2520     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2521     if (!decoder.decode(messageDecoder))
2522         return;
2523     
2524     WebFrameProxy* frame = m_process->webFrame(frameID);
2525     MESSAGE_CHECK(frame);
2526
2527     m_policyClient.unableToImplementPolicy(this, frame, error, userData.get());
2528 }
2529
2530 // FormClient
2531
2532 void WebPageProxy::willSubmitForm(uint64_t frameID, uint64_t sourceFrameID, const Vector<std::pair<String, String> >& textFieldValues, uint64_t listenerID, CoreIPC::MessageDecoder& decoder)
2533 {
2534     RefPtr<APIObject> userData;
2535     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2536     if (!decoder.decode(messageDecoder))
2537         return;
2538
2539     WebFrameProxy* frame = m_process->webFrame(frameID);
2540     MESSAGE_CHECK(frame);
2541
2542     WebFrameProxy* sourceFrame = m_process->webFrame(sourceFrameID);
2543     MESSAGE_CHECK(sourceFrame);
2544
2545     RefPtr<WebFormSubmissionListenerProxy> listener = frame->setUpFormSubmissionListenerProxy(listenerID);
2546     if (!m_formClient.willSubmitForm(this, frame, sourceFrame, textFieldValues, userData.get(), listener.get()))
2547         listener->continueSubmission();
2548 }
2549
2550 // UIClient
2551
2552 void WebPageProxy::createNewPage(const ResourceRequest& request, const WindowFeatures& windowFeatures, uint32_t opaqueModifiers, int32_t opaqueMouseButton, uint64_t& newPageID, WebPageCreationParameters& newPageParameters)
2553 {
2554     RefPtr<WebPageProxy> newPage = m_uiClient.createNewPage(this, request, windowFeatures, static_cast<WebEvent::Modifiers>(opaqueModifiers), static_cast<WebMouseEvent::Button>(opaqueMouseButton));
2555     if (!newPage) {
2556         newPageID = 0;
2557         return;
2558     }
2559
2560     newPageID = newPage->pageID();
2561     newPageParameters = newPage->creationParameters();
2562     process()->context()->storageManager().cloneSessionStorageNamespace(m_pageID, newPage->pageID());
2563 }
2564     
2565 void WebPageProxy::showPage()
2566 {
2567     m_uiClient.showPage(this);
2568 }
2569
2570 void WebPageProxy::closePage(bool stopResponsivenessTimer)
2571 {
2572     if (stopResponsivenessTimer)
2573         m_process->responsivenessTimer()->stop();
2574
2575     m_pageClient->clearAllEditCommands();
2576     m_uiClient.close(this);
2577 }
2578
2579 void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message)
2580 {
2581     WebFrameProxy* frame = m_process->webFrame(frameID);
2582     MESSAGE_CHECK(frame);
2583
2584     // Since runJavaScriptAlert() can spin a nested run loop we need to turn off the responsiveness timer.
2585     m_process->responsivenessTimer()->stop();
2586
2587     m_uiClient.runJavaScriptAlert(this, message, frame);
2588 }
2589
2590 void WebPageProxy::runJavaScriptConfirm(uint64_t frameID, const String& message, bool& result)
2591 {
2592     WebFrameProxy* frame = m_process->webFrame(frameID);
2593     MESSAGE_CHECK(frame);
2594
2595     // Since runJavaScriptConfirm() can spin a nested run loop we need to turn off the responsiveness timer.
2596     m_process->responsivenessTimer()->stop();
2597
2598     result = m_uiClient.runJavaScriptConfirm(this, message, frame);
2599 }
2600
2601 void WebPageProxy::runJavaScriptPrompt(uint64_t frameID, const String& message, const String& defaultValue, String& result)
2602 {
2603     WebFrameProxy* frame = m_process->webFrame(frameID);
2604     MESSAGE_CHECK(frame);
2605
2606     // Since runJavaScriptPrompt() can spin a nested run loop we need to turn off the responsiveness timer.
2607     m_process->responsivenessTimer()->stop();
2608
2609     result = m_uiClient.runJavaScriptPrompt(this, message, defaultValue, frame);
2610 }
2611
2612 void WebPageProxy::shouldInterruptJavaScript(bool& result)
2613 {
2614     // Since shouldInterruptJavaScript() can spin a nested run loop we need to turn off the responsiveness timer.
2615     m_process->responsivenessTimer()->stop();
2616
2617     result = m_uiClient.shouldInterruptJavaScript(this);
2618 }
2619
2620 void WebPageProxy::setStatusText(const String& text)
2621 {
2622     m_uiClient.setStatusText(this, text);
2623 }
2624
2625 void WebPageProxy::mouseDidMoveOverElement(const WebHitTestResult::Data& hitTestResultData, uint32_t opaqueModifiers, CoreIPC::MessageDecoder& decoder)
2626 {
2627     RefPtr<APIObject> userData;
2628     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
2629     if (!decoder.decode(messageDecoder))
2630         return;
2631
2632     WebEvent::Modifiers modifiers = static_cast<WebEvent::Modifiers>(opaqueModifiers);
2633
2634     m_uiClient.mouseDidMoveOverElement(this, hitTestResultData, modifiers, userData.get());
2635 }
2636
2637 void WebPageProxy::connectionWillOpen(CoreIPC::Connection* connection)
2638 {
2639     ASSERT(connection == m_process->connection());
2640
2641     m_process->context()->storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, connection);
2642 }
2643
2644 void WebPageProxy::connectionWillClose(CoreIPC::Connection* connection)
2645 {
2646     ASSERT(connection == m_process->connection());
2647
2648     m_process->context()->storageManager().setAllowedSessionStorageNamespaceConnection(m_pageID, 0);
2649 }
2650
2651 String WebPageProxy::pluginInformationBundleIdentifierKey()
2652 {
2653     return ASCIILiteral("PluginInformationBundleIdentifier");
2654 }
2655
2656 String WebPageProxy::pluginInformationBundleVersionKey()
2657 {
2658     return ASCIILiteral("PluginInformationBundleVersion");
2659 }
2660
2661 String WebPageProxy::pluginInformationDisplayNameKey()
2662 {
2663     return ASCIILiteral("PluginInformationDisplayName");
2664 }
2665
2666 String WebPageProxy::pluginInformationFrameURLKey()
2667 {
2668     return ASCIILiteral("PluginInformationFrameURL");
2669 }
2670
2671 String WebPageProxy::pluginInformationMIMETypeKey()
2672 {
2673     return ASCIILiteral("PluginInformationMIMEType");
2674 }
2675
2676 String WebPageProxy::pluginInformationPageURLKey()
2677 {
2678     return ASCIILiteral("PluginInformationPageURL");
2679 }
2680
2681 String WebPageProxy::pluginInformationPluginspageAttributeURLKey()
2682 {
2683     return ASCIILiteral("PluginInformationPluginspageAttributeURL");
2684 }
2685
2686 String WebPageProxy::pluginInformationPluginURLKey()
2687 {
2688     return ASCIILiteral("PluginInformationPluginURL");
2689 }
2690
2691 PassRefPtr<ImmutableDictionary> WebPageProxy::pluginInformationDictionary(const String& bundleIdentifier, const String& bundleVersion, const String& displayName, const String& frameURLString, const String& mimeType, const String& pageURLString, const String& pluginspageAttributeURLString, const String& pluginURLString)
2692 {
2693     HashMap<String, RefPtr<APIObject> > pluginInfoMap;
2694     if (!bundleIdentifier.isEmpty())
2695         pluginInfoMap.set(WebPageProxy::pluginInformationBundleIdentifierKey(), WebString::create(bundleIdentifier));
2696     if (!bundleVersion.isEmpty())
2697         pluginInfoMap.set(WebPageProxy::pluginInformationBundleVersionKey(), WebString::create(bundleVersion));
2698     if (!displayName.isEmpty())
2699         pluginInfoMap.set(WebPageProxy::pluginInformationDisplayNameKey(), WebString::create(displayName));
2700     if (!frameURLString.isEmpty())
2701         pluginInfoMap.set(WebPageProxy::pluginInformationFrameURLKey(), WebURL::create(frameURLString));
2702     if (!mimeType.isEmpty())
2703         pluginInfoMap.set(WebPageProxy::pluginInformationMIMETypeKey(), WebString::create(mimeType));
2704     if (!pageURLString.isEmpty())
2705         pluginInfoMap.set(WebPageProxy::pluginInformationPageURLKey(), WebURL::create(pageURLString));
2706     if (!pluginspageAttributeURLString.isEmpty())
2707         pluginInfoMap.set(WebPageProxy::pluginInformationPluginspageAttributeURLKey(), WebURL::create(pluginspageAttributeURLString));
2708     if (!pluginURLString.isEmpty())
2709         pluginInfoMap.set(WebPageProxy::pluginInformationPluginURLKey(), WebURL::create(pluginURLString));
2710
2711     return ImmutableDictionary::adopt(pluginInfoMap);
2712 }
2713
2714 void WebPageProxy::unavailablePluginButtonClicked(uint32_t opaquePluginUnavailabilityReason, const String& mimeType, const String& pluginURLString, const String& pluginspageAttributeURLString, const String& frameURLString, const String& pageURLString)
2715 {
2716     MESSAGE_CHECK_URL(pluginURLString);
2717     MESSAGE_CHECK_URL(pluginspageAttributeURLString);
2718     MESSAGE_CHECK_URL(frameURLString);
2719     MESSAGE_CHECK_URL(pageURLString);
2720
2721     String pluginBundleIdentifier;
2722     String pluginBundleVersion;
2723     String pluginName;
2724     String newMimeType = mimeType;
2725 #if ENABLE(NETSCAPE_PLUGIN_API)
2726     PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), pluginURLString));
2727 #if PLATFORM(MAC)
2728     pluginBundleIdentifier = plugin.bundleIdentifier;
2729     pluginBundleVersion = plugin.versionString;
2730 #endif
2731     pluginName = plugin.info.name;
2732 #endif
2733
2734     WKPluginUnavailabilityReason pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
2735     switch (static_cast<RenderEmbeddedObject::PluginUnavailabilityReason>(opaquePluginUnavailabilityReason)) {
2736     case RenderEmbeddedObject::PluginMissing:
2737         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginMissing;
2738         break;
2739     case RenderEmbeddedObject::InsecurePluginVersion:
2740         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonInsecurePluginVersion;
2741         break;
2742     case RenderEmbeddedObject::PluginCrashed:
2743         pluginUnavailabilityReason = kWKPluginUnavailabilityReasonPluginCrashed;
2744         break;
2745
2746     case RenderEmbeddedObject::PluginInactive: {
2747 #if ENABLE(NETSCAPE_PLUGIN_API)
2748         if (!plugin.path.isEmpty() && PluginInfoStore::reactivateInactivePlugin(plugin)) {
2749             // The plug-in has been reactivated now; reload the page so it'll be instantiated.
2750             reload(false);
2751         }
2752         return;
2753 #endif
2754     }
2755
2756     case RenderEmbeddedObject::PluginBlockedByContentSecurityPolicy:
2757         ASSERT_NOT_REACHED();
2758     }
2759
2760     m_uiClient.unavailablePluginButtonClicked(this, pluginUnavailabilityReason, mimeType, pluginBundleIdentifier, pluginBundleVersion, pluginName, pluginURLString, pluginspageAttributeURLString, frameURLString, pageURLString);
2761 }
2762
2763 void WebPageProxy::setToolbarsAreVisible(bool toolbarsAreVisible)
2764 {
2765     m_uiClient.setToolbarsAreVisible(this, toolbarsAreVisible);
2766 }
2767
2768 void WebPageProxy::getToolbarsAreVisible(bool& toolbarsAreVisible)
2769 {
2770     toolbarsAreVisible = m_uiClient.toolbarsAreVisible(this);
2771 }
2772
2773 void WebPageProxy::setMenuBarIsVisible(bool menuBarIsVisible)
2774 {
2775     m_uiClient.setMenuBarIsVisible(this, menuBarIsVisible);
2776 }
2777
2778 void WebPageProxy::getMenuBarIsVisible(bool& menuBarIsVisible)
2779 {
2780     menuBarIsVisible = m_uiClient.menuBarIsVisible(this);
2781 }
2782
2783 void WebPageProxy::setStatusBarIsVisible(bool statusBarIsVisible)
2784 {
2785     m_uiClient.setStatusBarIsVisible(this, statusBarIsVisible);
2786 }
2787
2788 void WebPageProxy::getStatusBarIsVisible(bool& statusBarIsVisible)
2789 {
2790     statusBarIsVisible = m_uiClient.statusBarIsVisible(this);
2791 }
2792
2793 void WebPageProxy::setIsResizable(bool isResizable)
2794 {
2795     m_uiClient.setIsResizable(this, isResizable);
2796 }
2797
2798 void WebPageProxy::getIsResizable(bool& isResizable)
2799 {
2800     isResizable = m_uiClient.isResizable(this);
2801 }
2802
2803 void WebPageProxy::setWindowFrame(const FloatRect& newWindowFrame)
2804 {
2805     m_uiClient.setWindowFrame(this, m_pageClient->convertToDeviceSpace(newWindowFrame));
2806 }
2807
2808 void WebPageProxy::getWindowFrame(FloatRect& newWindowFrame)
2809 {
2810     newWindowFrame = m_pageClient->convertToUserSpace(m_uiClient.windowFrame(this));
2811 }
2812     
2813 void WebPageProxy::screenToWindow(const IntPoint& screenPoint, IntPoint& windowPoint)
2814 {
2815     windowPoint = m_pageClient->screenToWindow(screenPoint);
2816 }
2817     
2818 void WebPageProxy::windowToScreen(const IntRect& viewRect, IntRect& result)
2819 {
2820     result = m_pageClient->windowToScreen(viewRect);
2821 }
2822     
2823 void WebPageProxy::runBeforeUnloadConfirmPanel(const String& message, uint64_t frameID, bool& shouldClose)
2824 {
2825     WebFrameProxy* frame = m_process->webFrame(frameID);
2826     MESSAGE_CHECK(frame);
2827
2828     // Since runBeforeUnloadConfirmPanel() can spin a nested run loop we need to turn off the responsiveness timer.
2829     m_process->responsivenessTimer()->stop();
2830
2831     shouldClose = m_uiClient.runBeforeUnloadConfirmPanel(this, message, frame);
2832 }
2833
2834 #if USE(TILED_BACKING_STORE)
2835 void WebPageProxy::pageDidRequestScroll(const IntPoint& point)
2836 {
2837     m_pageClient->pageDidRequestScroll(point);
2838 }
2839
2840 void WebPageProxy::pageTransitionViewportReady()
2841 {
2842     m_pageClient->pageTransitionViewportReady();
2843 }
2844
2845 void WebPageProxy::didRenderFrame(const WebCore::IntSize& contentsSize, const WebCore::IntRect& coveredRect)
2846 {
2847     m_pageClient->didRenderFrame(contentsSize, coveredRect);
2848 }
2849
2850 #endif
2851
2852 void WebPageProxy::didChangeViewportProperties(const ViewportAttributes& attr)
2853 {
2854     m_pageClient->didChangeViewportProperties(attr);
2855 }
2856
2857 void WebPageProxy::pageDidScroll()
2858 {
2859     m_uiClient.pageDidScroll(this);
2860 #if PLATFORM(MAC)
2861     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
2862 #endif
2863 }
2864
2865 void WebPageProxy::runOpenPanel(uint64_t frameID, const FileChooserSettings& settings)
2866 {
2867     if (m_openPanelResultListener) {
2868         m_openPanelResultListener->invalidate();
2869         m_openPanelResultListener = 0;
2870     }
2871
2872     WebFrameProxy* frame = m_process->webFrame(frameID);
2873     MESSAGE_CHECK(frame);
2874
2875     RefPtr<WebOpenPanelParameters> parameters = WebOpenPanelParameters::create(settings);
2876     m_openPanelResultListener = WebOpenPanelResultListenerProxy::create(this);
2877
2878     // Since runOpenPanel() can spin a nested run loop we need to turn off the responsiveness timer.
2879     m_process->responsivenessTimer()->stop();
2880
2881     if (!m_uiClient.runOpenPanel(this, frame, parameters.get(), m_openPanelResultListener.get()))
2882         didCancelForOpenPanel();
2883 }
2884
2885 void WebPageProxy::printFrame(uint64_t frameID)
2886 {
2887     ASSERT(!m_isPerformingDOMPrintOperation);
2888     m_isPerformingDOMPrintOperation = true;
2889
2890     WebFrameProxy* frame = m_process->webFrame(frameID);
2891     MESSAGE_CHECK(frame);
2892
2893     m_uiClient.printFrame(this, frame);
2894
2895     endPrinting(); // Send a message synchronously while m_isPerformingDOMPrintOperation is still true.
2896     m_isPerformingDOMPrintOperation = false;
2897 }
2898
2899 void WebPageProxy::printMainFrame()
2900 {
2901     printFrame(m_mainFrame->frameID());
2902 }
2903
2904 void WebPageProxy::setMediaVolume(float volume)
2905 {
2906     if (volume == m_mediaVolume)
2907         return;
2908     
2909     m_mediaVolume = volume;
2910     
2911     if (!isValid())
2912         return;
2913     
2914     m_process->send(Messages::WebPage::SetMediaVolume(volume), m_pageID);    
2915 }
2916
2917 void WebPageProxy::setMayStartMediaWhenInWindow(bool mayStartMedia)
2918 {
2919     if (mayStartMedia == m_mayStartMediaWhenInWindow)
2920         return;
2921
2922     m_mayStartMediaWhenInWindow = mayStartMedia;
2923
2924     if (!isValid())
2925         return;
2926
2927     process()->send(Messages::WebPage::SetMayStartMediaWhenInWindow(mayStartMedia), m_pageID);
2928 }
2929
2930 #if PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK)
2931 void WebPageProxy::handleDownloadRequest(DownloadProxy* download)
2932 {
2933     m_pageClient->handleDownloadRequest(download);
2934 }
2935 #endif // PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK)
2936
2937 #if PLATFORM(QT) || PLATFORM(EFL)
2938 void WebPageProxy::didChangeContentsSize(const IntSize& size)
2939 {
2940     m_pageClient->didChangeContentsSize(size);
2941 }
2942 #endif
2943
2944 #if ENABLE(TOUCH_EVENTS)
2945 void WebPageProxy::needTouchEvents(bool needTouchEvents)
2946 {
2947     m_needTouchEvents = needTouchEvents;
2948 }
2949 #endif
2950
2951 #if ENABLE(INPUT_TYPE_COLOR)
2952 void WebPageProxy::showColorChooser(const WebCore::Color& initialColor, const IntRect& elementRect)
2953 {
2954     ASSERT(!m_colorChooser);
2955
2956     if (m_colorPickerResultListener) {
2957         m_colorPickerResultListener->invalidate();
2958         m_colorPickerResultListener = nullptr;
2959     }
2960
2961     m_colorPickerResultListener = WebColorPickerResultListenerProxy::create(this);
2962     m_colorChooser = WebColorChooserProxy::create(this);
2963
2964     if (m_uiClient.showColorPicker(this, initialColor.serialized(), m_colorPickerResultListener.get()))
2965         return;
2966
2967     m_colorChooser = m_pageClient->createColorChooserProxy(this, initialColor, elementRect);
2968     if (!m_colorChooser)
2969         didEndColorChooser();
2970 }
2971
2972 void WebPageProxy::setColorChooserColor(const WebCore::Color& color)
2973 {
2974     ASSERT(m_colorChooser);
2975
2976     m_colorChooser->setSelectedColor(color);
2977 }
2978
2979 void WebPageProxy::endColorChooser()
2980 {
2981     ASSERT(m_colorChooser);
2982
2983     m_colorChooser->endChooser();
2984 }
2985
2986 void WebPageProxy::didChooseColor(const WebCore::Color& color)
2987 {
2988     if (!isValid())
2989         return;
2990
2991     m_process->send(Messages::WebPage::DidChooseColor(color), m_pageID);
2992 }
2993
2994 void WebPageProxy::didEndColorChooser()
2995 {
2996     if (!isValid())
2997         return;
2998
2999     if (m_colorChooser) {
3000         m_colorChooser->invalidate();
3001         m_colorChooser = nullptr;
3002     }
3003
3004     m_process->send(Messages::WebPage::DidEndColorChooser(), m_pageID);
3005
3006     m_colorPickerResultListener->invalidate();
3007     m_colorPickerResultListener = nullptr;
3008
3009     m_uiClient.hideColorPicker(this);
3010 }
3011 #endif
3012
3013 void WebPageProxy::didDraw()
3014 {
3015     m_uiClient.didDraw(this);
3016 }
3017
3018 // Inspector
3019
3020 #if ENABLE(INSPECTOR)
3021
3022 WebInspectorProxy* WebPageProxy::inspector()
3023 {
3024     if (isClosed() || !isValid())
3025         return 0;
3026     return m_inspector.get();
3027 }
3028
3029 #endif
3030
3031 #if ENABLE(FULLSCREEN_API)
3032 WebFullScreenManagerProxy* WebPageProxy::fullScreenManager()
3033 {
3034     return m_fullScreenManager.get();
3035 }
3036 #endif
3037
3038 // BackForwardList
3039
3040 void WebPageProxy::backForwardAddItem(uint64_t itemID)
3041 {
3042     m_backForwardList->addItem(m_process->webBackForwardItem(itemID));
3043 }
3044
3045 void WebPageProxy::backForwardGoToItem(uint64_t itemID, SandboxExtension::Handle& sandboxExtensionHandle)
3046 {
3047     WebBackForwardListItem* item = m_process->webBackForwardItem(itemID);
3048     if (!item)
3049         return;
3050
3051     bool createdExtension = maybeInitializeSandboxExtensionHandle(KURL(KURL(), item->url()), sandboxExtensionHandle);
3052     if (createdExtension)
3053         m_process->willAcquireUniversalFileReadSandboxExtension();
3054     m_backForwardList->goToItem(item);
3055 }
3056
3057 void WebPageProxy::backForwardItemAtIndex(int32_t index, uint64_t& itemID)
3058 {
3059     WebBackForwardListItem* item = m_backForwardList->itemAtIndex(index);
3060     itemID = item ? item->itemID() : 0;
3061 }
3062
3063 void WebPageProxy::backForwardBackListCount(int32_t& count)
3064 {
3065     count = m_backForwardList->backListCount();
3066 }
3067
3068 void WebPageProxy::backForwardForwardListCount(int32_t& count)
3069 {
3070     count = m_backForwardList->forwardListCount();
3071 }
3072
3073 void WebPageProxy::editorStateChanged(const EditorState& editorState)
3074 {
3075 #if PLATFORM(MAC)
3076     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
3077 #endif
3078
3079     m_editorState = editorState;
3080
3081 #if PLATFORM(MAC)
3082     m_pageClient->updateTextInputState(couldChangeSecureInputState);
3083 #elif PLATFORM(QT) || PLATFORM(EFL) || PLATFORM(GTK)
3084     m_pageClient->updateTextInputState();
3085 #endif
3086 }
3087
3088 // Undo management
3089
3090 void WebPageProxy::registerEditCommandForUndo(uint64_t commandID, uint32_t editAction)
3091 {
3092     registerEditCommand(WebEditCommandProxy::create(commandID, static_cast<EditAction>(editAction), this), Undo);
3093 }
3094
3095 void WebPageProxy::canUndoRedo(uint32_t action, bool& result)
3096 {
3097     result = m_pageClient->canUndoRedo(static_cast<UndoOrRedo>(action));
3098 }
3099
3100 void WebPageProxy::executeUndoRedo(uint32_t action, bool& result)
3101 {
3102     m_pageClient->executeUndoRedo(static_cast<UndoOrRedo>(action));
3103     result = true;
3104 }
3105
3106 void WebPageProxy::clearAllEditCommands()
3107 {
3108     m_pageClient->clearAllEditCommands();
3109 }
3110
3111 void WebPageProxy::didCountStringMatches(const String& string, uint32_t matchCount)
3112 {
3113     m_findClient.didCountStringMatches(this, string, matchCount);
3114 }
3115
3116 void WebPageProxy::didGetImageForFindMatch(const ShareableBitmap::Handle& contentImageHandle, uint32_t matchIndex)
3117 {
3118     m_findMatchesClient.didGetImageForMatchResult(this, WebImage::create(ShareableBitmap::create(contentImageHandle)).get(), matchIndex);
3119 }
3120
3121 void WebPageProxy::setFindIndicator(const FloatRect& selectionRectInWindowCoordinates, const Vector<FloatRect>& textRectsInSelectionRectCoordinates, float contentImageScaleFactor, const ShareableBitmap::Handle& contentImageHandle, bool fadeOut, bool animate)
3122 {
3123     RefPtr<FindIndicator> findIndicator = FindIndicator::create(selectionRectInWindowCoordinates, textRectsInSelectionRectCoordinates, contentImageScaleFactor, contentImageHandle);
3124     m_pageClient->setFindIndicator(findIndicator.release(), fadeOut, animate);
3125 }
3126
3127 void WebPageProxy::didFindString(const String& string, uint32_t matchCount)
3128 {
3129     m_findClient.didFindString(this, string, matchCount);
3130 }
3131
3132 void WebPageProxy::didFindStringMatches(const String& string, Vector<Vector<WebCore::IntRect> > matchRects, int32_t firstIndexAfterSelection)
3133 {
3134     Vector<RefPtr<APIObject> > matches;
3135     matches.reserveInitialCapacity(matchRects.size());
3136
3137     for (size_t i = 0; i < matchRects.size(); ++i) {
3138         const Vector<WebCore::IntRect>& rects = matchRects[i];
3139         size_t numRects = matchRects[i].size();
3140         Vector<RefPtr<APIObject> > apiRects;
3141         apiRects.reserveInitialCapacity(numRects);
3142
3143         for (size_t i = 0; i < numRects; ++i)
3144             apiRects.uncheckedAppend(WebRect::create(toAPI(rects[i])));
3145         matches.uncheckedAppend(ImmutableArray::adopt(apiRects));
3146     }
3147     m_findMatchesClient.didFindStringMatches(this, string, ImmutableArray::adopt(matches).get(), firstIndexAfterSelection);
3148 }
3149
3150 void WebPageProxy::didFailToFindString(const String& string)
3151 {
3152     m_findClient.didFailToFindString(this, string);
3153 }
3154
3155 void WebPageProxy::valueChangedForPopupMenu(WebPopupMenuProxy*, int32_t newSelectedIndex)
3156 {
3157     m_process->send(Messages::WebPage::DidChangeSelectedIndexForActivePopupMenu(newSelectedIndex), m_pageID);
3158 }
3159
3160 void WebPageProxy::setTextFromItemForPopupMenu(WebPopupMenuProxy*, int32_t index)
3161 {
3162     m_process->send(Messages::WebPage::SetTextForActivePopupMenu(index), m_pageID);
3163 }
3164
3165 NativeWebMouseEvent* WebPageProxy::currentlyProcessedMouseDownEvent()
3166 {
3167     return m_currentlyProcessedMouseDownEvent.get();
3168 }
3169
3170 void WebPageProxy::postMessageToInjectedBundle(const String& messageName, APIObject* messageBody)
3171 {
3172     process()->send(Messages::WebPage::PostInjectedBundleMessage(messageName, WebContextUserMessageEncoder(messageBody)), m_pageID);
3173 }
3174
3175 #if PLATFORM(GTK)
3176 void WebPageProxy::failedToShowPopupMenu()
3177 {
3178     m_process->send(Messages::WebPage::FailedToShowPopupMenu(), m_pageID);
3179 }
3180 #endif
3181
3182 void WebPageProxy::showPopupMenu(const IntRect& rect, uint64_t textDirection, const Vector<WebPopupItem>& items, int32_t selectedIndex, const PlatformPopupMenuData& data)
3183 {
3184     if (m_activePopupMenu) {
3185 #if PLATFORM(EFL)
3186         m_uiPopupMenuClient.hidePopupMenu(this);
3187 #else
3188         m_activePopupMenu->hidePopupMenu();
3189 #endif
3190         m_activePopupMenu->invalidate();
3191         m_activePopupMenu = 0;
3192     }
3193
3194     m_activePopupMenu = m_pageClient->createPopupMenuProxy(this);
3195
3196     if (!m_activePopupMenu)
3197         return;
3198
3199     // Since showPopupMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3200     m_process->responsivenessTimer()->stop();
3201
3202 #if PLATFORM(EFL)
3203     UNUSED_PARAM(data);
3204     m_uiPopupMenuClient.showPopupMenu(this, m_activePopupMenu.get(), rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, selectedIndex);
3205 #else
3206     RefPtr<WebPopupMenuProxy> protectedActivePopupMenu = m_activePopupMenu;
3207
3208     protectedActivePopupMenu->showPopupMenu(rect, static_cast<TextDirection>(textDirection), m_pageScaleFactor, items, data, selectedIndex);
3209
3210     // Since Qt and Efl doesn't use a nested mainloop to show the popup and get the answer, we need to keep the client pointer valid.
3211 #if !PLATFORM(QT)
3212     protectedActivePopupMenu->invalidate();
3213 #endif
3214     protectedActivePopupMenu = 0;
3215 #endif
3216 }
3217
3218 void WebPageProxy::hidePopupMenu()
3219 {
3220     if (!m_activePopupMenu)
3221         return;
3222
3223 #if PLATFORM(EFL)
3224     m_uiPopupMenuClient.hidePopupMenu(this);
3225 #else
3226     m_activePopupMenu->hidePopupMenu();
3227 #endif
3228     m_activePopupMenu->invalidate();
3229     m_activePopupMenu = 0;
3230 }
3231
3232 #if ENABLE(CONTEXT_MENUS)
3233 void WebPageProxy::showContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::MessageDecoder& decoder)
3234 {
3235     internalShowContextMenu(menuLocation, hitTestResultData, proposedItems, decoder);
3236     
3237     // No matter the result of internalShowContextMenu, always notify the WebProcess that the menu is hidden so it starts handling mouse events again.
3238     m_process->send(Messages::WebPage::ContextMenuHidden(), m_pageID);
3239 }
3240
3241 void WebPageProxy::internalShowContextMenu(const IntPoint& menuLocation, const WebHitTestResult::Data& hitTestResultData, const Vector<WebContextMenuItemData>& proposedItems, CoreIPC::MessageDecoder& decoder)
3242 {
3243     RefPtr<APIObject> userData;
3244     WebContextUserMessageDecoder messageDecoder(userData, m_process.get());
3245     if (!decoder.decode(messageDecoder))
3246         return;
3247
3248     m_activeContextMenuHitTestResultData = hitTestResultData;
3249
3250     if (m_activeContextMenu) {
3251         m_activeContextMenu->hideContextMenu();
3252         m_activeContextMenu = 0;
3253     }
3254
3255     m_activeContextMenu = m_pageClient->createContextMenuProxy(this);
3256     if (!m_activeContextMenu)
3257         return;
3258
3259     // Since showContextMenu() can spin a nested run loop we need to turn off the responsiveness timer.
3260     m_process->responsivenessTimer()->stop();
3261
3262     // Give the PageContextMenuClient one last swipe at changing the menu.
3263     Vector<WebContextMenuItemData> items;
3264     if (!m_contextMenuClient.getContextMenuFromProposedMenu(this, proposedItems, items, hitTestResultData, userData.get()))
3265         m_activeContextMenu->showContextMenu(menuLocation, proposedItems);
3266     else
3267         m_activeContextMenu->showContextMenu(menuLocation, items);
3268     
3269     m_contextMenuClient.contextMenuDismissed(this);
3270 }
3271
3272 void WebPageProxy::contextMenuItemSelected(const WebContextMenuItemData& item)
3273 {
3274     // Application custom items don't need to round-trip through to WebCore in the WebProcess.
3275     if (item.action() >= ContextMenuItemBaseApplicationTag) {
3276         m_contextMenuClient.customContextMenuItemSelected(this, item);
3277         return;
3278     }
3279
3280 #if PLATFORM(MAC)
3281     if (item.action() == ContextMenuItemTagSmartCopyPaste) {
3282         setSmartInsertDeleteEnabled(!isSmartInsertDeleteEnabled());
3283         return;
3284     }
3285     if (item.action() == ContextMenuItemTagSmartQuotes) {
3286         TextChecker::setAutomaticQuoteSubstitutionEnabled(!TextChecker::state().isAutomaticQuoteSubstitutionEnabled);
3287         m_process->updateTextCheckerState();
3288         return;
3289     }
3290     if (item.action() == ContextMenuItemTagSmartDashes) {
3291         TextChecker::setAutomaticDashSubstitutionEnabled(!TextChecker::state().isAutomaticDashSubstitutionEnabled);
3292         m_process->updateTextCheckerState();
3293         return;
3294     }
3295     if (item.action() == ContextMenuItemTagSmartLinks) {
3296         TextChecker::setAutomaticLinkDetectionEnabled(!TextChecker::state().isAutomaticLinkDetectionEnabled);
3297         m_process->updateTextCheckerState();
3298         return;
3299     }
3300     if (item.action() == ContextMenuItemTagTextReplacement) {
3301         TextChecker::setAutomaticTextReplacementEnabled(!TextChecker::state().isAutomaticTextReplacementEnabled);
3302         m_process->updateTextCheckerState();
3303         return;
3304     }
3305     if (item.action() == ContextMenuItemTagCorrectSpellingAutomatically) {
3306         TextChecker::setAutomaticSpellingCorrectionEnabled(!TextChecker::state().isAutomaticSpellingCorrectionEnabled);
3307         m_process->updateTextCheckerState();
3308         return;        
3309     }
3310     if (item.action() == ContextMenuItemTagShowSubstitutions) {
3311         TextChecker::toggleSubstitutionsPanelIsShowing();
3312         return;
3313     }
3314 #endif
3315     if (item.action() == ContextMenuItemTagDownloadImageToDisk) {
3316         m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteImageURL));
3317         return;    
3318     }
3319     if (item.action() == ContextMenuItemTagDownloadLinkToDisk) {
3320         m_process->context()->download(this, KURL(KURL(), m_activeContextMenuHitTestResultData.absoluteLinkURL));
3321         return;
3322     }
3323     if (item.action() == ContextMenuItemTagCheckSpellingWhileTyping) {
3324         TextChecker::setContinuousSpellCheckingEnabled(!TextChecker::state().isContinuousSpellCheckingEnabled);
3325         m_process->updateTextCheckerState();
3326         return;
3327     }
3328     if (item.action() == ContextMenuItemTagCheckGrammarWithSpelling) {
3329         TextChecker::setGrammarCheckingEnabled(!TextChecker::state().isGrammarCheckingEnabled);
3330         m_process->updateTextCheckerState();
3331         return;
3332     }
3333     if (item.action() == ContextMenuItemTagShowSpellingPanel) {
3334         if (!TextChecker::spellingUIIsShowing())
3335             advanceToNextMisspelling(true);
3336         TextChecker::toggleSpellingUIIsShowing();
3337         return;
3338     }
3339     if (item.action() == ContextMenuItemTagLearnSpelling || item.action() == ContextMenuItemTagIgnoreSpelling)
3340         ++m_pendingLearnOrIgnoreWordMessageCount;
3341
3342     m_process->send(Messages::WebPage::DidSelectItemFromActiveContextMenu(item), m_pageID);
3343 }
3344 #endif // ENABLE(CONTEXT_MENUS)
3345
3346 void WebPageProxy::didChooseFilesForOpenPanel(const Vector<String>& fileURLs)
3347 {
3348     if (!isValid())
3349         return;
3350
3351 #if ENABLE(WEB_PROCESS_SANDBOX)
3352     // FIXME: The sandbox extensions should be sent with the DidChooseFilesForOpenPanel message. This
3353     // is gated on a way of passing SandboxExtension::Handles in a Vector.
3354     for (size_t i = 0; i < fileURLs.size(); ++i) {
3355         SandboxExtension::Handle sandboxExtensionHandle;
3356         SandboxExtension::createHandle(fileURLs[i], SandboxExtension::ReadOnly, sandboxExtensionHandle);
3357         m_process->send(Messages::WebPage::ExtendSandboxForFileFromOpenPanel(sandboxExtensionHandle), m_pageID);
3358     }
3359 #endif
3360
3361     m_process->send(Messages::WebPage::DidChooseFilesForOpenPanel(fileURLs), m_pageID);
3362
3363     m_openPanelResultListener->invalidate();
3364     m_openPanelResultListener = 0;
3365 }
3366
3367 void WebPageProxy::didCancelForOpenPanel()
3368 {
3369     if (!isValid())
3370         return;
3371
3372     m_process->send(Messages::WebPage::DidCancelForOpenPanel(), m_pageID);
3373     
3374     m_openPanelResultListener->invalidate();
3375     m_openPanelResultListener = 0;
3376 }
3377
3378 void WebPageProxy::advanceToNextMisspelling(bool startBeforeSelection) const
3379 {
3380     m_process->send(Messages::WebPage::AdvanceToNextMisspelling(startBeforeSelection), m_pageID);
3381 }
3382
3383 void WebPageProxy::changeSpellingToWord(const String& word) const
3384 {
3385     if (word.isEmpty())
3386         return;
3387
3388     m_process->send(Messages::WebPage::ChangeSpellingToWord(word), m_pageID);
3389 }
3390
3391 void WebPageProxy::registerEditCommand(PassRefPtr<WebEditCommandProxy> commandProxy, UndoOrRedo undoOrRedo)
3392 {
3393     m_pageClient->registerEditCommand(commandProxy, undoOrRedo);
3394 }
3395
3396 void WebPageProxy::addEditCommand(WebEditCommandProxy* command)
3397 {
3398     m_editCommandSet.add(command);
3399 }
3400
3401 void WebPageProxy::removeEditCommand(WebEditCommandProxy* command)
3402 {
3403     m_editCommandSet.remove(command);
3404
3405     if (!isValid())
3406         return;
3407     m_process->send(Messages::WebPage::DidRemoveEditCommand(command->commandID()), m_pageID);
3408 }
3409
3410 bool WebPageProxy::isValidEditCommand(WebEditCommandProxy* command)
3411 {
3412     return m_editCommandSet.find(command) != m_editCommandSet.end();
3413 }
3414
3415 int64_t WebPageProxy::spellDocumentTag()
3416 {
3417     if (!m_hasSpellDocumentTag) {
3418         m_spellDocumentTag = TextChecker::uniqueSpellDocumentTag(this);
3419         m_hasSpellDocumentTag = true;
3420     }
3421
3422     return m_spellDocumentTag;
3423 }
3424
3425 #if USE(UNIFIED_TEXT_CHECKING)
3426 void WebPageProxy::checkTextOfParagraph(const String& text, uint64_t checkingTypes, Vector<TextCheckingResult>& results)
3427 {
3428     results = TextChecker::checkTextOfParagraph(spellDocumentTag(), text.characters(), text.length(), checkingTypes);
3429 }
3430 #endif
3431
3432 void WebPageProxy::checkSpellingOfString(const String& text, int32_t& misspellingLocation, int32_t& misspellingLength)
3433 {
3434     TextChecker::checkSpellingOfString(spellDocumentTag(), text.characters(), text.length(), misspellingLocation, misspellingLength);
3435 }
3436
3437 void WebPageProxy::checkGrammarOfString(const String& text, Vector<GrammarDetail>& grammarDetails, int32_t& badGrammarLocation, int32_t& badGrammarLength)
3438 {
3439     TextChecker::checkGrammarOfString(spellDocumentTag(), text.characters(), text.length(), grammarDetails, badGrammarLocation, badGrammarLength);
3440 }
3441
3442 void WebPageProxy::spellingUIIsShowing(bool& isShowing)
3443 {
3444     isShowing = TextChecker::spellingUIIsShowing();
3445 }
3446
3447 void WebPageProxy::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
3448 {
3449     TextChecker::updateSpellingUIWithMisspelledWord(spellDocumentTag(), misspelledWord);
3450 }
3451
3452 void WebPageProxy::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
3453 {
3454     TextChecker::updateSpellingUIWithGrammarString(spellDocumentTag(), badGrammarPhrase, grammarDetail);
3455 }
3456
3457 void WebPageProxy::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
3458 {
3459     TextChecker::getGuessesForWord(spellDocumentTag(), word, context, guesses);
3460 }
3461
3462 void WebPageProxy::learnWord(const String& word)
3463 {
3464     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3465     --m_pendingLearnOrIgnoreWordMessageCount;
3466
3467     TextChecker::learnWord(spellDocumentTag(), word);
3468 }
3469
3470 void WebPageProxy::ignoreWord(const String& word)
3471 {
3472     MESSAGE_CHECK(m_pendingLearnOrIgnoreWordMessageCount);
3473     --m_pendingLearnOrIgnoreWordMessageCount;
3474
3475     TextChecker::ignoreWord(spellDocumentTag(), word);
3476 }
3477
3478 void WebPageProxy::requestCheckingOfString(uint64_t requestID, const TextCheckingRequestData& request)
3479 {
3480     TextChecker::requestCheckingOfString(TextCheckerCompletion::create(requestID, request, this));
3481 }
3482
3483 void WebPageProxy::didFinishCheckingText(uint64_t requestID, const Vector<WebCore::TextCheckingResult>& result) const
3484 {
3485     m_process->send(Messages::WebPage::DidFinishCheckingText(requestID, result), m_pageID);
3486 }
3487
3488 void WebPageProxy::didCancelCheckingText(uint64_t requestID) const
3489 {
3490     m_process->send(Messages::WebPage::DidCancelCheckingText(requestID), m_pageID);
3491 }
3492 // Other
3493
3494 void WebPageProxy::setFocus(bool focused)
3495 {
3496     if (focused)
3497         m_uiClient.focus(this);
3498     else
3499         m_uiClient.unfocus(this);
3500 }
3501
3502 void WebPageProxy::takeFocus(uint32_t direction)
3503 {
3504     m_uiClient.takeFocus(this, (static_cast<FocusDirection>(direction) == FocusDirectionForward) ? kWKFocusDirectionForward : kWKFocusDirectionBackward);
3505 }
3506
3507 void WebPageProxy::setToolTip(const String& toolTip)
3508 {
3509     String oldToolTip = m_toolTip;
3510     m_toolTip = toolTip;
3511     m_pageClient->toolTipChanged(oldToolTip, m_toolTip);
3512 }
3513
3514 void WebPageProxy::setCursor(const WebCore::Cursor& cursor)
3515 {
3516     // The Web process may have asked to change the cursor when the view was in an active window, but
3517     // if it is no longer in a window or the window is not active, then the cursor should not change.
3518     if (m_pageClient->isViewWindowActive())
3519         m_pageClient->setCursor(cursor);
3520 }
3521
3522 void WebPageProxy::setCursorHiddenUntilMouseMoves(bool hiddenUntilMouseMoves)
3523 {
3524     m_pageClient->setCursorHiddenUntilMouseMoves(hiddenUntilMouseMoves);
3525 }
3526
3527 void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled)
3528 {
3529     WebEvent::Type type = static_cast<WebEvent::Type>(opaqueType);
3530
3531     switch (type) {
3532     case WebEvent::NoType:
3533     case WebEvent::MouseMove:
3534         break;
3535
3536     case WebEvent::MouseDown:
3537     case WebEvent::MouseUp:
3538     case WebEvent::Wheel:
3539     case WebEvent::KeyDown:
3540     case WebEvent::KeyUp:
3541     case WebEvent::RawKeyDown:
3542     case WebEvent::Char:
3543 #if ENABLE(GESTURE_EVENTS)
3544     case WebEvent::GestureScrollBegin:
3545     case WebEvent::GestureScrollEnd:
3546     case WebEvent::GestureSingleTap:
3547 #endif
3548 #if ENABLE(TOUCH_EVENTS)
3549     case WebEvent::TouchStart:
3550     case WebEvent::TouchMove:
3551     case WebEvent::TouchEnd:
3552     case WebEvent::TouchCancel:
3553 #endif
3554         m_process->responsivenessTimer()->stop();
3555         break;
3556     }
3557
3558     switch (type) {
3559     case WebEvent::NoType:
3560         break;
3561     case WebEvent::MouseMove:
3562         m_processingMouseMoveEvent = false;
3563         if (m_nextMouseMoveEvent) {
3564             handleMouseEvent(*m_nextMouseMoveEvent);
3565             m_nextMouseMoveEvent = nullptr;
3566         }
3567         break;
3568     case WebEvent::MouseDown:
3569         break;
3570 #if ENABLE(GESTURE_EVENTS)
3571     case WebEvent::GestureScrollBegin:
3572     case WebEvent::GestureScrollEnd:
3573     case WebEvent::GestureSingleTap: {
3574         WebGestureEvent event = m_gestureEventQueue.first();
3575         MESSAGE_CHECK(type == event.type());
3576
3577         m_gestureEventQueue.removeFirst();
3578         m_pageClient->doneWithGestureEvent(event, handled);
3579         break;
3580     }
3581 #endif
3582     case WebEvent::MouseUp:
3583         m_currentlyProcessedMouseDownEvent = nullptr;
3584         break;
3585
3586     case WebEvent::Wheel: {
3587         ASSERT(!m_currentlyProcessedWheelEvents.isEmpty());
3588
3589         OwnPtr<Vector<NativeWebWheelEvent> > oldestCoalescedEvent = m_currentlyProcessedWheelEvents.takeFirst();
3590
3591         // FIXME: Dispatch additional events to the didNotHandleWheelEvent client function.
3592         if (!handled && m_uiClient.implementsDidNotHandleWheelEvent())
3593             m_uiClient.didNotHandleWheelEvent(this, oldestCoalescedEvent->last());
3594
3595         if (!m_wheelEventQueue.isEmpty())
3596             processNextQueuedWheelEvent();
3597         break;
3598     }
3599
3600     case WebEvent::KeyDown:
3601     case WebEvent::KeyUp:
3602     case WebEvent::RawKeyDown:
3603     case WebEvent::Char: {
3604         LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type));
3605
3606         NativeWebKeyboardEvent event = m_keyEventQueue.first();
3607         MESSAGE_CHECK(type == event.type());
3608
3609         m_keyEventQueue.removeFirst();
3610
3611         if (!m_keyEventQueue.isEmpty())
3612             m_process->send(Messages::WebPage::KeyEvent(m_keyEventQueue.first()), m_pageID);
3613
3614         m_pageClient->doneWithKeyEvent(event, handled);
3615         if (handled)
3616             break;
3617
3618         if (m_uiClient.implementsDidNotHandleKeyEvent())
3619             m_uiClient.didNotHandleKeyEvent(this, event);
3620         break;
3621     }
3622 #if ENABLE(TOUCH_EVENTS)
3623     case WebEvent::TouchStart:
3624     case WebEvent::TouchMove:
3625     case WebEvent::TouchEnd:
3626     case WebEvent::TouchCancel: {
3627         QueuedTouchEvents queuedEvents = m_touchEventQueue.first();
3628         MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type());
3629         m_touchEventQueue.removeFirst();
3630
3631         m_pageClient->doneWithTouchEvent(queuedEvents.forwardedEvent, handled);
3632         for (size_t i = 0; i < queuedEvents.deferredTouchEvents.size(); ++i) {
3633             bool isEventHandled = false;
3634             m_pageClient->doneWithTouchEvent(queuedEvents.deferredTouchEvents.at(i), isEventHandled);
3635         }
3636         break;
3637     }
3638 #endif
3639     }
3640 }
3641
3642 void WebPageProxy::stopResponsivenessTimer()
3643 {
3644     m_process->responsivenessTimer()->stop();
3645 }
3646
3647 void WebPageProxy::voidCallback(uint64_t callbackID)
3648 {
3649     RefPtr<VoidCallback> callback = m_voidCallbacks.take(callbackID);
3650     if (!callback) {
3651         // FIXME: Log error or assert.
3652         return;
3653     }
3654
3655     callback->performCallback();
3656 }
3657
3658 void WebPageProxy::dataCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
3659 {
3660     RefPtr<DataCallback> callback = m_dataCallbacks.take(callbackID);
3661     if (!callback) {
3662         // FIXME: Log error or assert.
3663         return;
3664     }
3665
3666     callback->performCallbackWithReturnValue(WebData::create(dataReference.data(), dataReference.size()).get());
3667 }
3668
3669 void WebPageProxy::imageCallback(const ShareableBitmap::Handle& bitmapHandle, uint64_t callbackID)
3670 {
3671     RefPtr<ImageCallback> callback = m_imageCallbacks.take(callbackID);
3672     if (!callback) {
3673         // FIXME: Log error or assert.
3674         return;
3675     }
3676
3677     callback->performCallbackWithReturnValue(bitmapHandle);
3678 }
3679
3680 void WebPageProxy::stringCallback(const String& resultString, uint64_t callbackID)
3681 {
3682     RefPtr<StringCallback> callback = m_stringCallbacks.take(callbackID);
3683     if (!callback) {
3684         // FIXME: Log error or assert.
3685         // this can validly happen if a load invalidated the callback, though
3686         return;
3687     }
3688
3689     m_loadDependentStringCallbackIDs.remove(callbackID);
3690
3691     callback->performCallbackWithReturnValue(resultString.impl());
3692 }
3693
3694 void WebPageProxy::scriptValueCallback(const CoreIPC::DataReference& dataReference, uint64_t callbackID)
3695 {
3696     RefPtr<ScriptValueCallback> callback = m_scriptValueCallbacks.take(callbackID);
3697     if (!callback) {
3698         // FIXME: Log error or assert.
3699         return;
3700     }
3701
3702     Vector<uint8_t> data;
3703     data.reserveInitialCapacity(dataReference.size());
3704     data.append(dataReference.data(), dataReference.size());
3705
3706     callback->performCallbackWithReturnValue(data.size() ? WebSerializedScriptValue::adopt(data).get() : 0);
3707 }
3708
3709 void WebPageProxy::computedPagesCallback(const Vector<IntRect>& pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
3710 {
3711     RefPtr<ComputedPagesCallback> callback = m_computedPagesCallbacks.take(callbackID);
3712     if (!callback) {
3713         // FIXME: Log error or assert.
3714         return;
3715     }
3716
3717     callback->performCallbackWithReturnValue(pageRects, totalScaleFactorForPrinting);
3718 }
3719
3720 void WebPageProxy::validateCommandCallback(const String& commandName, bool isEnabled, int state, uint64_t callbackID)
3721 {
3722     RefPtr<ValidateCommandCallback> callback = m_validateCommandCallbacks.take(callbackID);
3723     if (!callback) {
3724         // FIXME: Log error or assert.
3725         return;
3726     }
3727
3728     callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
3729 }
3730
3731 #if PLATFORM(GTK)
3732 void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID)
3733 {
3734     RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID);
3735     if (!callback) {
3736         // FIXME: Log error or assert.
3737         return;
3738     }
3739
3740     RefPtr<WebError> error = WebError::create(printError);
3741     callback->performCallbackWithReturnValue(error.get());
3742 }
3743 #endif
3744
3745 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
3746 {
3747     if (!frameID) {
3748         m_focusedFrame = 0;
3749         return;
3750     }
3751
3752     WebFrameProxy* frame = m_process->webFrame(frameID);
3753     MESSAGE_CHECK(frame);
3754
3755     m_focusedFrame = frame;
3756 }
3757
3758 void WebPageProxy::frameSetLargestFrameChanged(uint64_t frameID)
3759 {
3760     if (!frameID) {
3761         m_frameSetLargestFrame = 0;
3762         return;
3763     }
3764
3765     WebFrameProxy* frame = m_process->webFrame(frameID);
3766     MESSAGE_CHECK(frame);
3767
3768     m_frameSetLargestFrame = frame;
3769 }
3770
3771 void WebPageProxy::processDidBecomeUnresponsive()
3772 {
3773     if (!isValid())
3774         return;
3775
3776     updateBackingStoreDiscardableState();
3777
3778     m_loaderClient.processDidBecomeUnresponsive(this);
3779 }
3780
3781 void WebPageProxy::interactionOccurredWhileProcessUnresponsive()
3782 {
3783     if (!isValid())
3784         return;
3785
3786     m_loaderClient.interactionOccurredWhileProcessUnresponsive(this);
3787 }
3788
3789 void WebPageProxy::processDidBecomeResponsive()
3790 {
3791     if (!isValid())
3792         return;
3793     
3794     updateBackingStoreDiscardableState();
3795
3796     m_loaderClient.processDidBecomeResponsive(this);
3797 }
3798
3799 void WebPageProxy::processDidCrash()
3800 {
3801     ASSERT(m_pageClient);
3802
3803     m_process->removeMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_pageID);
3804
3805     m_isValid = false;
3806     m_isPageSuspended = false;
3807
3808     if (m_mainFrame) {
3809         m_urlAtProcessExit = m_mainFrame->url();
3810         m_loadStateAtProcessExit = m_mainFrame->loadState();
3811     }
3812
3813     m_mainFrame = nullptr;
3814     m_drawingArea = nullptr;
3815
3816 #if ENABLE(INSPECTOR)
3817     m_inspector->invalidate();
3818     m_inspector = nullptr;
3819 #endif
3820
3821 #if ENABLE(FULLSCREEN_API)
3822     m_fullScreenManager->invalidate();
3823     m_fullScreenManager = nullptr;
3824 #endif
3825
3826 #if ENABLE(VIBRATION)
3827     m_vibration->invalidate();
3828 #endif
3829
3830     if (m_openPanelResultListener) {
3831         m_openPanelResultListener->invalidate();
3832         m_openPanelResultListener = nullptr;
3833     }
3834
3835 #if ENABLE(INPUT_TYPE_COLOR)
3836     if (m_colorChooser) {
3837         m_colorChooser->invalidate();
3838         m_colorChooser = nullptr;
3839     }
3840
3841     if (m_colorPickerResultListener) {
3842         m_colorPickerResultListener->invalidate();
3843         m_colorPickerResultListener = nullptr;
3844     }
3845 #endif
3846
3847 #if ENABLE(GEOLOCATION)
3848     m_geolocationPermissionRequestManager.invalidateRequests();
3849 #endif
3850
3851     m_notificationPermissionRequestManager.invalidateRequests();
3852
3853     m_toolTip = String();
3854
3855     m_mainFrameHasHorizontalScrollbar = false;
3856     m_mainFrameHasVerticalScrollbar = false;
3857
3858     m_mainFrameIsPinnedToLeftSide = false;
3859     m_mainFrameIsPinnedToRightSide = false;
3860     m_mainFrameIsPinnedToTopSide = false;
3861     m_mainFrameIsPinnedToBottomSide = false;
3862
3863     m_visibleScrollerThumbRect = IntRect();
3864
3865     invalidateCallbackMap(m_voidCallbacks);
3866     invalidateCallbackMap(m_dataCallbacks);
3867     invalidateCallbackMap(m_stringCallbacks);
3868     m_loadDependentStringCallbackIDs.clear();
3869     invalidateCallbackMap(m_scriptValueCallbacks);
3870     invalidateCallbackMap(m_computedPagesCallbacks);
3871     invalidateCallbackMap(m_validateCommandCallbacks);
3872 #if PLATFORM(GTK)
3873     invalidateCallbackMap(m_printFinishedCallbacks);
3874 #endif
3875
3876     Vector<WebEditCommandProxy*> editCommandVector;
3877     copyToVector(m_editCommandSet, editCommandVector);
3878     m_editCommandSet.clear();
3879     for (size_t i = 0, size = editCommandVector.size(); i < size; ++i)
3880         editCommandVector[i]->invalidate();
3881     m_pageClient->clearAllEditCommands();
3882
3883     m_activePopupMenu = 0;
3884
3885     m_estimatedProgress = 0.0;
3886
3887     m_pendingLearnOrIgnoreWordMessageCount = 0;
3888
3889     m_pageClient->processDidCrash();
3890     m_loaderClient.processDidCrash(this);
3891
3892     if (!m_isValid) {
3893         // If the call out to the loader client didn't cause the web process to be relaunched, 
3894         // we'll call setNeedsDisplay on the view so that we won't have the old contents showing.
3895         // If the call did cause the web process to be relaunched, we'll keep the old page contents showing
3896         // until the new web process has painted its contents.
3897         setViewNeedsDisplay(IntRect(IntPoint(), viewSize()));
3898     }
3899
3900     // Can't expect DidReceiveEvent notifications from a crashed web process.
3901     m_keyEventQueue.clear();
3902     
3903     m_wheelEventQueue.clear();
3904     m_currentlyProcessedWheelEvents.clear();
3905
3906     m_nextMouseMoveEvent = nullptr;
3907     m_currentlyProcessedMouseDownEvent = nullptr;
3908
3909     m_processingMouseMoveEvent = false;
3910
3911 #if ENABLE(TOUCH_EVENTS)
3912     m_needTouchEvents = false;
3913     m_touchEventQueue.clear();
3914 #endif
3915
3916 #if PLATFORM(MAC)
3917     dismissCorrectionPanel(ReasonForDismissingAlternativeTextIgnored);
3918     m_pageClient->dismissDictionaryLookupPanel();
3919 #endif
3920 }
3921
3922 WebPageCreationParameters WebPageProxy::creationParameters() const
3923 {
3924     WebPageCreationParameters parameters;
3925
3926     parameters.viewSize = m_pageClient->viewSize();
3927     parameters.isActive = m_pageClient->isViewWindowActive();
3928     parameters.isFocused = m_pageClient->isViewFocused();
3929     parameters.isVisible = m_pageClient->isViewVisible();
3930     parameters.isInWindow = m_pageClient->isViewInWindow();
3931     parameters.drawingAreaType = m_drawingArea->type();
3932     parameters.store = m_pageGroup->preferences()->store();
3933     parameters.pageGroupData = m_pageGroup->data();
3934     parameters.drawsBackground = m_drawsBackground;
3935     parameters.drawsTransparentBackground = m_drawsTransparentBackground;
3936     parameters.underlayColor = m_underlayColor;
3937     parameters.areMemoryCacheClientCallsEnabled = m_areMemoryCacheClientCallsEnabled;
3938     parameters.useFixedLayout = m_useFixedLayout;
3939     parameters.fixedLayoutSize = m_fixedLayoutSize;
3940     parameters.suppressScrollbarAnimations = m_suppressScrollbarAnimations;
3941     parameters.paginationMode = m_paginationMode;
3942     parameters.paginationBehavesLikeColumns = m_paginationBehavesLikeColumns;
3943     parameters.pageLength = m_pageLength;
3944     parameters.gapBetweenPages = m_gapBetweenPages;
3945     parameters.userAgent = userAgent();
3946     parameters.sessionState = SessionState(m_backForwardList->entries(), m_backForwardList->currentIndex());
3947     parameters.highestUsedBackForwardItemID = WebBackForwardListItem::highedUsedItemID();
3948     parameters.canRunBeforeUnloadConfirmPanel = m_uiClient.canRunBeforeUnloadConfirmPanel();
3949     parameters.canRunModal = m_canRunModal;
3950     parameters.deviceScaleFactor = m_intrinsicDeviceScaleFactor;
3951     parameters.mediaVolume = m_mediaVolume;
3952     parameters.mayStartMediaWhenInWindow = m_mayStartMediaWhenInWindow;
3953     parameters.overridePrivateBrowsingEnabled = m_overridePrivateBrowsingEnabled;
3954
3955 #if PLATFORM(MAC)
3956     parameters.layerHostingMode = m_layerHostingMode;
3957     parameters.colorSpace = m_pageClient->colorSpace();
3958 #endif
3959
3960     return parameters;
3961 }
3962
3963 #if USE(ACCELERATED_COMPOSITING)
3964 void WebPageProxy::enterAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
3965 {
3966     m_pageClient->enterAcceleratedCompositingMode(layerTreeContext);
3967 }
3968
3969 void WebPageProxy::exitAcceleratedCompositingMode()
3970 {
3971     m_pageClient->exitAcceleratedCompositingMode();
3972 }
3973
3974 void WebPageProxy::updateAcceleratedCompositingMode(const LayerTreeContext& layerTreeContext)
3975 {
3976     m_pageClient->updateAcceleratedCompositingMode(layerTreeContext);
3977 }
3978 #endif // USE(ACCELERATED_COMPOSITING)
3979
3980 void WebPageProxy::backForwardClear()
3981 {
3982     m_backForwardList->clear();
3983 }
3984
3985 void WebPageProxy::canAuthenticateAgainstProtectionSpaceInFrame(uint64_t frameID, const ProtectionSpace& coreProtectionSpace, bool& canAuthenticate)
3986 {
3987     WebFrameProxy* frame = m_process->webFrame(frameID);
3988     MESSAGE_CHECK(frame);
3989
3990     RefPtr<WebProtectionSpace> protectionSpace = WebProtectionSpace::create(coreProtectionSpace);
3991     
3992     canAuthenticate = m_loaderClient.canAuthenticateAgainstProtectionSpaceInFrame(this, frame, protectionSpace.get());
3993 }
3994
3995 void WebPageProxy::didReceiveAuthenticationChallenge(uint64_t frameID, const AuthenticationChallenge& coreChallenge, uint64_t challengeID)
3996 {
3997     didReceiveAuthenticationChallengeProxy(frameID, AuthenticationChallengeProxy::create(coreChallenge, challengeID, m_process->connection()));
3998 }
3999
4000 void WebPageProxy::didReceiveAuthenticationChallengeProxy(uint64_t frameID, PassRefPtr<AuthenticationChallengeProxy> prpAuthenticationChallenge)
4001 {
4002     ASSERT(prpAuthenticationChallenge);
4003
4004     WebFrameProxy* frame = m_process->webFrame(frameID);
4005     MESSAGE_CHECK(frame);
4006
4007     RefPtr<AuthenticationChallengeProxy> authenticationChallenge = prpAuthenticationChallenge;
4008     m_loaderClient.didReceiveAuthenticationChallengeInFrame(this, frame, authenticationChallenge.get());
4009 }
4010
4011 void WebPageProxy::exceededDatabaseQuota(uint64_t frameID, const String& originIdentifier, const String& databaseName, const String& displayName, uint64_t currentQuota, uint64_t currentOriginUsage, uint64_t currentDatabaseUsage, uint64_t expectedUsage, PassRefPtr<Messages::WebPageProxy::ExceededDatabaseQuota::DelayedReply> reply)
4012 {
4013     ExceededDatabaseQuotaRecords& records = ExceededDatabaseQuotaRecords::shared();
4014     OwnPtr<ExceededDatabaseQuotaRecords::Record> newRecord =  records.createRecord(frameID,
4015         originIdentifier, databaseName, displayName, currentQuota, currentOriginUsage,
4016         currentDatabaseUsage, expectedUsage, reply);
4017     records.add(newRecord.release());
4018
4019     if (records.areBeingProcessed())
4020         return;
4021
4022     ExceededDatabaseQuotaRecords::Record* record = records.next();
4023     while (record) {
4024         WebFrameProxy* frame = m_process->webFrame(record->frameID);
4025         MESSAGE_CHECK(frame);
4026
4027         RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(record->originIdentifier);
4028
4029         uint64_t newQuota = m_uiClient.exceededDatabaseQuota(this, frame, origin.get(),
4030             record->databaseName, record->displayName, record->currentQuota,
4031             record->currentOriginUsage, record->currentDatabaseUsage, record->expectedUsage);
4032
4033         record->reply->send(newQuota);
4034         record = records.next();
4035     }
4036 }
4037
4038 void WebPageProxy::requestGeolocationPermissionForFrame(uint64_t geolocationID, uint64_t frameID, String originIdentifier)
4039 {
4040     WebFrameProxy* frame = m_process->webFrame(frameID);
4041     MESSAGE_CHECK(frame);
4042
4043     // FIXME: Geolocation should probably be using toString() as its string representation instead of databaseIdentifier().
4044     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier);
4045     RefPtr<GeolocationPermissionRequestProxy> request = m_geolocationPermissionRequestManager.createRequest(geolocationID);
4046
4047     if (!m_uiClient.decidePolicyForGeolocationPermissionRequest(this, frame, origin.get(), request.get()))
4048         request->deny();
4049 }
4050
4051 void WebPageProxy::requestNotificationPermission(uint64_t requestID, const String& originString)
4052 {
4053     if (!isRequestIDValid(requestID))
4054         return;
4055
4056     RefPtr<WebSecurityOrigin> origin = WebSecurityOrigin::createFromString(originString);
4057     RefPtr<NotificationPermissionRequest> request = m_notificationPermissionRequestManager.createRequest(requestID);
4058     
4059     if (!m_uiClient.decidePolicyForNotificationPermissionRequest(this, origin.get(), request.get()))
4060         request->deny();
4061 }
4062
4063 void WebPageProxy::showNotification(const String& title, const String& body, const String& iconURL, const String& tag, const String& lang, const String& dir, const String& originString, uint64_t notificationID)
4064 {
4065     m_process->context()->supplement<WebNotificationManagerProxy>()->show(this, title, body, iconURL, tag, lang, dir, originString, notificationID);
4066 }
4067
4068 float WebPageProxy::headerHeight(WebFrameProxy* frame)
4069 {
4070     if (frame->isDisplayingPDFDocument())
4071         return 0;
4072     return m_uiClient.headerHeight(this, frame);
4073 }
4074
4075 float WebPageProxy::footerHeight(WebFrameProxy* frame)
4076 {
4077     if (frame->isDisplayingPDFDocument())
4078         return 0;
4079     return m_uiClient.footerHeight(this, frame);
4080 }
4081
4082 void WebPageProxy::drawHeader(WebFrameProxy* frame, const FloatRect& rect)
4083 {
4084     if (frame->isDisplayingPDFDocument())
4085         return;
4086     m_uiClient.drawHeader(this, frame, rect);
4087 }
4088
4089 void WebPageProxy::drawFooter(WebFrameProxy* frame, const FloatRect& rect)
4090 {
4091     if (frame->isDisplayingPDFDocument())
4092         return;
4093     m_uiClient.drawFooter(this, frame, rect);
4094 }
4095
4096 void WebPageProxy::runModal()
4097 {
4098     // Since runModal() can (and probably will) spin a nested run loop we need to turn off the responsiveness timer.
4099     m_process->responsivenessTimer()->stop();
4100
4101     // Our Connection's run loop might have more messages waiting to be handled after this RunModal message.
4102     // To make sure they are handled inside of the the nested modal run loop we must first signal the Connection's
4103     // run loop so we're guaranteed that it has a chance to wake up.
4104     // See http://webkit.org/b/89590 for more discussion.
4105     m_process->connection()->wakeUpRunLoop();
4106
4107     m_uiClient.runModal(this);
4108 }
4109
4110 void WebPageProxy::notifyScrollerThumbIsVisibleInRect(const IntRect& scrollerThumb)
4111 {
4112     m_visibleScrollerThumbRect = scrollerThumb;
4113 }
4114
4115 void WebPageProxy::recommendedScrollbarStyleDidChange(int32_t newStyle)
4116 {
4117 #if PLATFORM(MAC)
4118     m_pageClient->recommendedScrollbarStyleDidChange(newStyle);
4119 #else
4120     UNUSED_PARAM(newStyle);
4121 #endif
4122 }
4123
4124 void WebPageProxy::didChangeScrollbarsForMainFrame(bool hasHorizontalScrollbar, bool hasVerticalScrollbar)
4125 {
4126     m_mainFrameHasHorizontalScrollbar = hasHorizontalScrollbar;
4127     m_mainFrameHasVerticalScrollbar = hasVerticalScrollbar;
4128 }
4129
4130 void WebPageProxy::didChangeScrollOffsetPinningForMainFrame(bool pinnedToLeftSide, bool pinnedToRightSide, bool pinnedToTopSide, bool pinnedToBottomSide)
4131 {
4132     m_mainFrameIsPinnedToLeftSide = pinnedToLeftSide;
4133     m_mainFrameIsPinnedToRightSide = pinnedToRightSide;
4134     m_mainFrameIsPinnedToTopSide = pinnedToTopSide;
4135     m_mainFrameIsPinnedToBottomSide = pinnedToBottomSide;
4136 }
4137
4138 void WebPageProxy::didChangePageCount(unsigned pageCount)
4139 {
4140     m_pageCount = pageCount;
4141 }
4142
4143 void WebPageProxy::didFailToInitializePlugin(const String& mimeType, const String& frameURLString, const String& pageURLString)
4144 {
4145     m_loaderClient.didFailToInitializePlugin(this, mimeType, frameURLString, pageURLString);
4146 }
4147
4148 // FIXME: ENABLE(NETSCAPE_PLUGIN_API)
4149 void WebPageProxy::didBlockInsecurePluginVersion(const String& mimeType, const String& pluginURLString, const String& frameURLString, const String& pageURLString)
4150 {
4151     String pluginBundleIdentifier;
4152     String pluginBundleVersion;
4153     String newMimeType = mimeType;
4154
4155 #if PLATFORM(MAC) && ENABLE(NETSCAPE_PLUGIN_API)
4156     PluginModuleInfo plugin = m_process->context()->pluginInfoStore().findPlugin(newMimeType, KURL(KURL(), pluginURLString));
4157
4158     pluginBundleIdentifier = plugin.bundleIdentifier;
4159     pluginBundleVersion = plugin.versionString;
4160 #else
4161     UNUSED_PARAM(pluginURLString);
4162 #endif
4163
4164     m_loaderClient.didBlockInsecurePluginVersion(this, newMimeType, pluginBundleIdentifier, pluginBundleVersion, frameURLString, pageURLString);
4165 }
4166
4167 bool WebPageProxy::willHandleHorizontalScrollEvents() const
4168 {
4169     return !m_canShortCircuitHorizontalWheelEvents;
4170 }
4171
4172 void WebPageProxy::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference& dataReference)
4173 {
4174     m_pageClient->didFinishLoadingDataForCustomRepresentation(suggestedFilename, dataReference);
4175 }
4176
4177 void WebPageProxy::backForwardRemovedItem(uint64_t itemID)
4178 {
4179     m_process->send(Messages::WebPage::DidRemoveBackForwardItem(itemID), m_pageID);
4180 }
4181
4182 void WebPageProxy::setCanRunModal(bool canRunModal)
4183 {
4184     if (!isValid())
4185         return;
4186
4187     // It's only possible to change the state for a WebPage which
4188     // already qualifies for running modal child web pages, otherwise
4189     // there's no other possibility than not allowing it.
4190     m_canRunModal = m_uiClient.canRunModal() && canRunModal;
4191     m_process->send(Messages::WebPage::SetCanRunModal(m_canRunModal), m_pageID);
4192 }
4193
4194 bool WebPageProxy::canRunModal()
4195 {
4196     return isValid() ? m_canRunModal : false;
4197 }
4198
4199 void WebPageProxy::beginPrinting(WebFrameProxy* frame, const PrintInfo& printInfo)
4200 {
4201     if (m_isInPrintingMode)
4202         return;
4203
4204     m_isInPrintingMode = true;
4205     m_process->send(Messages::WebPage::BeginPrinting(frame->frameID(), printInfo), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4206 }
4207
4208 void WebPageProxy::endPrinting()
4209 {
4210     if (!m_isInPrintingMode)
4211         return;
4212
4213     m_isInPrintingMode = false;
4214     m_process->send(Messages::WebPage::EndPrinting(), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4215 }
4216
4217 void WebPageProxy::computePagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<ComputedPagesCallback> prpCallback)
4218 {
4219     RefPtr<ComputedPagesCallback> callback = prpCallback;
4220     if (!isValid()) {
4221         callback->invalidate();
4222         return;
4223     }
4224
4225     uint64_t callbackID = callback->callbackID();
4226     m_computedPagesCallbacks.set(callbackID, callback.get());
4227     m_isInPrintingMode = true;
4228     m_process->send(Messages::WebPage::ComputePagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4229 }
4230
4231 #if PLATFORM(MAC)
4232 void WebPageProxy::drawRectToImage(WebFrameProxy* frame, const PrintInfo& printInfo, const IntRect& rect, const WebCore::IntSize& imageSize, PassRefPtr<ImageCallback> prpCallback)
4233 {
4234     RefPtr<ImageCallback> callback = prpCallback;
4235     if (!isValid()) {
4236         callback->invalidate();
4237         return;
4238     }
4239     
4240     uint64_t callbackID = callback->callbackID();
4241     m_imageCallbacks.set(callbackID, callback.get());
4242     m_process->send(Messages::WebPage::DrawRectToImage(frame->frameID(), printInfo, rect, imageSize, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4243 }
4244
4245 void WebPageProxy::drawPagesToPDF(WebFrameProxy* frame, const PrintInfo& printInfo, uint32_t first, uint32_t count, PassRefPtr<DataCallback> prpCallback)
4246 {
4247     RefPtr<DataCallback> callback = prpCallback;
4248     if (!isValid()) {
4249         callback->invalidate();
4250         return;
4251     }
4252     
4253     uint64_t callbackID = callback->callbackID();
4254     m_dataCallbacks.set(callbackID, callback.get());
4255     m_process->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4256 }
4257 #elif PLATFORM(GTK)
4258 void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<PrintFinishedCallback> didPrintCallback)
4259 {
4260     RefPtr<PrintFinishedCallback> callback = didPrintCallback;
4261     if (!isValid()) {
4262         callback->invalidate();
4263         return;
4264     }
4265
4266     uint64_t callbackID = callback->callbackID();
4267     m_printFinishedCallbacks.set(callbackID, callback.get());
4268     m_isInPrintingMode = true;
4269     m_process->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
4270 }
4271 #endif
4272
4273 void WebPageProxy::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
4274 {
4275     m_pageClient->flashBackingStoreUpdates(updateRects);
4276 }
4277
4278 void WebPageProxy::updateBackingStoreDiscardableState()
4279 {
4280     ASSERT(isValid());
4281
4282     bool isDiscardable;
4283
4284     if (!m_process->responsivenessTimer()->isResponsive())
4285         isDiscardable = false;
4286     else
4287         isDiscardable = !m_pageClient->isViewWindowActive() || !isViewVisible();
4288
4289     m_drawingArea->setBackingStoreIsDiscardable(isDiscardable);
4290 }
4291
4292 Color WebPageProxy::viewUpdatesFlashColor()
4293 {
4294     return Color(0, 200, 255);
4295 }
4296
4297 Color WebPageProxy::backingStoreUpdatesFlashColor()
4298 {
4299     return Color(200, 0, 255);
4300 }
4301
4302 void WebPageProxy::saveDataToFileInDownloadsFolder(const String& suggestedFilename, const String& mimeType, const String& originatingURLString, WebData* data)
4303 {