Add WKUIDelegatePrivate equivalent of WKPageUIClient's saveDataToFileInDownloadsFolder
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / UIDelegate.mm
1 /*
2  * Copyright (C) 2014-2016 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 #if WK_API_ENABLED
30
31 #import "APIFrameInfo.h"
32 #import "CompletionHandlerCallChecker.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 "WKNavigationActionInternal.h"
40 #import "WKOpenPanelParametersInternal.h"
41 #import "WKSecurityOriginInternal.h"
42 #import "WKUIDelegatePrivate.h"
43 #import "WKWebViewConfigurationInternal.h"
44 #import "WKWebViewInternal.h"
45 #import "WKWindowFeaturesInternal.h"
46 #import "WebOpenPanelResultListenerProxy.h"
47 #import "WebProcessProxy.h"
48 #import "_WKContextMenuElementInfo.h"
49 #import "_WKFrameHandleInternal.h"
50 #import <WebCore/SecurityOriginData.h>
51 #import <WebCore/URL.h>
52 #import <wtf/BlockPtr.h>
53
54 #if PLATFORM(IOS)
55 #import <AVFoundation/AVCaptureDevice.h>
56 #import <AVFoundation/AVMediaFormat.h>
57 #import <wtf/SoftLinking.h>
58
59 SOFT_LINK_FRAMEWORK(AVFoundation);
60 SOFT_LINK_CLASS(AVFoundation, AVCaptureDevice);
61 SOFT_LINK_CONSTANT(AVFoundation, AVMediaTypeAudio, NSString *);
62 SOFT_LINK_CONSTANT(AVFoundation, AVMediaTypeVideo, NSString *);
63 #endif
64
65 namespace WebKit {
66
67 UIDelegate::UIDelegate(WKWebView *webView)
68     : m_webView(webView)
69 {
70 }
71
72 UIDelegate::~UIDelegate()
73 {
74 }
75
76 #if ENABLE(CONTEXT_MENUS)
77 std::unique_ptr<API::ContextMenuClient> UIDelegate::createContextMenuClient()
78 {
79     return std::make_unique<ContextMenuClient>(*this);
80 }
81 #endif
82
83 std::unique_ptr<API::UIClient> UIDelegate::createUIClient()
84 {
85     return std::make_unique<UIClient>(*this);
86 }
87
88 RetainPtr<id <WKUIDelegate> > UIDelegate::delegate()
89 {
90     return m_delegate.get();
91 }
92
93 void UIDelegate::setDelegate(id <WKUIDelegate> delegate)
94 {
95     m_delegate = delegate;
96
97     m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeatures = [delegate respondsToSelector:@selector(webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:)];
98     m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync = [delegate respondsToSelector:@selector(_webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:completionHandler:)];
99     m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:)];
100     m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
101     m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:)];
102     m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:)];
103
104 #if PLATFORM(MAC)
105     m_delegateMethods.showWebView = [delegate respondsToSelector:@selector(_showWebView:)];
106     m_delegateMethods.focusWebView = [delegate respondsToSelector:@selector(_focusWebView:)];
107     m_delegateMethods.unfocusWebView = [delegate respondsToSelector:@selector(_unfocusWebView:)];
108     m_delegateMethods.webViewTakeFocus = [delegate respondsToSelector:@selector(_webView:takeFocus:)];
109     m_delegateMethods.webViewDidNotHandleWheelEvent = [delegate respondsToSelector:@selector(_webView:didNotHandleWheelEvent:)];
110     m_delegateMethods.webViewHandleAutoplayEventWithFlags = [delegate respondsToSelector:@selector(_webView:handleAutoplayEvent:withFlags:)];
111     m_delegateMethods.webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL = [delegate respondsToSelector:@selector(_webView:saveDataToFile:suggestedFilename:mimeType:originatingURL:)];
112     m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler = [delegate respondsToSelector:@selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:)];
113 #endif
114     m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler = [delegate respondsToSelector:@selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:)];
115     m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded = [delegate respondsToSelector:@selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:)];
116     m_delegateMethods.webViewPrintFrame = [delegate respondsToSelector:@selector(_webView:printFrame:)];
117     m_delegateMethods.webViewDidClose = [delegate respondsToSelector:@selector(webViewDidClose:)];
118     m_delegateMethods.webViewClose = [delegate respondsToSelector:@selector(_webViewClose:)];
119     m_delegateMethods.webViewFullscreenMayReturnToInline = [delegate respondsToSelector:@selector(_webViewFullscreenMayReturnToInline:)];
120     m_delegateMethods.webViewDidEnterFullscreen = [delegate respondsToSelector:@selector(_webViewDidEnterFullscreen:)];
121     m_delegateMethods.webViewDidExitFullscreen = [delegate respondsToSelector:@selector(_webViewDidExitFullscreen:)];
122 #if PLATFORM(IOS)
123 #if HAVE(APP_LINKS)
124     m_delegateMethods.webViewShouldIncludeAppLinkActionsForElement = [delegate respondsToSelector:@selector(_webView:shouldIncludeAppLinkActionsForElement:)];
125 #endif
126     m_delegateMethods.webViewActionsForElementDefaultActions = [delegate respondsToSelector:@selector(_webView:actionsForElement:defaultActions:)];
127     m_delegateMethods.webViewDidNotHandleTapAsClickAtPoint = [delegate respondsToSelector:@selector(_webView:didNotHandleTapAsClickAtPoint:)];
128     m_delegateMethods.presentingViewControllerForWebView = [delegate respondsToSelector:@selector(_presentingViewControllerForWebView:)];
129 #endif
130     m_delegateMethods.webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler = [delegate respondsToSelector:@selector(_webView:requestUserMediaAuthorizationForDevices:url:mainFrameURL:decisionHandler:)];
131     m_delegateMethods.webViewCheckUserMediaPermissionForURLMainFrameURLFrameIdentifierDecisionHandler = [delegate respondsToSelector:@selector(_webView:checkUserMediaPermissionForURL:mainFrameURL:frameIdentifier:decisionHandler:)];
132     m_delegateMethods.webViewMediaCaptureStateDidChange = [delegate respondsToSelector:@selector(_webView:mediaCaptureStateDidChange:)];
133     m_delegateMethods.dataDetectionContextForWebView = [delegate respondsToSelector:@selector(_dataDetectionContextForWebView:)];
134     m_delegateMethods.webViewImageOrMediaDocumentSizeChanged = [delegate respondsToSelector:@selector(_webView:imageOrMediaDocumentSizeChanged:)];
135
136 #if ENABLE(POINTER_LOCK)
137     m_delegateMethods.webViewRequestPointerLock = [delegate respondsToSelector:@selector(_webViewRequestPointerLock:)];
138     m_delegateMethods.webViewDidLosePointerLock = [delegate respondsToSelector:@selector(_webViewDidLosePointerLock:)];
139 #endif
140 #if ENABLE(CONTEXT_MENUS)
141     m_delegateMethods.webViewContextMenuForElement = [delegate respondsToSelector:@selector(_webView:contextMenu:forElement:)];
142     m_delegateMethods.webViewContextMenuForElementUserInfo = [delegate respondsToSelector:@selector(_webView:contextMenu:forElement:userInfo:)];
143 #endif
144     
145     m_delegateMethods.webViewHasVideoInPictureInPictureDidChange = [delegate respondsToSelector:@selector(_webView:hasVideoInPictureInPictureDidChange:)];
146 }
147
148 #if ENABLE(CONTEXT_MENUS)
149 UIDelegate::ContextMenuClient::ContextMenuClient(UIDelegate& uiDelegate)
150     : m_uiDelegate(uiDelegate)
151 {
152 }
153
154 UIDelegate::ContextMenuClient::~ContextMenuClient()
155 {
156 }
157
158 RetainPtr<NSMenu> UIDelegate::ContextMenuClient::menuFromProposedMenu(WebKit::WebPageProxy&, NSMenu *menu, const WebKit::WebHitTestResultData&, API::Object* userInfo)
159 {
160     if (!m_uiDelegate.m_delegateMethods.webViewContextMenuForElement && !m_uiDelegate.m_delegateMethods.webViewContextMenuForElementUserInfo)
161         return menu;
162
163     auto delegate = m_uiDelegate.m_delegate.get();
164     if (!delegate)
165         return menu;
166
167     auto contextMenuElementInfo = adoptNS([[_WKContextMenuElementInfo alloc] init]);
168
169     if (m_uiDelegate.m_delegateMethods.webViewContextMenuForElement)
170         return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView contextMenu:menu forElement:contextMenuElementInfo.get()];
171
172     return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView contextMenu:menu forElement:contextMenuElementInfo.get() userInfo:static_cast<id <NSSecureCoding>>(userInfo->wrapper())];
173 }
174 #endif
175
176 UIDelegate::UIClient::UIClient(UIDelegate& uiDelegate)
177     : m_uiDelegate(uiDelegate)
178 {
179 }
180
181 UIDelegate::UIClient::~UIClient()
182 {
183 }
184
185 RefPtr<WebKit::WebPageProxy> UIDelegate::UIClient::createNewPageCommon(WebKit::WebPageProxy* page, API::FrameInfo& sourceFrameInfo, WebCore::ResourceRequest&& request, const WebCore::WindowFeatures& windowFeatures, WebKit::NavigationActionData&& navigationActionData, WTF::Function<void(RefPtr<WebKit::WebPageProxy>&&)>&& completionHandler)
186 {
187     auto delegate = m_uiDelegate.m_delegate.get();
188     ASSERT(delegate);
189
190     auto configuration = adoptNS([m_uiDelegate.m_webView->_configuration copy]);
191     [configuration _setRelatedWebView:m_uiDelegate.m_webView];
192
193     auto userInitiatedActivity = page->process().userInitiatedActivity(navigationActionData.userGestureTokenIdentifier);
194     bool shouldOpenAppLinks = !hostsAreEqual(sourceFrameInfo.request().url(), request.url());
195     auto apiNavigationAction = API::NavigationAction::create(WTFMove(navigationActionData), &sourceFrameInfo, nullptr, WTFMove(request), WebCore::URL(), shouldOpenAppLinks, WTFMove(userInitiatedActivity));
196
197     auto apiWindowFeatures = API::WindowFeatures::create(windowFeatures);
198
199     if (completionHandler) {
200         RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:createWebViewWithConfiguration:forNavigationAction:windowFeatures:completionHandler:));
201
202         [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView createWebViewWithConfiguration:configuration.get() forNavigationAction:wrapper(apiNavigationAction) windowFeatures:wrapper(apiWindowFeatures) completionHandler:BlockPtr<void (WKWebView *)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker), relatedWebView = RetainPtr<WKWebView>(m_uiDelegate.m_webView)](WKWebView *webView) {
203             if (checker->completionHandlerHasBeenCalled())
204                 return;
205             checker->didCallCompletionHandler();
206
207             if (!webView) {
208                 completionHandler(nullptr);
209                 return;
210             }
211
212             if ([webView->_configuration _relatedWebView] != relatedWebView.get())
213                 [NSException raise:NSInternalInconsistencyException format:@"Returned WKWebView was not created with the given configuration."];
214
215             completionHandler(webView->_page.get());
216         }).get()];
217
218         return nullptr;
219     }
220
221     RetainPtr<WKWebView> webView = [delegate webView:m_uiDelegate.m_webView createWebViewWithConfiguration:configuration.get() forNavigationAction:wrapper(apiNavigationAction) windowFeatures:wrapper(apiWindowFeatures)];
222
223     if (!webView)
224         return nullptr;
225
226     if ([webView->_configuration _relatedWebView] != m_uiDelegate.m_webView)
227         [NSException raise:NSInternalInconsistencyException format:@"Returned WKWebView was not created with the given configuration."];
228
229     return webView->_page.get();
230 }
231
232 RefPtr<WebPageProxy> UIDelegate::UIClient::createNewPage(WebPageProxy* page, API::FrameInfo& originatingFrameInfo, WebCore::ResourceRequest&& request, const WebCore::WindowFeatures& windowFeatures, NavigationActionData&& navigationActionData)
233 {
234     if (!m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeatures)
235         return nullptr;
236
237     auto delegate = m_uiDelegate.m_delegate.get();
238     if (!delegate)
239         return nullptr;
240
241     return createNewPageCommon(page, originatingFrameInfo, WTFMove(request), windowFeatures, WTFMove(navigationActionData), nullptr);
242 }
243
244 bool UIDelegate::UIClient::canCreateNewPageAsync()
245 {
246     return m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync
247         && m_uiDelegate.m_delegate.get();
248 }
249
250 void UIDelegate::UIClient::createNewPageAsync(WebPageProxy* page, API::FrameInfo& originatingFrameInfo, WebCore::ResourceRequest&& request, const WebCore::WindowFeatures& windowFeatures, NavigationActionData&& navigationActionData, WTF::Function<void(RefPtr<WebPageProxy>&&)>&& completionHandler)
251 {
252     ASSERT(canCreateNewPageAsync());
253     ASSERT(m_uiDelegate.m_delegateMethods.webViewCreateWebViewWithConfigurationForNavigationActionWindowFeaturesAsync);
254
255     auto delegate = m_uiDelegate.m_delegate.get();
256     ASSERT(delegate);
257
258     createNewPageCommon(page, originatingFrameInfo, WTFMove(request), windowFeatures, WTFMove(navigationActionData), WTFMove(completionHandler));
259 }
260
261 void UIDelegate::UIClient::runJavaScriptAlert(WebKit::WebPageProxy*, const WTF::String& message, WebKit::WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void ()>&& completionHandler)
262 {
263     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptAlertPanelWithMessageInitiatedByFrameCompletionHandler) {
264         completionHandler();
265         return;
266     }
267
268     auto delegate = m_uiDelegate.m_delegate.get();
269     if (!delegate) {
270         completionHandler();
271         return;
272     }
273
274     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptAlertPanelWithMessage:initiatedByFrame:completionHandler:));
275     [delegate webView:m_uiDelegate.m_webView runJavaScriptAlertPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:BlockPtr<void ()>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)] {
276         if (checker->completionHandlerHasBeenCalled())
277             return;
278         completionHandler();
279         checker->didCallCompletionHandler();
280     }).get()];
281 }
282
283 void UIDelegate::UIClient::runJavaScriptConfirm(WebKit::WebPageProxy*, const WTF::String& message, WebKit::WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void (bool)>&& completionHandler)
284 {
285     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptConfirmPanelWithMessageInitiatedByFrameCompletionHandler) {
286         completionHandler(false);
287         return;
288     }
289
290     auto delegate = m_uiDelegate.m_delegate.get();
291     if (!delegate) {
292         completionHandler(false);
293         return;
294     }
295
296     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptConfirmPanelWithMessage:initiatedByFrame:completionHandler:));
297     [delegate webView:m_uiDelegate.m_webView runJavaScriptConfirmPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:BlockPtr<void (BOOL)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](BOOL result) {
298         if (checker->completionHandlerHasBeenCalled())
299             return;
300         completionHandler(result);
301         checker->didCallCompletionHandler();
302     }).get()];
303 }
304
305 void UIDelegate::UIClient::runJavaScriptPrompt(WebKit::WebPageProxy*, const WTF::String& message, const WTF::String& defaultValue, WebKit::WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void (const WTF::String&)>&& completionHandler)
306 {
307     if (!m_uiDelegate.m_delegateMethods.webViewRunJavaScriptTextInputPanelWithPromptDefaultTextInitiatedByFrameCompletionHandler) {
308         completionHandler(String());
309         return;
310     }
311
312     auto delegate = m_uiDelegate.m_delegate.get();
313     if (!delegate) {
314         completionHandler(String());
315         return;
316     }
317
318     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:));
319     [delegate webView:m_uiDelegate.m_webView runJavaScriptTextInputPanelWithPrompt:message defaultText:defaultValue initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:BlockPtr<void (NSString *)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](NSString *result) {
320         if (checker->completionHandlerHasBeenCalled())
321             return;
322         completionHandler(result);
323         checker->didCallCompletionHandler();
324     }).get()];
325 }
326
327 bool UIDelegate::UIClient::canRunBeforeUnloadConfirmPanel() const
328 {
329     return m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler;
330 }
331
332 void UIDelegate::UIClient::runBeforeUnloadConfirmPanel(WebKit::WebPageProxy*, const WTF::String& message, WebKit::WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, Function<void (bool)>&& completionHandler)
333 {
334     if (!m_uiDelegate.m_delegateMethods.webViewRunBeforeUnloadConfirmPanelWithMessageInitiatedByFrameCompletionHandler) {
335         completionHandler(false);
336         return;
337     }
338
339     auto delegate = m_uiDelegate.m_delegate.get();
340     if (!delegate) {
341         completionHandler(false);
342         return;
343     }
344
345     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:runBeforeUnloadConfirmPanelWithMessage:initiatedByFrame:completionHandler:));
346     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView runBeforeUnloadConfirmPanelWithMessage:message initiatedByFrame:wrapper(API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin())) completionHandler:BlockPtr<void (BOOL)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](BOOL result) {
347         if (checker->completionHandlerHasBeenCalled())
348             return;
349         completionHandler(result);
350         checker->didCallCompletionHandler();
351     }).get()];
352 }
353
354 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)
355 {
356     if (!m_uiDelegate.m_delegateMethods.webViewDecideDatabaseQuotaForSecurityOriginCurrentQuotaCurrentOriginUsageCurrentDatabaseUsageExpectedUsageDecisionHandler) {
357
358         // Use 50 MB as the default database quota.
359         unsigned long long defaultPerOriginDatabaseQuota = 50 * 1024 * 1024;
360
361         completionHandler(defaultPerOriginDatabaseQuota);
362         return;
363     }
364
365     auto delegate = m_uiDelegate.m_delegate.get();
366     if (!delegate) {
367         completionHandler(currentQuota);
368         return;
369     }
370
371     ASSERT(securityOrigin);
372     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:decideDatabaseQuotaForSecurityOrigin:currentQuota:currentOriginUsage:currentDatabaseUsage:expectedUsage:decisionHandler:));
373     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView decideDatabaseQuotaForSecurityOrigin:wrapper(*securityOrigin) currentQuota:currentQuota currentOriginUsage:currentOriginUsage currentDatabaseUsage:currentUsage expectedUsage:expectedUsage decisionHandler:BlockPtr<void (unsigned long long newQuota)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long newQuota) {
374         if (checker->completionHandlerHasBeenCalled())
375             return;
376         checker->didCallCompletionHandler();
377         completionHandler(newQuota);
378     }).get()];
379 }
380
381 #if PLATFORM(MAC)
382 static inline _WKFocusDirection toWKFocusDirection(WKFocusDirection direction)
383 {
384     switch (direction) {
385     case kWKFocusDirectionBackward:
386         return _WKFocusDirectionBackward;
387     case kWKFocusDirectionForward:
388         return _WKFocusDirectionForward;
389     }
390     ASSERT_NOT_REACHED();
391     return _WKFocusDirectionForward;
392 }
393
394 void UIDelegate::UIClient::takeFocus(WebKit::WebPageProxy*, WKFocusDirection direction)
395 {
396     if (!m_uiDelegate.m_delegateMethods.webViewTakeFocus)
397         return;
398     
399     auto delegate = m_uiDelegate.m_delegate.get();
400     if (!delegate)
401         return;
402     
403     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView takeFocus:toWKFocusDirection(direction)];
404 }
405
406 void UIDelegate::UIClient::focus(WebKit::WebPageProxy*)
407 {
408     if (!m_uiDelegate.m_delegateMethods.focusWebView)
409         return;
410     
411     auto delegate = m_uiDelegate.m_delegate.get();
412     if (!delegate)
413         return;
414     
415     [(id <WKUIDelegatePrivate>)delegate _focusWebView:m_uiDelegate.m_webView];
416 }
417
418 void UIDelegate::UIClient::unfocus(WebKit::WebPageProxy*)
419 {
420     if (!m_uiDelegate.m_delegateMethods.unfocusWebView)
421         return;
422     
423     auto delegate = m_uiDelegate.m_delegate.get();
424     if (!delegate)
425         return;
426     
427     [(id <WKUIDelegatePrivate>)delegate _unfocusWebView:m_uiDelegate.m_webView];
428 }
429
430 void UIDelegate::UIClient::didNotHandleWheelEvent(WebKit::WebPageProxy*, const WebKit::NativeWebWheelEvent& event)
431 {
432     if (!m_uiDelegate.m_delegateMethods.webViewDidNotHandleWheelEvent)
433         return;
434     
435     auto delegate = m_uiDelegate.m_delegate.get();
436     if (!delegate)
437         return;
438     
439     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView didNotHandleWheelEvent:event.nativeEvent()];
440 }
441
442 static _WKAutoplayEventFlags toWKAutoplayEventFlags(OptionSet<WebCore::AutoplayEventFlags> flags)
443 {
444     _WKAutoplayEventFlags wkFlags = _WKAutoplayEventFlagsNone;
445     if (flags.contains(WebCore::AutoplayEventFlags::HasAudio))
446         wkFlags |= _WKAutoplayEventFlagsHasAudio;
447     
448     return wkFlags;
449 }
450
451 static _WKAutoplayEvent toWKAutoplayEvent(WebCore::AutoplayEvent event)
452 {
453     switch (event) {
454     case WebCore::AutoplayEvent::DidPreventMediaFromPlaying:
455         return _WKAutoplayEventDidPreventFromAutoplaying;
456     case WebCore::AutoplayEvent::DidPlayMediaPreventedFromPlaying:
457         return _WKAutoplayEventDidPlayMediaPreventedFromAutoplaying;
458     case WebCore::AutoplayEvent::DidAutoplayMediaPastThresholdWithoutUserInterference:
459         return _WKAutoplayEventDidAutoplayMediaPastThresholdWithoutUserInterference;
460     case WebCore::AutoplayEvent::UserDidInterfereWithPlayback:
461         return _WKAutoplayEventUserDidInterfereWithPlayback;
462     }
463     ASSERT_NOT_REACHED();
464     return _WKAutoplayEventDidPlayMediaPreventedFromAutoplaying;
465 }
466
467 void UIDelegate::UIClient::handleAutoplayEvent(WebKit::WebPageProxy&, WebCore::AutoplayEvent event, OptionSet<WebCore::AutoplayEventFlags> flags)
468 {
469     if (!m_uiDelegate.m_delegateMethods.webViewHandleAutoplayEventWithFlags)
470         return;
471     
472     auto delegate = m_uiDelegate.m_delegate.get();
473     if (!delegate)
474         return;
475     
476     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView handleAutoplayEvent:toWKAutoplayEvent(event) withFlags:toWKAutoplayEventFlags(flags)];
477 }
478
479 void UIDelegate::UIClient::showPage(WebPageProxy*)
480 {
481     if (!m_uiDelegate.m_delegateMethods.showWebView)
482         return;
483
484     auto delegate = m_uiDelegate.m_delegate.get();
485     if (!delegate)
486         return;
487     
488     [(id <WKUIDelegatePrivate>)delegate _showWebView:m_uiDelegate.m_webView];
489 }
490     
491 void UIDelegate::UIClient::saveDataToFileInDownloadsFolder(WebPageProxy*, const WTF::String& suggestedFilename, const WTF::String& mimeType, const WebCore::URL& originatingURL, API::Data& data)
492 {
493     if (!m_uiDelegate.m_delegateMethods.webViewSaveDataToFileSuggestedFilenameMimeTypeOriginatingURL)
494         return;
495     
496     auto delegate = m_uiDelegate.m_delegate.get();
497     if (!delegate)
498         return;
499
500     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView saveDataToFile:wrapper(data) suggestedFilename:suggestedFilename mimeType:mimeType originatingURL:originatingURL];
501 }
502     
503 bool UIDelegate::UIClient::runOpenPanel(WebPageProxy*, WebFrameProxy* webFrameProxy, const WebCore::SecurityOriginData& securityOriginData, API::OpenPanelParameters* openPanelParameters, WebOpenPanelResultListenerProxy* listener)
504 {
505     if (!m_uiDelegate.m_delegateMethods.webViewRunOpenPanelWithParametersInitiatedByFrameCompletionHandler)
506         return false;
507
508     auto delegate = m_uiDelegate.m_delegate.get();
509     if (!delegate)
510         return false;
511
512     auto frame = API::FrameInfo::create(*webFrameProxy, securityOriginData.securityOrigin());
513     RefPtr<WebOpenPanelResultListenerProxy> resultListener = listener;
514
515     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(webView:runOpenPanelWithParameters:initiatedByFrame:completionHandler:));
516
517     [delegate webView:m_uiDelegate.m_webView runOpenPanelWithParameters:wrapper(*openPanelParameters) initiatedByFrame:wrapper(frame) completionHandler:[checker, resultListener](NSArray *URLs) {
518         if (checker->completionHandlerHasBeenCalled())
519             return;
520         checker->didCallCompletionHandler();
521
522         if (!URLs) {
523             resultListener->cancel();
524             return;
525         }
526
527         Vector<String> filenames;
528         for (NSURL *url in URLs)
529             filenames.append(url.path);
530
531         resultListener->chooseFiles(filenames);
532     }];
533
534     return true;
535 }
536 #endif
537
538 static void requestUserMediaAuthorizationForDevices(const WebKit::WebFrameProxy& frame, WebKit::UserMediaPermissionRequestProxy& request, id <WKUIDelegatePrivate> delegate, WKWebView& webView)
539 {
540     auto decisionHandler = BlockPtr<void(BOOL)>::fromCallable([protectedRequest = makeRef(request)](BOOL authorized) {
541         if (!authorized) {
542             protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
543             return;
544         }
545         const String& videoDeviceUID = protectedRequest->requiresVideo() ? protectedRequest->videoDeviceUIDs().first() : String();
546         const String& audioDeviceUID = protectedRequest->requiresAudio() ? protectedRequest->audioDeviceUIDs().first() : String();
547         protectedRequest->allow(audioDeviceUID, videoDeviceUID);
548     });
549
550     const WebFrameProxy* mainFrame = frame.page()->mainFrame();
551     WebCore::URL requestFrameURL(WebCore::URL(), frame.url());
552     WebCore::URL mainFrameURL(WebCore::URL(), mainFrame->url());
553
554     _WKCaptureDevices devices = 0;
555     if (request.requiresAudio())
556         devices |= _WKCaptureDeviceMicrophone;
557     if (request.requiresVideo())
558         devices |= _WKCaptureDeviceCamera;
559
560     auto protectedWebView = RetainPtr<WKWebView>(&webView);
561     [delegate _webView:protectedWebView.get() requestUserMediaAuthorizationForDevices:devices url:requestFrameURL mainFrameURL:mainFrameURL decisionHandler:decisionHandler.get()];
562 }
563
564 bool UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest(WebKit::WebPageProxy& page, WebKit::WebFrameProxy& frame, API::SecurityOrigin& userMediaOrigin, API::SecurityOrigin& topLevelOrigin, WebKit::UserMediaPermissionRequestProxy& request)
565 {
566     auto delegate = m_uiDelegate.m_delegate.get();
567     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler) {
568         request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled);
569         return true;
570     }
571
572     bool requiresAudio = request.requiresAudio();
573     bool requiresVideo = request.requiresVideo();
574     if (!requiresAudio && !requiresVideo) {
575         request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints);
576         return true;
577     }
578
579 #if PLATFORM(IOS)
580     auto requestCameraAuthorization = BlockPtr<void()>::fromCallable([this, &frame, protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView)]() {
581
582         if (!protectedRequest->requiresVideo()) {
583             requestUserMediaAuthorizationForDevices(frame, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
584             return;
585         }
586         AVAuthorizationStatus cameraAuthorizationStatus = [getAVCaptureDeviceClass() authorizationStatusForMediaType:getAVMediaTypeVideo()];
587         switch (cameraAuthorizationStatus) {
588         case AVAuthorizationStatusAuthorized:
589             requestUserMediaAuthorizationForDevices(frame, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
590             break;
591         case AVAuthorizationStatusDenied:
592         case AVAuthorizationStatusRestricted:
593             protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
594             return;
595         case AVAuthorizationStatusNotDetermined:
596             auto decisionHandler = BlockPtr<void(BOOL)>::fromCallable([this, &frame, protectedRequest = makeRef(protectedRequest.get()), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView)](BOOL authorized) {
597                 if (!authorized) {
598                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
599                     return;
600                 }
601                 requestUserMediaAuthorizationForDevices(frame, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
602             });
603
604             [getAVCaptureDeviceClass() requestAccessForMediaType:getAVMediaTypeVideo() completionHandler:decisionHandler.get()];
605             break;
606         }
607     });
608
609     if (requiresAudio) {
610         AVAuthorizationStatus microphoneAuthorizationStatus = [getAVCaptureDeviceClass() authorizationStatusForMediaType:getAVMediaTypeAudio()];
611         switch (microphoneAuthorizationStatus) {
612         case AVAuthorizationStatusAuthorized:
613             requestCameraAuthorization();
614             break;
615         case AVAuthorizationStatusDenied:
616         case AVAuthorizationStatusRestricted:
617             request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
618             return true;
619         case AVAuthorizationStatusNotDetermined:
620             auto decisionHandler = BlockPtr<void(BOOL)>::fromCallable([protectedRequest = makeRef(request), requestCameraAuthorization](BOOL authorized) {
621                 if (!authorized) {
622                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
623                     return;
624                 }
625                 requestCameraAuthorization();
626             });
627
628             [getAVCaptureDeviceClass() requestAccessForMediaType:getAVMediaTypeAudio() completionHandler:decisionHandler.get()];
629             break;
630         }
631     } else
632         requestCameraAuthorization();
633 #else
634     requestUserMediaAuthorizationForDevices(frame, request, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *m_uiDelegate.m_webView);
635 #endif
636
637     return true;
638 }
639
640 bool UIDelegate::UIClient::checkUserMediaPermissionForOrigin(WebKit::WebPageProxy& page, WebKit::WebFrameProxy& frame, API::SecurityOrigin& userMediaOrigin, API::SecurityOrigin& topLevelOrigin, WebKit::UserMediaPermissionCheckProxy& request)
641 {
642     auto delegate = m_uiDelegate.m_delegate.get();
643     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewCheckUserMediaPermissionForURLMainFrameURLFrameIdentifierDecisionHandler) {
644         request.setUserMediaAccessInfo(String(), false);
645         return true;
646     }
647
648     WKWebView *webView = m_uiDelegate.m_webView;
649     const WebFrameProxy* mainFrame = frame.page()->mainFrame();
650     WebCore::URL requestFrameURL(WebCore::URL(), frame.url());
651     WebCore::URL mainFrameURL(WebCore::URL(), mainFrame->url());
652
653     auto decisionHandler = BlockPtr<void(NSString *, BOOL)>::fromCallable([protectedRequest = makeRef(request)](NSString *salt, BOOL authorized) {
654         protectedRequest->setUserMediaAccessInfo(String(salt), authorized);
655     });
656
657     [(id <WKUIDelegatePrivate>)delegate _webView:webView checkUserMediaPermissionForURL:requestFrameURL mainFrameURL:mainFrameURL frameIdentifier:frame.frameID() decisionHandler:decisionHandler.get()];
658
659     return true;
660 }
661
662 void UIDelegate::UIClient::mediaCaptureStateDidChange(WebCore::MediaProducer::MediaStateFlags state)
663 {
664     WKWebView *webView = m_uiDelegate.m_webView;
665     auto delegate = m_uiDelegate.m_delegate.get();
666     if (!delegate || !m_uiDelegate.m_delegateMethods.webViewMediaCaptureStateDidChange)
667         return;
668
669     _WKMediaCaptureState mediaCaptureState = _WKMediaCaptureStateNone;
670     if (state & WebCore::MediaProducer::HasActiveAudioCaptureDevice)
671         mediaCaptureState |= _WKMediaCaptureStateActiveMicrophone;
672     if (state & WebCore::MediaProducer::HasActiveVideoCaptureDevice)
673         mediaCaptureState |= _WKMediaCaptureStateActiveCamera;
674     if (state & WebCore::MediaProducer::HasMutedAudioCaptureDevice)
675         mediaCaptureState |= _WKMediaCaptureStateMutedMicrophone;
676     if (state & WebCore::MediaProducer::HasMutedVideoCaptureDevice)
677         mediaCaptureState |= _WKMediaCaptureStateMutedCamera;
678
679     [(id <WKUIDelegatePrivate>)delegate _webView:webView mediaCaptureStateDidChange:mediaCaptureState];
680 }
681
682 void UIDelegate::UIClient::reachedApplicationCacheOriginQuota(WebPageProxy*, const WebCore::SecurityOrigin& securityOrigin, uint64_t currentQuota, uint64_t totalBytesNeeded, Function<void (unsigned long long)>&& completionHandler)
683 {
684     if (!m_uiDelegate.m_delegateMethods.webViewDecideWebApplicationCacheQuotaForSecurityOriginCurrentQuotaTotalBytesNeeded) {
685         completionHandler(currentQuota);
686         return;
687     }
688
689     auto delegate = m_uiDelegate.m_delegate.get();
690     if (!delegate) {
691         completionHandler(currentQuota);
692         return;
693     }
694
695     RefPtr<CompletionHandlerCallChecker> checker = CompletionHandlerCallChecker::create(delegate.get(), @selector(_webView:decideWebApplicationCacheQuotaForSecurityOrigin:currentQuota:totalBytesNeeded:decisionHandler:));
696     RefPtr<API::SecurityOrigin> apiOrigin = API::SecurityOrigin::create(securityOrigin);
697     
698     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView decideWebApplicationCacheQuotaForSecurityOrigin:wrapper(*apiOrigin) currentQuota:currentQuota totalBytesNeeded:totalBytesNeeded decisionHandler:BlockPtr<void (unsigned long long)>::fromCallable([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long newQuota) {
699         if (checker->completionHandlerHasBeenCalled())
700             return;
701         checker->didCallCompletionHandler();
702         completionHandler(newQuota);
703     }).get()];
704 }
705
706 void UIDelegate::UIClient::printFrame(WebKit::WebPageProxy*, WebKit::WebFrameProxy* webFrameProxy)
707 {
708     ASSERT_ARG(webFrameProxy, webFrameProxy);
709
710     if (!m_uiDelegate.m_delegateMethods.webViewPrintFrame)
711         return;
712
713     auto delegate = m_uiDelegate.m_delegate.get();
714     if (!delegate)
715         return;
716
717     [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView printFrame:wrapper(API::FrameHandle::create(webFrameProxy->frameID()))];
718 }
719
720 void UIDelegate::UIClient::close(WebKit::WebPageProxy*)
721 {
722     if (m_uiDelegate.m_delegateMethods.webViewClose) {
723         auto delegate = m_uiDelegate.m_delegate.get();
724         if (!delegate)
725             return;
726
727         [(id <WKUIDelegatePrivate>)delegate _webViewClose:m_uiDelegate.m_webView];
728         return;
729     }
730
731     if (!m_uiDelegate.m_delegateMethods.webViewDidClose)
732         return;
733
734     auto delegate = m_uiDelegate.m_delegate.get();
735     if (!delegate)
736         return;
737
738     [delegate webViewDidClose:m_uiDelegate.m_webView];
739 }
740
741 void UIDelegate::UIClient::fullscreenMayReturnToInline(WebKit::WebPageProxy*)
742 {
743     if (!m_uiDelegate.m_delegateMethods.webViewFullscreenMayReturnToInline)
744         return;
745     
746     auto delegate = m_uiDelegate.m_delegate.get();
747     if (!delegate)
748         return;
749     
750     [(id <WKUIDelegatePrivate>)delegate _webViewFullscreenMayReturnToInline:m_uiDelegate.m_webView];
751 }
752
753 void UIDelegate::UIClient::didEnterFullscreen(WebKit::WebPageProxy*)
754 {
755     if (!m_uiDelegate.m_delegateMethods.webViewDidEnterFullscreen)
756         return;
757
758     auto delegate = m_uiDelegate.m_delegate.get();
759     if (!delegate)
760         return;
761
762     [(id <WKUIDelegatePrivate>)delegate _webViewDidEnterFullscreen:m_uiDelegate.m_webView];
763 }
764
765 void UIDelegate::UIClient::didExitFullscreen(WebKit::WebPageProxy*)
766 {
767     if (!m_uiDelegate.m_delegateMethods.webViewDidExitFullscreen)
768         return;
769
770     auto delegate = m_uiDelegate.m_delegate.get();
771     if (!delegate)
772         return;
773
774     [(id <WKUIDelegatePrivate>)delegate _webViewDidExitFullscreen:m_uiDelegate.m_webView];
775 }
776     
777 #if PLATFORM(IOS)
778 #if HAVE(APP_LINKS)
779 bool UIDelegate::UIClient::shouldIncludeAppLinkActionsForElement(_WKActivatedElementInfo *elementInfo)
780 {
781     if (!m_uiDelegate.m_delegateMethods.webViewShouldIncludeAppLinkActionsForElement)
782         return true;
783
784     auto delegate = m_uiDelegate.m_delegate.get();
785     if (!delegate)
786         return true;
787
788     return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView shouldIncludeAppLinkActionsForElement:elementInfo];
789 }
790 #endif
791
792 RetainPtr<NSArray> UIDelegate::UIClient::actionsForElement(_WKActivatedElementInfo *elementInfo, RetainPtr<NSArray> defaultActions)
793 {
794     if (!m_uiDelegate.m_delegateMethods.webViewActionsForElementDefaultActions)
795         return defaultActions;
796
797     auto delegate = m_uiDelegate.m_delegate.get();
798     if (!delegate)
799         return defaultActions;
800
801     return [(id <WKUIDelegatePrivate>)delegate _webView:m_uiDelegate.m_webView actionsForElement:elementInfo defaultActions:defaultActions.get()];
802 }
803
804 void UIDelegate::UIClient::didNotHandleTapAsClick(const WebCore::IntPoint& point)
805 {
806     if (!m_uiDelegate.m_delegateMethods.webViewDidNotHandleTapAsClickAtPoint)
807         return;
808
809     auto delegate = m_uiDelegate.m_delegate.get();
810     if (!delegate)
811         return;
812
813     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView didNotHandleTapAsClickAtPoint:point];
814 }
815
816 UIViewController *UIDelegate::UIClient::presentingViewController()
817 {
818     if (!m_uiDelegate.m_delegateMethods.presentingViewControllerForWebView)
819         return nullptr;
820
821     auto delegate = m_uiDelegate.m_delegate.get();
822     if (!delegate)
823         return nullptr;
824
825     return [static_cast<id <WKUIDelegatePrivate>>(delegate) _presentingViewControllerForWebView:m_uiDelegate.m_webView];
826 }
827
828 #endif
829
830 NSDictionary *UIDelegate::UIClient::dataDetectionContext()
831 {
832     if (!m_uiDelegate.m_delegateMethods.dataDetectionContextForWebView)
833         return nullptr;
834
835     auto delegate = m_uiDelegate.m_delegate.get();
836     if (!delegate)
837         return nullptr;
838
839     return [static_cast<id <WKUIDelegatePrivate>>(delegate) _dataDetectionContextForWebView:m_uiDelegate.m_webView];
840 }
841
842 #if ENABLE(POINTER_LOCK)
843
844 void UIDelegate::UIClient::requestPointerLock(WebKit::WebPageProxy*)
845 {
846     if (!m_uiDelegate.m_delegateMethods.webViewRequestPointerLock)
847         return;
848
849     auto delegate = m_uiDelegate.m_delegate.get();
850     if (!delegate)
851         return;
852
853     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewRequestPointerLock:m_uiDelegate.m_webView];
854 }
855
856 void UIDelegate::UIClient::didLosePointerLock(WebKit::WebPageProxy*)
857 {
858     if (!m_uiDelegate.m_delegateMethods.webViewDidLosePointerLock)
859         return;
860
861     auto delegate = m_uiDelegate.m_delegate.get();
862     if (!delegate)
863         return;
864
865     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webViewDidLosePointerLock:m_uiDelegate.m_webView];
866 }
867
868 #endif
869     
870 void UIDelegate::UIClient::hasVideoInPictureInPictureDidChange(WebKit::WebPageProxy*, bool hasVideoInPictureInPicture)
871 {
872     if (!m_uiDelegate.m_delegateMethods.webViewHasVideoInPictureInPictureDidChange)
873         return;
874     
875     auto delegate = m_uiDelegate.m_delegate.get();
876     if (!delegate)
877         return;
878     
879     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView hasVideoInPictureInPictureDidChange:hasVideoInPictureInPicture];
880 }
881
882 void UIDelegate::UIClient::imageOrMediaDocumentSizeChanged(const WebCore::IntSize& newSize)
883 {
884     if (!m_uiDelegate.m_delegateMethods.webViewImageOrMediaDocumentSizeChanged)
885         return;
886
887     auto delegate = m_uiDelegate.m_delegate.get();
888     if (!delegate)
889         return;
890
891     [static_cast<id <WKUIDelegatePrivate>>(delegate) _webView:m_uiDelegate.m_webView imageOrMediaDocumentSizeChanged:newSize];
892 }
893
894 } // namespace WebKit
895
896 #endif // WK_API_ENABLED