[iOS] Input field on ddg.gg is auto focused when url is entered with the software...
[WebKit-https.git] / Source / WebKit / UIProcess / ios / WebPageProxyIOS.mm
1 /*
2  * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WebPageProxy.h"
28
29 #if PLATFORM(IOS_FAMILY)
30
31 #import "APINavigationAction.h"
32 #import "APIUIClient.h"
33 #import "APIWebsitePolicies.h"
34 #import "Connection.h"
35 #import "DataReference.h"
36 #import "DocumentEditingContext.h"
37 #import "EditingRange.h"
38 #import "GlobalFindInPageState.h"
39 #import "InteractionInformationAtPosition.h"
40 #import "Logging.h"
41 #import "NativeWebKeyboardEvent.h"
42 #import "NavigationState.h"
43 #import "PageClient.h"
44 #import "PaymentAuthorizationViewController.h"
45 #import "PrintInfo.h"
46 #import "RemoteLayerTreeDrawingAreaProxy.h"
47 #import "RemoteLayerTreeDrawingAreaProxyMessages.h"
48 #import "RemoteLayerTreeTransaction.h"
49 #import "UIKitSPI.h"
50 #import "UserData.h"
51 #import "VideoFullscreenManagerProxy.h"
52 #import "ViewUpdateDispatcherMessages.h"
53 #import "WKBrowsingContextControllerInternal.h"
54 #import "WebAutocorrectionContext.h"
55 #import "WebPageMessages.h"
56 #import "WebProcessPool.h"
57 #import "WebProcessProxy.h"
58 #import <WebCore/FrameView.h>
59 #import <WebCore/NotImplemented.h>
60 #import <WebCore/PlatformScreen.h>
61 #import <WebCore/RuntimeApplicationChecks.h>
62 #import <WebCore/SharedBuffer.h>
63 #import <WebCore/UserAgent.h>
64 #import <WebCore/ValidationBubble.h>
65 #import <wtf/text/TextStream.h>
66
67 #if USE(QUICK_LOOK)
68 #import "APILoaderClient.h"
69 #import "APINavigationClient.h"
70 #import <wtf/text/WTFString.h>
71 #endif
72
73 namespace WebKit {
74 using namespace WebCore;
75
76 void WebPageProxy::platformInitialize()
77 {
78 }
79
80 String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent)
81 {
82     return standardUserAgentWithApplicationName(applicationNameForUserAgent);
83 }
84
85 #if HAVE(VISIBILITY_PROPAGATION_VIEW)
86 void WebPageProxy::didCreateContextForVisibilityPropagation(LayerHostingContextID contextID)
87 {
88     pageClient().didCreateContextForVisibilityPropagation(contextID);
89 }
90 #endif
91
92 void WebPageProxy::getIsSpeaking(CompletionHandler<void(bool)>&& completionHandler)
93 {
94     notImplemented();
95     completionHandler(false);
96 }
97
98 void WebPageProxy::speak(const String&)
99 {
100     notImplemented();
101 }
102
103 void WebPageProxy::stopSpeaking()
104 {
105     notImplemented();
106 }
107
108 void WebPageProxy::searchWithSpotlight(const String&)
109 {
110     notImplemented();
111 }
112
113 void WebPageProxy::searchTheWeb(const String&)
114 {
115     notImplemented();
116 }
117
118 void WebPageProxy::windowAndViewFramesChanged(const FloatRect&, const FloatPoint&)
119 {
120     notImplemented();
121 }
122
123 String WebPageProxy::stringSelectionForPasteboard()
124 {
125     notImplemented();
126     return String();
127 }
128
129 RefPtr<WebCore::SharedBuffer> WebPageProxy::dataSelectionForPasteboard(const String&)
130 {
131     notImplemented();
132     return nullptr;
133 }
134
135 bool WebPageProxy::readSelectionFromPasteboard(const String&)
136 {
137     notImplemented();
138     return false;
139 }
140
141 void WebPageProxy::gestureCallback(const WebCore::IntPoint& point, uint32_t gestureType, uint32_t gestureState, uint32_t flags, CallbackID callbackID)
142 {
143     auto callback = m_callbacks.take<GestureCallback>(callbackID);
144     if (!callback) {
145         ASSERT_NOT_REACHED();
146         return;
147     }
148     
149     callback->performCallbackWithReturnValue(point, gestureType, gestureState, flags);
150 }
151
152 void WebPageProxy::touchesCallback(const WebCore::IntPoint& point, uint32_t touches, uint32_t flags, CallbackID callbackID)
153 {
154     auto callback = m_callbacks.take<TouchesCallback>(callbackID);
155     if (!callback) {
156         ASSERT_NOT_REACHED();
157         return;
158     }
159
160     callback->performCallbackWithReturnValue(point, touches, flags);
161 }
162
163 void WebPageProxy::autocorrectionDataCallback(const Vector<WebCore::FloatRect>& rects, const String& fontName, float fontSize, uint64_t fontTraits, CallbackID callbackID)
164 {
165     auto callback = m_callbacks.take<AutocorrectionDataCallback>(callbackID);
166     if (!callback) {
167         ASSERT_NOT_REACHED();
168         return;
169     }
170
171     callback->performCallbackWithReturnValue(rects, fontName, fontSize, fontTraits);
172 }
173
174 void WebPageProxy::selectionContextCallback(const String& selectedText, const String& beforeText, const String& afterText, CallbackID callbackID)
175 {
176     auto callback = m_callbacks.take<SelectionContextCallback>(callbackID);
177     if (!callback) {
178         ASSERT_NOT_REACHED();
179         return;
180     }
181
182     callback->performCallbackWithReturnValue(selectedText, beforeText, afterText);
183 }
184
185 void WebPageProxy::autocorrectionContextCallback(const WebAutocorrectionContext& context, CallbackID callbackID)
186 {
187     auto callback = m_callbacks.take<AutocorrectionContextCallback>(callbackID);
188     if (!callback) {
189         ASSERT_NOT_REACHED();
190         return;
191     }
192
193     callback->performCallbackWithReturnValue(context);
194 }
195
196 void WebPageProxy::selectionRectsCallback(const Vector<WebCore::SelectionRect>& selectionRects, CallbackID callbackID)
197 {
198     auto callback = m_callbacks.take<SelectionRectsCallback>(callbackID);
199     if (!callback) {
200         ASSERT_NOT_REACHED();
201         return;
202     }
203     
204     callback->performCallbackWithReturnValue(selectionRects);
205 }
206
207 void WebPageProxy::focusedElementInformationCallback(const FocusedElementInformation& info, CallbackID callbackID)
208 {
209     auto callback = m_callbacks.take<FocusedElementInformationCallback>(callbackID);
210     if (!callback) {
211         ASSERT_NOT_REACHED();
212         return;
213     }
214
215     callback->performCallbackWithReturnValue(info);
216 }
217
218 void WebPageProxy::requestFocusedElementInformation(Function<void(const FocusedElementInformation&, CallbackBase::Error)>&& callback)
219 {
220     if (!hasRunningProcess()) {
221         callback({ }, CallbackBase::Error::OwnerWasInvalidated);
222         return;
223     }
224
225     auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
226     m_process->send(Messages::WebPage::RequestFocusedElementInformation(callbackID), m_pageID);
227 }
228
229 void WebPageProxy::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visibleContentRectUpdate)
230 {
231     if (visibleContentRectUpdate == m_lastVisibleContentRectUpdate)
232         return;
233
234     m_lastVisibleContentRectUpdate = visibleContentRectUpdate;
235
236     if (!hasRunningProcess())
237         return;
238
239     m_process->send(Messages::ViewUpdateDispatcher::VisibleContentRectUpdate(m_pageID, visibleContentRectUpdate), 0);
240 }
241
242 void WebPageProxy::resendLastVisibleContentRects()
243 {
244     m_process->send(Messages::ViewUpdateDispatcher::VisibleContentRectUpdate(m_pageID, m_lastVisibleContentRectUpdate), 0);
245 }
246
247 void WebPageProxy::updateStringForFind(const String& string)
248 {
249     if (!hasRunningProcess())
250         return;
251
252     WebKit::updateStringForFind(string);
253 }
254
255 static inline float adjustedUnexposedEdge(float documentEdge, float exposedRectEdge, float factor)
256 {
257     if (exposedRectEdge < documentEdge)
258         return documentEdge - factor * (documentEdge - exposedRectEdge);
259     
260     return exposedRectEdge;
261 }
262
263 static inline float adjustedUnexposedMaxEdge(float documentEdge, float exposedRectEdge, float factor)
264 {
265     if (exposedRectEdge > documentEdge)
266         return documentEdge + factor * (exposedRectEdge - documentEdge);
267     
268     return exposedRectEdge;
269 }
270
271 // FIXME: rename this when visual viewports are the default.
272 WebCore::FloatRect WebPageProxy::computeCustomFixedPositionRect(const FloatRect& unobscuredContentRect, const FloatRect& unobscuredContentRectRespectingInputViewBounds, const FloatRect& currentCustomFixedPositionRect, double displayedContentScale, FrameView::LayoutViewportConstraint constraint) const
273 {
274     FloatRect constrainedUnobscuredRect = unobscuredContentRect;
275     FloatRect documentRect = pageClient().documentRect();
276
277     if (constraint == FrameView::LayoutViewportConstraint::ConstrainedToDocumentRect)
278         constrainedUnobscuredRect.intersect(documentRect);
279
280     double minimumScale = pageClient().minimumZoomScale();
281     bool isBelowMinimumScale = displayedContentScale < minimumScale;
282     if (isBelowMinimumScale) {
283         const CGFloat slope = 12;
284         CGFloat factor = std::max<CGFloat>(1 - slope * (minimumScale - displayedContentScale), 0);
285             
286         constrainedUnobscuredRect.setX(adjustedUnexposedEdge(documentRect.x(), constrainedUnobscuredRect.x(), factor));
287         constrainedUnobscuredRect.setY(adjustedUnexposedEdge(documentRect.y(), constrainedUnobscuredRect.y(), factor));
288         constrainedUnobscuredRect.setWidth(adjustedUnexposedMaxEdge(documentRect.maxX(), constrainedUnobscuredRect.maxX(), factor) - constrainedUnobscuredRect.x());
289         constrainedUnobscuredRect.setHeight(adjustedUnexposedMaxEdge(documentRect.maxY(), constrainedUnobscuredRect.maxY(), factor) - constrainedUnobscuredRect.y());
290     }
291
292     FloatSize constrainedSize = isBelowMinimumScale ? constrainedUnobscuredRect.size() : unobscuredContentRect.size();
293     FloatRect unobscuredContentRectForViewport = isBelowMinimumScale ? constrainedUnobscuredRect : unobscuredContentRectRespectingInputViewBounds;
294
295     auto layoutViewportSize = FrameView::expandedLayoutViewportSize(m_baseLayoutViewportSize, LayoutSize(documentRect.size()), m_preferences->layoutViewportHeightExpansionFactor());
296     FloatRect layoutViewportRect = FrameView::computeUpdatedLayoutViewportRect(LayoutRect(currentCustomFixedPositionRect), LayoutRect(documentRect), LayoutSize(constrainedSize), LayoutRect(unobscuredContentRectForViewport), layoutViewportSize, m_minStableLayoutViewportOrigin, m_maxStableLayoutViewportOrigin, constraint);
297     
298     if (layoutViewportRect != currentCustomFixedPositionRect)
299         LOG_WITH_STREAM(VisibleRects, stream << "WebPageProxy::computeCustomFixedPositionRect: new layout viewport  " << layoutViewportRect);
300     return layoutViewportRect;
301 }
302
303 void WebPageProxy::scrollingNodeScrollViewWillStartPanGesture()
304 {
305     pageClient().scrollingNodeScrollViewWillStartPanGesture();
306 }
307
308 void WebPageProxy::scrollingNodeScrollViewDidScroll()
309 {
310     pageClient().scrollingNodeScrollViewDidScroll();
311 }
312
313 void WebPageProxy::scrollingNodeScrollWillStartScroll()
314 {
315     pageClient().scrollingNodeScrollWillStartScroll();
316 }
317
318 void WebPageProxy::scrollingNodeScrollDidEndScroll()
319 {
320     pageClient().scrollingNodeScrollDidEndScroll();
321 }
322
323 void WebPageProxy::dynamicViewportSizeUpdate(const FloatSize& viewLayoutSize, const WebCore::FloatSize& maximumUnobscuredSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, const FloatRect& targetUnobscuredRectInScrollViewCoordinates, const WebCore::FloatBoxExtent& unobscuredSafeAreaInsets, double targetScale, int32_t deviceOrientation, DynamicViewportSizeUpdateID dynamicViewportSizeUpdateID)
324 {
325     if (!hasRunningProcess())
326         return;
327
328     hideValidationMessage();
329
330     m_process->send(Messages::WebPage::DynamicViewportSizeUpdate(viewLayoutSize,
331         maximumUnobscuredSize, targetExposedContentRect, targetUnobscuredRect,
332         targetUnobscuredRectInScrollViewCoordinates, unobscuredSafeAreaInsets,
333         targetScale, deviceOrientation, dynamicViewportSizeUpdateID), m_pageID);
334 }
335
336 void WebPageProxy::setViewportConfigurationViewLayoutSize(const WebCore::FloatSize& size, double scaleFactor, double minimumEffectiveDeviceWidth)
337 {
338     m_viewportConfigurationViewLayoutSize = size;
339     m_viewportConfigurationLayoutSizeScaleFactor = scaleFactor;
340     m_viewportConfigurationMinimumEffectiveDeviceWidth = minimumEffectiveDeviceWidth;
341
342     if (hasRunningProcess())
343         m_process->send(Messages::WebPage::SetViewportConfigurationViewLayoutSize(size, scaleFactor, minimumEffectiveDeviceWidth), m_pageID);
344 }
345
346 void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
347 {
348     if (m_forceAlwaysUserScalable == userScalable)
349         return;
350     m_forceAlwaysUserScalable = userScalable;
351
352     if (hasRunningProcess())
353         m_process->send(Messages::WebPage::SetForceAlwaysUserScalable(userScalable), m_pageID);
354 }
355
356 void WebPageProxy::setMaximumUnobscuredSize(const WebCore::FloatSize& size)
357 {
358     m_maximumUnobscuredSize = size;
359
360     if (hasRunningProcess())
361         m_process->send(Messages::WebPage::SetMaximumUnobscuredSize(size), m_pageID);
362 }
363
364 void WebPageProxy::setDeviceOrientation(int32_t deviceOrientation)
365 {
366     if (deviceOrientation != m_deviceOrientation) {
367         m_deviceOrientation = deviceOrientation;
368         if (hasRunningProcess())
369             m_process->send(Messages::WebPage::SetDeviceOrientation(deviceOrientation), m_pageID);
370     }
371 }
372
373 void WebPageProxy::setOverrideViewportArguments(const Optional<ViewportArguments>& viewportArguments)
374 {
375     if (viewportArguments == m_overrideViewportArguments)
376         return;
377
378     m_overrideViewportArguments = viewportArguments;
379
380     if (hasRunningProcess())
381         m_process->send(Messages::WebPage::SetOverrideViewportArguments(viewportArguments), m_pageID);
382 }
383
384 static bool exceedsRenderTreeSizeSizeThreshold(uint64_t thresholdSize, uint64_t committedSize)
385 {
386     const double thesholdSizeFraction = 0.5; // Empirically-derived.
387     return committedSize > thresholdSize * thesholdSizeFraction;
388 }
389
390 void WebPageProxy::didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
391 {
392     m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
393
394     if (!m_hasReceivedLayerTreeTransactionAfterDidCommitLoad) {
395         if (layerTreeTransaction.transactionID() >= m_firstLayerTreeTransactionIdAfterDidCommitLoad) {
396             m_hasReceivedLayerTreeTransactionAfterDidCommitLoad = true;
397             m_lastVisibleContentRectUpdate = VisibleContentRectUpdateInfo();
398         }
399     }
400
401     pageClient().didCommitLayerTree(layerTreeTransaction);
402
403     // FIXME: Remove this special mechanism and fold it into the transaction's layout milestones.
404     if (m_observedLayoutMilestones.contains(WebCore::ReachedSessionRestorationRenderTreeSizeThreshold) && !m_hitRenderTreeSizeThreshold
405         && exceedsRenderTreeSizeSizeThreshold(m_sessionRestorationRenderTreeSize, layerTreeTransaction.renderTreeSize())) {
406         m_hitRenderTreeSizeThreshold = true;
407         didReachLayoutMilestone(WebCore::ReachedSessionRestorationRenderTreeSizeThreshold);
408     }
409
410     if (auto arguments = std::exchange(m_deferredElementDidFocusArguments, nullptr))
411         pageClient().elementDidFocus(arguments->information, arguments->userIsInteracting, arguments->blurPreviousNode, arguments->activityStateChanges, arguments->userData.get());
412 }
413
414 bool WebPageProxy::updateLayoutViewportParameters(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
415 {
416     if (m_baseLayoutViewportSize == layerTreeTransaction.baseLayoutViewportSize()
417         && m_minStableLayoutViewportOrigin == layerTreeTransaction.minStableLayoutViewportOrigin()
418         && m_maxStableLayoutViewportOrigin == layerTreeTransaction.maxStableLayoutViewportOrigin())
419         return false;
420
421     m_baseLayoutViewportSize = layerTreeTransaction.baseLayoutViewportSize();
422     m_minStableLayoutViewportOrigin = layerTreeTransaction.minStableLayoutViewportOrigin();
423     m_maxStableLayoutViewportOrigin = layerTreeTransaction.maxStableLayoutViewportOrigin();
424
425     LOG_WITH_STREAM(VisibleRects, stream << "WebPageProxy::updateLayoutViewportParameters: baseLayoutViewportSize: " << m_baseLayoutViewportSize << " minStableLayoutViewportOrigin: " << m_minStableLayoutViewportOrigin << " maxStableLayoutViewportOrigin: " << m_maxStableLayoutViewportOrigin);
426
427     return true;
428 }
429
430 void WebPageProxy::layerTreeCommitComplete()
431 {
432     pageClient().layerTreeCommitComplete();
433 }
434
435 void WebPageProxy::selectWithGesture(const WebCore::IntPoint point, WebCore::TextGranularity granularity, uint32_t gestureType, uint32_t gestureState, bool isInteractingWithFocusedElement, WTF::Function<void(const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&& callbackFunction)
436 {
437     if (!hasRunningProcess()) {
438         callbackFunction(WebCore::IntPoint(), 0, 0, 0, CallbackBase::Error::Unknown);
439         return;
440     }
441
442     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
443     m_process->send(Messages::WebPage::SelectWithGesture(point, (uint32_t)granularity, gestureType, gestureState, isInteractingWithFocusedElement, callbackID), m_pageID);
444 }
445
446 void WebPageProxy::updateSelectionWithTouches(const WebCore::IntPoint point, uint32_t touches, bool baseIsStart, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, CallbackBase::Error)>&& callbackFunction)
447 {
448     if (!hasRunningProcess()) {
449         callbackFunction(WebCore::IntPoint(), 0, 0, CallbackBase::Error::Unknown);
450         return;
451     }
452
453     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
454     m_process->send(Messages::WebPage::UpdateSelectionWithTouches(point, touches, baseIsStart, callbackID), m_pageID);
455 }
456     
457 void WebPageProxy::replaceDictatedText(const String& oldText, const String& newText)
458 {
459     m_process->send(Messages::WebPage::ReplaceDictatedText(oldText, newText), m_pageID);
460 }
461
462 void WebPageProxy::replaceSelectedText(const String& oldText, const String& newText)
463 {
464     m_process->send(Messages::WebPage::ReplaceSelectedText(oldText, newText), m_pageID);
465 }
466
467 void WebPageProxy::requestAutocorrectionData(const String& textForAutocorrection, WTF::Function<void (const Vector<WebCore::FloatRect>&, const String&, double, uint64_t, CallbackBase::Error)>&& callbackFunction)
468 {
469     if (!hasRunningProcess()) {
470         callbackFunction(Vector<WebCore::FloatRect>(), String(), 0, 0, CallbackBase::Error::Unknown);
471         return;
472     }
473
474     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
475     m_process->send(Messages::WebPage::RequestAutocorrectionData(textForAutocorrection, callbackID), m_pageID);
476 }
477
478 void WebPageProxy::applyAutocorrection(const String& correction, const String& originalText, WTF::Function<void (const String&, CallbackBase::Error)>&& callbackFunction)
479 {
480     if (!hasRunningProcess()) {
481         callbackFunction(String(), CallbackBase::Error::Unknown);
482         return;
483     }
484
485     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
486     m_process->send(Messages::WebPage::ApplyAutocorrection(correction, originalText, callbackID), m_pageID);
487 }
488
489 bool WebPageProxy::applyAutocorrection(const String& correction, const String& originalText)
490 {
491     bool autocorrectionApplied = false;
492     m_process->sendSync(Messages::WebPage::SyncApplyAutocorrection(correction, originalText), Messages::WebPage::SyncApplyAutocorrection::Reply(autocorrectionApplied), m_pageID);
493     return autocorrectionApplied;
494 }
495
496 void WebPageProxy::selectTextWithGranularityAtPoint(const WebCore::IntPoint point, WebCore::TextGranularity granularity, bool isInteractingWithFocusedElement, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
497 {
498     if (!hasRunningProcess()) {
499         callbackFunction(CallbackBase::Error::Unknown);
500         return;
501     }
502     
503     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
504     m_process->send(Messages::WebPage::SelectTextWithGranularityAtPoint(point, static_cast<uint32_t>(granularity), isInteractingWithFocusedElement, callbackID), m_pageID);
505 }
506
507 void WebPageProxy::selectPositionAtBoundaryWithDirection(const WebCore::IntPoint point, WebCore::TextGranularity granularity, WebCore::SelectionDirection direction, bool isInteractingWithFocusedElement, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
508 {
509     if (!hasRunningProcess()) {
510         callbackFunction(CallbackBase::Error::Unknown);
511         return;
512     }
513     
514     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
515     m_process->send(Messages::WebPage::SelectPositionAtBoundaryWithDirection(point, static_cast<uint32_t>(granularity), static_cast<uint32_t>(direction), isInteractingWithFocusedElement, callbackID), m_pageID);
516 }
517
518 void WebPageProxy::moveSelectionAtBoundaryWithDirection(WebCore::TextGranularity granularity, WebCore::SelectionDirection direction, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
519 {
520     if (!hasRunningProcess()) {
521         callbackFunction(CallbackBase::Error::Unknown);
522         return;
523     }
524     
525     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
526     m_process->send(Messages::WebPage::MoveSelectionAtBoundaryWithDirection(static_cast<uint32_t>(granularity), static_cast<uint32_t>(direction), callbackID), m_pageID);
527 }
528     
529 void WebPageProxy::selectPositionAtPoint(const WebCore::IntPoint point, bool isInteractingWithFocusedElement, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
530 {
531     if (!hasRunningProcess()) {
532         callbackFunction(CallbackBase::Error::Unknown);
533         return;
534     }
535     
536     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
537     m_process->send(Messages::WebPage::SelectPositionAtPoint(point, isInteractingWithFocusedElement, callbackID), m_pageID);
538 }
539
540 void WebPageProxy::beginSelectionInDirection(WebCore::SelectionDirection direction, WTF::Function<void (uint64_t, CallbackBase::Error)>&& callbackFunction)
541 {
542     if (!hasRunningProcess()) {
543         callbackFunction(0, CallbackBase::Error::Unknown);
544         return;
545     }
546     
547     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
548     m_process->send(Messages::WebPage::BeginSelectionInDirection(direction, callbackID), m_pageID);
549 }
550
551 void WebPageProxy::updateSelectionWithExtentPoint(const WebCore::IntPoint point, bool isInteractingWithFocusedElement, WTF::Function<void(uint64_t, CallbackBase::Error)>&& callbackFunction)
552 {
553     if (!hasRunningProcess()) {
554         callbackFunction(0, CallbackBase::Error::Unknown);
555         return;
556     }
557     
558     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
559     m_process->send(Messages::WebPage::UpdateSelectionWithExtentPoint(point, isInteractingWithFocusedElement, callbackID), m_pageID);
560     
561 }
562
563 void WebPageProxy::updateSelectionWithExtentPointAndBoundary(const WebCore::IntPoint point, WebCore::TextGranularity granularity, bool isInteractingWithFocusedElement, WTF::Function<void(uint64_t, CallbackBase::Error)>&& callbackFunction)
564 {
565     if (!hasRunningProcess()) {
566         callbackFunction(0, CallbackBase::Error::Unknown);
567         return;
568     }
569     
570     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
571     m_process->send(Messages::WebPage::UpdateSelectionWithExtentPointAndBoundary(point, granularity, isInteractingWithFocusedElement, callbackID), m_pageID);
572     
573 }
574
575 void WebPageProxy::requestDictationContext(WTF::Function<void (const String&, const String&, const String&, CallbackBase::Error)>&& callbackFunction)
576 {
577     if (!hasRunningProcess()) {
578         callbackFunction(String(), String(), String(), CallbackBase::Error::Unknown);
579         return;
580     }
581
582     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
583     m_process->send(Messages::WebPage::RequestDictationContext(callbackID), m_pageID);
584 }
585
586 void WebPageProxy::requestAutocorrectionContext()
587 {
588     m_process->send(Messages::WebPage::RequestAutocorrectionContext(), m_pageID);
589 }
590
591 void WebPageProxy::handleAutocorrectionContext(const WebAutocorrectionContext& context)
592 {
593     pageClient().handleAutocorrectionContext(context);
594 }
595
596 void WebPageProxy::getSelectionContext(WTF::Function<void(const String&, const String&, const String&, CallbackBase::Error)>&& callbackFunction)
597 {
598     if (!hasRunningProcess()) {
599         callbackFunction(String(), String(), String(), CallbackBase::Error::Unknown);
600         return;
601     }
602     
603     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
604     m_process->send(Messages::WebPage::GetSelectionContext(callbackID), m_pageID);
605 }
606
607 void WebPageProxy::handleTwoFingerTapAtPoint(const WebCore::IntPoint& point, OptionSet<WebEvent::Modifier> modifiers, uint64_t requestID)
608 {
609     process().send(Messages::WebPage::HandleTwoFingerTapAtPoint(point, modifiers, requestID), m_pageID);
610 }
611
612 void WebPageProxy::handleStylusSingleTapAtPoint(const WebCore::IntPoint& point, uint64_t requestID)
613 {
614     process().send(Messages::WebPage::HandleStylusSingleTapAtPoint(point, requestID), m_pageID);
615 }
616
617 void WebPageProxy::selectWithTwoTouches(const WebCore::IntPoint from, const WebCore::IntPoint to, uint32_t gestureType, uint32_t gestureState, WTF::Function<void (const WebCore::IntPoint&, uint32_t, uint32_t, uint32_t, CallbackBase::Error)>&& callbackFunction)
618 {
619     if (!hasRunningProcess()) {
620         callbackFunction(WebCore::IntPoint(), 0, 0, 0, CallbackBase::Error::Unknown);
621         return;
622     }
623
624     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
625     m_process->send(Messages::WebPage::SelectWithTwoTouches(from, to, gestureType, gestureState, callbackID), m_pageID);
626 }
627
628 void WebPageProxy::didReceivePositionInformation(const InteractionInformationAtPosition& info)
629 {
630     pageClient().positionInformationDidChange(info);
631 }
632
633 void WebPageProxy::requestPositionInformation(const InteractionInformationRequest& request)
634 {
635     m_process->send(Messages::WebPage::RequestPositionInformation(request), m_pageID);
636 }
637
638 void WebPageProxy::startInteractionWithElementAtPosition(const WebCore::IntPoint& point)
639 {
640     m_process->send(Messages::WebPage::StartInteractionWithElementAtPosition(point), m_pageID);
641 }
642
643 void WebPageProxy::stopInteraction()
644 {
645     m_process->send(Messages::WebPage::StopInteraction(), m_pageID);
646 }
647
648 void WebPageProxy::performActionOnElement(uint32_t action)
649 {
650     m_process->send(Messages::WebPage::PerformActionOnElement(action), m_pageID);
651 }
652
653 void WebPageProxy::saveImageToLibrary(const SharedMemory::Handle& imageHandle, uint64_t imageSize)
654 {
655     auto sharedMemoryBuffer = SharedMemory::map(imageHandle, SharedMemory::Protection::ReadOnly);
656     auto buffer = SharedBuffer::create(static_cast<unsigned char*>(sharedMemoryBuffer->data()), imageSize);
657     pageClient().saveImageToLibrary(WTFMove(buffer));
658 }
659
660 void WebPageProxy::applicationDidEnterBackground()
661 {
662     bool isSuspendedUnderLock = [UIApp isSuspendedUnderLock];
663
664 #if !PLATFORM(WATCHOS)
665     // We normally delay process suspension when the app is backgrounded until the current page load completes. However,
666     // we do not want to do so when the screen is locked for power reasons.
667     if (isSuspendedUnderLock)
668         NavigationState::fromWebPage(*this).releaseNetworkActivityToken(NavigationState::NetworkActivityTokenReleaseReason::ScreenLocked);
669 #endif
670     m_process->send(Messages::WebPage::ApplicationDidEnterBackground(isSuspendedUnderLock), m_pageID);
671 }
672
673 void WebPageProxy::applicationDidFinishSnapshottingAfterEnteringBackground()
674 {
675     if (m_drawingArea) {
676         m_drawingArea->prepareForAppSuspension();
677         m_drawingArea->hideContentUntilPendingUpdate();
678     }
679     m_process->send(Messages::WebPage::ApplicationDidFinishSnapshottingAfterEnteringBackground(), m_pageID);
680 }
681
682 bool WebPageProxy::isInHardwareKeyboardMode()
683 {
684     return [UIKeyboard isInHardwareKeyboardMode];
685 }
686
687 void WebPageProxy::applicationWillEnterForeground()
688 {
689     bool isSuspendedUnderLock = [UIApp isSuspendedUnderLock];
690     m_process->send(Messages::WebPage::ApplicationWillEnterForeground(isSuspendedUnderLock), m_pageID);
691     m_process->send(Messages::WebPage::HardwareKeyboardAvailabilityChanged(isInHardwareKeyboardMode()), m_pageID);
692 }
693
694 void WebPageProxy::applicationWillResignActive()
695 {
696     m_process->send(Messages::WebPage::ApplicationWillResignActive(), m_pageID);
697 }
698
699 void WebPageProxy::applicationDidBecomeActive()
700 {
701 #if HAVE(AVKIT)
702     if (m_videoFullscreenManager)
703         m_videoFullscreenManager->applicationDidBecomeActive();
704 #endif
705     m_process->send(Messages::WebPage::ApplicationDidBecomeActive(), m_pageID);
706 }
707
708 void WebPageProxy::extendSelection(WebCore::TextGranularity granularity)
709 {
710     m_process->send(Messages::WebPage::ExtendSelection(static_cast<uint32_t>(granularity)), m_pageID);
711 }
712
713 void WebPageProxy::selectWordBackward()
714 {
715     m_process->send(Messages::WebPage::SelectWordBackward(), m_pageID);
716 }
717
718 void WebPageProxy::requestRectsForGranularityWithSelectionOffset(WebCore::TextGranularity granularity, uint32_t offset, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&& callbackFunction)
719 {
720     if (!hasRunningProcess()) {
721         callbackFunction(Vector<WebCore::SelectionRect>(), CallbackBase::Error::Unknown);
722         return;
723     }
724     
725     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
726     m_process->send(Messages::WebPage::GetRectsForGranularityWithSelectionOffset(static_cast<uint32_t>(granularity), offset, callbackID), m_pageID);
727 }
728
729 void WebPageProxy::requestRectsAtSelectionOffsetWithText(int32_t offset, const String& text, WTF::Function<void(const Vector<WebCore::SelectionRect>&, CallbackBase::Error)>&& callbackFunction)
730 {
731     if (!hasRunningProcess()) {
732         callbackFunction(Vector<WebCore::SelectionRect>(), CallbackBase::Error::Unknown);
733         return;
734     }
735     
736     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
737     m_process->send(Messages::WebPage::GetRectsAtSelectionOffsetWithText(offset, text, callbackID), m_pageID);
738 }
739
740 void WebPageProxy::storeSelectionForAccessibility(bool shouldStore)
741 {
742     m_process->send(Messages::WebPage::StoreSelectionForAccessibility(shouldStore), m_pageID);
743 }
744
745 void WebPageProxy::startAutoscrollAtPosition(const WebCore::FloatPoint& positionInWindow)
746 {
747     m_process->send(Messages::WebPage::StartAutoscrollAtPosition(positionInWindow), m_pageID);
748 }
749     
750 void WebPageProxy::cancelAutoscroll()
751 {
752     m_process->send(Messages::WebPage::CancelAutoscroll(), m_pageID);
753 }
754
755 void WebPageProxy::moveSelectionByOffset(int32_t offset, WTF::Function<void (CallbackBase::Error)>&& callbackFunction)
756 {
757     if (!hasRunningProcess()) {
758         callbackFunction(CallbackBase::Error::Unknown);
759         return;
760     }
761     
762     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
763     m_process->send(Messages::WebPage::MoveSelectionByOffset(offset, callbackID), m_pageID);
764 }
765
766 void WebPageProxy::interpretKeyEvent(const EditorState& state, bool isCharEvent, CompletionHandler<void(bool)>&& completionHandler)
767 {
768     m_editorState = state;
769     completionHandler(pageClient().interpretKeyEvent(m_keyEventQueue.first(), isCharEvent));
770 }
771
772 // Complex text input support for plug-ins.
773 void WebPageProxy::sendComplexTextInputToPlugin(uint64_t, const String&)
774 {
775     notImplemented();
776 }
777
778 void WebPageProxy::setSmartInsertDeleteEnabled(bool)
779 {
780     notImplemented();
781 }
782
783 void WebPageProxy::registerWebProcessAccessibilityToken(const IPC::DataReference& data)
784 {
785     pageClient().accessibilityWebProcessTokenReceived(data);
786 }    
787
788 void WebPageProxy::assistiveTechnologyMakeFirstResponder()
789 {
790     notImplemented();
791 }
792     
793 void WebPageProxy::makeFirstResponder()
794 {
795     notImplemented();
796 }
797
798 void WebPageProxy::registerUIProcessAccessibilityTokens(const IPC::DataReference& elementToken, const IPC::DataReference& windowToken)
799 {
800     if (!hasRunningProcess())
801         return;
802     
803     process().send(Messages::WebPage::RegisterUIProcessAccessibilityTokens(elementToken, windowToken), m_pageID);
804 }
805
806 void WebPageProxy::pluginFocusOrWindowFocusChanged(uint64_t, bool)
807 {
808     notImplemented();
809 }
810
811 void WebPageProxy::setPluginComplexTextInputState(uint64_t, uint64_t)
812 {
813     notImplemented();
814 }
815
816 void WebPageProxy::executeSavedCommandBySelector(const String&, CompletionHandler<void(bool)>&& completionHandler)
817 {
818     notImplemented();
819     completionHandler(false);
820 }
821
822 bool WebPageProxy::shouldDelayWindowOrderingForEvent(const WebKit::WebMouseEvent&)
823 {
824     notImplemented();
825     return false;
826 }
827
828 bool WebPageProxy::acceptsFirstMouse(int, const WebKit::WebMouseEvent&)
829 {
830     notImplemented();
831     return false;
832 }
833
834 void WebPageProxy::willStartUserTriggeredZooming()
835 {
836     process().send(Messages::WebPage::WillStartUserTriggeredZooming(), m_pageID);
837 }
838
839 void WebPageProxy::potentialTapAtPosition(const WebCore::FloatPoint& position, bool shouldRequestMagnificationInformation, uint64_t& requestID)
840 {
841     hideValidationMessage();
842     process().send(Messages::WebPage::PotentialTapAtPosition(requestID, position, shouldRequestMagnificationInformation), m_pageID);
843 }
844
845 void WebPageProxy::commitPotentialTap(OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart)
846 {
847     process().send(Messages::WebPage::CommitPotentialTap(modifiers, layerTreeTransactionIdAtLastTouchStart), m_pageID);
848 }
849
850 void WebPageProxy::cancelPotentialTap()
851 {
852     process().send(Messages::WebPage::CancelPotentialTap(), m_pageID);
853 }
854
855 void WebPageProxy::tapHighlightAtPosition(const WebCore::FloatPoint& position, uint64_t& requestID)
856 {
857     process().send(Messages::WebPage::TapHighlightAtPosition(requestID, position), m_pageID);
858 }
859
860 void WebPageProxy::handleTap(const FloatPoint& location, OptionSet<WebEvent::Modifier> modifiers, uint64_t layerTreeTransactionIdAtLastTouchStart)
861 {
862     process().send(Messages::WebPage::HandleTap(roundedIntPoint(location), modifiers, layerTreeTransactionIdAtLastTouchStart), m_pageID);
863 }
864
865 void WebPageProxy::didRecognizeLongPress()
866 {
867     process().send(Messages::WebPage::DidRecognizeLongPress(), m_pageID);
868 }
869
870 void WebPageProxy::inspectorNodeSearchMovedToPosition(const WebCore::FloatPoint& position)
871 {
872     process().send(Messages::WebPage::InspectorNodeSearchMovedToPosition(position), m_pageID);
873 }
874
875 void WebPageProxy::inspectorNodeSearchEndedAtPosition(const WebCore::FloatPoint& position)
876 {
877     process().send(Messages::WebPage::InspectorNodeSearchEndedAtPosition(position), m_pageID);
878 }
879
880 void WebPageProxy::blurFocusedElement()
881 {
882     process().send(Messages::WebPage::BlurFocusedElement(), m_pageID);
883 }
884
885 FloatSize WebPageProxy::screenSize()
886 {
887     return WebCore::screenSize();
888 }
889
890 FloatSize WebPageProxy::availableScreenSize()
891 {
892     return WebCore::availableScreenSize();
893 }
894
895 FloatSize WebPageProxy::overrideScreenSize()
896 {
897     return WebCore::overrideScreenSize();
898 }
899
900 float WebPageProxy::textAutosizingWidth()
901 {
902     return WebCore::screenSize().width();
903 }
904
905 void WebPageProxy::couldNotRestorePageState()
906 {
907     pageClient().couldNotRestorePageState();
908 }
909
910 void WebPageProxy::restorePageState(Optional<WebCore::FloatPoint> scrollPosition, const WebCore::FloatPoint& scrollOrigin, const WebCore::FloatBoxExtent& obscuredInsetsOnSave, double scale)
911 {
912     pageClient().restorePageState(scrollPosition, scrollOrigin, obscuredInsetsOnSave, scale);
913 }
914
915 void WebPageProxy::restorePageCenterAndScale(Optional<WebCore::FloatPoint> center, double scale)
916 {
917     pageClient().restorePageCenterAndScale(center, scale);
918 }
919
920 void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color& color, const Vector<WebCore::FloatQuad>& highlightedQuads, const WebCore::IntSize& topLeftRadius, const WebCore::IntSize& topRightRadius, const WebCore::IntSize& bottomLeftRadius, const WebCore::IntSize& bottomRightRadius, bool nodeHasBuiltInClickHandling)
921 {
922     pageClient().didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius, nodeHasBuiltInClickHandling);
923 }
924
925 void WebPageProxy::setIsShowingInputViewForFocusedElement(bool showingInputView)
926 {
927     process().send(Messages::WebPage::SetIsShowingInputViewForFocusedElement(showingInputView), m_pageID);
928 }
929
930 void WebPageProxy::elementDidFocus(const FocusedElementInformation& information, bool userIsInteracting, bool blurPreviousNode, OptionSet<WebCore::ActivityState::Flag> activityStateChanges, const UserData& userData)
931 {
932     m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement = true;
933
934     API::Object* userDataObject = process().transformHandlesToObjects(userData.object()).get();
935     if (m_editorState.isMissingPostLayoutData) {
936         // FIXME: We should try to eliminate m_deferredElementDidFocusArguments altogether, in favor of only deferring actions that are dependent on post-layout editor state information.
937         m_deferredElementDidFocusArguments = std::make_unique<ElementDidFocusArguments>(ElementDidFocusArguments { information, userIsInteracting, blurPreviousNode, activityStateChanges, userDataObject });
938         return;
939     }
940
941     pageClient().elementDidFocus(information, userIsInteracting, blurPreviousNode, activityStateChanges, userDataObject);
942 }
943
944 void WebPageProxy::elementDidBlur()
945 {
946     m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement = false;
947     m_deferredElementDidFocusArguments = nullptr;
948     pageClient().elementDidBlur();
949 }
950
951 void WebPageProxy::focusedElementDidChangeInputMode(WebCore::InputMode mode)
952 {
953     pageClient().focusedElementDidChangeInputMode(mode);
954 }
955
956 void WebPageProxy::autofillLoginCredentials(const String& username, const String& password)
957 {
958     m_process->send(Messages::WebPage::AutofillLoginCredentials(username, password), m_pageID);
959 }
960
961 void WebPageProxy::showInspectorHighlight(const WebCore::Highlight& highlight)
962 {
963     pageClient().showInspectorHighlight(highlight);
964 }
965
966 void WebPageProxy::hideInspectorHighlight()
967 {
968     pageClient().hideInspectorHighlight();
969 }
970
971 void WebPageProxy::showInspectorIndication()
972 {
973     pageClient().showInspectorIndication();
974 }
975
976 void WebPageProxy::hideInspectorIndication()
977 {
978     pageClient().hideInspectorIndication();
979 }
980
981 void WebPageProxy::enableInspectorNodeSearch()
982 {
983     pageClient().enableInspectorNodeSearch();
984 }
985
986 void WebPageProxy::disableInspectorNodeSearch()
987 {
988     pageClient().disableInspectorNodeSearch();
989 }
990
991 void WebPageProxy::focusNextFocusedElement(bool isForward, WTF::Function<void(CallbackBase::Error)>&& callbackFunction)
992 {
993     if (!hasRunningProcess()) {
994         callbackFunction(CallbackBase::Error::Unknown);
995         return;
996     }
997     
998     auto callbackID = m_callbacks.put(WTFMove(callbackFunction), m_process->throttler().backgroundActivityToken());
999     process().send(Messages::WebPage::FocusNextFocusedElement(isForward, callbackID), m_pageID);
1000 }
1001
1002 void WebPageProxy::setFocusedElementValue(const String& value)
1003 {
1004     process().send(Messages::WebPage::SetFocusedElementValue(value), m_pageID);
1005 }
1006
1007 void WebPageProxy::setFocusedElementValueAsNumber(double value)
1008 {
1009     process().send(Messages::WebPage::SetFocusedElementValueAsNumber(value), m_pageID);
1010 }
1011
1012 void WebPageProxy::setFocusedElementSelectedIndex(uint32_t index, bool allowMultipleSelection)
1013 {
1014     process().send(Messages::WebPage::SetFocusedElementSelectedIndex(index, allowMultipleSelection), m_pageID);
1015 }
1016
1017 void WebPageProxy::didPerformDictionaryLookup(const DictionaryPopupInfo& dictionaryPopupInfo)
1018 {
1019     pageClient().didPerformDictionaryLookup(dictionaryPopupInfo);
1020 }
1021
1022 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplication(const String&, const String&, const IPC::DataReference&, const String&)
1023 {
1024     notImplemented();
1025 }
1026
1027 void WebPageProxy::savePDFToTemporaryFolderAndOpenWithNativeApplicationRaw(const String&, const String&, const uint8_t*, unsigned long, const String&)
1028 {
1029     notImplemented();
1030 }
1031
1032 void WebPageProxy::openPDFFromTemporaryFolderWithNativeApplication(const String&)
1033 {
1034     notImplemented();
1035 }
1036
1037 void WebPageProxy::setRemoteLayerTreeRootNode(RemoteLayerTreeNode* rootNode)
1038 {
1039     pageClient().setRemoteLayerTreeRootNode(rootNode);
1040     m_frozenRemoteLayerTreeHost = nullptr;
1041 }
1042
1043 void WebPageProxy::showPlaybackTargetPicker(bool hasVideo, const IntRect& elementRect, WebCore::RouteSharingPolicy policy, const String& contextUID)
1044 {
1045     pageClient().showPlaybackTargetPicker(hasVideo, elementRect, policy, contextUID);
1046 }
1047
1048 void WebPageProxy::commitPotentialTapFailed()
1049 {
1050     pageClient().commitPotentialTapFailed();
1051 }
1052
1053 void WebPageProxy::didNotHandleTapAsClick(const WebCore::IntPoint& point)
1054 {
1055     pageClient().didNotHandleTapAsClick(point);
1056     m_uiClient->didNotHandleTapAsClick(point);
1057 }
1058     
1059 void WebPageProxy::didCompleteSyntheticClick()
1060 {
1061     pageClient().didCompleteSyntheticClick();
1062 }
1063
1064 void WebPageProxy::disableDoubleTapGesturesDuringTapIfNecessary(uint64_t requestID)
1065 {
1066     pageClient().disableDoubleTapGesturesDuringTapIfNecessary(requestID);
1067 }
1068
1069 void WebPageProxy::handleSmartMagnificationInformationForPotentialTap(uint64_t requestID, const WebCore::FloatRect& renderRect, bool fitEntireRect, double viewportMinimumScale, double viewportMaximumScale)
1070 {
1071     pageClient().handleSmartMagnificationInformationForPotentialTap(requestID, renderRect, fitEntireRect, viewportMinimumScale, viewportMaximumScale);
1072 }
1073
1074 uint32_t WebPageProxy::computePagesForPrintingAndDrawToPDF(uint64_t frameID, const PrintInfo& printInfo, DrawToPDFCallback::CallbackFunction&& callback)
1075 {
1076     if (!hasRunningProcess()) {
1077         callback(IPC::DataReference(), CallbackBase::Error::OwnerWasInvalidated);
1078         return 0;
1079     }
1080
1081     uint32_t pageCount = 0;
1082     auto callbackID = m_callbacks.put(WTFMove(callback), m_process->throttler().backgroundActivityToken());
1083     using Message = Messages::WebPage::ComputePagesForPrintingAndDrawToPDF;
1084     process().sendSync(Message(frameID, printInfo, callbackID), Message::Reply(pageCount), m_pageID, Seconds::infinity());
1085     return pageCount;
1086 }
1087
1088 void WebPageProxy::drawToPDFCallback(const IPC::DataReference& pdfData, CallbackID callbackID)
1089 {
1090     auto callback = m_callbacks.take<DrawToPDFCallback>(callbackID);
1091     RELEASE_ASSERT(callback);
1092     callback->performCallbackWithReturnValue(pdfData);
1093 }
1094
1095 void WebPageProxy::contentSizeCategoryDidChange(const String& contentSizeCategory)
1096 {
1097     process().send(Messages::WebPage::ContentSizeCategoryDidChange(contentSizeCategory), m_pageID);
1098 }
1099
1100 void WebPageProxy::editorStateChanged(const EditorState& editorState)
1101 {
1102     bool couldChangeSecureInputState = m_editorState.isInPasswordField != editorState.isInPasswordField || m_editorState.selectionIsNone;
1103     
1104     m_editorState = editorState;
1105     
1106     // Selection being none is a temporary state when editing. Flipping secure input state too quickly was causing trouble (not fully understood).
1107     if (couldChangeSecureInputState && !editorState.selectionIsNone)
1108         pageClient().updateSecureInputState();
1109     
1110     if (editorState.shouldIgnoreSelectionChanges)
1111         return;
1112     
1113     // We always need to notify the client on iOS to make sure the selection is redrawn,
1114     // even during composition to support phrase boundary gesture.
1115     pageClient().selectionDidChange();
1116     updateFontAttributesAfterEditorStateChange();
1117
1118     if (m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement && !m_editorState.isMissingPostLayoutData) {
1119         pageClient().didReceiveEditorStateUpdateAfterFocus();
1120         m_waitingForPostLayoutEditorStateUpdateAfterFocusingElement = false;
1121     }
1122 }
1123
1124 void WebPageProxy::showValidationMessage(const IntRect& anchorClientRect, const String& message)
1125 {
1126     m_validationBubble = pageClient().createValidationBubble(message, { m_preferences->minimumFontSize() });
1127     m_validationBubble->setAnchorRect(anchorClientRect, uiClient().presentingViewController());
1128
1129     // If we are currently doing a scrolling / zoom animation, then we'll delay showing the validation
1130     // bubble until the animation is over.
1131     if (!m_isScrollingOrZooming)
1132         m_validationBubble->show();
1133 }
1134
1135 void WebPageProxy::setIsScrollingOrZooming(bool isScrollingOrZooming)
1136 {
1137     m_isScrollingOrZooming = isScrollingOrZooming;
1138
1139     // We finished doing the scrolling / zoom animation so we can now show the validation
1140     // bubble if we're supposed to.
1141     if (!m_isScrollingOrZooming && m_validationBubble)
1142         m_validationBubble->show();
1143 }
1144
1145 void WebPageProxy::hardwareKeyboardAvailabilityChanged(bool keyboardIsAttached)
1146 {
1147     updateCurrentModifierState();
1148     m_process->send(Messages::WebPage::HardwareKeyboardAvailabilityChanged(keyboardIsAttached), m_pageID);
1149 }
1150
1151 void WebPageProxy::requestEvasionRectsAboveSelection(CompletionHandler<void(const Vector<WebCore::FloatRect>&)>&& callback)
1152 {
1153     if (!hasRunningProcess()) {
1154         callback({ });
1155         return;
1156     }
1157
1158     m_process->connection()->sendWithAsyncReply(Messages::WebPage::RequestEvasionRectsAboveSelection(), WTFMove(callback), m_pageID);
1159 }
1160
1161 void WebPageProxy::updateSelectionWithDelta(int64_t locationDelta, int64_t lengthDelta, CompletionHandler<void()>&& completionHandler)
1162 {
1163     if (!hasRunningProcess()) {
1164         completionHandler();
1165         return;
1166     }
1167
1168     m_process->connection()->sendWithAsyncReply(Messages::WebPage::UpdateSelectionWithDelta(locationDelta, lengthDelta), WTFMove(completionHandler), m_pageID);
1169 }
1170
1171 void WebPageProxy::requestDocumentEditingContext(WebKit::DocumentEditingContextRequest request, CompletionHandler<void(WebKit::DocumentEditingContext)>&& completionHandler)
1172 {
1173     if (!hasRunningProcess()) {
1174         completionHandler({ });
1175         return;
1176     }
1177
1178     m_process->connection()->sendWithAsyncReply(Messages::WebPage::RequestDocumentEditingContext(request), WTFMove(completionHandler), m_pageID);
1179 }
1180
1181 #if ENABLE(DATA_INTERACTION)
1182
1183 void WebPageProxy::didHandleDragStartRequest(bool started)
1184 {
1185     pageClient().didHandleDragStartRequest(started);
1186 }
1187
1188 void WebPageProxy::didHandleAdditionalDragItemsRequest(bool added)
1189 {
1190     pageClient().didHandleAdditionalDragItemsRequest(added);
1191 }
1192
1193 void WebPageProxy::requestDragStart(const WebCore::IntPoint& clientPosition, const WebCore::IntPoint& globalPosition, WebCore::DragSourceAction allowedActions)
1194 {
1195     if (hasRunningProcess())
1196         m_process->send(Messages::WebPage::RequestDragStart(clientPosition, globalPosition, allowedActions), m_pageID);
1197 }
1198
1199 void WebPageProxy::requestAdditionalItemsForDragSession(const IntPoint& clientPosition, const IntPoint& globalPosition, WebCore::DragSourceAction allowedActions)
1200 {
1201     if (hasRunningProcess())
1202         m_process->send(Messages::WebPage::RequestAdditionalItemsForDragSession(clientPosition, globalPosition, allowedActions), m_pageID);
1203 }
1204
1205 void WebPageProxy::didConcludeEditDrag(Optional<TextIndicatorData> data)
1206 {
1207     pageClient().didConcludeEditDrag(data);
1208 }
1209
1210 #endif
1211
1212 #if USE(QUICK_LOOK)
1213     
1214 void WebPageProxy::didStartLoadForQuickLookDocumentInMainFrame(const String& fileName, const String& uti)
1215 {
1216     // Ensure that fileName isn't really a path name
1217     static_assert(notFound + 1 == 0, "The following line assumes WTF::notFound equals -1");
1218     m_navigationClient->didStartLoadForQuickLookDocumentInMainFrame(fileName.substring(fileName.reverseFind('/') + 1), uti);
1219 }
1220
1221 void WebPageProxy::didFinishLoadForQuickLookDocumentInMainFrame(const QuickLookDocumentData& data)
1222 {
1223     m_navigationClient->didFinishLoadForQuickLookDocumentInMainFrame(data);
1224 }
1225
1226 void WebPageProxy::didRequestPasswordForQuickLookDocumentInMainFrame(const String& fileName)
1227 {
1228     didRequestPasswordForQuickLookDocumentInMainFrameShared(m_process.copyRef(), fileName);
1229 }
1230
1231 void WebPageProxy::didRequestPasswordForQuickLookDocumentInMainFrameShared(Ref<WebProcessProxy>&& process, const String& fileName)
1232 {
1233     pageClient().requestPasswordForQuickLookDocument(fileName, [process = WTFMove(process), pageID = m_pageID](const String& password) {
1234         process->send(Messages::WebPage::DidReceivePasswordForQuickLookDocument(password), pageID);
1235     });
1236 }
1237
1238 #endif
1239
1240 #if ENABLE(APPLE_PAY)
1241
1242 std::unique_ptr<PaymentAuthorizationPresenter> WebPageProxy::paymentCoordinatorAuthorizationPresenter(WebPaymentCoordinatorProxy& paymentCoordinatorProxy, PKPaymentRequest *paymentRequest)
1243 {
1244     return std::make_unique<PaymentAuthorizationViewController>(paymentCoordinatorProxy, paymentRequest);
1245 }
1246
1247 UIViewController *WebPageProxy::paymentCoordinatorPresentingViewController(const WebPaymentCoordinatorProxy&)
1248 {
1249     return uiClient().presentingViewController();
1250 }
1251
1252 const String& WebPageProxy::paymentCoordinatorCTDataConnectionServiceType(const WebPaymentCoordinatorProxy&, PAL::SessionID sessionID)
1253 {
1254     ASSERT_UNUSED(sessionID, sessionID == websiteDataStore().sessionID());
1255     return process().processPool().configuration().ctDataConnectionServiceType();
1256 }
1257
1258 #endif
1259
1260 #if USE(APPLE_INTERNAL_SDK)
1261 #import <WebKitAdditions/WebPageProxyIOSAdditions.mm>
1262 #endif
1263
1264 } // namespace WebKit
1265
1266 #endif // PLATFORM(IOS_FAMILY)