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