Add default prompt implementation for the Storage Access API
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / UIDelegate.mm
1 /*
2  * Copyright (C) 2014-2018 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 "UIDelegate.h"
28
29 #import "APIFrameInfo.h"
30 #import "APIHitTestResult.h"
31 #import "CompletionHandlerCallChecker.h"
32 #import "MediaCaptureUtilities.h"
33 #import "NativeWebWheelEvent.h"
34 #import "NavigationActionData.h"
35 #import "UserMediaPermissionCheckProxy.h"
36 #import "UserMediaPermissionRequestProxy.h"
37 #import "WKFrameInfoInternal.h"
38 #import "WKNSData.h"
39 #import "WKNSDictionary.h"
40 #import "WKNavigationActionInternal.h"
41 #import "WKOpenPanelParametersInternal.h"
42 #import "WKSecurityOriginInternal.h"
43 #import "WKStorageAccessAlert.h"
44 #import "WKUIDelegatePrivate.h"
45 #import "WKWebViewConfigurationInternal.h"
46 #import "WKWebViewInternal.h"
47 #import "WKWindowFeaturesInternal.h"
48 #import "WebEventFactory.h"
49 #import "WebOpenPanelResultListenerProxy.h"
50 #import "WebProcessProxy.h"
51 #import "_WKContextMenuElementInfo.h"
52 #import "_WKFrameHandleInternal.h"
53 #import "_WKHitTestResultInternal.h"
54 #import <WebCore/FontAttributes.h>
55 #import <WebCore/SecurityOriginData.h>
56 #import <wtf/BlockPtr.h>
57 #import <wtf/URL.h>
58
59 #if HAVE(AUTHORIZATION_STATUS_FOR_MEDIA_TYPE)
60 #import <AVFoundation/AVCaptureDevice.h>
61 #import <AVFoundation/AVMediaFormat.h>
62 #import <wtf/SoftLinking.h>
63
64 SOFT_LINK_FRAMEWORK(AVFoundation);
65 SOFT_LINK_CLASS(AVFoundation, AVCaptureDevice);
66 SOFT_LINK_CONSTANT(AVFoundation, AVMediaTypeAudio, NSString *);
67 SOFT_LINK_CONSTANT(AVFoundation, AVMediaTypeVideo, NSString *);
68 #endif
69
70 namespace WebKit {
71
72 UIDelegate::UIDelegate(WKWebView *webView)
73     : m_webView(webView)
74 {
75 }
76
77 UIDelegate::~UIDelegate()
78 {
79 }
80
81 #if ENABLE(CONTEXT_MENUS)
82 std::unique_ptr<API::ContextMenuClient> UIDelegate::createContextMenuClient()
83 {
84     return std::make_unique<ContextMenuClient>(*this);
85 }
86 #endif
87
88 std::unique_ptr<API::UIClient> UIDelegate::createUIClient()
89 {
90     return std::make_unique<UIClient>(*this);
91 }
92
93 RetainPtr<id <WKUIDelegate> > UIDelegate::delegate()
94 {
95     return m_delegate.get();
96 }
97
98 void UIDelegate::setDelegate(id <WKUIDelegate> delegate)
99 {
100     m_delegate = delegate;
101
102     m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeatures = [delegate respondsToSelector:@selector(webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:)];
103     m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync = [delegate respondsToSelector:@selector(_webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:completionHandler:)];
104     m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
105     m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
106     m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
107     m_delegateMethods.webViewRequestStorageAccessPanelForTopPrivatelyControlledDomainUnderFirstPartyTopPrivatelyControlledDomainCompletionHandler = [delegate respondsToSelector:@selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:)];
108     m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
109     m_delegateMethods.webViewRequestGeolocationPermissionForFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestGeolocationPermissionForFrame:decisionHandler:)];
110     m_delegateMethods.webViewDidResignInputElementStrongPasswordAppearanceWithUserInfo = [delegate respondsToSelector:@selector(_webView:didResignInputElementStrongPasswordAppearanceWithUserInfo:)];
111     m_delegateMethods.webViewTakeFocus = [delegate respondsToSelector:@selector(_webView:takeFocus:)];
112
113 #if PLATFORM(MAC)
114     m_delegateMethods.showWebView = [delegate respondsToSelector:@selector(_showWebView:)];
115     m_delegateMethods.focusWebView = [delegate respondsToSelector:@selector(_focusWebView:)];
116     m_delegateMethods.unfocusWebView = [delegate respondsToSelector:@selector(_unfocusWebView:)];
117     m_delegateMethods.webViewRunModal = [delegate respondsToSelector:@selector(_webViewRunModal:)];
118     m_delegateMethods.webViewDidScroll = [delegate respondsToSelector:@selector(_webViewDidScroll:)];
119     m_delegateMethods.webViewGetToolbarsAreVisibleWithCompletionHandler = [delegate respondsToSelector:@selector(_webView:getToolbarsAreVisibleWithCompletionHandler:)];
120     m_delegateMethods.webViewDidNotHandleWheelEvent = [delegate respondsToSelector:@selector(_webView:didNotHandleWheelEvent:)];
121     m_delegateMethods.webViewSetResizable = [delegate respondsToSelector:@selector(_webView:setResizable:)];
122     m_delegateMethods.webViewGetWindowFrameWithCompletionHandler = [delegate respondsToSelector:@selector(_webView:getWindowFrameWithCompletionHandler:)];
123     m_delegateMethods.webViewSetWindowFrame = [delegate respondsToSelector:@selector(_webView:setWindowFrame:)];
124     m_delegateMethods.webViewUnavailablePlugInButtonClicked = [delegate respondsToSelector:@selector(_webView:unavailablePlugInButtonClickedWithReason:plugInInfo:)];
125     m_delegateMethods.webViewHandleAutoplayEventWithFlags = [delegate respondsToSelector:@selector(_webView:handleAutoplayEvent:withFlags:)];
126     m_delegateMethods.webViewDidClickAutoFillButtonWithUserInfo = [delegate respondsToSelector:@selector(_webView:didClickAutoFillButtonWithUserInfo:)];
127     m_delegateMethods.webViewDrawHeaderInRectForPageWithTitleURL = [delegate respondsToSelector:@selector(_webView:drawHeaderInRect:forPageWithTitle:URL:)];
128     m_delegateMethods.webViewDrawFooterInRectForPageWithTitleURL = [delegate respondsToSelector:@selector(_webView:drawFooterInRect:forPageWithTitle:URL:)];
129     m_delegateMethods.webViewHeaderHeight = [delegate respondsToSelector:@selector(_webViewHeaderHeight:)];
130     m_delegateMethods.webViewFooterHeight = [delegate respondsToSelector:@selector(_webViewFooterHeight:)];
131     m_delegateMethods.webViewMouseDidMoveOverElementWithFlagsUserInfo = [delegate respondsToSelector:@selector(_webView:mouseDidMoveOverElement:withFlags:userInfo:)];
132     m_delegateMethods.webViewDidExceedBackgroundResourceLimitWhileInForeground = [delegate respondsToSelector:@selector(_webView:didExceedBackgroundResourceLimitWhileInForeground:)];
133     m_delegateMethods.webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL = [delegate respondsToSelector:@selector(_webView:saveDataToFile:suggestedFilename:mimeType:originatingURL:)];
134     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
135     m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:)];
136 #endif
137 #if ENABLE(DEVICE_ORIENTATION)
138     m_delegateMethods.webViewShouldAllowDeviceOrientationAndMotionAccessRequestedByFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:shouldAllowDeviceOrientationAndMotionAccessRequestedByFrame:decisionHandler:)];
139 #endif
140     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
141     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:databaseName:displayName:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
142     m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded = [delegate respondsToSelector:@selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:)];
143     m_delegateMethods.webViewPrintFrame = [delegate respondsToSelector:@selector(_webView:printFrame:)];
144     m_delegateMethods.webViewDidClose = [delegate respondsToSelector:@selector(webViewDidClose:)];
145     m_delegateMethods.webViewClose = [delegate respondsToSelector:@selector(_webViewClose:)];
146     m_delegateMethods.webViewFullscreenMayReturnToInline = [delegate respondsToSelector:@selector(_webViewFullscreenMayReturnToInline:)];
147     m_delegateMethods.webViewDidEnterFullscreen = [delegate respondsToSelector:@selector(_webViewDidEnterFullscreen:)];
148     m_delegateMethods.webViewDidExitFullscreen = [delegate respondsToSelector:@selector(_webViewDidExitFullscreen:)];
149 #if PLATFORM(IOS_FAMILY)
150 #if HAVE(APP_LINKS)
151     m_delegateMethods.webViewShouldIncludeAppLinkActionsForElement = [delegate respondsToSelector:@selector(_webView:shouldIncludeAppLinkActionsForElement:)];
152 #endif
153     m_delegateMethods.webViewActionsForElementDefaultActions = [delegate respondsToSelector:@selector(_webView:actionsForElement:defaultActions:)];
154     m_delegateMethods.webViewDidNotHandleTapAsClickAtPoint = [delegate respondsToSelector:@selector(_webView:didNotHandleTapAsClickAtPoint:)];
155     m_delegateMethods.presentingViewControllerForWebView = [delegate respondsToSelector:@selector(_presentingViewControllerForWebView:)];
156 #endif
157     m_delegateMethods.webViewRequestMediaCaptureAuthorizationForFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:)] || [delegate respondsToSelector:@selector(_webView:requestMediaCaptureAuthorization:decisionHandler:)];
158     m_delegateMethods.webViewIsMediaCaptureAuthorizedForFrameDecisionHandler = [delegate respondsToSelector:@selector(_webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:)] || [delegate respondsToSelector:@selector(_webView:includeSensitiveMediaDeviceDetails:)];
159
160     m_delegateMethods.webViewMediaCaptureStateDidChange = [delegate respondsToSelector:@selector(_webView:mediaCaptureStateDidChange:)];
161     m_delegateMethods.webViewDidChangeFontAttributes = [delegate respondsToSelector:@selector(_webView:didChangeFontAttributes:)];
162     m_delegateMethods.dataDetectionContextForWebView = [delegate respondsToSelector:@selector(_dataDetectionContextForWebView:)];
163     m_delegateMethods.webViewImageOrMediaDocumentSizeChanged = [delegate respondsToSelector:@selector(_webView:imageOrMediaDocumentSizeChanged:)];
164
165 #if ENABLE(POINTER_LOCK)
166     m_delegateMethods.webViewRequestPointerLock = [delegate respondsToSelector:@selector(_webViewRequestPointerLock:)];
167     m_delegateMethods.webViewDidRequestPointerLockCompletionHandler = [delegate respondsToSelector:@selector(_webViewDidRequestPointerLock:completionHandler:)];
168     m_delegateMethods.webViewDidLosePointerLock = [delegate respondsToSelector:@selector(_webViewDidLosePointerLock:)];
169 #endif
170 #if ENABLE(CONTEXT_MENUS)
171     m_delegateMethods.webViewContextMenuForElement = [delegate respondsToSelector:@selector(_webView:contextMenu:forElement:)];
172     m_delegateMethods.webViewContextMenuForElementUserInfo = [delegate respondsToSelector:@selector(_webView:contextMenu:forElement:userInfo:)];
173     m_delegateMethods.webViewGetContextMenuFromProposedMenuForElementUserInfoCompletionHandler = [delegate respondsToSelector:@selector(_webView:getContextMenuFromProposedMenu:forElement:userInfo:completionHandler:)];
174 #endif
175     
176     m_delegateMethods.webViewHasVideoInPictureInPictureDidChange = [delegate respondsToSelector:@selector(_webView:hasVideoInPictureInPictureDidChange:)];
177     m_delegateMethods.webViewDidShowSafeBrowsingWarning = [delegate respondsToSelector:@selector(_webViewDidShowSafeBrowsingWarning:)];
178 }
179
180 #if ENABLE(CONTEXT_MENUS)
181 UIDelegate::ContextMenuClient::ContextMenuClient(UIDelegate& uiDelegate)
182     : m_uiDelegate(uiDelegate)
183 {
184 }
185
186 UIDelegate::ContextMenuClient::~ContextMenuClient()
187 {
188 }
189
190 void UIDelegate::ContextMenuClient::menuFromProposedMenu(WebPageProxy&, NSMenu *menu, const WebHitTestResultData&, API::Object* userInfo, CompletionHandler<void(RetainPtr<NSMenu>&&)>&& completionHandler)
191 {
192     if (!m_uiDelegate.m_delegateMethods.webViewContextMenuForElement
193         && !m_uiDelegate.m_delegateMethods.webViewContextMenuForElementUserInfo
194         && !m_uiDelegate.m_delegateMethods.webViewGetContextMenuFromProposedMenuForElementUserInfoCompletionHandler)
195         return completionHandler(menu);
196
197     auto delegate = m_uiDelegate.m_delegate.get();
198     if (!delegate)
199         return completionHandler(menu);
200
201     auto contextMenuElementInfo = adoptNS([[_WKContextMenuElementInfo alloc] init]);
202
203     if (m_uiDelegate.m_delegateMethods.webViewGetContextMenuFromProposedMenuForElementUserInfoCompletionHandler) {
204         auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:getContextMenuFromProposedMenu:forElement:userInfo:completionHandler:));
205         [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView getContextMenuFromProposedMenu:menu forElement:contextMenuElementInfo.get() userInfo:userInfo ? static_cast<id <NSSecureCoding>>(userInfo->wrapper()) : nil completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (NSMenu *menu) mutable {
206             if (checker->completionHandlerHasBeenCalled())
207                 return;
208             checker->didCallCompletionHandler();
209             completionHandler(menu);
210         }).get()];
211         return;
212     }
213     
214     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
215     if (m_uiDelegate.m_delegateMethods.webViewContextMenuForElement)
216         return completionHandler([(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView contextMenu:menu forElement:contextMenuElementInfo.get()]);
217
218     completionHandler([(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView contextMenu:menu forElement:contextMenuElementInfo.get() userInfo:userInfo ? static_cast<id <NSSecureCoding>>(userInfo->wrapper()) : nil]);
219     ALLOW_DEPRECATED_DECLARATIONS_END
220 }
221 #endif
222
223 UIDelegate::UIClient::UIClient(UIDelegate& uiDelegate)
224     : m_uiDelegate(uiDelegate)
225 {
226 }
227
228 UIDelegate::UIClient::~UIClient()
229 {
230 }
231
232 void UIDelegate::UIClient::createNewPage(WebKit::WebPageProxy&, WebCore::WindowFeatures&& windowFeatures, Ref<API::NavigationAction>&& navigationAction, CompletionHandler<void(RefPtr<WebPageProxy>&&)>&& completionHandler)
233 {
234     auto delegate = m_uiDelegate.m_delegate.get();
235     ASSERT(delegate);
236
237     auto configuration = adoptNS([m_uiDelegate.m_webView->_configuration copy]);
238     [configuration _setRelatedWebView:m_uiDelegate.m_webView];
239
240     auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
241
242     if (m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync) {
243         auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:completionHandler:));
244
245         [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView createWebViewWithConfiguration:configuration.get() forNavigationAction:wrapper(navigationAction) windowFeatures:wrapper(apiWindowFeatures) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker), relatedWebView = RetainPtr<WKWebView>(m_uiDelegate.m_webView)] (WKWebView *webView) mutable {
246             if (checker->completionHandlerHasBeenCalled())
247                 return;
248             checker->didCallCompletionHandler();
249
250             if (!webView) {
251                 completionHandler(nullptr);
252                 return;
253             }
254
255             if ([webView->_configuration _relatedWebView] != relatedWebView.get())
256                 [NSException raise:NSInternalInconsistencyException format:@"Returned WKWebView was not created with the given configuration."];
257
258             completionHandler(webView->_page.get());
259         }).get()];
260         return;
261     }
262     if (!m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeatures)
263         return completionHandler(nullptr);
264
265     RetainPtr<WKWebView> webView = [delegate webView:m_uiDelegate.m_webView createWebViewWithConfiguration:configuration.get() forNavigationAction:wrapper(navigationAction) windowFeatures:wrapper(apiWindowFeatures)];
266     if (!webView)
267         return completionHandler(nullptr);
268
269     if ([webView->_configuration _relatedWebView] != m_uiDelegate.m_webView)
270         [NSException raise:NSInternalInconsistencyException format:@"Returned WKWebView was not created with the given configuration."];
271     completionHandler(webView->_page.get());
272 }
273
274 void UIDelegate::UIClient::runJavaScriptAlert(WebPageProxy*, const WTF::String& message, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void()>&& completionHandler)
275 {
276     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler) {
277         completionHandler();
278         return;
279     }
280
281     auto delegate = m_uiDelegate.m_delegate.get();
282     if (!delegate) {
283         completionHandler();
284         return;
285     }
286
287     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:));
288     [delegate webView:m_uiDelegate.m_webView runJavaScriptAlertPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] {
289         if (checker->completionHandlerHasBeenCalled())
290             return;
291         completionHandler();
292         checker->didCallCompletionHandler();
293     }).get()];
294 }
295
296 void UIDelegate::UIClient::runJavaScriptConfirm(WebPageProxy*, const WTF::String& message, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void(bool)>&& completionHandler)
297 {
298     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler) {
299         completionHandler(false);
300         return;
301     }
302
303     auto delegate = m_uiDelegate.m_delegate.get();
304     if (!delegate) {
305         completionHandler(false);
306         return;
307     }
308
309     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:));
310     [delegate webView:m_uiDelegate.m_webView runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
311         if (checker->completionHandlerHasBeenCalled())
312             return;
313         completionHandler(result);
314         checker->didCallCompletionHandler();
315     }).get()];
316 }
317
318 void UIDelegate::UIClient::runJavaScriptPrompt(WebPageProxy*, const WTF::String& message, const WTF::String& defaultValue, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void(const WTF::String&)>&& completionHandler)
319 {
320     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler) {
321         completionHandler(String());
322         return;
323     }
324
325     auto delegate = m_uiDelegate.m_delegate.get();
326     if (!delegate) {
327         completionHandler(String());
328         return;
329     }
330
331     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:));
332     [delegate webView:m_uiDelegate.m_webView runJavaScriptTextInputPanelWithPrompt:message defaultText:defaultValue initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (NSString *result) mutable {
333         if (checker->completionHandlerHasBeenCalled())
334             return;
335         completionHandler(result);
336         checker->didCallCompletionHandler();
337     }).get()];
338 }
339
340 void UIDelegate::UIClient::requestStorageAccessConfirm(WebPageProxy&, WebFrameProxy*, const WTF::String& requestingDomain, const WTF::String& currentDomain, CompletionHandler<void(bool)>&& completionHandler)
341 {
342     auto delegate = m_uiDelegate.m_delegate.get();
343     if (!delegate) {
344         completionHandler(false);
345         return;
346     }
347     
348     if (!m_uiDelegate.m_delegateMethods.webViewRequestStorageAccessPanelForTopPrivatelyControlledDomainUnderFirstPartyTopPrivatelyControlledDomainCompletionHandler) {
349         presentStorageAccessAlert(m_uiDelegate.m_webView, requestingDomain, currentDomain, WTFMove(completionHandler));
350         return;
351     }
352
353     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:requestStorageAccessPanelForDomain:underCurrentDomain:completionHandler:));
354     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView requestStorageAccessPanelForDomain:requestingDomain underCurrentDomain:currentDomain completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
355         if (checker->completionHandlerHasBeenCalled())
356             return;
357         completionHandler(result);
358         checker->didCallCompletionHandler();
359     }).get()];
360 }
361
362 void UIDelegate::UIClient::decidePolicyForGeolocationPermissionRequest(WebKit::WebPageProxy&, WebKit::WebFrameProxy& frame, API::SecurityOrigin& securityOrigin, Function<void(bool)>& completionHandler)
363 {
364     if (!m_uiDelegate.m_delegateMethods.webViewRequestGeolocationPermissionForFrameDecisionHandler)
365         return;
366     
367     auto delegate = m_uiDelegate.m_delegate.get();
368     if (!delegate)
369         return;
370
371     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:requestGeolocationPermissionForFrame:decisionHandler:));
372     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView requestGeolocationPermissionForFrame:wrapper(API::FrameInfo::create(frame, securityOrigin.securityOrigin())) decisionHandler:makeBlockPtr([completionHandler = std::exchange(completionHandler, nullptr), checker = WTFMove(checker)] (BOOL result) mutable {
373         if (checker->completionHandlerHasBeenCalled())
374             return;
375         checker->didCallCompletionHandler();
376         completionHandler(result);
377     }).get()];
378 }
379
380 void UIDelegate::UIClient::didResignInputElementStrongPasswordAppearance(WebPageProxy&, API::Object* userInfo)
381 {
382     if (!m_uiDelegate.m_delegateMethods.webViewDidResignInputElementStrongPasswordAppearanceWithUserInfo)
383         return;
384
385     auto delegate = m_uiDelegate.m_delegate.get();
386     if (!delegate)
387         return;
388
389     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView didResignInputElementStrongPasswordAppearanceWithUserInfo:userInfo ? static_cast<id <NSSecureCoding>>(userInfo->wrapper()) : nil];
390 }
391
392 bool UIDelegate::UIClient::canRunBeforeUnloadConfirmPanel() const
393 {
394     return m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler;
395 }
396
397 void UIDelegate::UIClient::runBeforeUnloadConfirmPanel(WebPageProxy*, const WTF::String& message, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void(bool)>&& completionHandler)
398 {
399     if (!m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler) {
400         completionHandler(false);
401         return;
402     }
403
404     auto delegate = m_uiDelegate.m_delegate.get();
405     if (!delegate) {
406         completionHandler(false);
407         return;
408     }
409
410     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:));
411     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
412         if (checker->completionHandlerHasBeenCalled())
413             return;
414         completionHandler(result);
415         checker->didCallCompletionHandler();
416     }).get()];
417 }
418
419 void UIDelegate::UIClient::exceededDatabaseQuota(WebPageProxy*, WebFrameProxy*, API::SecurityOrigin* securityOrigin, const WTF::String& databaseName, const WTF::String& displayName, unsigned long long currentQuota, unsigned long long currentOriginUsage, unsigned long long currentUsage, unsigned long long expectedUsage, Function<void (unsigned long long)>&& completionHandler)
420 {
421     if (!m_uiDelegate.m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler && !m_uiDelegate.m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler) {
422
423         // Use 50 MB as the default database quota.
424         unsigned long long defaultPerOriginDatabaseQuota = 50 * 1024 * 1024;
425
426         completionHandler(defaultPerOriginDatabaseQuota);
427         return;
428     }
429
430     auto delegate = m_uiDelegate.m_delegate.get();
431     if (!delegate) {
432         completionHandler(currentQuota);
433         return;
434     }
435
436     ASSERT(securityOrigin);
437
438     if (m_uiDelegate.m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginDatabaseNameDisplayNameCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler) {
439         auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:decideDatabaseQuotaForSecurityOrigin:databaseName:displayName:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:));
440         [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView decideDatabaseQuotaForSecurityOrigin:wrapper(*securityOrigin) databaseName:databaseName displayName:displayName currentQuota:currentQuota currentOriginUsage:currentOriginUsage currentDatabaseUsage:currentUsage expectedUsage:expectedUsage decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long newQuota) {
441             if (checker->completionHandlerHasBeenCalled())
442                 return;
443             checker->didCallCompletionHandler();
444             completionHandler(newQuota);
445         }).get()];
446         return;
447     }
448
449     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:));
450     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView decideDatabaseQuotaForSecurityOrigin:wrapper(*securityOrigin) currentQuota:currentQuota currentOriginUsage:currentOriginUsage currentDatabaseUsage:currentUsage expectedUsage:expectedUsage decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long newQuota) {
451         if (checker->completionHandlerHasBeenCalled())
452             return;
453         checker->didCallCompletionHandler();
454         completionHandler(newQuota);
455     }).get()];
456 }
457
458 static inline _WKFocusDirection toWKFocusDirection(WKFocusDirection direction)
459 {
460     switch (direction) {
461     case kWKFocusDirectionBackward:
462         return _WKFocusDirectionBackward;
463     case kWKFocusDirectionForward:
464         return _WKFocusDirectionForward;
465     }
466     ASSERT_NOT_REACHED();
467     return _WKFocusDirectionForward;
468 }
469
470 bool UIDelegate::UIClient::takeFocus(WebPageProxy*, WKFocusDirection direction)
471 {
472     if (!m_uiDelegate.m_delegateMethods.webViewTakeFocus)
473         return false;
474     
475     auto delegate = m_uiDelegate.m_delegate.get();
476     if (!delegate)
477         return false;
478     
479     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView takeFocus:toWKFocusDirection(direction)];
480     return true;
481 }
482
483 #if PLATFORM(MAC)
484 bool UIDelegate::UIClient::canRunModal() const
485 {
486     return m_uiDelegate.m_delegateMethods.webViewRunModal;
487 }
488
489 void UIDelegate::UIClient::runModal(WebPageProxy&)
490 {
491     if (!m_uiDelegate.m_delegateMethods.webViewRunModal)
492         return;
493     
494     auto delegate = m_uiDelegate.m_delegate.get();
495     if (!delegate)
496         return;
497
498     [(id <WKUIDelegatePrivate>)delegate _webViewRunModal:m_uiDelegate.m_webView];
499 }
500
501 float UIDelegate::UIClient::headerHeight(WebPageProxy&, WebFrameProxy& webFrameProxy)
502 {
503     if (!m_uiDelegate.m_delegateMethods.webViewHeaderHeight)
504         return 0;
505     
506     auto delegate = m_uiDelegate.m_delegate.get();
507     if (!delegate)
508         return 0;
509     
510     return [(id <WKUIDelegatePrivate>)delegate _webViewHeaderHeight:m_uiDelegate.m_webView];
511 }
512
513 float UIDelegate::UIClient::footerHeight(WebPageProxy&, WebFrameProxy&)
514 {
515     if (!m_uiDelegate.m_delegateMethods.webViewFooterHeight)
516         return 0;
517     
518     auto delegate = m_uiDelegate.m_delegate.get();
519     if (!delegate)
520         return 0;
521     
522     return [(id <WKUIDelegatePrivate>)delegate _webViewFooterHeight:m_uiDelegate.m_webView];
523 }
524
525 void UIDelegate::UIClient::drawHeader(WebPageProxy&, WebFrameProxy& frame, WebCore::FloatRect&& rect)
526 {
527     if (!m_uiDelegate.m_delegateMethods.webViewDrawHeaderInRectForPageWithTitleURL)
528         return;
529     
530     auto delegate = m_uiDelegate.m_delegate.get();
531     if (!delegate)
532         return;
533     
534     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView drawHeaderInRect:rect forPageWithTitle:frame.title() URL:frame.url()];
535 }
536
537 void UIDelegate::UIClient::drawFooter(WebPageProxy&, WebFrameProxy& frame, WebCore::FloatRect&& rect)
538 {
539     if (!m_uiDelegate.m_delegateMethods.webViewDrawFooterInRectForPageWithTitleURL)
540         return;
541     
542     auto delegate = m_uiDelegate.m_delegate.get();
543     if (!delegate)
544         return;
545     
546     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView drawFooterInRect:rect forPageWithTitle:frame.title() URL:frame.url()];
547 }
548
549 void UIDelegate::UIClient::pageDidScroll(WebPageProxy*)
550 {
551     if (!m_uiDelegate.m_delegateMethods.webViewDidScroll)
552         return;
553     
554     auto delegate = m_uiDelegate.m_delegate.get();
555     if (!delegate)
556         return;
557     
558     [(id <WKUIDelegatePrivate>)delegate _webViewDidScroll:m_uiDelegate.m_webView];
559 }
560
561 void UIDelegate::UIClient::focus(WebPageProxy*)
562 {
563     if (!m_uiDelegate.m_delegateMethods.focusWebView)
564         return;
565     
566     auto delegate = m_uiDelegate.m_delegate.get();
567     if (!delegate)
568         return;
569     
570     [(id <WKUIDelegatePrivate>)delegate _focusWebView:m_uiDelegate.m_webView];
571 }
572
573 void UIDelegate::UIClient::unfocus(WebPageProxy*)
574 {
575     if (!m_uiDelegate.m_delegateMethods.unfocusWebView)
576         return;
577     
578     auto delegate = m_uiDelegate.m_delegate.get();
579     if (!delegate)
580         return;
581     
582     [(id <WKUIDelegatePrivate>)delegate _unfocusWebView:m_uiDelegate.m_webView];
583 }
584
585 static _WKPlugInUnavailabilityReason toWKPlugInUnavailabilityReason(WKPluginUnavailabilityReason reason)
586 {
587     switch (reason) {
588     case kWKPluginUnavailabilityReasonPluginMissing:
589         return _WKPlugInUnavailabilityReasonPluginMissing;
590     case kWKPluginUnavailabilityReasonPluginCrashed:
591         return _WKPlugInUnavailabilityReasonPluginCrashed;
592     case kWKPluginUnavailabilityReasonInsecurePluginVersion:
593         return _WKPlugInUnavailabilityReasonInsecurePluginVersion;
594     }
595     ASSERT_NOT_REACHED();
596     return _WKPlugInUnavailabilityReasonPluginMissing;
597 }
598     
599 void UIDelegate::UIClient::unavailablePluginButtonClicked(WebPageProxy&, WKPluginUnavailabilityReason reason, API::Dictionary& plugInInfo)
600 {
601     if (!m_uiDelegate.m_delegateMethods.webViewUnavailablePlugInButtonClicked)
602         return;
603     
604     auto delegate = m_uiDelegate.m_delegate.get();
605     if (!delegate)
606         return;
607
608     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView unavailablePlugInButtonClickedWithReason:toWKPlugInUnavailabilityReason(reason) plugInInfo:wrapper(plugInInfo)];
609 }
610     
611 static _WKResourceLimit toWKResourceLimit(WKResourceLimit limit)
612 {
613     switch (limit) {
614     case kWKResourceLimitMemory:
615         return _WKResourceLimitMemory;
616     case kWKResourceLimitCPU:
617         return _WKResourceLimitCPU;
618     }
619     ASSERT_NOT_REACHED();
620     return _WKResourceLimitMemory;
621 }
622
623 void UIDelegate::UIClient::didExceedBackgroundResourceLimitWhileInForeground(WebPageProxy&, WKResourceLimit limit)
624 {
625     if (!m_uiDelegate.m_delegateMethods.webViewDidExceedBackgroundResourceLimitWhileInForeground)
626         return;
627     
628     auto delegate = m_uiDelegate.m_delegate.get();
629     if (!delegate)
630         return;
631     
632     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView didExceedBackgroundResourceLimitWhileInForeground:toWKResourceLimit(limit)];
633 }
634
635 void UIDelegate::UIClient::didNotHandleWheelEvent(WebPageProxy*, const NativeWebWheelEvent& event)
636 {
637     if (!m_uiDelegate.m_delegateMethods.webViewDidNotHandleWheelEvent)
638         return;
639     
640     auto delegate = m_uiDelegate.m_delegate.get();
641     if (!delegate)
642         return;
643     
644     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView didNotHandleWheelEvent:event.nativeEvent()];
645 }
646
647 void UIDelegate::UIClient::setIsResizable(WebKit::WebPageProxy&, bool resizable)
648 {
649     if (!m_uiDelegate.m_delegateMethods.webViewSetResizable)
650         return;
651     
652     auto delegate = m_uiDelegate.m_delegate.get();
653     if (!delegate)
654         return;
655     
656     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView setResizable:resizable];
657 }
658
659 void UIDelegate::UIClient::setWindowFrame(WebKit::WebPageProxy&, const WebCore::FloatRect& frame)
660 {
661     if (!m_uiDelegate.m_delegateMethods.webViewSetWindowFrame)
662         return;
663     
664     auto delegate = m_uiDelegate.m_delegate.get();
665     if (!delegate)
666         return;
667     
668     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView setWindowFrame:frame];
669 }
670
671 void UIDelegate::UIClient::windowFrame(WebKit::WebPageProxy&, Function<void(WebCore::FloatRect)>&& completionHandler)
672 {
673     if (!m_uiDelegate.m_delegateMethods.webViewGetWindowFrameWithCompletionHandler)
674         return completionHandler({ });
675     
676     auto delegate = m_uiDelegate.m_delegate.get();
677     if (!delegate)
678         return completionHandler({ });
679     
680     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView getWindowFrameWithCompletionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:getWindowFrameWithCompletionHandler:))](CGRect frame) {
681         if (checker->completionHandlerHasBeenCalled())
682             return;
683         checker->didCallCompletionHandler();
684         completionHandler(frame);
685     }).get()];
686 }
687
688 void UIDelegate::UIClient::mouseDidMoveOverElement(WebPageProxy&, const WebHitTestResultData& data, OptionSet<WebEvent::Modifier> modifiers, API::Object* userInfo)
689 {
690     if (!m_uiDelegate.m_delegateMethods.webViewMouseDidMoveOverElementWithFlagsUserInfo)
691         return;
692
693     auto delegate = m_uiDelegate.m_delegate.get();
694     if (!delegate)
695         return;
696
697     auto apiHitTestResult = API::HitTestResult::create(data);
698     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView mouseDidMoveOverElement:wrapper(apiHitTestResult.get()) withFlags:WebEventFactory::toNSEventModifierFlags(modifiers) userInfo:userInfo ? static_cast<id <NSSecureCoding>>(userInfo->wrapper()) : nil];
699 }
700
701 static _WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
702 {
703     _WKAutoplayEventFlags wkFlags = _WKAutoplayEventFlagsNone;
704     if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
705         wkFlags |= _WKAutoplayEventFlagsHasAudio;
706     if (flags.contains(WebCore::AutoplayEventFlags::PlaybackWasPrevented))
707         wkFlags |= _WKAutoplayEventFlagsPlaybackWasPrevented;
708     if (flags.contains(WebCore::AutoplayEventFlags::MediaIsMainContent))
709         wkFlags |= _WKAutoplayEventFlagsMediaIsMainContent;
710     
711     return wkFlags;
712 }
713
714 static _WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
715 {
716     switch (event) {
717     case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
718         return _WKAutoplayEventDidPreventFromAutoplaying;
719     case WebCore::AutoplayEvent::DidPlayMediaWithUserGesture:
720         return _WKAutoplayEventDidPlayMediaWithUserGesture;
721     case WebCore::AutoplayEvent::DidAutoplayMediaPastThresholdWithoutUserInterference:
722         return _WKAutoplayEventDidAutoplayMediaPastThresholdWithoutUserInterference;
723     case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
724         return _WKAutoplayEventUserDidInterfereWithPlayback;
725     }
726     ASSERT_NOT_REACHED();
727     return _WKAutoplayEventDidPlayMediaWithUserGesture;
728 }
729
730 void UIDelegate::UIClient::toolbarsAreVisible(WebPageProxy&, Function<void(bool)>&& completionHandler)
731 {
732     if (!m_uiDelegate.m_delegateMethods.webViewGetToolbarsAreVisibleWithCompletionHandler)
733         return completionHandler(true);
734     
735     auto delegate = m_uiDelegate.m_delegate.get();
736     if (!delegate)
737         return completionHandler(true);
738     
739     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView getToolbarsAreVisibleWithCompletionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:getToolbarsAreVisibleWithCompletionHandler:))](BOOL visible) {
740         if (checker->completionHandlerHasBeenCalled())
741             return;
742         checker->didCallCompletionHandler();
743         completionHandler(visible);
744     }).get()];
745 }
746
747 void UIDelegate::UIClient::didClickAutoFillButton(WebPageProxy&, API::Object* userInfo)
748 {
749     if (!m_uiDelegate.m_delegateMethods.webViewDidClickAutoFillButtonWithUserInfo)
750         return;
751     
752     auto delegate = m_uiDelegate.m_delegate.get();
753     if (!delegate)
754         return;
755     
756     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView didClickAutoFillButtonWithUserInfo:userInfo ? static_cast<id <NSSecureCoding>>(userInfo->wrapper()) : nil];
757 }
758
759 void UIDelegate::UIClient::handleAutoplayEvent(WebPageProxy&, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags)
760 {
761     if (!m_uiDelegate.m_delegateMethods.webViewHandleAutoplayEventWithFlags)
762         return;
763     
764     auto delegate = m_uiDelegate.m_delegate.get();
765     if (!delegate)
766         return;
767     
768     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView handleAutoplayEvent:toWKAutoplayEvent(event) withFlags:toWKAutoplayEventFlags(flags)];
769 }
770
771 void UIDelegate::UIClient::showPage(WebPageProxy*)
772 {
773     if (!m_uiDelegate.m_delegateMethods.showWebView)
774         return;
775
776     auto delegate = m_uiDelegate.m_delegate.get();
777     if (!delegate)
778         return;
779     
780     [(id <WKUIDelegatePrivate>)delegate _showWebView:m_uiDelegate.m_webView];
781 }
782     
783 void UIDelegate::UIClient::saveDataToFileInDownloadsFolder(WebPageProxy*, const WTF::String& suggestedFilename, const WTF::String& mimeType, const URL& originatingURL, API::Data& data)
784 {
785     if (!m_uiDelegate.m_delegateMethods.webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL)
786         return;
787     
788     auto delegate = m_uiDelegate.m_delegate.get();
789     if (!delegate)
790         return;
791
792     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView saveDataToFile:wrapper(data) suggestedFilename:suggestedFilename mimeType:mimeType originatingURL:originatingURL];
793 }
794
795 void UIDelegate::UIClient::decidePolicyForNotificationPermissionRequest(WebKit::WebPageProxy&, API::SecurityOrigin& securityOrigin, WTF::Function<void(bool)>&& completionHandler)
796 {
797     if (!m_uiDelegate.m_delegateMethods.webViewRequestNotificationPermissionForSecurityOriginDecisionHandler)
798         return completionHandler(false);
799     
800     auto delegate = m_uiDelegate.m_delegate.get();
801     if (!delegate)
802         return completionHandler(false);
803
804     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:requestNotificationPermissionForSecurityOrigin:decisionHandler:));
805     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView requestNotificationPermissionForSecurityOrigin:wrapper(securityOrigin) decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL result) mutable {
806         if (checker->completionHandlerHasBeenCalled())
807             return;
808         checker->didCallCompletionHandler();
809         completionHandler(result);
810     }).get()];
811 }
812
813 bool UIDelegate::UIClient::runOpenPanel(WebPageProxy*, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, API::OpenPanelParameters* openPanelParameters, WebOpenPanelResultListenerProxy* listener)
814 {
815     if (!m_uiDelegate.m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler)
816         return false;
817
818     auto delegate = m_uiDelegate.m_delegate.get();
819     if (!delegate)
820         return false;
821
822     auto frame = API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin());
823
824     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:));
825
826     [delegate webView:m_uiDelegate.m_webView runOpenPanelWithParameters:wrapper(*openPanelParameters) initiatedByFrame:wrapper(frame) completionHandler:makeBlockPtr([checker = WTFMove(checker), listener = WTFMove(listener)] (NSArray *URLs) mutable {
827         if (checker->completionHandlerHasBeenCalled())
828             return;
829         checker->didCallCompletionHandler();
830
831         if (!URLs) {
832             listener->cancel();
833             return;
834         }
835
836         Vector<String> filenames;
837         for (NSURL *url in URLs)
838             filenames.append(url.path);
839
840         listener->chooseFiles(filenames);
841     }).get()];
842
843     return true;
844 }
845 #endif
846
847 #if ENABLE(DEVICE_ORIENTATION)
848 void UIDelegate::UIClient::shouldAllowDeviceOrientationAndMotionAccess(WebKit::WebPageProxy&, WebFrameProxy& webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, CompletionHandler<void(bool)>&& completionHandler)
849 {
850     if (!m_uiDelegate.m_delegateMethods.webViewShouldAllowDeviceOrientationAndMotionAccessRequestedByFrameDecisionHandler)
851         return completionHandler(false);
852
853     auto delegate = m_uiDelegate.m_delegate.get();
854     if (!delegate)
855         return completionHandler(false);
856
857     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:shouldAllowDeviceOrientationAndMotionAccessRequestedByFrame:decisionHandler:));
858     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView shouldAllowDeviceOrientationAndMotionAccessRequestedByFrame:wrapper(API::FrameInfo::create(webFrameProxy, securityOriginData.securityOrigin())) decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] (BOOL granted) mutable {
859         if (checker->completionHandlerHasBeenCalled())
860             return;
861         checker->didCallCompletionHandler();
862         completionHandler(granted);
863     }).get()];
864 }
865 #endif
866
867 void UIDelegate::UIClient::didChangeFontAttributes(const WebCore::FontAttributes& fontAttributes)
868 {
869     if (!needsFontAttributes())
870         return;
871
872     auto privateUIDelegate = (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get();
873     [privateUIDelegate _webView:m_uiDelegate.m_webView didChangeFontAttributes:fontAttributes.createDictionary().get()];
874 }
875
876 #if ENABLE(MEDIA_STREAM)
877 static void requestUserMediaAuthorizationForFrame(const WebFrameProxy& frame, API::SecurityOrigin& topLevelOrigin, UserMediaPermissionRequestProxy& request, id <WKUIDelegatePrivate> delegate, WKWebView& webView)
878 {
879     auto checker = CompletionHandlerCallChecker::create(delegate, @selector(_webView:requestMediaCaptureAuthorization:decisionHandler:));
880     auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), checker = WTFMove(checker)](BOOL authorized) {
881         if (checker->completionHandlerHasBeenCalled())
882             return;
883         checker->didCallCompletionHandler();
884
885         if (!authorized) {
886             protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
887             return;
888         }
889         const String& videoDeviceUID = (protectedRequest->requiresVideoCapture() || protectedRequest->requiresDisplayCapture()) ? protectedRequest->videoDeviceUIDs().first() : String();
890         const String& audioDeviceUID = protectedRequest->requiresAudioCapture() ? protectedRequest->audioDeviceUIDs().first() : String();
891         protectedRequest->allow(audioDeviceUID, videoDeviceUID);
892     });
893
894     _WKCaptureDevices devices = 0;
895     if (request.requiresAudioCapture())
896         devices |= _WKCaptureDeviceMicrophone;
897     if (request.requiresVideoCapture())
898         devices |= _WKCaptureDeviceCamera;
899     if (request.requiresDisplayCapture()) {
900         devices |= _WKCaptureDeviceDisplay;
901         ASSERT(!(devices & _WKCaptureDeviceCamera));
902     }
903
904     const auto* mainFrame = frame.page()->mainFrame();
905
906     // FIXME: Provide a specific delegate for display capture.
907     if (!request.requiresDisplayCapture() && [delegate respondsToSelector:@selector(_webView:requestMediaCaptureAuthorization:decisionHandler:)]) {
908
909         [delegate _webView:&webView requestMediaCaptureAuthorization:devices decisionHandler:decisionHandler.get()];
910         return;
911     }
912
913     URL requestFrameURL { URL(), frame.url() };
914     URL mainFrameURL { URL(), mainFrame->url() };
915
916     [delegate _webView:&webView requestUserMediaAuthorizationForDevices:devices url:requestFrameURL mainFrameURL:mainFrameURL decisionHandler:decisionHandler.get()];
917 }
918 #endif
919
920 void UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaOrigin, API::SecurityOrigin& topLevelOrigin, UserMediaPermissionRequestProxy& request)
921 {
922 #if ENABLE(MEDIA_STREAM)
923     auto delegate = m_uiDelegate.m_delegate.get();
924     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewRequestMediaCaptureAuthorizationForFrameDecisionHandler) {
925         request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled);
926         return;
927     }
928
929     bool requiresAudioCapture = request.requiresAudioCapture();
930     bool requiresVideoCapture = request.requiresVideoCapture();
931     bool requiresDisplayCapture = request.requiresDisplayCapture();
932     if (!requiresAudioCapture && !requiresVideoCapture && !requiresDisplayCapture) {
933         request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints);
934         return;
935     }
936
937 #if HAVE(AUTHORIZATION_STATUS_FOR_MEDIA_TYPE)
938     bool usingMockCaptureDevices = page.preferences().mockCaptureDevicesEnabled();
939     auto requestCameraAuthorization = makeBlockPtr([this, &frame, protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = makeRef(topLevelOrigin), usingMockCaptureDevices]() mutable {
940
941         if (!protectedRequest->requiresVideoCapture()) {
942             requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
943             return;
944         }
945         AVAuthorizationStatus cameraAuthorizationStatus = usingMockCaptureDevices ? AVAuthorizationStatusAuthorized : [getAVCaptureDeviceClass() authorizationStatusForMediaType:getAVMediaTypeVideo()];
946         switch (cameraAuthorizationStatus) {
947         case AVAuthorizationStatusAuthorized:
948             requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
949             break;
950         case AVAuthorizationStatusDenied:
951         case AVAuthorizationStatusRestricted:
952             protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
953             return;
954         case AVAuthorizationStatusNotDetermined:
955             auto decisionHandler = makeBlockPtr([this, &frame, protectedRequest = makeRef(protectedRequest.get()), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = WTFMove(topLevelOrigin)](BOOL authorized) {
956                 if (!authorized) {
957                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
958                     return;
959                 }
960                 requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
961             });
962
963             [getAVCaptureDeviceClass() requestAccessForMediaType:getAVMediaTypeVideo() completionHandler:decisionHandler.get()];
964             break;
965         }
966     });
967
968     if (requiresAudioCapture) {
969         AVAuthorizationStatus microphoneAuthorizationStatus = usingMockCaptureDevices ? AVAuthorizationStatusAuthorized : [getAVCaptureDeviceClass() authorizationStatusForMediaType:getAVMediaTypeAudio()];
970         switch (microphoneAuthorizationStatus) {
971         case AVAuthorizationStatusAuthorized:
972             requestCameraAuthorization();
973             break;
974         case AVAuthorizationStatusDenied:
975         case AVAuthorizationStatusRestricted:
976             request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
977             return;
978         case AVAuthorizationStatusNotDetermined:
979             auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), requestCameraAuthorization](BOOL authorized) {
980                 if (!authorized) {
981                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
982                     return;
983                 }
984                 requestCameraAuthorization();
985             });
986
987             [getAVCaptureDeviceClass() requestAccessForMediaType:getAVMediaTypeAudio() completionHandler:decisionHandler.get()];
988             break;
989         }
990     } else
991         requestCameraAuthorization();
992 #else
993     requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, request, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *m_uiDelegate.m_webView);
994 #endif
995 #endif
996 }
997
998 void UIDelegate::UIClient::checkUserMediaPermissionForOrigin(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaOrigin, API::SecurityOrigin& topLevelOrigin, UserMediaPermissionCheckProxy& request)
999 {
1000     auto delegate = m_uiDelegate.m_delegate.get();
1001     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewIsMediaCaptureAuthorizedForFrameDecisionHandler) {
1002         request.setUserMediaAccessInfo(false);
1003         return;
1004     }
1005
1006     const auto* mainFrame = frame.page()->mainFrame();
1007
1008     if ([delegate respondsToSelector:@selector(_webView:includeSensitiveMediaDeviceDetails:)]) {
1009         auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:includeSensitiveMediaDeviceDetails:));
1010         auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), checker = WTFMove(checker)](BOOL includeSensitiveDetails) {
1011             if (checker->completionHandlerHasBeenCalled())
1012                 return;
1013             checker->didCallCompletionHandler();
1014
1015             protectedRequest->setUserMediaAccessInfo(includeSensitiveDetails);
1016         });
1017
1018         [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView includeSensitiveMediaDeviceDetails:decisionHandler.get()];
1019         return;
1020     }
1021
1022     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:));
1023     auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), checker = WTFMove(checker)](NSString*, BOOL authorized) {
1024         if (checker->completionHandlerHasBeenCalled())
1025             return;
1026         checker->didCallCompletionHandler();
1027
1028         protectedRequest->setUserMediaAccessInfo(authorized);
1029     });
1030
1031     URL requestFrameURL { URL(), frame.url() };
1032     URL mainFrameURL { URL(), mainFrame->url() };
1033
1034     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView checkUserMediaPermissionForURL:requestFrameURL mainFrameURL:mainFrameURL frameIdentifier:frame.frameID() decisionHandler:decisionHandler.get()];
1035 }
1036
1037 void UIDelegate::UIClient::mediaCaptureStateDidChange(WebCore::MediaProducer::MediaStateFlags state)
1038 {
1039     WKWebView *webView = m_uiDelegate.m_webView;
1040
1041     [webView didChangeValueForKey:@"mediaCaptureState"];
1042
1043     auto delegate = m_uiDelegate.m_delegate.get();
1044     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewMediaCaptureStateDidChange)
1045         return;
1046
1047     [(id <WKUIDelegatePrivate>)delegate _webView:webView mediaCaptureStateDidChange:toWKMediaCaptureState(state)];
1048 }
1049
1050 void UIDelegate::UIClient::reachedApplicationCacheOriginQuota(WebPageProxy*, const WebCore::SecurityOrigin& securityOrigin, uint64_t currentQuota, uint64_t totalBytesNeeded, Function<void (unsigned long long)>&& completionHandler)
1051 {
1052     if (!m_uiDelegate.m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded) {
1053         completionHandler(currentQuota);
1054         return;
1055     }
1056
1057     auto delegate = m_uiDelegate.m_delegate.get();
1058     if (!delegate) {
1059         completionHandler(currentQuota);
1060         return;
1061     }
1062
1063     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:));
1064     auto apiOrigin = API::SecurityOrigin::create(securityOrigin);
1065     
1066     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView decideWebApplicationCacheQuotaForSecurityOrigin:wrapper(apiOrigin.get()) currentQuota:currentQuota totalBytesNeeded:totalBytesNeeded decisionHandler:makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long newQuota) {
1067         if (checker->completionHandlerHasBeenCalled())
1068             return;
1069         checker->didCallCompletionHandler();
1070         completionHandler(newQuota);
1071     }).get()];
1072 }
1073
1074 void UIDelegate::UIClient::printFrame(WebPageProxy&, WebFrameProxy& webFrameProxy)
1075 {
1076     if (!m_uiDelegate.m_delegateMethods.webViewPrintFrame)
1077         return;
1078
1079     auto delegate = m_uiDelegate.m_delegate.get();
1080     if (!delegate)
1081         return;
1082
1083     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView printFrame:wrapper(API::FrameHandle::create(webFrameProxy.frameID()))];
1084 }
1085
1086 void UIDelegate::UIClient::close(WebPageProxy*)
1087 {
1088     if (m_uiDelegate.m_delegateMethods.webViewClose) {
1089         auto delegate = m_uiDelegate.m_delegate.get();
1090         if (!delegate)
1091             return;
1092
1093         [(id <WKUIDelegatePrivate>)delegate _webViewClose:m_uiDelegate.m_webView];
1094         return;
1095     }
1096
1097     if (!m_uiDelegate.m_delegateMethods.webViewDidClose)
1098         return;
1099
1100     auto delegate = m_uiDelegate.m_delegate.get();
1101     if (!delegate)
1102         return;
1103
1104     [delegate webViewDidClose:m_uiDelegate.m_webView];
1105 }
1106
1107 void UIDelegate::UIClient::fullscreenMayReturnToInline(WebPageProxy*)
1108 {
1109     if (!m_uiDelegate.m_delegateMethods.webViewFullscreenMayReturnToInline)
1110         return;
1111     
1112     auto delegate = m_uiDelegate.m_delegate.get();
1113     if (!delegate)
1114         return;
1115     
1116     [(id <WKUIDelegatePrivate>)delegate _webViewFullscreenMayReturnToInline:m_uiDelegate.m_webView];
1117 }
1118
1119 void UIDelegate::UIClient::didEnterFullscreen(WebPageProxy*)
1120 {
1121     if (!m_uiDelegate.m_delegateMethods.webViewDidEnterFullscreen)
1122         return;
1123
1124     auto delegate = m_uiDelegate.m_delegate.get();
1125     if (!delegate)
1126         return;
1127
1128     [(id <WKUIDelegatePrivate>)delegate _webViewDidEnterFullscreen:m_uiDelegate.m_webView];
1129 }
1130
1131 void UIDelegate::UIClient::didExitFullscreen(WebPageProxy*)
1132 {
1133     if (!m_uiDelegate.m_delegateMethods.webViewDidExitFullscreen)
1134         return;
1135
1136     auto delegate = m_uiDelegate.m_delegate.get();
1137     if (!delegate)
1138         return;
1139
1140     [(id <WKUIDelegatePrivate>)delegate _webViewDidExitFullscreen:m_uiDelegate.m_webView];
1141 }
1142     
1143 #if PLATFORM(IOS_FAMILY)
1144 #if HAVE(APP_LINKS)
1145 bool UIDelegate::UIClient::shouldIncludeAppLinkActionsForElement(_WKActivatedElementInfo *elementInfo)
1146 {
1147     if (!m_uiDelegate.m_delegateMethods.webViewShouldIncludeAppLinkActionsForElement)
1148         return true;
1149
1150     auto delegate = m_uiDelegate.m_delegate.get();
1151     if (!delegate)
1152         return true;
1153
1154     return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView shouldIncludeAppLinkActionsForElement:elementInfo];
1155 }
1156 #endif
1157
1158 RetainPtr<NSArray> UIDelegate::UIClient::actionsForElement(_WKActivatedElementInfo *elementInfo, RetainPtr<NSArray> defaultActions)
1159 {
1160     if (!m_uiDelegate.m_delegateMethods.webViewActionsForElementDefaultActions)
1161         return defaultActions;
1162
1163     auto delegate = m_uiDelegate.m_delegate.get();
1164     if (!delegate)
1165         return defaultActions;
1166
1167     return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView actionsForElement:elementInfo defaultActions:defaultActions.get()];
1168 }
1169
1170 void UIDelegate::UIClient::didNotHandleTapAsClick(const WebCore::IntPoint& point)
1171 {
1172     if (!m_uiDelegate.m_delegateMethods.webViewDidNotHandleTapAsClickAtPoint)
1173         return;
1174
1175     auto delegate = m_uiDelegate.m_delegate.get();
1176     if (!delegate)
1177         return;
1178
1179     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView didNotHandleTapAsClickAtPoint:point];
1180 }
1181
1182 UIViewController *UIDelegate::UIClient::presentingViewController()
1183 {
1184     if (!m_uiDelegate.m_delegateMethods.presentingViewControllerForWebView)
1185         return nullptr;
1186
1187     auto delegate = m_uiDelegate.m_delegate.get();
1188     if (!delegate)
1189         return nullptr;
1190
1191     return [static_cast<id <WKUIDelegatePrivate>>(delegate) _presentingViewControllerForWebView:m_uiDelegate.m_webView];
1192 }
1193
1194 #endif
1195
1196 NSDictionary *UIDelegate::UIClient::dataDetectionContext()
1197 {
1198     if (!m_uiDelegate.m_delegateMethods.dataDetectionContextForWebView)
1199         return nullptr;
1200
1201     auto delegate = m_uiDelegate.m_delegate.get();
1202     if (!delegate)
1203         return nullptr;
1204
1205     return [static_cast<id <WKUIDelegatePrivate>>(delegate) _dataDetectionContextForWebView:m_uiDelegate.m_webView];
1206 }
1207
1208 #if ENABLE(POINTER_LOCK)
1209
1210 void UIDelegate::UIClient::requestPointerLock(WebPageProxy* page)
1211 {
1212     if (!m_uiDelegate.m_delegateMethods.webViewRequestPointerLock && !m_uiDelegate.m_delegateMethods.webViewDidRequestPointerLockCompletionHandler)
1213         return;
1214
1215     auto delegate = m_uiDelegate.m_delegate.get();
1216     if (!delegate)
1217         return;
1218
1219     if (m_uiDelegate.m_delegateMethods.webViewRequestPointerLock) {
1220         [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewRequestPointerLock:m_uiDelegate.m_webView];
1221         return;
1222     }
1223
1224     auto checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webViewDidRequestPointerLock:completionHandler:));
1225     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewDidRequestPointerLock:m_uiDelegate.m_webView completionHandler:makeBlockPtr([checker = WTFMove(checker), page = makeRefPtr(page)] (BOOL allow) {
1226         if (checker->completionHandlerHasBeenCalled())
1227             return;
1228         checker->didCallCompletionHandler();
1229
1230         if (allow)
1231             page->didAllowPointerLock();
1232         else
1233             page->didDenyPointerLock();
1234     }).get()];
1235 }
1236
1237 void UIDelegate::UIClient::didLosePointerLock(WebPageProxy*)
1238 {
1239     if (!m_uiDelegate.m_delegateMethods.webViewDidLosePointerLock)
1240         return;
1241
1242     auto delegate = m_uiDelegate.m_delegate.get();
1243     if (!delegate)
1244         return;
1245
1246     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewDidLosePointerLock:m_uiDelegate.m_webView];
1247 }
1248
1249 #endif
1250     
1251 void UIDelegate::UIClient::didShowSafeBrowsingWarning()
1252 {
1253     if (!m_uiDelegate.m_delegateMethods.webViewDidShowSafeBrowsingWarning)
1254         return;
1255
1256     auto delegate = m_uiDelegate.m_delegate.get();
1257     if (!delegate)
1258         return;
1259
1260     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewDidShowSafeBrowsingWarning:m_uiDelegate.m_webView];
1261 }
1262
1263 void UIDelegate::UIClient::hasVideoInPictureInPictureDidChange(WebPageProxy*, bool hasVideoInPictureInPicture)
1264 {
1265     if (!m_uiDelegate.m_delegateMethods.webViewHasVideoInPictureInPictureDidChange)
1266         return;
1267     
1268     auto delegate = m_uiDelegate.m_delegate.get();
1269     if (!delegate)
1270         return;
1271     
1272     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView hasVideoInPictureInPictureDidChange:hasVideoInPictureInPicture];
1273 }
1274
1275 void UIDelegate::UIClient::imageOrMediaDocumentSizeChanged(const WebCore::IntSize& newSize)
1276 {
1277     if (!m_uiDelegate.m_delegateMethods.webViewImageOrMediaDocumentSizeChanged)
1278         return;
1279
1280     auto delegate = m_uiDelegate.m_delegate.get();
1281     if (!delegate)
1282         return;
1283
1284     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView imageOrMediaDocumentSizeChanged:newSize];
1285 }
1286
1287 } // namespace WebKit