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